Validate OCSP response is signed by expected issuer (#26091)

* Validate OCSP response is signed by expected issuer and serial number matches request

 - There was a bug in the OCSP response signature logic, it properly
   verified but kept around the ocspRes object around so we ignored
   the errors found and passed the response object back up the stack.
 - Now extract the verification logic into a dedicated function, if
   it returns an error, blank the ocspRes response as we can't trust it.
 - Address an issue that the OCSP requests from multiple servers were
   clobbering each others responses as the index loop variable was not
   properly captured.
 - Add a missing validation that the response was for the serial number
    we requested

* Add cl
This commit is contained in:
Steven Clark
2024-03-22 09:28:02 -04:00
committed by GitHub
parent 5a1d20bd35
commit 2fe676e75b
5 changed files with 379 additions and 65 deletions

View File

@@ -2346,6 +2346,98 @@ func TestBackend_CertUpgrade(t *testing.T) {
}
}
// TestOCSPFailOpenWithBadIssuer validates we fail all different types of cert auth
// login scenarios if we encounter an OCSP verification error
func TestOCSPFailOpenWithBadIssuer(t *testing.T) {
caFile := "test-fixtures/root/rootcacert.pem"
pemCa, err := os.ReadFile(caFile)
require.NoError(t, err, "failed reading in file %s", caFile)
caTLS := loadCerts(t, caFile, "test-fixtures/root/rootcakey.pem")
leafTLS := loadCerts(t, "test-fixtures/keys/cert.pem", "test-fixtures/keys/key.pem")
rootConfig := &rootcerts.Config{
CAFile: caFile,
}
rootCAs, err := rootcerts.LoadCACerts(rootConfig)
connState, err := testConnStateWithCert(leafTLS, rootCAs)
require.NoError(t, err, "error testing connection state: %v", err)
badCa, badCaKey := createCa(t)
// Setup an OCSP handler
ocspHandler := func(ca *x509.Certificate, caKey crypto.Signer) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
now := time.Now()
ocspRes := ocsp.Response{
SerialNumber: leafTLS.Leaf.SerialNumber,
ThisUpdate: now.Add(-1 * time.Hour),
NextUpdate: now.Add(30 * time.Minute),
Status: ocsp.Good,
}
response, err := ocsp.CreateResponse(ca, ca, ocspRes, caKey)
if err != nil {
t.Fatalf("failed generating OCSP response: %v", err)
}
_, _ = w.Write(response)
})
}
goodTs := httptest.NewServer(ocspHandler(caTLS.Leaf, caTLS.PrivateKey.(crypto.Signer)))
badTs := httptest.NewServer(ocspHandler(badCa, badCaKey))
defer goodTs.Close()
defer badTs.Close()
steps := []logicaltest.TestStep{
// step 1/2: This should fail as we get a response from a bad root, even with ocsp_fail_open is set to true
testAccStepCertWithExtraParams(t, "web", pemCa, "foo", allowed{names: "cert.example.com"}, false,
map[string]interface{}{
"ocsp_enabled": true,
"ocsp_servers_override": []string{badTs.URL},
"ocsp_query_all_servers": false,
"ocsp_fail_open": true,
}),
testAccStepLoginInvalid(t, connState),
// step 3/4: This should fail as we query all the servers which will get a response with an invalid signature
testAccStepCertWithExtraParams(t, "web", pemCa, "foo", allowed{names: "cert.example.com"}, false,
map[string]interface{}{
"ocsp_enabled": true,
"ocsp_servers_override": []string{goodTs.URL, badTs.URL},
"ocsp_query_all_servers": true,
"ocsp_fail_open": true,
}),
testAccStepLoginInvalid(t, connState),
// step 5/6: This should fail as we will query the OCSP server with the bad root key first.
testAccStepCertWithExtraParams(t, "web", pemCa, "foo", allowed{names: "cert.example.com"}, false,
map[string]interface{}{
"ocsp_enabled": true,
"ocsp_servers_override": []string{badTs.URL, goodTs.URL},
"ocsp_query_all_servers": false,
"ocsp_fail_open": true,
}),
testAccStepLoginInvalid(t, connState),
// step 7/8: This should pass as we will only query the first server with the valid root signature
testAccStepCertWithExtraParams(t, "web", pemCa, "foo", allowed{names: "cert.example.com"}, false,
map[string]interface{}{
"ocsp_enabled": true,
"ocsp_servers_override": []string{goodTs.URL, badTs.URL},
"ocsp_query_all_servers": false,
"ocsp_fail_open": true,
}),
testAccStepLogin(t, connState),
}
// Setup a new factory everytime to avoid OCSP caching from influencing the test
for i := 0; i < len(steps); i += 2 {
setup := i
execute := i + 1
t.Run(fmt.Sprintf("steps-%d-%d", setup+1, execute+1), func(t *testing.T) {
logicaltest.Test(t, logicaltest.TestCase{
CredentialBackend: testFactory(t),
Steps: []logicaltest.TestStep{steps[setup], steps[execute]},
})
})
}
}
// TestOCSPWithMixedValidResponses validates the expected behavior of multiple OCSP servers configured,
// with and without ocsp_query_all_servers enabled or disabled.
func TestOCSPWithMixedValidResponses(t *testing.T) {
@@ -2402,6 +2494,14 @@ func TestOCSPWithMixedValidResponses(t *testing.T) {
"ocsp_query_all_servers": false,
}),
testAccStepLoginInvalid(t, connState),
// step 5/6: This should fail as we will query all the OCSP servers and prefer the revoke response
testAccStepCertWithExtraParams(t, "web", pemCa, "foo",
allowed{names: "cert.example.com"}, false, map[string]interface{}{
"ocsp_enabled": true,
"ocsp_servers_override": []string{goodTs.URL, revokeTs.URL},
"ocsp_query_all_servers": true,
}),
testAccStepLoginInvalid(t, connState),
}
// Setup a new factory everytime to avoid OCSP caching from influencing the test
@@ -2496,6 +2596,28 @@ func TestOCSPFailOpenWithGoodResponse(t *testing.T) {
"ocsp_max_retries": 0,
}),
testAccStepLogin(t, connState),
// Step 9/10 With a single positive response, query all servers set to true and fail open true, pass validation
// as fail open is true
testAccStepCertWithExtraParams(t, "web", pemCa, "foo", allowed{names: "cert.example.com"}, false,
map[string]interface{}{
"ocsp_enabled": true,
"ocsp_servers_override": []string{ts.URL, "http://127.0.0.1:30001"},
"ocsp_fail_open": true,
"ocsp_query_all_servers": true,
"ocsp_max_retries": 0,
}),
testAccStepLogin(t, connState),
// Step 11/12 With a single positive response, query all servers set to true and fail open false, fail validation
// as not all servers agree
testAccStepCertWithExtraParams(t, "web", pemCa, "foo",
allowed{names: "cert.example.com"}, false, map[string]interface{}{
"ocsp_enabled": true,
"ocsp_servers_override": []string{ts.URL, "http://127.0.0.1:30001"},
"ocsp_fail_open": false,
"ocsp_query_all_servers": true,
"ocsp_max_retries": 0,
}),
testAccStepLoginInvalid(t, connState),
}
// Setup a new factory everytime to avoid OCSP caching from influencing the test
@@ -2567,6 +2689,26 @@ func TestOCSPFailOpenWithRevokeResponse(t *testing.T) {
"ocsp_max_retries": 0,
}),
testAccStepLoginInvalid(t, connState),
// Step 5/6 With a single revoke response, query all servers set to true and fail open false, fail validation
testAccStepCertWithExtraParams(t, "web", pemCa, "foo",
allowed{names: "cert.example.com"}, false, map[string]interface{}{
"ocsp_enabled": true,
"ocsp_servers_override": []string{ts.URL, "http://127.0.0.1:30001"},
"ocsp_fail_open": false,
"ocsp_query_all_servers": true,
"ocsp_max_retries": 0,
}),
testAccStepLoginInvalid(t, connState),
// Step 7/8 With a single revoke response, query all servers set to true and fail open true, fail validation
testAccStepCertWithExtraParams(t, "web", pemCa, "foo", allowed{names: "cert.example.com"}, false,
map[string]interface{}{
"ocsp_enabled": true,
"ocsp_servers_override": []string{ts.URL, "http://127.0.0.1:30001"},
"ocsp_fail_open": true,
"ocsp_query_all_servers": true,
"ocsp_max_retries": 0,
}),
testAccStepLoginInvalid(t, connState),
}
// Setup a new factory everytime to avoid OCSP caching from influencing the test
@@ -2638,6 +2780,26 @@ func TestOCSPFailOpenWithUnknownResponse(t *testing.T) {
"ocsp_max_retries": 0,
}),
testAccStepLoginInvalid(t, connState),
// Step 5/6 With a single unknown response, query all servers set to true and fail open true, fail validation
testAccStepCertWithExtraParams(t, "web", pemCa, "foo", allowed{names: "cert.example.com"}, false,
map[string]interface{}{
"ocsp_enabled": true,
"ocsp_servers_override": []string{ts.URL, "http://127.0.0.1:30001"},
"ocsp_fail_open": true,
"ocsp_query_all_servers": true,
"ocsp_max_retries": 0,
}),
testAccStepLogin(t, connState),
// Step 7/8 With a single unknown response, query all servers set to true and fail open false, fail validation
testAccStepCertWithExtraParams(t, "web", pemCa, "foo",
allowed{names: "cert.example.com"}, false, map[string]interface{}{
"ocsp_enabled": true,
"ocsp_servers_override": []string{ts.URL, "http://127.0.0.1:30001"},
"ocsp_fail_open": false,
"ocsp_query_all_servers": true,
"ocsp_max_retries": 0,
}),
testAccStepLoginInvalid(t, connState),
}
// Setup a new factory everytime to avoid OCSP caching from influencing the test
@@ -2751,3 +2913,28 @@ func loadCerts(t *testing.T, certFile, certKey string) tls.Certificate {
return caTLS
}
func createCa(t *testing.T) (*x509.Certificate, *ecdsa.PrivateKey) {
rootCaKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
require.NoError(t, err, "failed generated root key for CA")
// Validate we reject CSRs that contain CN that aren't in the original order
cr := &x509.Certificate{
Subject: pkix.Name{CommonName: "Root Cert"},
SerialNumber: big.NewInt(1),
IsCA: true,
BasicConstraintsValid: true,
SignatureAlgorithm: x509.ECDSAWithSHA256,
NotBefore: time.Now().Add(-1 * time.Second),
NotAfter: time.Now().AddDate(1, 0, 0),
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageOCSPSigning},
}
rootCaBytes, err := x509.CreateCertificate(rand.Reader, cr, cr, &rootCaKey.PublicKey, rootCaKey)
require.NoError(t, err, "failed generating root ca")
rootCa, err := x509.ParseCertificate(rootCaBytes)
require.NoError(t, err, "failed parsing root ca")
return rootCa, rootCaKey
}

View File

@@ -687,6 +687,10 @@ func (b *backend) checkForCertInOCSP(ctx context.Context, clientCert *x509.Certi
defer b.ocspClientMutex.RUnlock()
err := b.ocspClient.VerifyLeafCertificate(ctx, clientCert, chain[1], conf)
if err != nil {
if ocsp.IsOcspVerificationError(err) {
// We don't want anything to override an OCSP verification error
return false, err
}
if conf.OcspFailureMode == ocsp.FailOpenTrue {
onlyNetworkErrors := b.handleOcspErrorInFailOpen(err)
if onlyNetworkErrors {

3
changelog/26091.txt Normal file
View File

@@ -0,0 +1,3 @@
```release-note:security
auth/cert: validate OCSP response was signed by the expected issuer and serial number matched request
```

View File

@@ -76,6 +76,15 @@ const (
cacheExpire = float64(24 * 60 * 60)
)
// ErrOcspIssuerVerification indicates an error verifying the identity of an OCSP response occurred
type ErrOcspIssuerVerification struct {
Err error
}
func (e *ErrOcspIssuerVerification) Error() string {
return fmt.Sprintf("ocsp response verification error: %v", e.Err)
}
type ocspCachedResponse struct {
time float64
producedAt float64
@@ -308,6 +317,7 @@ func (c *Client) retryOCSP(
ocspHost *url.URL,
headers map[string]string,
reqBody []byte,
subject,
issuer *x509.Certificate,
) (ocspRes *ocsp.Response, ocspResBytes []byte, ocspS *ocspStatus, retErr error) {
doRequest := func(request *retryablehttp.Request) (*http.Response, error) {
@@ -379,66 +389,19 @@ func (c *Client) retryOCSP(
continue
}
// Above, we use the unsafe issuer=nil parameter to ocsp.ParseResponse
// because Go's library does the wrong thing.
//
// Here, we lack a full chain, but we know we trust the parent issuer,
// so if the Go library incorrectly discards useful certificates, we
// likely cannot verify this without passing through the full chain
// back to the root.
//
// Instead, take one of two paths: 1. if there is no certificate in
// the ocspRes, verify the OCSP response directly with our trusted
// issuer certificate, or 2. if there is a certificate, either verify
// it directly matches our trusted issuer certificate, or verify it
// is signed by our trusted issuer certificate.
//
// See also: https://github.com/golang/go/issues/59641
//
// This addresses the !!unsafe!! behavior above.
if ocspRes.Certificate == nil {
if err := ocspRes.CheckSignatureFrom(issuer); err != nil {
err = fmt.Errorf("error directly verifying signature on %v OCSP response: %w", method, err)
retErr = multierror.Append(retErr, err)
continue
}
} else {
// Because we have at least one certificate here, we know that
// Go's ocsp library verified the signature from this certificate
// onto the response and it was valid. Now we need to know we trust
// this certificate. There's two ways we can do this:
//
// 1. Via confirming issuer == ocspRes.Certificate, or
// 2. Via confirming ocspRes.Certificate.CheckSignatureFrom(issuer).
if !bytes.Equal(issuer.Raw, ocspRes.Raw) {
// 1 must not hold, so 2 holds; verify the signature.
if err := ocspRes.Certificate.CheckSignatureFrom(issuer); err != nil {
err = fmt.Errorf("error checking chain of trust on %v OCSP response via %v failed: %w", method, issuer.Subject.String(), err)
retErr = multierror.Append(retErr, err)
continue
}
if err := validateOCSPParsedResponse(ocspRes, subject, issuer); err != nil {
err = fmt.Errorf("error validating %v OCSP response: %w", method, err)
// Verify the OCSP responder certificate is still valid and
// contains the required EKU since it is a delegated OCSP
// responder certificate.
if ocspRes.Certificate.NotAfter.Before(time.Now()) {
err := fmt.Errorf("error checking delegated OCSP responder on %v OCSP response: certificate has expired", method)
retErr = multierror.Append(retErr, err)
continue
}
haveEKU := false
for _, ku := range ocspRes.Certificate.ExtKeyUsage {
if ku == x509.ExtKeyUsageOCSPSigning {
haveEKU = true
break
}
}
if !haveEKU {
err := fmt.Errorf("error checking delegated OCSP responder on %v OCSP response: certificate lacks the OCSP Signing EKU", method)
retErr = multierror.Append(retErr, err)
continue
}
if IsOcspVerificationError(err) {
// We want to immediately give up on a verification error to a response
// and inform the user something isn't correct
return nil, nil, nil, err
}
retErr = multierror.Append(retErr, err)
// Clear the response out as we can't trust it.
ocspRes = nil
continue
}
// While we haven't validated the signature on the OCSP response, we
@@ -473,6 +436,80 @@ func (c *Client) retryOCSP(
return
}
func IsOcspVerificationError(err error) bool {
errOcspIssuer := &ErrOcspIssuerVerification{}
return errors.As(err, &errOcspIssuer)
}
func validateOCSPParsedResponse(ocspRes *ocsp.Response, subject, issuer *x509.Certificate) error {
// Above, we use the unsafe issuer=nil parameter to ocsp.ParseResponse
// because Go's library does the wrong thing.
//
// Here, we lack a full chain, but we know we trust the parent issuer,
// so if the Go library incorrectly discards useful certificates, we
// likely cannot verify this without passing through the full chain
// back to the root.
//
// Instead, take one of two paths: 1. if there is no certificate in
// the ocspRes, verify the OCSP response directly with our trusted
// issuer certificate, or 2. if there is a certificate, either verify
// it directly matches our trusted issuer certificate, or verify it
// is signed by our trusted issuer certificate.
//
// See also: https://github.com/golang/go/issues/59641
//
// This addresses the !!unsafe!! behavior above.
if ocspRes.Certificate == nil {
if err := ocspRes.CheckSignatureFrom(issuer); err != nil {
return &ErrOcspIssuerVerification{fmt.Errorf("error directly verifying signature: %w", err)}
}
} else {
// Because we have at least one certificate here, we know that
// Go's ocsp library verified the signature from this certificate
// onto the response and it was valid. Now we need to know we trust
// this certificate. There's two ways we can do this:
//
// 1. Via confirming issuer == ocspRes.Certificate, or
// 2. Via confirming ocspRes.Certificate.CheckSignatureFrom(issuer).
if !bytes.Equal(issuer.Raw, ocspRes.Raw) {
// 1 must not hold, so 2 holds; verify the signature.
if err := ocspRes.Certificate.CheckSignatureFrom(issuer); err != nil {
return &ErrOcspIssuerVerification{fmt.Errorf("error checking chain of trust %v failed: %w", issuer.Subject.String(), err)}
}
// Verify the OCSP responder certificate is still valid and
// contains the required EKU since it is a delegated OCSP
// responder certificate.
if ocspRes.Certificate.NotAfter.Before(time.Now()) {
return &ErrOcspIssuerVerification{fmt.Errorf("error checking delegated OCSP responder OCSP response: certificate has expired")}
}
haveEKU := false
for _, ku := range ocspRes.Certificate.ExtKeyUsage {
if ku == x509.ExtKeyUsageOCSPSigning {
haveEKU = true
break
}
}
if !haveEKU {
return &ErrOcspIssuerVerification{fmt.Errorf("error checking delegated OCSP responder: certificate lacks the OCSP Signing EKU")}
}
}
}
// Verify the response was for our original subject
if ocspRes.SerialNumber == nil || subject.SerialNumber == nil {
return &ErrOcspIssuerVerification{fmt.Errorf("OCSP response or cert did not contain a serial number")}
}
if ocspRes.SerialNumber.Cmp(subject.SerialNumber) != 0 {
return &ErrOcspIssuerVerification{fmt.Errorf(
"OCSP response serial number %s did not match the leaf certificate serial number %s",
certutil.GetHexFormatted(ocspRes.SerialNumber.Bytes(), ":"),
certutil.GetHexFormatted(subject.SerialNumber.Bytes(), ":"))}
}
return nil
}
// GetRevocationStatus checks the certificate revocation status for subject using issuer certificate.
func (c *Client) GetRevocationStatus(ctx context.Context, subject, issuer *x509.Certificate, conf *VerifyConfig) (*ocspStatus, error) {
status, ocspReq, encodedCertID, err := c.validateWithCache(subject, issuer, conf)
@@ -520,12 +557,12 @@ func (c *Client) GetRevocationStatus(ctx context.Context, subject, issuer *x509.
ocspClient.HTTPClient.Timeout = timeout
ocspClient.HTTPClient.Transport = newInsecureOcspTransport(conf.ExtraCas)
doRequest := func() error {
doRequest := func(i int) error {
if conf.QueryAllServers {
defer wg.Done()
}
ocspRes, _, ocspS, err := c.retryOCSP(
ctx, ocspClient, retryablehttp.NewRequest, u, headers, ocspReq, issuer)
ctx, ocspClient, retryablehttp.NewRequest, u, headers, ocspReq, subject, issuer)
ocspResponses[i] = ocspRes
if err != nil {
errors[i] = err
@@ -553,9 +590,9 @@ func (c *Client) GetRevocationStatus(ctx context.Context, subject, issuer *x509.
}
if conf.QueryAllServers {
wg.Add(1)
go doRequest()
go doRequest(i)
} else {
err = doRequest()
err = doRequest(i)
if err == nil {
break
}
@@ -570,6 +607,9 @@ func (c *Client) GetRevocationStatus(ctx context.Context, subject, issuer *x509.
var firstError error
for i := range ocspHosts {
if errors[i] != nil {
if IsOcspVerificationError(errors[i]) {
return nil, errors[i]
}
if firstError == nil {
firstError = errors[i]
}

View File

@@ -298,11 +298,14 @@ func TestUnitValidOCSPResponse(t *testing.T) {
// OCSP response conditions
func TestUnitBadOCSPResponses(t *testing.T) {
rootCaKey, rootCa, leafCert := createCaLeafCerts(t)
rootCaKey2, rootCa2, _ := createCaLeafCerts(t)
type tests struct {
name string
ocspRes ocsp.Response
maxAge time.Duration
ca *x509.Certificate
caKey *ecdsa.PrivateKey
errContains string
}
@@ -310,6 +313,30 @@ func TestUnitBadOCSPResponses(t *testing.T) {
ctx := context.Background()
tt := []tests{
{
name: "bad-signing-issuer",
ocspRes: ocsp.Response{
SerialNumber: leafCert.SerialNumber,
ThisUpdate: now.Add(-1 * time.Hour),
NextUpdate: now.Add(30 * time.Minute),
Status: ocsp.Good,
},
ca: rootCa2,
caKey: rootCaKey2,
errContains: "error directly verifying signature",
},
{
name: "incorrect-serial-number",
ocspRes: ocsp.Response{
SerialNumber: big.NewInt(1000),
ThisUpdate: now.Add(-1 * time.Hour),
NextUpdate: now.Add(30 * time.Minute),
Status: ocsp.Good,
},
ca: rootCa,
caKey: rootCaKey,
errContains: "did not match the leaf certificate serial number",
},
{
name: "expired-next-update",
ocspRes: ocsp.Response{
@@ -374,7 +401,15 @@ func TestUnitBadOCSPResponses(t *testing.T) {
for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
ocspHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
response := buildOcspResponse(t, rootCa, rootCaKey, tc.ocspRes)
useCa := rootCa
useCaKey := rootCaKey
if tc.ca != nil {
useCa = tc.ca
}
if tc.caKey != nil {
useCaKey = tc.caKey
}
response := buildOcspResponse(t, useCa, useCaKey, tc.ocspRes)
_, _ = w.Write(response)
})
ts := httptest.NewServer(ocspHandler)
@@ -449,6 +484,51 @@ func TestUnitZeroNextUpdateAreNotCached(t *testing.T) {
require.Equal(t, uint32(2), numQueries.Load())
}
// TestUnitResponsesAreCached verify that the OCSP responses are properly cached when
// querying for the same leaf certificates
func TestUnitResponsesAreCached(t *testing.T) {
rootCaKey, rootCa, leafCert := createCaLeafCerts(t)
numQueries := &atomic.Uint32{}
ocspHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
numQueries.Add(1)
now := time.Now()
ocspRes := ocsp.Response{
SerialNumber: leafCert.SerialNumber,
ThisUpdate: now.Add(-1 * time.Hour),
NextUpdate: now.Add(1 * time.Hour),
Status: ocsp.Good,
}
response := buildOcspResponse(t, rootCa, rootCaKey, ocspRes)
_, _ = w.Write(response)
})
ts1 := httptest.NewServer(ocspHandler)
ts2 := httptest.NewServer(ocspHandler)
defer ts1.Close()
defer ts2.Close()
logFactory := func() hclog.Logger {
return hclog.NewNullLogger()
}
client := New(logFactory, 100)
config := &VerifyConfig{
OcspEnabled: true,
OcspServersOverride: []string{ts1.URL, ts2.URL},
QueryAllServers: true,
}
_, err := client.GetRevocationStatus(context.Background(), leafCert, rootCa, config)
require.NoError(t, err, "Failed fetching revocation status")
// Make sure that we queried both servers and not the cache
require.Equal(t, uint32(2), numQueries.Load())
// These query should be cached and not influence our counter
_, err = client.GetRevocationStatus(context.Background(), leafCert, rootCa, config)
require.NoError(t, err, "Failed fetching revocation status second time")
require.Equal(t, uint32(2), numQueries.Load())
}
func buildOcspResponse(t *testing.T, ca *x509.Certificate, caKey *ecdsa.PrivateKey, ocspRes ocsp.Response) []byte {
response, err := ocsp.CreateResponse(ca, ca, ocspRes, caKey)
if err != nil {
@@ -598,7 +678,7 @@ func TestOCSPRetry(t *testing.T) {
context.TODO(),
client, fakeRequestFunc,
dummyOCSPHost,
make(map[string]string), []byte{0}, certs[len(certs)-1])
make(map[string]string), []byte{0}, certs[0], certs[len(certs)-1])
if err == nil {
fmt.Printf("should fail: %v, %v, %v\n", res, b, st)
}
@@ -613,7 +693,7 @@ func TestOCSPRetry(t *testing.T) {
context.TODO(),
client, fakeRequestFunc,
dummyOCSPHost,
make(map[string]string), []byte{0}, certs[len(certs)-1])
make(map[string]string), []byte{0}, certs[0], certs[len(certs)-1])
if err == nil {
fmt.Printf("should fail: %v, %v, %v\n", res, b, st)
}