@@ -11,6 +11,7 @@ import (
11
11
"crypto"
12
12
"crypto/ecdsa"
13
13
"crypto/elliptic"
14
+ "crypto/ed25519"
14
15
"crypto/rand"
15
16
"crypto/rsa"
16
17
_ "crypto/sha1"
@@ -151,6 +152,7 @@ var (
151
152
oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier {1 , 2 , 840 , 10045 , 4 , 3 , 2 }
152
153
oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier {1 , 2 , 840 , 10045 , 4 , 3 , 3 }
153
154
oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier {1 , 2 , 840 , 10045 , 4 , 3 , 4 }
155
+ oidSignatureEd25519 = asn1.ObjectIdentifier {1 , 3 , 101 , 112 }
154
156
)
155
157
156
158
var hashOIDs = map [crypto.Hash ]asn1.ObjectIdentifier {
@@ -179,6 +181,7 @@ var signatureAlgorithmDetails = []struct {
179
181
{x509 .ECDSAWithSHA256 , oidSignatureECDSAWithSHA256 , x509 .ECDSA , crypto .SHA256 },
180
182
{x509 .ECDSAWithSHA384 , oidSignatureECDSAWithSHA384 , x509 .ECDSA , crypto .SHA384 },
181
183
{x509 .ECDSAWithSHA512 , oidSignatureECDSAWithSHA512 , x509 .ECDSA , crypto .SHA512 },
184
+ {x509 .PureEd25519 , oidSignatureEd25519 , x509 .Ed25519 , crypto .Hash (0 ) /* no pre-hashing */ },
182
185
}
183
186
184
187
// 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
211
214
err = errors .New ("x509: unknown elliptic curve" )
212
215
}
213
216
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
+
214
223
default :
215
- err = errors .New ("x509: only RSA and ECDSA keys supported" )
224
+ err = errors .New ("x509: only RSA, ECDSA, and Ed25519 keys supported" )
216
225
}
217
226
218
227
if err != nil {
@@ -231,7 +240,8 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo x509.SignatureA
231
240
return
232
241
}
233
242
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 {
235
245
err = errors .New ("x509: cannot sign with hash function requested" )
236
246
return
237
247
}
@@ -758,9 +768,18 @@ func CreateResponse(issuer, responderCert *x509.Certificate, template Response,
758
768
return nil , err
759
769
}
760
770
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
+
764
783
if err != nil {
765
784
return nil , err
766
785
}
0 commit comments