Skip to content

Commit f56949c

Browse files
committed
Deduplicate between pulpcore and pulp_certguard
1 parent 05a3529 commit f56949c

3 files changed

Lines changed: 40 additions & 120 deletions

File tree

pulp_certguard/tests/functional/api/test_x509_certguard.py

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -48,50 +48,29 @@ def x509_guarded_distribution(
4848
return distribution
4949

5050

51-
PQC_ALGORITHMS = ["ML-DSA-65", "ML-DSA-87"]
52-
53-
54-
# def _pqc_available():
55-
# try:
56-
# from cryptography.hazmat.primitives.asymmetric import mldsa # noqa: F401
57-
58-
# return True
59-
# except ImportError:
60-
# return False
61-
62-
63-
# _pqc_skip = pytest.mark.skipif(
64-
# not _pqc_available(),
65-
# reason="PQC (ML-DSA) requires cryptography with ML-DSA support",
66-
# )
67-
68-
69-
@pytest.fixture(scope="class", params=PQC_ALGORITHMS)
51+
@pytest.fixture(scope="class")
7052
def pqc_guarded_distribution(
71-
request,
53+
pqc_certificate_authority,
7254
x509_content_guards_api_client,
7355
gen_object_with_cleanup,
7456
file_distribution_factory,
7557
repository_test_file,
7658
):
77-
from pulp_certguard.tests.functional.conftest import _generate_pqc_certguard_certs
78-
79-
algorithm = request.param
80-
ca_cert_pem, client_cert_pem, untrusted_client_cert_pem = _generate_pqc_certguard_certs(
81-
algorithm
82-
)
59+
pca = pqc_certificate_authority
8360
content_guard = gen_object_with_cleanup(
8461
x509_content_guards_api_client,
8562
{
8663
"name": str(uuid.uuid4()),
87-
"ca_certificate": ca_cert_pem,
64+
"ca_certificate": pca.ca_cert_pem,
8865
},
8966
)
9067
distribution = file_distribution_factory(
9168
repository=repository_test_file.pulp_href,
9269
content_guard=content_guard.pulp_href,
9370
)
94-
return PQCGuardedDistribution(distribution, algorithm, client_cert_pem, untrusted_client_cert_pem)
71+
return PQCGuardedDistribution(
72+
distribution, pca.algorithm, pca.client_cert_pem, pca.untrusted_client_cert_pem
73+
)
9574

9675

9776
@pytest.fixture(

pulp_certguard/tests/functional/conftest.py

Lines changed: 0 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,6 @@
1-
import datetime
2-
31
import pytest
42

53

6-
def _generate_pqc_certguard_certs(algorithm):
7-
"""Generate PQC CA, client, and untrusted-client certs on demand.
8-
9-
Returns (ca_cert_pem, client_cert_pem, untrusted_client_cert_pem).
10-
"""
11-
from cryptography import x509
12-
from cryptography.hazmat.primitives.asymmetric import mldsa
13-
from cryptography.hazmat.primitives.serialization import Encoding
14-
from cryptography.x509.oid import NameOID
15-
16-
key_classes = {
17-
"ML-DSA-65": mldsa.MLDSA65PrivateKey,
18-
"ML-DSA-87": mldsa.MLDSA87PrivateKey,
19-
}
20-
key_cls = key_classes[algorithm]
21-
now = datetime.datetime.now(datetime.timezone.utc)
22-
not_before = now - datetime.timedelta(minutes=1)
23-
not_after = now + datetime.timedelta(days=1)
24-
25-
ca_key = key_cls.generate()
26-
ca_name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, f"PQC Test CA ({algorithm})")])
27-
ca_cert = (
28-
x509.CertificateBuilder()
29-
.subject_name(ca_name)
30-
.issuer_name(ca_name)
31-
.public_key(ca_key.public_key())
32-
.serial_number(x509.random_serial_number())
33-
.not_valid_before(not_before)
34-
.not_valid_after(not_after)
35-
.add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True)
36-
.add_extension(
37-
x509.KeyUsage(
38-
digital_signature=True,
39-
content_commitment=False,
40-
key_encipherment=False,
41-
data_encipherment=False,
42-
key_agreement=False,
43-
key_cert_sign=True,
44-
crl_sign=True,
45-
encipher_only=False,
46-
decipher_only=False,
47-
),
48-
critical=True,
49-
)
50-
.sign(private_key=ca_key, algorithm=None)
51-
)
52-
53-
def _issue_client_cert(cn, signing_key, issuer_name):
54-
key = key_cls.generate()
55-
cert = (
56-
x509.CertificateBuilder()
57-
.subject_name(x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, cn)]))
58-
.issuer_name(issuer_name)
59-
.public_key(key.public_key())
60-
.serial_number(x509.random_serial_number())
61-
.not_valid_before(not_before)
62-
.not_valid_after(not_after)
63-
.add_extension(x509.BasicConstraints(ca=False, path_length=None), critical=True)
64-
.add_extension(
65-
x509.KeyUsage(
66-
digital_signature=True,
67-
content_commitment=False,
68-
key_encipherment=False,
69-
data_encipherment=False,
70-
key_agreement=False,
71-
key_cert_sign=False,
72-
crl_sign=False,
73-
encipher_only=False,
74-
decipher_only=False,
75-
),
76-
critical=True,
77-
)
78-
.sign(private_key=signing_key, algorithm=None)
79-
)
80-
return cert.public_bytes(Encoding.PEM).decode()
81-
82-
ca_cert_pem = ca_cert.public_bytes(Encoding.PEM).decode()
83-
client_cert_pem = _issue_client_cert("PQC Test Client", ca_key, ca_name)
84-
85-
untrusted_ca_key = key_cls.generate()
86-
untrusted_ca_name = x509.Name(
87-
[x509.NameAttribute(NameOID.COMMON_NAME, f"PQC Untrusted CA ({algorithm})")]
88-
)
89-
untrusted_client_cert_pem = _issue_client_cert(
90-
"PQC Untrusted Client", untrusted_ca_key, untrusted_ca_name
91-
)
92-
93-
return ca_cert_pem, client_cert_pem, untrusted_client_cert_pem
94-
95-
964
@pytest.fixture(scope="class")
975
def repository_test_file(
986
file_bindings,

pulpcore/pytest_plugin.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ class PQCCertificateAuthority:
493493
client_key_path: str
494494
client_cert_pem: str
495495
client_key_pem: str
496+
untrusted_client_cert_pem: str = ""
496497

497498

498499
_PQC_KEY_CLASSES = {
@@ -614,6 +615,37 @@ def _issue_cert(name, cn, eku_oid):
614615
"client", host, ExtendedKeyUsageOID.CLIENT_AUTH
615616
)
616617

618+
# Untrusted client: signed by a different CA so cert-chain verification rejects it
619+
untrusted_ca_key = key_cls.generate()
620+
untrusted_ca_name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "PQC Untrusted CA")])
621+
untrusted_key = key_cls.generate()
622+
untrusted_cert = (
623+
x509.CertificateBuilder()
624+
.subject_name(x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "PQC Untrusted Client")]))
625+
.issuer_name(untrusted_ca_name)
626+
.public_key(untrusted_key.public_key())
627+
.serial_number(x509.random_serial_number())
628+
.not_valid_before(not_before)
629+
.not_valid_after(not_after)
630+
.add_extension(x509.BasicConstraints(ca=False, path_length=None), critical=True)
631+
.add_extension(
632+
x509.KeyUsage(
633+
digital_signature=True,
634+
content_commitment=False,
635+
key_encipherment=False,
636+
data_encipherment=False,
637+
key_agreement=False,
638+
key_cert_sign=False,
639+
crl_sign=False,
640+
encipher_only=False,
641+
decipher_only=False,
642+
),
643+
critical=True,
644+
)
645+
.sign(private_key=untrusted_ca_key, algorithm=None)
646+
)
647+
untrusted_client_cert_pem = untrusted_cert.public_bytes(Encoding.PEM).decode()
648+
617649
return PQCCertificateAuthority(
618650
algorithm=algorithm,
619651
ca_cert_path=ca_cert_path,
@@ -626,6 +658,7 @@ def _issue_cert(name, cn, eku_oid):
626658
client_key_path=client_key_path,
627659
client_cert_pem=client_cert_pem,
628660
client_key_pem=client_key_pem,
661+
untrusted_client_cert_pem=untrusted_client_cert_pem,
629662
)
630663

631664

0 commit comments

Comments
 (0)