boulder/cmd/ceremony/ocsp_test.go

139 lines
4.9 KiB
Go

package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"math/big"
"testing"
"time"
"github.com/letsencrypt/boulder/test"
)
func TestGenerateOCSPResponse(t *testing.T) {
kA, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
test.AssertNotError(t, err, "failed to generate test key")
kB, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
test.AssertNotError(t, err, "failed to generate test key")
kC, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
test.AssertNotError(t, err, "failed to generate test key")
template := &x509.Certificate{
SerialNumber: big.NewInt(9),
Subject: pkix.Name{
CommonName: "cn",
},
KeyUsage: x509.KeyUsageCertSign,
BasicConstraintsValid: true,
IsCA: true,
NotBefore: time.Time{}.Add(time.Hour * 10),
NotAfter: time.Time{}.Add(time.Hour * 20),
}
issuerBytes, err := x509.CreateCertificate(rand.Reader, template, template, kA.Public(), kA)
test.AssertNotError(t, err, "failed to create test issuer")
issuer, err := x509.ParseCertificate(issuerBytes)
test.AssertNotError(t, err, "failed to parse test issuer")
delegatedIssuerBytes, err := x509.CreateCertificate(rand.Reader, template, issuer, kB.Public(), kA)
test.AssertNotError(t, err, "failed to create test delegated issuer")
badDelegatedIssuer, err := x509.ParseCertificate(delegatedIssuerBytes)
test.AssertNotError(t, err, "failed to parse test delegated issuer")
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageOCSPSigning}
delegatedIssuerBytes, err = x509.CreateCertificate(rand.Reader, template, issuer, kB.Public(), kA)
test.AssertNotError(t, err, "failed to create test delegated issuer")
goodDelegatedIssuer, err := x509.ParseCertificate(delegatedIssuerBytes)
test.AssertNotError(t, err, "failed to parse test delegated issuer")
template.BasicConstraintsValid, template.IsCA = false, false
certBytes, err := x509.CreateCertificate(rand.Reader, template, issuer, kC.Public(), kA)
test.AssertNotError(t, err, "failed to create test cert")
cert, err := x509.ParseCertificate(certBytes)
test.AssertNotError(t, err, "failed to parse test cert")
cases := []struct {
name string
issuer *x509.Certificate
delegatedIssuer *x509.Certificate
cert *x509.Certificate
thisUpdate time.Time
nextUpdate time.Time
expectedError string
}{
{
name: "invalid signature from issuer on certificate",
issuer: &x509.Certificate{},
cert: &x509.Certificate{},
expectedError: "invalid signature on certificate from issuer: x509: cannot verify signature: algorithm unimplemented",
},
{
name: "nextUpdate before thisUpdate",
issuer: issuer,
cert: cert,
thisUpdate: time.Time{}.Add(time.Hour),
nextUpdate: time.Time{},
expectedError: "thisUpdate must be before nextUpdate",
},
{
name: "thisUpdate before signer notBefore",
issuer: issuer,
cert: cert,
thisUpdate: time.Time{},
nextUpdate: time.Time{}.Add(time.Hour),
expectedError: "thisUpdate is before signing certificate's notBefore",
},
{
name: "nextUpdate after signer notAfter",
issuer: issuer,
cert: cert,
thisUpdate: time.Time{}.Add(time.Hour * 11),
nextUpdate: time.Time{}.Add(time.Hour * 21),
expectedError: "nextUpdate is after signing certificate's notAfter",
},
{
name: "bad delegated issuer signature",
issuer: issuer,
cert: cert,
delegatedIssuer: &x509.Certificate{},
expectedError: "invalid signature on delegated issuer from issuer: x509: cannot verify signature: algorithm unimplemented",
},
{
name: "good",
issuer: issuer,
cert: cert,
thisUpdate: time.Time{}.Add(time.Hour * 11),
nextUpdate: time.Time{}.Add(time.Hour * 12),
},
{
name: "bad delegated issuer without EKU",
issuer: issuer,
cert: cert,
delegatedIssuer: badDelegatedIssuer,
expectedError: "delegated issuer certificate doesn't contain OCSPSigning extended key usage",
},
{
name: "good delegated issuer",
issuer: issuer,
cert: cert,
delegatedIssuer: goodDelegatedIssuer,
thisUpdate: time.Time{}.Add(time.Hour * 11),
nextUpdate: time.Time{}.Add(time.Hour * 12),
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
_, err := generateOCSPResponse(kA, tc.issuer, tc.delegatedIssuer, tc.cert, tc.thisUpdate, tc.nextUpdate, 0)
if err != nil {
if tc.expectedError != "" && tc.expectedError != err.Error() {
t.Errorf("unexpected error: got %q, want %q", err.Error(), tc.expectedError)
} else if tc.expectedError == "" {
t.Errorf("unexpected error: %s", err)
}
} else if tc.expectedError != "" {
t.Errorf("expected error: %s", tc.expectedError)
}
})
}
}