Skip to content

Commit 1b51374

Browse files
Add more test cases
1 parent 2753140 commit 1b51374

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed

test/unit/test_crl.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,99 @@ def test_cross_signed_certificate_chain(cert_gen, session_manager):
650650
assert validator.validate_certificate_chains(chains)
651651

652652

653+
def test_starfield_incident(cert_gen, session_manager):
654+
# leaf is signed by A, who is signed by CA (revoked) and B, who is also a trusted CA
655+
chain = cert_gen.create_cross_signed_chain()
656+
validator = CRLValidator(
657+
session_manager,
658+
cert_revocation_check_mode=CertRevocationCheckMode.ENABLED,
659+
trusted_certificates=[cert_gen.ca_certificate, chain.rootB],
660+
)
661+
662+
def mock_validate(cert, _):
663+
if cert == chain.rootA:
664+
return CRLValidationResult.REVOKED
665+
return CRLValidationResult.UNREVOKED
666+
667+
validator._validate_certificate = mock_validate
668+
669+
assert (
670+
validator._validate_single_chain([chain.leafA, chain.BsignA, chain.rootA])
671+
== CRLValidationResult.UNREVOKED
672+
)
673+
674+
675+
def test_validate_single_chain(cert_gen, session_manager):
676+
chain = cert_gen.create_cross_signed_chain()
677+
validator = CRLValidator(
678+
session_manager,
679+
cert_revocation_check_mode=CertRevocationCheckMode.ENABLED,
680+
trusted_certificates=[cert_gen.ca_certificate],
681+
)
682+
683+
input_chain = [chain.leafA, chain.leafB, chain.rootA, chain.rootB]
684+
685+
# case 1: at least one valid path
686+
def mock_validate_with_special_cert(revoked_cert, error_result):
687+
validator._validate_certificate_with_cache = lambda cert, _: (
688+
error_result if cert == revoked_cert else CRLValidationResult.UNREVOKED
689+
)
690+
691+
for error_result in [CRLValidationResult.ERROR, CRLValidationResult.REVOKED]:
692+
for revoked_cert in [chain.rootA, chain.rootB, chain.leafA, chain.leafB]:
693+
mock_validate_with_special_cert(revoked_cert, error_result)
694+
assert (
695+
validator._validate_single_chain(input_chain)
696+
== CRLValidationResult.UNREVOKED
697+
)
698+
699+
# case 2: all paths revoked
700+
def mock_validate(cert, _):
701+
if cert in [chain.rootA, chain.rootB]:
702+
return CRLValidationResult.REVOKED
703+
return CRLValidationResult.UNREVOKED
704+
705+
validator._validate_certificate_with_cache = mock_validate
706+
assert validator._validate_single_chain(input_chain) == CRLValidationResult.REVOKED
707+
708+
# case 3: revoked + error should result in revoked\
709+
def mock_validate(cert, _):
710+
if cert in [chain.rootA, chain.leafB]:
711+
return CRLValidationResult.REVOKED
712+
return CRLValidationResult.ERROR
713+
714+
validator._validate_certificate_with_cache = mock_validate
715+
assert validator._validate_single_chain(input_chain) == CRLValidationResult.REVOKED
716+
717+
# case 4: no path to trusted certificate
718+
def mock_validate(cert, _):
719+
return CRLValidationResult.UNREVOKED
720+
721+
validator._validate_certificate_with_cache = mock_validate
722+
assert (
723+
validator._validate_single_chain(
724+
[chain.leafA, chain.leafB, chain.AsignB, chain.BsignA]
725+
)
726+
== CRLValidationResult.ERROR
727+
)
728+
729+
# case 5: only unrevoked path has an error
730+
def mock_validate(cert, _):
731+
if cert in [chain.rootA, chain.leafB]:
732+
return CRLValidationResult.REVOKED
733+
if cert == chain.BsignA:
734+
return CRLValidationResult.ERROR
735+
return CRLValidationResult.UNREVOKED
736+
737+
validator._validate_certificate_with_cache = mock_validate
738+
assert (
739+
validator._validate_single_chain(
740+
[chain.leafA, chain.rootA, chain.leafB, chain.rootB, chain.BsignA]
741+
)
742+
== CRLValidationResult.ERROR
743+
)
744+
745+
653746
@responses.activate
654747
def test_should_validate_non_revoked_certificate_successfully(
655748
cert_gen, crl_urls, session_manager

0 commit comments

Comments
 (0)