diff options
author | Ian Lance Taylor <iant@golang.org> | 2019-09-06 18:12:46 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-09-06 18:12:46 +0000 |
commit | aa8901e9bb0399d2c16f988ba2fe46eb0c0c5d13 (patch) | |
tree | 7e63b06d1eec92beec6997c9d3ab47a5d6a835be /libgo/go/crypto/x509/x509.go | |
parent | 920ea3b8ba3164b61ac9490dfdfceb6936eda6dd (diff) | |
download | gcc-aa8901e9bb0399d2c16f988ba2fe46eb0c0c5d13.zip gcc-aa8901e9bb0399d2c16f988ba2fe46eb0c0c5d13.tar.gz gcc-aa8901e9bb0399d2c16f988ba2fe46eb0c0c5d13.tar.bz2 |
libgo: update to Go 1.13beta1 release
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/193497
From-SVN: r275473
Diffstat (limited to 'libgo/go/crypto/x509/x509.go')
-rw-r--r-- | libgo/go/crypto/x509/x509.go | 156 |
1 files changed, 109 insertions, 47 deletions
diff --git a/libgo/go/crypto/x509/x509.go b/libgo/go/crypto/x509/x509.go index 58098ad..1cd8fde 100644 --- a/libgo/go/crypto/x509/x509.go +++ b/libgo/go/crypto/x509/x509.go @@ -14,6 +14,7 @@ import ( "crypto" "crypto/dsa" "crypto/ecdsa" + "crypto/ed25519" "crypto/elliptic" "crypto/rsa" _ "crypto/sha1" @@ -24,8 +25,8 @@ import ( "encoding/pem" "errors" "fmt" - "internal/x/crypto/cryptobyte" - cryptobyte_asn1 "internal/x/crypto/cryptobyte/asn1" + "golang.org/x/crypto/cryptobyte" + cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1" "io" "math/big" "net" @@ -43,17 +44,18 @@ type pkixPublicKey struct { BitString asn1.BitString } -// ParsePKIXPublicKey parses a DER encoded public key. These values are -// typically found in PEM blocks with "BEGIN PUBLIC KEY". +// ParsePKIXPublicKey parses a public key in PKIX, ASN.1 DER form. // -// Supported key types include RSA, DSA, and ECDSA. Unknown key -// types result in an error. +// It returns a *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey, or +// ed25519.PublicKey. More types might be supported in the future. // -// On success, pub will be of type *rsa.PublicKey, *dsa.PublicKey, -// or *ecdsa.PublicKey. +// This kind of key is commonly encoded in PEM blocks of type "PUBLIC KEY". func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error) { var pki publicKeyInfo if rest, err := asn1.Unmarshal(derBytes, &pki); err != nil { + if _, err := asn1.Unmarshal(derBytes, &pkcs1PublicKey{}); err == nil { + return nil, errors.New("x509: failed to parse public key (use ParsePKCS1PublicKey instead for this key format)") + } return nil, err } else if len(rest) != 0 { return nil, errors.New("x509: trailing data after ASN.1 of public-key") @@ -92,6 +94,9 @@ func marshalPublicKey(pub interface{}) (publicKeyBytes []byte, publicKeyAlgorith return } publicKeyAlgorithm.Parameters.FullBytes = paramBytes + case ed25519.PublicKey: + publicKeyBytes = pub + publicKeyAlgorithm.Algorithm = oidPublicKeyEd25519 default: return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: only RSA and ECDSA public keys supported") } @@ -99,7 +104,12 @@ func marshalPublicKey(pub interface{}) (publicKeyBytes []byte, publicKeyAlgorith return publicKeyBytes, publicKeyAlgorithm, nil } -// MarshalPKIXPublicKey serialises a public key to DER-encoded PKIX format. +// MarshalPKIXPublicKey converts a public key to PKIX, ASN.1 DER form. +// +// The following key types are currently supported: *rsa.PublicKey, *ecdsa.PublicKey +// and ed25519.PublicKey. Unsupported key types result in an error. +// +// This kind of key is commonly encoded in PEM blocks of type "PUBLIC KEY". func MarshalPKIXPublicKey(pub interface{}) ([]byte, error) { var publicKeyBytes []byte var publicKeyAlgorithm pkix.AlgorithmIdentifier @@ -188,6 +198,7 @@ const ( SHA256WithRSAPSS SHA384WithRSAPSS SHA512WithRSAPSS + PureEd25519 ) func (algo SignatureAlgorithm) isRSAPSS() bool { @@ -215,12 +226,14 @@ const ( RSA DSA ECDSA + Ed25519 ) var publicKeyAlgoName = [...]string{ - RSA: "RSA", - DSA: "DSA", - ECDSA: "ECDSA", + RSA: "RSA", + DSA: "DSA", + ECDSA: "ECDSA", + Ed25519: "Ed25519", } func (algo PublicKeyAlgorithm) String() string { @@ -279,6 +292,11 @@ func (algo PublicKeyAlgorithm) String() string { // // ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) // us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 } +// +// +// RFC 8410 3 Curve25519 and Curve448 Algorithm Identifiers +// +// id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 } var ( oidSignatureMD2WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2} @@ -294,6 +312,7 @@ var ( oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2} oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3} oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4} + oidSignatureEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112} oidSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1} oidSHA384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2} @@ -330,6 +349,7 @@ var signatureAlgorithmDetails = []struct { {ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, ECDSA, crypto.SHA256}, {ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, ECDSA, crypto.SHA384}, {ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, ECDSA, crypto.SHA512}, + {PureEd25519, "Ed25519", oidSignatureEd25519, Ed25519, crypto.Hash(0) /* no pre-hashing */}, } // pssParameters reflects the parameters in an AlgorithmIdentifier that @@ -390,6 +410,14 @@ func rsaPSSParameters(hashFunc crypto.Hash) asn1.RawValue { } func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) SignatureAlgorithm { + if ai.Algorithm.Equal(oidSignatureEd25519) { + // RFC 8410, Section 3 + // > For all of the OIDs, the parameters MUST be absent. + if len(ai.Parameters.FullBytes) != 0 { + return UnknownSignatureAlgorithm + } + } + if !ai.Algorithm.Equal(oidSignatureRSAPSS) { for _, details := range signatureAlgorithmDetails { if ai.Algorithm.Equal(details.oid) { @@ -452,9 +480,10 @@ func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) SignatureAlgorithm // id-ecPublicKey OBJECT IDENTIFIER ::= { // iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 } var ( - oidPublicKeyRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1} - oidPublicKeyDSA = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1} - oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1} + oidPublicKeyRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1} + oidPublicKeyDSA = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1} + oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1} + oidPublicKeyEd25519 = oidSignatureEd25519 ) func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) PublicKeyAlgorithm { @@ -465,6 +494,8 @@ func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) PublicKeyAlgorithm return DSA case oid.Equal(oidPublicKeyECDSA): return ECDSA + case oid.Equal(oidPublicKeyEd25519): + return Ed25519 } return UnknownPublicKeyAlgorithm } @@ -871,28 +902,29 @@ func checkSignature(algo SignatureAlgorithm, signed, signature []byte, publicKey switch hashType { case crypto.Hash(0): - return ErrUnsupportedAlgorithm + if pubKeyAlgo != Ed25519 { + return ErrUnsupportedAlgorithm + } case crypto.MD5: return InsecureAlgorithmError(algo) + default: + if !hashType.Available() { + return ErrUnsupportedAlgorithm + } + h := hashType.New() + h.Write(signed) + signed = h.Sum(nil) } - if !hashType.Available() { - return ErrUnsupportedAlgorithm - } - h := hashType.New() - - h.Write(signed) - digest := h.Sum(nil) - switch pub := publicKey.(type) { case *rsa.PublicKey: if pubKeyAlgo != RSA { return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub) } if algo.isRSAPSS() { - return rsa.VerifyPSS(pub, hashType, digest, signature, &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash}) + return rsa.VerifyPSS(pub, hashType, signed, signature, &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash}) } else { - return rsa.VerifyPKCS1v15(pub, hashType, digest, signature) + return rsa.VerifyPKCS1v15(pub, hashType, signed, signature) } case *dsa.PublicKey: if pubKeyAlgo != DSA { @@ -907,7 +939,7 @@ func checkSignature(algo SignatureAlgorithm, signed, signature []byte, publicKey if dsaSig.R.Sign() <= 0 || dsaSig.S.Sign() <= 0 { return errors.New("x509: DSA signature contained zero or negative values") } - if !dsa.Verify(pub, digest, dsaSig.R, dsaSig.S) { + if !dsa.Verify(pub, signed, dsaSig.R, dsaSig.S) { return errors.New("x509: DSA verification failure") } return @@ -924,10 +956,18 @@ func checkSignature(algo SignatureAlgorithm, signed, signature []byte, publicKey if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { return errors.New("x509: ECDSA signature contained zero or negative values") } - if !ecdsa.Verify(pub, digest, ecdsaSig.R, ecdsaSig.S) { + if !ecdsa.Verify(pub, signed, ecdsaSig.R, ecdsaSig.S) { return errors.New("x509: ECDSA verification failure") } return + case ed25519.PublicKey: + if pubKeyAlgo != Ed25519 { + return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub) + } + if !ed25519.Verify(pub, signed, signature) { + return errors.New("x509: Ed25519 verification failure") + } + return } return ErrUnsupportedAlgorithm } @@ -1065,6 +1105,18 @@ func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{ Y: y, } return pub, nil + case Ed25519: + // RFC 8410, Section 3 + // > For all of the OIDs, the parameters MUST be absent. + if len(keyData.Algorithm.Parameters.FullBytes) != 0 { + return nil, errors.New("x509: Ed25519 key encoded with illegal parameters") + } + if len(asn1Data) != ed25519.PublicKeySize { + return nil, errors.New("x509: wrong Ed25519 public key size") + } + pub := make([]byte, ed25519.PublicKeySize) + copy(pub, asn1Data) + return ed25519.PublicKey(pub), nil default: return nil, nil } @@ -1927,7 +1979,7 @@ func buildExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId dp := distributionPoint{ DistributionPoint: distributionPointName{ FullName: []asn1.RawValue{ - asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)}, + {Tag: 6, Class: 2, Bytes: []byte(name)}, }, }, } @@ -1986,8 +2038,12 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgori err = errors.New("x509: unknown elliptic curve") } + case ed25519.PublicKey: + pubType = Ed25519 + sigAlgo.Algorithm = oidSignatureEd25519 + default: - err = errors.New("x509: only RSA and ECDSA keys supported") + err = errors.New("x509: only RSA, ECDSA and Ed25519 keys supported") } if err != nil { @@ -2006,7 +2062,7 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgori return } sigAlgo.Algorithm, hashFunc = details.oid, details.hash - if hashFunc == 0 { + if hashFunc == 0 && pubType != Ed25519 { err = errors.New("x509: cannot sign with hash function requested") return } @@ -2070,8 +2126,9 @@ var emptyASN1Subject = []byte{0x30, 0} // // The returned slice is the certificate in DER encoding. // -// All keys types that are implemented via crypto.Signer are supported (This -// includes *rsa.PublicKey and *ecdsa.PublicKey.) +// The currently supported key types are *rsa.PublicKey, *ecdsa.PublicKey and +// ed25519.PublicKey. pub must be a supported key type, and priv must be a +// crypto.Signer with a supported public key. // // The AuthorityKeyId will be taken from the SubjectKeyId of parent, if any, // unless the resulting certificate is self-signed. Otherwise the value from @@ -2132,15 +2189,16 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv if err != nil { return } - c.Raw = tbsCertContents - h := hashFunc.New() - h.Write(tbsCertContents) - digest := h.Sum(nil) + signed := tbsCertContents + if hashFunc != 0 { + h := hashFunc.New() + h.Write(signed) + signed = h.Sum(nil) + } - var signerOpts crypto.SignerOpts - signerOpts = hashFunc + var signerOpts crypto.SignerOpts = hashFunc if template.SignatureAlgorithm != 0 && template.SignatureAlgorithm.isRSAPSS() { signerOpts = &rsa.PSSOptions{ SaltLength: rsa.PSSSaltLengthEqualsHash, @@ -2149,7 +2207,7 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv } var signature []byte - signature, err = key.Sign(rand, digest, signerOpts) + signature, err = key.Sign(rand, signed, signerOpts) if err != nil { return } @@ -2275,7 +2333,7 @@ type CertificateRequest struct { // Attributes contains the CSR attributes that can parse as // pkix.AttributeTypeAndValueSET. // - // Deprecated: use Extensions and ExtraExtensions instead for parsing and + // Deprecated: Use Extensions and ExtraExtensions instead for parsing and // generating the requestedExtensions attribute. Attributes []pkix.AttributeTypeAndValueSET @@ -2400,8 +2458,9 @@ func parseCSRExtensions(rawAttributes []asn1.RawValue) ([]pkix.Extension, error) // // priv is the private key to sign the CSR with, and the corresponding public // key will be included in the CSR. It must implement crypto.Signer and its -// Public() method must return a *rsa.PublicKey or a *ecdsa.PublicKey. (A -// *rsa.PrivateKey or *ecdsa.PrivateKey satisfies this.) +// Public() method must return a *rsa.PublicKey or a *ecdsa.PublicKey or a +// ed25519.PublicKey. (A *rsa.PrivateKey, *ecdsa.PrivateKey or +// ed25519.PrivateKey satisfies this.) // // The returned slice is the certificate request in DER encoding. func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv interface{}) (csr []byte, err error) { @@ -2550,12 +2609,15 @@ func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv } tbsCSR.Raw = tbsCSRContents - h := hashFunc.New() - h.Write(tbsCSRContents) - digest := h.Sum(nil) + signed := tbsCSRContents + if hashFunc != 0 { + h := hashFunc.New() + h.Write(signed) + signed = h.Sum(nil) + } var signature []byte - signature, err = key.Sign(rand, digest, hashFunc) + signature, err = key.Sign(rand, signed, hashFunc) if err != nil { return } |