CA: use mockable clock in CA's OCSP signer. (#4539)
This brings OCSP signing into alignment with the other components of the CA in that they use ca.clk, which can be mocked out in unittests. This tweaks test_ocsp_exp_unauth to be compatible with the change. Fixes #4441.
This commit is contained in:
parent
a44f346f88
commit
2ab1729a18
11
ca/ca.go
11
ca/ca.go
|
@ -412,16 +412,7 @@ func (ca *CertificateAuthorityImpl) GenerateOCSP(ctx context.Context, xferObj co
|
|||
core.SerialToString(cert.SerialNumber), cn, err)
|
||||
}
|
||||
|
||||
// We use time.Now() rather than ca.clk.Now() here as we use openssl
|
||||
// to verify the validity of the OCSP responses we generate during testing
|
||||
// and openssl doesn't understand our concept of fake time so it thinks
|
||||
// our responses are expired when we are doing things with our fake clock
|
||||
// time set in the past. Since we don't rely on fake clock time for any
|
||||
// OCSP unit tests always using the real time doesn't cause any problems.
|
||||
// Currently the only integration test case that triggers this is
|
||||
// ocsp_exp_unauth_setup, but any other integration test introduced that
|
||||
// sets the fake clock into the past and verifies OCSP will also do so.
|
||||
now := time.Now().Truncate(time.Hour)
|
||||
now := ca.clk.Now().Truncate(time.Hour)
|
||||
tbsResponse := ocsp.Response{
|
||||
Status: ocspStatusToCode[xferObj.Status],
|
||||
SerialNumber: cert.SerialNumber,
|
||||
|
|
|
@ -1173,6 +1173,25 @@ def test_auth_deactivation_v2():
|
|||
raise Exception("unexpected authorization status")
|
||||
|
||||
|
||||
def check_ocsp_basic_oid(cert_file, issuer_file, url):
|
||||
"""
|
||||
This function checks if an OCSP response was successful, but doesn't verify
|
||||
the signature or timestamp. This is useful when simulating the past, so we
|
||||
don't incorrectly reject a response for being in the past.
|
||||
"""
|
||||
ocsp_request = make_ocsp_req(cert_file, issuer_file)
|
||||
responses = fetch_ocsp(ocsp_request, url)
|
||||
# An unauthorized response (for instance, if the OCSP responder doesn't know
|
||||
# about this cert) will just be 30 03 0A 01 06. A "good" or "revoked"
|
||||
# response will contain, among other things, the id-pkix-ocsp-basic OID
|
||||
# identifying the response type. We look for that OID to confirm we got a
|
||||
# succesful response.
|
||||
expected = bytearray.fromhex("06 09 2B 06 01 05 05 07 30 01 01")
|
||||
for resp in responses:
|
||||
if not expected in bytearray(resp):
|
||||
raise Exception("Did not receive successful OCSP response: %s doesn't contain %s" %
|
||||
(base64.b64encode(resp), base64.b64encode(expected)))
|
||||
|
||||
expired_cert_name = ""
|
||||
@register_six_months_ago
|
||||
def ocsp_exp_unauth_setup():
|
||||
|
@ -1184,7 +1203,11 @@ def ocsp_exp_unauth_setup():
|
|||
with open(cert_file_pem, "w") as f:
|
||||
f.write(OpenSSL.crypto.dump_certificate(
|
||||
OpenSSL.crypto.FILETYPE_PEM, cert).decode())
|
||||
verify_ocsp(cert_file_pem, "test/test-ca2.pem", "http://localhost:4002", "good")
|
||||
|
||||
# Since we're pretending to be in the past, we'll get an expired OCSP
|
||||
# response. Just check that it exists; don't do the full verification (which
|
||||
# would fail).
|
||||
check_ocsp_basic_oid(cert_file_pem, "test/test-ca2.pem", "http://localhost:4002")
|
||||
global expired_cert_name
|
||||
expired_cert_name = cert_file_pem
|
||||
|
||||
|
|
Loading…
Reference in New Issue