139 lines
4.9 KiB
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)
|
|
}
|
|
})
|
|
}
|
|
}
|