diff options
| author | Nicholas Sullivan <nicholas.sullivan@gmail.com> | 2013-09-12 12:23:34 -0400 |
|---|---|---|
| committer | Adam Langley <agl@golang.org> | 2013-09-12 12:23:34 -0400 |
| commit | 4874bc9b76da2362cdec0a8c6b56cd740d45c5ad (patch) | |
| tree | db91271e74221fecf6571af9f320fceabbd90b5b /src/pkg | |
| parent | 4c56457d5882cfd8f3f697921f94de7d6c162577 (diff) | |
| download | go-4874bc9b76da2362cdec0a8c6b56cd740d45c5ad.tar.xz | |
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
Diffstat (limited to 'src/pkg')
| -rw-r--r-- | src/pkg/crypto/x509/x509.go | 80 |
1 files changed, 41 insertions, 39 deletions
diff --git a/src/pkg/crypto/x509/x509.go b/src/pkg/crypto/x509/x509.go index 4abe1f0848..57f68ba7ed 100644 --- a/src/pkg/crypto/x509/x509.go +++ b/src/pkg/crypto/x509/x509.go @@ -45,33 +45,55 @@ func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error) { return parsePublicKey(algo, &pki) } -// MarshalPKIXPublicKey serialises a public key to DER-encoded PKIX format. -func MarshalPKIXPublicKey(pub interface{}) ([]byte, error) { - var pubBytes []byte - +func marshalPublicKey(pub interface{}) (publicKeyBytes []byte, publicKeyAlgorithm pkix.AlgorithmIdentifier, err error) { switch pub := pub.(type) { case *rsa.PublicKey: - pubBytes, _ = asn1.Marshal(rsaPublicKey{ + publicKeyBytes, err = asn1.Marshal(rsaPublicKey{ N: pub.N, 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: - 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{ - Algo: pkix.AlgorithmIdentifier{ - 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, - }, - }, + Algo: publicKeyAlgorithm, BitString: asn1.BitString{ - Bytes: pubBytes, - BitLength: 8 * len(pubBytes), + Bytes: publicKeyBytes, + BitLength: 8 * len(publicKeyBytes), }, } @@ -1338,28 +1360,8 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub interf var publicKeyBytes []byte var publicKeyAlgorithm pkix.AlgorithmIdentifier - switch pub := pub.(type) { - case *rsa.PublicKey: - 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") + if publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(pub); err != nil { + return nil, err } var signatureAlgorithm pkix.AlgorithmIdentifier |
