Skip to content

Commit ea8fe06

Browse files
committed
Test ExtensionPolicy with all extension types.
1 parent 5e41c95 commit ea8fe06

File tree

1 file changed

+92
-50
lines changed

1 file changed

+92
-50
lines changed

tests/x509/verification/test_verification.py

Lines changed: 92 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66
import os
77
from functools import lru_cache
88
from ipaddress import IPv4Address
9-
from typing import Optional
9+
from typing import Optional, Type
1010

1111
import pytest
1212

1313
from cryptography import utils, x509
1414
from cryptography.hazmat._oid import ExtendedKeyUsageOID
15-
from cryptography.x509.extensions import ExtendedKeyUsage
15+
from cryptography.x509.extensions import (
16+
ExtendedKeyUsage,
17+
ExtensionType,
18+
)
1619
from cryptography.x509.general_name import DNSName, IPAddress
1720
from cryptography.x509.verification import (
1821
Criticality,
@@ -300,6 +303,18 @@ def test_error_message(self):
300303
verifier.verify(leaf, [])
301304

302305

306+
TESTED_EXTENSION_TYPES = (
307+
x509.AuthorityInformationAccess,
308+
x509.AuthorityKeyIdentifier,
309+
x509.SubjectKeyIdentifier,
310+
x509.KeyUsage,
311+
x509.SubjectAlternativeName,
312+
x509.BasicConstraints,
313+
x509.NameConstraints,
314+
x509.ExtendedKeyUsage,
315+
)
316+
317+
303318
class TestCustomExtensionPolicies:
304319
leaf = _load_cert(
305320
os.path.join("x509", "cryptography.io.pem"),
@@ -345,71 +360,103 @@ class _Extension:
345360
None,
346361
)
347362

348-
@staticmethod
349-
def _eku_validator_cb(policy, cert, ext: Optional[ExtendedKeyUsage]):
350-
assert isinstance(policy, Policy)
351-
assert (
352-
policy.validation_time
353-
== TestCustomExtensionPolicies.validation_time.replace(tzinfo=None)
363+
def test_unsupported_extension(self):
364+
ext_policy = ExtensionPolicy.permit_all()
365+
message = (
366+
f"Unsupported extension OID: {x509.Admissions.oid.dotted_string}"
354367
)
355-
assert isinstance(cert, x509.Certificate)
356-
assert ext is None or isinstance(ext, x509.ExtendedKeyUsage)
368+
with pytest.raises(
369+
ValueError,
370+
match=message,
371+
):
372+
ext_policy.may_be_present(
373+
x509.Admissions,
374+
Criticality.AGNOSTIC,
375+
None,
376+
)
357377

358-
def test_custom_cb_pass(self):
359-
ca_ext_policy = ExtensionPolicy.webpki_defaults_ca()
360-
ee_ext_policy = ExtensionPolicy.webpki_defaults_ee()
378+
@staticmethod
379+
def _make_validator_cb(extension_type: Type[ExtensionType]):
380+
def validator_cb(policy, cert, ext: Optional[ExtensionType]):
381+
assert isinstance(policy, Policy)
382+
assert (
383+
policy.validation_time
384+
== TestCustomExtensionPolicies.validation_time.replace(
385+
tzinfo=None
386+
)
387+
)
388+
assert isinstance(cert, x509.Certificate)
389+
assert ext is None or isinstance(ext, extension_type)
361390

362-
ee_ext_policy = ee_ext_policy.may_be_present(
363-
ExtendedKeyUsage, Criticality.AGNOSTIC, self._eku_validator_cb
364-
)
365-
ca_ext_policy = ca_ext_policy.may_be_present(
366-
ExtendedKeyUsage, Criticality.AGNOSTIC, self._eku_validator_cb
367-
)
391+
return validator_cb
368392

369-
ca_validator_called = False
393+
# def test_all_extension_types(self):
394+
# ca_ext_policy = ExtensionPolicy.webpki_defaults_ca()
395+
# ee_ext_policy = ExtensionPolicy.webpki_defaults_ee()
370396

371-
def ca_basic_constraints_validator(policy, cert, ext):
372-
assert cert == self.ca
373-
assert isinstance(policy, Policy)
374-
assert isinstance(cert, x509.Certificate)
375-
assert isinstance(ext, x509.BasicConstraints)
376-
nonlocal ca_validator_called
377-
ca_validator_called = True
397+
# ca_validator_called = False
378398

379-
ca_ext_policy = ca_ext_policy.may_be_present(
380-
x509.BasicConstraints,
399+
# extension_types = [
400+
# AuthorityInformationAccess,
401+
# AuthorityKeyIdentifier,
402+
# SubjectKeyIdentifier,
403+
# KeyUsage,
404+
# SubjectAlternativeName,
405+
# BasicConstraints,
406+
# ]
407+
408+
# for
409+
410+
# ca_ext_policy = ca_ext_policy.may_be_present(
411+
# x509.BasicConstraints,
412+
# Criticality.AGNOSTIC,
413+
# ca_basic_constraints_validator,
414+
# )
415+
416+
# builder = PolicyBuilder().store(self.store)
417+
# builder = builder.time(self.validation_time)
418+
# builder = builder.extension_policies(ca_ext_policy, ee_ext_policy)
419+
420+
# builder.build_client_verifier().verify(self.leaf, [])
421+
422+
@pytest.mark.parametrize(
423+
"extension_type",
424+
TESTED_EXTENSION_TYPES,
425+
)
426+
def test_custom_cb_pass(self, extension_type: Type[x509.ExtensionType]):
427+
ca_ext_policy = ExtensionPolicy.webpki_defaults_ca()
428+
ee_ext_policy = ExtensionPolicy.webpki_defaults_ee()
429+
430+
ee_ext_policy = ee_ext_policy.may_be_present(
431+
extension_type,
381432
Criticality.AGNOSTIC,
382-
ca_basic_constraints_validator,
433+
self._make_validator_cb(extension_type),
383434
)
384435

385436
builder = PolicyBuilder().store(self.store)
386437
builder = builder.time(self.validation_time).max_chain_depth(16)
387438
builder = builder.extension_policies(ca_ext_policy, ee_ext_policy)
388439

389440
builder.build_client_verifier().verify(self.leaf, [])
390-
assert ca_validator_called
391-
ca_validator_called = False
392441

393442
path = builder.build_server_verifier(
394443
DNSName("cryptography.io")
395444
).verify(self.leaf, [])
396-
assert ca_validator_called
397445
assert path == [self.leaf, self.ca]
398446

399-
def test_custom_cb_no_retval_enforced(self):
447+
@pytest.mark.parametrize(
448+
"extension_type",
449+
TESTED_EXTENSION_TYPES,
450+
)
451+
def test_custom_cb_exception_fails_verification(self, extension_type):
400452
ca_ext_policy = ExtensionPolicy.webpki_defaults_ca()
401453
ee_ext_policy = ExtensionPolicy.webpki_defaults_ee()
402454

403455
def validator(*_):
404-
return False
456+
raise ValueError("test")
405457

406458
ca_ext_policy = ca_ext_policy.may_be_present(
407-
x509.BasicConstraints,
408-
Criticality.AGNOSTIC,
409-
validator,
410-
)
411-
ee_ext_policy = ee_ext_policy.may_be_present(
412-
ExtendedKeyUsage,
459+
extension_type,
413460
Criticality.AGNOSTIC,
414461
validator,
415462
)
@@ -423,22 +470,17 @@ def validator(*_):
423470
):
424471
with pytest.raises(
425472
VerificationError,
426-
match="Python validator must return None.",
473+
match="Python extension validator failed: ValueError: test",
427474
):
428475
verifier.verify(self.leaf, [])
429476

430-
def test_custom_cb_exception_fails_verification(self):
477+
def test_custom_cb_no_retval_enforced(self):
431478
ca_ext_policy = ExtensionPolicy.webpki_defaults_ca()
432479
ee_ext_policy = ExtensionPolicy.webpki_defaults_ee()
433480

434481
def validator(*_):
435-
raise ValueError("test")
482+
return False
436483

437-
ca_ext_policy = ca_ext_policy.may_be_present(
438-
x509.BasicConstraints,
439-
Criticality.AGNOSTIC,
440-
validator,
441-
)
442484
ee_ext_policy = ee_ext_policy.may_be_present(
443485
ExtendedKeyUsage,
444486
Criticality.AGNOSTIC,
@@ -454,6 +496,6 @@ def validator(*_):
454496
):
455497
with pytest.raises(
456498
VerificationError,
457-
match="Python extension validator failed: ValueError: test",
499+
match="Python validator must return None.",
458500
):
459501
verifier.verify(self.leaf, [])

0 commit comments

Comments
 (0)