mirror of
https://github.com/golang/go
synced 2024-11-23 23:10:09 -07:00
crypto/x509: allow ECDSA public keys to be marshaled.
The public key serialization from CreateCertificate is factored out to be used in MarshalPKIXPublicKey. Testcode with one P224 ECDSA keypair has been added. R=golang-dev, agl CC=agl, golang-dev https://golang.org/cl/13427044
This commit is contained in:
parent
4c56457d58
commit
4874bc9b76
@ -45,33 +45,55 @@ func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error) {
|
|||||||
return parsePublicKey(algo, &pki)
|
return parsePublicKey(algo, &pki)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalPKIXPublicKey serialises a public key to DER-encoded PKIX format.
|
func marshalPublicKey(pub interface{}) (publicKeyBytes []byte, publicKeyAlgorithm pkix.AlgorithmIdentifier, err error) {
|
||||||
func MarshalPKIXPublicKey(pub interface{}) ([]byte, error) {
|
|
||||||
var pubBytes []byte
|
|
||||||
|
|
||||||
switch pub := pub.(type) {
|
switch pub := pub.(type) {
|
||||||
case *rsa.PublicKey:
|
case *rsa.PublicKey:
|
||||||
pubBytes, _ = asn1.Marshal(rsaPublicKey{
|
publicKeyBytes, err = asn1.Marshal(rsaPublicKey{
|
||||||
N: pub.N,
|
N: pub.N,
|
||||||
E: pub.E,
|
E: pub.E,
|
||||||
})
|
})
|
||||||
|
publicKeyAlgorithm.Algorithm = oidPublicKeyRSA
|
||||||
|
// This is a NULL parameters value which is technically
|
||||||
|
// superfluous, but most other code includes it and, by
|
||||||
|
// doing this, we match their public key hashes.
|
||||||
|
publicKeyAlgorithm.Parameters = asn1.RawValue{
|
||||||
|
Tag: 5,
|
||||||
|
}
|
||||||
|
case *ecdsa.PublicKey:
|
||||||
|
publicKeyBytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y)
|
||||||
|
oid, ok := oidFromNamedCurve(pub.Curve)
|
||||||
|
if !ok {
|
||||||
|
return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: unsupported elliptic curve")
|
||||||
|
}
|
||||||
|
publicKeyAlgorithm.Algorithm = oidPublicKeyECDSA
|
||||||
|
var paramBytes []byte
|
||||||
|
paramBytes, err = asn1.Marshal(oid)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
publicKeyAlgorithm.Parameters.FullBytes = paramBytes
|
||||||
default:
|
default:
|
||||||
return nil, errors.New("x509: unknown public key type")
|
return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: only RSA and ECDSA public keys supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
return publicKeyBytes, publicKeyAlgorithm, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalPKIXPublicKey serialises a public key to DER-encoded PKIX format.
|
||||||
|
func MarshalPKIXPublicKey(pub interface{}) ([]byte, error) {
|
||||||
|
var publicKeyBytes []byte
|
||||||
|
var publicKeyAlgorithm pkix.AlgorithmIdentifier
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(pub); err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pkix := pkixPublicKey{
|
pkix := pkixPublicKey{
|
||||||
Algo: pkix.AlgorithmIdentifier{
|
Algo: publicKeyAlgorithm,
|
||||||
Algorithm: []int{1, 2, 840, 113549, 1, 1, 1},
|
|
||||||
// This is a NULL parameters value which is technically
|
|
||||||
// superfluous, but most other code includes it and, by
|
|
||||||
// doing this, we match their public key hashes.
|
|
||||||
Parameters: asn1.RawValue{
|
|
||||||
Tag: 5,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
BitString: asn1.BitString{
|
BitString: asn1.BitString{
|
||||||
Bytes: pubBytes,
|
Bytes: publicKeyBytes,
|
||||||
BitLength: 8 * len(pubBytes),
|
BitLength: 8 * len(publicKeyBytes),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1338,28 +1360,8 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub interf
|
|||||||
var publicKeyBytes []byte
|
var publicKeyBytes []byte
|
||||||
var publicKeyAlgorithm pkix.AlgorithmIdentifier
|
var publicKeyAlgorithm pkix.AlgorithmIdentifier
|
||||||
|
|
||||||
switch pub := pub.(type) {
|
if publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(pub); err != nil {
|
||||||
case *rsa.PublicKey:
|
return nil, err
|
||||||
publicKeyBytes, err = asn1.Marshal(rsaPublicKey{
|
|
||||||
N: pub.N,
|
|
||||||
E: pub.E,
|
|
||||||
})
|
|
||||||
publicKeyAlgorithm.Algorithm = oidPublicKeyRSA
|
|
||||||
case *ecdsa.PublicKey:
|
|
||||||
oid, ok := oidFromNamedCurve(pub.Curve)
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("x509: unknown elliptic curve")
|
|
||||||
}
|
|
||||||
publicKeyAlgorithm.Algorithm = oidPublicKeyECDSA
|
|
||||||
var paramBytes []byte
|
|
||||||
paramBytes, err = asn1.Marshal(oid)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
publicKeyAlgorithm.Parameters.FullBytes = paramBytes
|
|
||||||
publicKeyBytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y)
|
|
||||||
default:
|
|
||||||
return nil, errors.New("x509: only RSA and ECDSA public keys supported")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var signatureAlgorithm pkix.AlgorithmIdentifier
|
var signatureAlgorithm pkix.AlgorithmIdentifier
|
||||||
|
Loading…
Reference in New Issue
Block a user