diff --git a/ocsp/ocsp.go b/ocsp/ocsp.go index e6c645e7ce..9b194bc195 100644 --- a/ocsp/ocsp.go +++ b/ocsp/ocsp.go @@ -11,6 +11,7 @@ import ( "crypto" "crypto/ecdsa" "crypto/elliptic" + "crypto/ed25519" "crypto/rand" "crypto/rsa" _ "crypto/sha1" @@ -151,6 +152,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} ) var hashOIDs = map[crypto.Hash]asn1.ObjectIdentifier{ @@ -179,6 +181,7 @@ var signatureAlgorithmDetails = []struct { {x509.ECDSAWithSHA256, oidSignatureECDSAWithSHA256, x509.ECDSA, crypto.SHA256}, {x509.ECDSAWithSHA384, oidSignatureECDSAWithSHA384, x509.ECDSA, crypto.SHA384}, {x509.ECDSAWithSHA512, oidSignatureECDSAWithSHA512, x509.ECDSA, crypto.SHA512}, + {x509.PureEd25519, oidSignatureEd25519, x509.Ed25519, crypto.Hash(0) /* no pre-hashing */}, } // TODO(rlb): This is also from crypto/x509, so same comment as AGL's below @@ -211,8 +214,14 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo x509.SignatureA err = errors.New("x509: unknown elliptic curve") } + case ed25519.PublicKey: + pubType = x509.Ed25519 + hashFunc = 0 // EdDSA does not use external hash + sigAlgo.Algorithm = oidSignatureEd25519 + // Do not set sigAlgo.Parameters — RFC 8410 says it MUST be absent + 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 { @@ -231,7 +240,8 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo x509.SignatureA return } sigAlgo.Algorithm, hashFunc = details.oid, details.hash - if hashFunc == 0 { + // EdDSA is special: hashFunc can be 0 + if details.hash == 0 && requestedSigAlgo != x509.PureEd25519 { err = errors.New("x509: cannot sign with hash function requested") return } @@ -758,9 +768,18 @@ func CreateResponse(issuer, responderCert *x509.Certificate, template Response, return nil, err } - responseHash := hashFunc.New() - responseHash.Write(tbsResponseDataDER) - signature, err := priv.Sign(rand.Reader, responseHash.Sum(nil), hashFunc) + var digest []byte + if hashFunc == crypto.Hash(0) { + // Ed25519 and similar: sign raw DER + digest = tbsResponseDataDER + } else { + h := hashFunc.New() + h.Write(tbsResponseDataDER) + digest = h.Sum(nil) + } + + signature, err := priv.Sign(rand.Reader, digest, hashFunc) + if err != nil { return nil, err }