Add test for re-signed OCSP revocation reasons (#4937)

This commit is contained in:
Aaron Gable 2020-07-10 11:13:33 -07:00 committed by GitHub
parent dee757c057
commit e906b9e272
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 72 additions and 10 deletions

View File

@ -82,7 +82,7 @@ def ocsp_verify(cert_file, issuer_file, ocsp_response):
raise(Exception("OCSP verify failure"))
return output
def verify_ocsp(cert_file, issuer_file, url, status):
def verify_ocsp(cert_file, issuer_file, url, status="revoked"):
ocsp_request = make_ocsp_req(cert_file, issuer_file)
responses = fetch_ocsp(ocsp_request, url)
@ -96,9 +96,11 @@ def verify_ocsp(cert_file, issuer_file, url, status):
# status
resp = responses[0]
verify_output = ocsp_verify(cert_file, issuer_file, resp)
if not re.search("%s: %s" % (cert_file, status), verify_output):
print(verify_output)
raise(Exception("OCSP response wasn't '%s'" % status))
if status is not None:
if not re.search("%s: %s" % (cert_file, status), verify_output):
print(verify_output)
raise(Exception("OCSP response wasn't '%s'" % status))
return verify_output
def reset_akamai_purges():
requests.post("http://localhost:6789/debug/reset-purges", data="{}")

View File

@ -1213,9 +1213,9 @@ def ocsp_exp_unauth_setup():
f.write(OpenSSL.crypto.dump_certificate(
OpenSSL.crypto.FILETYPE_PEM, cert).decode())
# 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).
# Since our servers are pretending to be in the past, but the openssl cli
# isn't, 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, "/tmp/intermediate-cert-rsa-a.pem", "http://localhost:4002")
global expired_cert_name
expired_cert_name = cert_file_pem
@ -1224,7 +1224,7 @@ def test_ocsp_exp_unauth():
tries = 0
if expired_cert_name == "":
raise Exception("ocsp_exp_unauth_setup didn't run")
while True:
while tries < 5:
try:
verify_ocsp(expired_cert_name, "/tmp/intermediate-cert-rsa-a.pem", "http://localhost:4002", "XXX")
raise(Exception("Unexpected return from verify_ocsp"))
@ -1233,10 +1233,10 @@ def test_ocsp_exp_unauth():
break
except:
pass
if tries is 5:
raise(Exception("timed out waiting for unauthorized OCSP response for expired certificate"))
tries += 1
time.sleep(0.25)
else:
raise(Exception("timed out waiting for unauthorized OCSP response for expired certificate"))
def test_blocked_key_account():
# Only config-next has a blocked keys file configured.
@ -1554,3 +1554,63 @@ def test_auth_deactivation():
resp = client.deactivate_authorization(order.authorizations[0])
if resp.body.status is not messages.STATUS_DEACTIVATED:
raise Exception("unexpected authorization status")
def get_ocsp_response_and_reason(cert_file, issuer_file, url):
"""Returns the ocsp response output and revocation reason."""
output = verify_ocsp(cert_file, issuer_file, url, None)
m = re.search('Reason: (\w+)', output)
reason = m.group(1) if m is not None else ""
return output, reason
ocsp_resigning_setup_data = {}
@register_twenty_days_ago
def ocsp_resigning_setup():
"""Issue and then revoke a cert in the past.
Useful setup for test_ocsp_resigning, which needs to check that the
revocation reason is still correctly set after re-signing and old OCSP
response.
"""
client = chisel2.make_client(None)
order = chisel2.auth_and_issue([random_domain()], client=client)
cert = OpenSSL.crypto.load_certificate(
OpenSSL.crypto.FILETYPE_PEM, order.fullchain_pem)
# Revoke for reason 1: keyCompromise
client.revoke(josepy.ComparableX509(cert), 1)
cert_file = os.path.join(tempdir, "compromised.pem")
with open(cert_file, "w") as f:
f.write(OpenSSL.crypto.dump_certificate(
OpenSSL.crypto.FILETYPE_PEM, cert).decode())
response, reason = get_ocsp_response_and_reason(
cert_file, "/tmp/intermediate-cert-rsa-a.pem", "http://localhost:4002")
global ocsp_resigning_setup_data
ocsp_resigning_setup_data = {
'response': response,
'reason': reason
}
def test_ocsp_resigning():
"""Check that, after re-signing an OCSP, the reason is still set."""
if 'response' not in ocsp_resigning_setup_data:
raise Exception("ocsp_resigning_setup didn't run")
cert_file = os.path.join(tempdir, "compromised.pem")
tries = 0
while tries < 5:
resp, reason = get_ocsp_response_and_reason(
cert_file, "/tmp/intermediate-cert-rsa-a.pem", "http://localhost:4002")
if resp != ocsp_resigning_setup_data['response']:
break
tries += 1
time.sleep(0.25)
else:
raise(Exception("timed out waiting for re-signed OCSP response for certificate"))
if reason != ocsp_resigning_setup_data['reason']:
raise(Exception("re-signed ocsp response has different reason %s expected %s" % (
reason, ocsp_resigning_setup_data['reason'])))
if reason != "keyCompromise":
raise(Exception("re-signed ocsp response has wrong reason %s" % reason))