]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/x509: fix CreateCRL for Ed25519 CAs
authorLorenz Brun <lorenz@brun.one>
Wed, 30 Oct 2019 02:29:23 +0000 (02:29 +0000)
committerFilippo Valsorda <filippo@golang.org>
Mon, 11 Nov 2019 18:00:18 +0000 (18:00 +0000)
This makes Ed25519 certificates work for CreateCRL(). This previously
failed (panic: crypto: requested hash function #0 is unavailable) because
the hash could not be skipped, but Ed25519 uses no hash.

A similar fix has been applied in a few other places when Ed25519 was added
when Ed25519 certificates were originally introduced, but was missed
here.

Change-Id: I16fcfcd53ba3bb8f773e5de972b8fedde1f6350e

Change-Id: I16fcfcd53ba3bb8f773e5de972b8fedde1f6350e
GitHub-Last-Rev: bf7f1458f850d01605c619c3f53f86649477dd4d
GitHub-Pull-Request: golang/go#35241
Reviewed-on: https://go-review.googlesource.com/c/go/+/204046
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
src/crypto/x509/x509.go
src/crypto/x509/x509_test.go

index cc382e52c64d3396611e26f0a526421c129dea24..013f1c996d9a0c735cfb8ae9139dc8f724432a68 100644 (file)
@@ -2256,12 +2256,15 @@ func (c *Certificate) CreateCRL(rand io.Reader, priv interface{}, revokedCerts [
                return
        }
 
-       h := hashFunc.New()
-       h.Write(tbsCertListContents)
-       digest := h.Sum(nil)
+       signed := tbsCertListContents
+       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
        }
index d5b168e78ff55704924cdfc692acb205b0ee961d..9e15b8adbfe068b0ef1ae9ac24e3cc341da6e4f7 100644 (file)
@@ -1193,11 +1193,77 @@ KVcg7fBd484ht/sS+l0dsB4KDOSpd8JzVDMF8OZqlaydizoJO0yWr9GbCN1+OKq5
 EhLrEqU=
 -----END CERTIFICATE-----`
 
+const ed25519CRLCertificate = `
+Certificate:
+Data:
+       Version: 3 (0x2)
+       Serial Number:
+               7a:07:a0:9d:14:04:16:fc:1f:d8:e5:fe:d1:1d:1f:8d
+       Signature Algorithm: ED25519
+       Issuer: CN = Ed25519 CRL Test CA
+       Validity
+               Not Before: Oct 30 01:20:20 2019 GMT
+               Not After : Dec 31 23:59:59 9999 GMT
+       Subject: CN = Ed25519 CRL Test CA
+       Subject Public Key Info:
+               Public Key Algorithm: ED25519
+                       ED25519 Public-Key:
+                       pub:
+                               95:73:3b:b0:06:2a:31:5a:b6:a7:a6:6e:ef:71:df:
+                               ac:6f:6b:39:03:85:5e:63:4b:f8:a6:0f:68:c6:6f:
+                               75:21
+       X509v3 extensions:
+               X509v3 Key Usage: critical
+                       Digital Signature, Certificate Sign, CRL Sign
+               X509v3 Extended Key Usage: 
+                       TLS Web Client Authentication, TLS Web Server Authentication, OCSP Signing
+               X509v3 Basic Constraints: critical
+                       CA:TRUE
+               X509v3 Subject Key Identifier: 
+                       B7:17:DA:16:EA:C5:ED:1F:18:49:44:D3:D2:E3:A0:35:0A:81:93:60
+               X509v3 Authority Key Identifier: 
+                       keyid:B7:17:DA:16:EA:C5:ED:1F:18:49:44:D3:D2:E3:A0:35:0A:81:93:60
+
+Signature Algorithm: ED25519
+        fc:3e:14:ea:bb:70:c2:6f:38:34:70:bc:c8:a7:f4:7c:0d:1e:
+        28:d7:2a:9f:22:8a:45:e8:02:76:84:1e:2d:64:2d:1e:09:b5:
+        29:71:1f:95:8a:4e:79:87:51:60:9a:e7:86:40:f6:60:c7:d1:
+        ee:68:76:17:1d:90:cc:92:93:07
+-----BEGIN CERTIFICATE-----
+MIIBijCCATygAwIBAgIQegegnRQEFvwf2OX+0R0fjTAFBgMrZXAwHjEcMBoGA1UE
+AxMTRWQyNTUxOSBDUkwgVGVzdCBDQTAgFw0xOTEwMzAwMTIwMjBaGA85OTk5MTIz
+MTIzNTk1OVowHjEcMBoGA1UEAxMTRWQyNTUxOSBDUkwgVGVzdCBDQTAqMAUGAytl
+cAMhAJVzO7AGKjFatqembu9x36xvazkDhV5jS/imD2jGb3Uho4GNMIGKMA4GA1Ud
+DwEB/wQEAwIBhjAnBgNVHSUEIDAeBggrBgEFBQcDAgYIKwYBBQUHAwEGCCsGAQUF
+BwMJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLcX2hbqxe0fGElE09LjoDUK
+gZNgMB8GA1UdIwQYMBaAFLcX2hbqxe0fGElE09LjoDUKgZNgMAUGAytlcANBAPw+
+FOq7cMJvODRwvMin9HwNHijXKp8iikXoAnaEHi1kLR4JtSlxH5WKTnmHUWCa54ZA
+9mDH0e5odhcdkMySkwc=
+-----END CERTIFICATE-----`
+
+const ed25519CRLKey = `-----BEGIN PRIVATE KEY-----
+MC4CAQAwBQYDK2VwBCIEINdKh2096vUBYu4EIFpjShsUSh3vimKya1sQ1YTT4RZG
+-----END PRIVATE KEY-----`
+
 func TestCRLCreation(t *testing.T) {
        block, _ := pem.Decode([]byte(pemPrivateKey))
-       priv, _ := ParsePKCS1PrivateKey(block.Bytes)
+       privRSA, _ := ParsePKCS1PrivateKey(block.Bytes)
        block, _ = pem.Decode([]byte(pemCertificate))
-       cert, _ := ParseCertificate(block.Bytes)
+       certRSA, _ := ParseCertificate(block.Bytes)
+
+       block, _ = pem.Decode([]byte(ed25519CRLKey))
+       privEd25519, _ := ParsePKCS8PrivateKey(block.Bytes)
+       block, _ = pem.Decode([]byte(ed25519CRLCertificate))
+       certEd25519, _ := ParseCertificate(block.Bytes)
+
+       tests := []struct {
+               name string
+               priv interface{}
+               cert *Certificate
+       }{
+               {"RSA CA", privRSA, certRSA},
+               {"Ed25519 CA", privEd25519, certEd25519},
+       }
 
        loc := time.FixedZone("Oz/Atlantis", int((2 * time.Hour).Seconds()))
 
@@ -1227,18 +1293,20 @@ func TestCRLCreation(t *testing.T) {
                },
        }
 
-       crlBytes, err := cert.CreateCRL(rand.Reader, priv, revokedCerts, now, expiry)
-       if err != nil {
-               t.Errorf("error creating CRL: %s", err)
-       }
+       for _, test := range tests {
+               crlBytes, err := test.cert.CreateCRL(rand.Reader, test.priv, revokedCerts, now, expiry)
+               if err != nil {
+                       t.Errorf("%s: error creating CRL: %s", test.name, err)
+               }
 
-       parsedCRL, err := ParseDERCRL(crlBytes)
-       if err != nil {
-               t.Errorf("error reparsing CRL: %s", err)
-       }
-       if !reflect.DeepEqual(parsedCRL.TBSCertList.RevokedCertificates, expectedCerts) {
-               t.Errorf("RevokedCertificates mismatch: got %v; want %v.",
-                       parsedCRL.TBSCertList.RevokedCertificates, expectedCerts)
+               parsedCRL, err := ParseDERCRL(crlBytes)
+               if err != nil {
+                       t.Errorf("%s: error reparsing CRL: %s", test.name, err)
+               }
+               if !reflect.DeepEqual(parsedCRL.TBSCertList.RevokedCertificates, expectedCerts) {
+                       t.Errorf("%s: RevokedCertificates mismatch: got %v; want %v.", test.name,
+                               parsedCRL.TBSCertList.RevokedCertificates, expectedCerts)
+               }
        }
 }