aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/crypto/x509/x509.go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2019-09-06 18:12:46 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-09-06 18:12:46 +0000
commitaa8901e9bb0399d2c16f988ba2fe46eb0c0c5d13 (patch)
tree7e63b06d1eec92beec6997c9d3ab47a5d6a835be /libgo/go/crypto/x509/x509.go
parent920ea3b8ba3164b61ac9490dfdfceb6936eda6dd (diff)
downloadgcc-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.go156
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
}