|
|
|
|
@ -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) |
|
|
|
|
|