Skip to content

Commit 8a741bd

Browse files
committed
draft: PKCS#7 extension policies
added tests accordingly
1 parent fed4a18 commit 8a741bd

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

src/cryptography/hazmat/primitives/serialization/pkcs7.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@
2121
algorithms,
2222
)
2323
from cryptography.utils import _check_byteslike
24+
from cryptography.x509 import Certificate
25+
from cryptography.x509.verification import (
26+
Criticality,
27+
ExtensionPolicy,
28+
Policy,
29+
)
2430

2531
load_pem_pkcs7_certificates = rust_pkcs7.load_pem_pkcs7_certificates
2632

@@ -53,6 +59,45 @@ class PKCS7Options(utils.Enum):
5359
NoCerts = "Don't embed signer certificate"
5460

5561

62+
def pkcs7_x509_extension_policies() -> tuple[ExtensionPolicy, ExtensionPolicy]:
63+
"""
64+
Gets the default X.509 extension policy for S/MIME. Some specifications
65+
that differ from the standard ones:
66+
- Certificates used as end entities (i.e., the cert used to sign
67+
a PKCS#7/SMIME message) should not have ca=true in their basic
68+
constraints extension.
69+
- EKU_CLIENT_AUTH_OID is not required
70+
- EKU_EMAIL_PROTECTION_OID is required
71+
"""
72+
73+
# CA policy
74+
def _validate_ca(
75+
policy: Policy, cert: Certificate, bc: x509.BasicConstraints
76+
):
77+
assert not bc.ca
78+
79+
ca_policy = ExtensionPolicy.permit_all().require_present(
80+
x509.BasicConstraints,
81+
Criticality.AGNOSTIC,
82+
_validate_ca,
83+
)
84+
85+
# EE policy
86+
def _validate_eku(
87+
policy: Policy, cert: Certificate, eku: x509.ExtendedKeyUsage
88+
):
89+
# Checking for EKU_EMAIL_PROTECTION_OID
90+
assert x509.ExtendedKeyUsageOID.EMAIL_PROTECTION in eku # type: ignore[attr-defined]
91+
92+
ee_policy = ExtensionPolicy.permit_all().require_present(
93+
x509.ExtendedKeyUsage,
94+
Criticality.AGNOSTIC,
95+
_validate_eku,
96+
)
97+
98+
return ca_policy, ee_policy
99+
100+
56101
class PKCS7SignatureBuilder:
57102
def __init__(
58103
self,

tests/hazmat/primitives/test_pkcs7.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from cryptography.hazmat.primitives.asymmetric import ed25519, padding, rsa
1919
from cryptography.hazmat.primitives.ciphers import algorithms
2020
from cryptography.hazmat.primitives.serialization import pkcs7
21+
from cryptography.x509.verification import PolicyBuilder, Store
2122
from tests.x509.test_x509 import _generate_ca_and_leaf
2223

2324
from ...hazmat.primitives.fixtures_rsa import (
@@ -139,6 +140,19 @@ def _load_cert_key():
139140
return cert, key
140141

141142

143+
def test_verify_pkcs7_certificate():
144+
certificate, _ = _load_cert_key()
145+
146+
builder = (
147+
PolicyBuilder()
148+
.store(Store([certificate]))
149+
.extension_policies(*pkcs7.pkcs7_x509_extension_policies())
150+
)
151+
152+
verifier = builder.build_client_verifier()
153+
verifier.verify(certificate, [])
154+
155+
142156
@pytest.mark.supported(
143157
only_if=lambda backend: backend.pkcs7_supported(),
144158
skip_message="Requires OpenSSL with PKCS7 support",

0 commit comments

Comments
 (0)