@@ -11,6 +11,7 @@ import (
1111 "crypto"
1212 "crypto/ecdsa"
1313 "crypto/elliptic"
14+ "crypto/ed25519"
1415 "crypto/rand"
1516 "crypto/rsa"
1617 _ "crypto/sha1"
@@ -151,6 +152,7 @@ var (
151152 oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier {1 , 2 , 840 , 10045 , 4 , 3 , 2 }
152153 oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier {1 , 2 , 840 , 10045 , 4 , 3 , 3 }
153154 oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier {1 , 2 , 840 , 10045 , 4 , 3 , 4 }
155+ oidSignatureEd25519 = asn1.ObjectIdentifier {1 , 3 , 101 , 112 }
154156)
155157
156158var hashOIDs = map [crypto.Hash ]asn1.ObjectIdentifier {
@@ -179,6 +181,7 @@ var signatureAlgorithmDetails = []struct {
179181 {x509 .ECDSAWithSHA256 , oidSignatureECDSAWithSHA256 , x509 .ECDSA , crypto .SHA256 },
180182 {x509 .ECDSAWithSHA384 , oidSignatureECDSAWithSHA384 , x509 .ECDSA , crypto .SHA384 },
181183 {x509 .ECDSAWithSHA512 , oidSignatureECDSAWithSHA512 , x509 .ECDSA , crypto .SHA512 },
184+ {x509 .PureEd25519 , oidSignatureEd25519 , x509 .Ed25519 , crypto .Hash (0 ) /* no pre-hashing */ },
182185}
183186
184187// 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
211214 err = errors .New ("x509: unknown elliptic curve" )
212215 }
213216
217+ case ed25519.PublicKey :
218+ pubType = x509 .Ed25519
219+ hashFunc = 0 // EdDSA does not use external hash
220+ sigAlgo .Algorithm = oidSignatureEd25519
221+ // Do not set sigAlgo.Parameters — RFC 8410 says it MUST be absent
222+
214223 default :
215- err = errors .New ("x509: only RSA and ECDSA keys supported" )
224+ err = errors .New ("x509: only RSA, ECDSA, and Ed25519 keys supported" )
216225 }
217226
218227 if err != nil {
@@ -231,7 +240,8 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo x509.SignatureA
231240 return
232241 }
233242 sigAlgo .Algorithm , hashFunc = details .oid , details .hash
234- if hashFunc == 0 {
243+ // EdDSA is special: hashFunc can be 0
244+ if details .hash == 0 && requestedSigAlgo != x509 .PureEd25519 {
235245 err = errors .New ("x509: cannot sign with hash function requested" )
236246 return
237247 }
@@ -758,9 +768,18 @@ func CreateResponse(issuer, responderCert *x509.Certificate, template Response,
758768 return nil , err
759769 }
760770
761- responseHash := hashFunc .New ()
762- responseHash .Write (tbsResponseDataDER )
763- signature , err := priv .Sign (rand .Reader , responseHash .Sum (nil ), hashFunc )
771+ var digest []byte
772+ if hashFunc == crypto .Hash (0 ) {
773+ // Ed25519 and similar: sign raw DER
774+ digest = tbsResponseDataDER
775+ } else {
776+ h := hashFunc .New ()
777+ h .Write (tbsResponseDataDER )
778+ digest = h .Sum (nil )
779+ }
780+
781+ signature , err := priv .Sign (rand .Reader , digest , hashFunc )
782+
764783 if err != nil {
765784 return nil , err
766785 }
0 commit comments