|
|
@@ -6,6 +6,7 @@ package prober
|
|
|
import (
|
|
|
"bytes"
|
|
|
"context"
|
|
|
+ "crypto/ecdsa"
|
|
|
"crypto/rand"
|
|
|
"crypto/rsa"
|
|
|
"crypto/tls"
|
|
|
@@ -140,16 +141,60 @@ func (s *CRLServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
|
w.Write(s.crlBytes)
|
|
|
}
|
|
|
|
|
|
-func TestCRL(t *testing.T) {
|
|
|
- // Generate CA key and self-signed CA cert
|
|
|
- caKey, err := rsa.GenerateKey(rand.Reader, 4096)
|
|
|
+// someECDSAKey{1,2,3} are different EC private keys in PEM format
|
|
|
+// as generated by:
|
|
|
+//
|
|
|
+// openssl ecparam -name prime256v1 -genkey -noout -out -
|
|
|
+//
|
|
|
+// They're used in tests to avoid burning CPU at test time to just
|
|
|
+// to make some arbitrary test keys.
|
|
|
+const (
|
|
|
+ someECDSAKey1 = `
|
|
|
+-----BEGIN EC PRIVATE KEY-----
|
|
|
+MHcCAQEEIDKggO47Si0/JgqF0q9m0HfQ92lbERWsBaKS5YihtuheoAoGCCqGSM49
|
|
|
+AwEHoUQDQgAE/JtNZkfFmAGQJHW5Xgz0Eoyi9MKVxl77sXjIFDMX233QDIWPEM/B
|
|
|
+vmNMvdFkuYBjwbq6H+SNf1NXRNladEGU/Q==
|
|
|
+-----END EC PRIVATE KEY-----
|
|
|
+`
|
|
|
+ someECDSAKey2 = `
|
|
|
+-----BEGIN EC PRIVATE KEY-----
|
|
|
+MHcCAQEEIPIJhRf4MpzLil1ZKcRqMx+jPeJXw96KtYYzV2AcgBzgoAoGCCqGSM49
|
|
|
+AwEHoUQDQgAEhA9CSWFmUvdvXMzyt+as+6f+0luydHU1x/gEksVByYIgYxahaGts
|
|
|
+xbSKj6F2WgAN/ok1gFLqhH3UWMNVthM1wA==
|
|
|
+-----END EC PRIVATE KEY-----
|
|
|
+`
|
|
|
+ someECDSAKey3 = `
|
|
|
+-----BEGIN EC PRIVATE KEY-----
|
|
|
+MHcCAQEEIKgZ1OJjK2St9O0i52N1K+IgSiu2/NSMk9Yt2+kDMHd7oAoGCCqGSM49
|
|
|
+AwEHoUQDQgAExFp80etkjy/AEUtSgJjXRA39jTU7eiEmCGRREewFQhwcEscBEfrg
|
|
|
+6NN31r9YlEs+hZ8gXE1L3Deu6jn5jW3pig==
|
|
|
+-----END EC PRIVATE KEY-----
|
|
|
+`
|
|
|
+)
|
|
|
+
|
|
|
+// parseECKey parses an EC private key from a PEM-encoded string.
|
|
|
+func parseECKey(t *testing.T, pemPriv string) *ecdsa.PrivateKey {
|
|
|
+ t.Helper()
|
|
|
+ block, _ := pem.Decode([]byte(pemPriv))
|
|
|
+ if block == nil {
|
|
|
+ t.Fatal("failed to decode PEM")
|
|
|
+ }
|
|
|
+ key, err := x509.ParseECPrivateKey(block.Bytes)
|
|
|
if err != nil {
|
|
|
- t.Fatal(err)
|
|
|
+ t.Fatalf("failed to parse EC key: %v", err)
|
|
|
}
|
|
|
+ return key
|
|
|
+}
|
|
|
+
|
|
|
+func TestCRL(t *testing.T) {
|
|
|
+ // Generate CA key and self-signed CA cert
|
|
|
+ caKey := parseECKey(t, someECDSAKey1)
|
|
|
+
|
|
|
caTpl := issuerCertTpl
|
|
|
caTpl.BasicConstraintsValid = true
|
|
|
caTpl.IsCA = true
|
|
|
caTpl.KeyUsage = x509.KeyUsageCertSign | x509.KeyUsageCRLSign | x509.KeyUsageDigitalSignature
|
|
|
+ caTpl.SignatureAlgorithm = x509.ECDSAWithSHA256
|
|
|
caBytes, err := x509.CreateCertificate(rand.Reader, &caTpl, &caTpl, &caKey.PublicKey, caKey)
|
|
|
if err != nil {
|
|
|
t.Fatal(err)
|
|
|
@@ -162,11 +207,9 @@ func TestCRL(t *testing.T) {
|
|
|
// Issue a leaf cert signed by the CA
|
|
|
leaf := leafCert
|
|
|
leaf.SerialNumber = big.NewInt(20001)
|
|
|
+ leaf.SignatureAlgorithm = x509.ECDSAWithSHA256
|
|
|
leaf.Issuer = caCert.Subject
|
|
|
- leafKey, err := rsa.GenerateKey(rand.Reader, 4096)
|
|
|
- if err != nil {
|
|
|
- t.Fatal(err)
|
|
|
- }
|
|
|
+ leafKey := parseECKey(t, someECDSAKey2)
|
|
|
leafBytes, err := x509.CreateCertificate(rand.Reader, &leaf, caCert, &leafKey.PublicKey, caKey)
|
|
|
if err != nil {
|
|
|
t.Fatal(err)
|
|
|
@@ -182,10 +225,8 @@ func TestCRL(t *testing.T) {
|
|
|
noCRLCert.CRLDistributionPoints = []string{}
|
|
|
noCRLCert.NotBefore = time.Unix(letsEncryptStartedStaplingCRL, 0).Add(-48 * time.Hour)
|
|
|
noCRLCert.Issuer = caCert.Subject
|
|
|
- noCRLCertKey, err := rsa.GenerateKey(rand.Reader, 4096)
|
|
|
- if err != nil {
|
|
|
- t.Fatal(err)
|
|
|
- }
|
|
|
+ noCRLCert.SignatureAlgorithm = x509.ECDSAWithSHA256
|
|
|
+ noCRLCertKey := parseECKey(t, someECDSAKey3)
|
|
|
noCRLStapledBytes, err := x509.CreateCertificate(rand.Reader, &noCRLCert, caCert, &noCRLCertKey.PublicKey, caKey)
|
|
|
if err != nil {
|
|
|
t.Fatal(err)
|