Upgrade cryptography from 2.5 to 3.3
Source code is from https://github.com/pyca/cryptography/tree/3.3.x
Run setup.py locally and rename _openssl.so/_padding.so
Bug: 205265538
Test: None
Change-Id: If031739ef5830ba2fb177add74515e4660e2906e
diff --git a/tests/x509/test_ocsp.py b/tests/x509/test_ocsp.py
index 3abaff5..b649402 100644
--- a/tests/x509/test_ocsp.py
+++ b/tests/x509/test_ocsp.py
@@ -13,7 +13,7 @@
from cryptography import x509
from cryptography.exceptions import UnsupportedAlgorithm
from cryptography.hazmat.primitives import hashes, serialization
-from cryptography.hazmat.primitives.asymmetric import ec
+from cryptography.hazmat.primitives.asymmetric import ec, ed25519, ed448
from cryptography.hazmat.primitives.asymmetric.padding import PKCS1v15
from cryptography.x509 import ocsp
@@ -24,51 +24,52 @@
def _load_data(filename, loader):
return load_vectors_from_file(
- filename=filename,
- loader=lambda data: loader(data.read()),
- mode="rb"
+ filename=filename, loader=lambda data: loader(data.read()), mode="rb"
)
def _cert_and_issuer():
from cryptography.hazmat.backends.openssl.backend import backend
+
cert = _load_cert(
os.path.join("x509", "cryptography.io.pem"),
x509.load_pem_x509_certificate,
- backend
+ backend,
)
issuer = _load_cert(
os.path.join("x509", "rapidssl_sha256_ca_g3.pem"),
x509.load_pem_x509_certificate,
- backend
+ backend,
)
return cert, issuer
-def _generate_root():
+def _generate_root(private_key=None, algorithm=hashes.SHA256()):
from cryptography.hazmat.backends.openssl.backend import backend
- private_key = EC_KEY_SECP256R1.private_key(backend)
- subject = x509.Name([
- x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u'US'),
- x509.NameAttribute(x509.NameOID.COMMON_NAME, u'Cryptography CA'),
- ])
+ if private_key is None:
+ private_key = EC_KEY_SECP256R1.private_key(backend)
- builder = x509.CertificateBuilder().serial_number(
- 123456789
- ).issuer_name(
- subject
- ).subject_name(
- subject
- ).public_key(
- private_key.public_key()
- ).not_valid_before(
- datetime.datetime.now()
- ).not_valid_after(
- datetime.datetime.now() + datetime.timedelta(days=3650)
+ subject = x509.Name(
+ [
+ x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u"US"),
+ x509.NameAttribute(x509.NameOID.COMMON_NAME, u"Cryptography CA"),
+ ]
)
- cert = builder.sign(private_key, hashes.SHA256(), backend)
+ builder = (
+ x509.CertificateBuilder()
+ .serial_number(123456789)
+ .issuer_name(subject)
+ .subject_name(subject)
+ .public_key(private_key.public_key())
+ .not_valid_before(datetime.datetime.now())
+ .not_valid_after(
+ datetime.datetime.now() + datetime.timedelta(days=3650)
+ )
+ )
+
+ cert = builder.sign(private_key, algorithm, backend)
return cert, private_key
@@ -82,10 +83,12 @@
os.path.join("x509", "ocsp", "req-sha1.der"),
ocsp.load_der_ocsp_request,
)
- assert req.issuer_name_hash == (b"8\xcaF\x8c\x07D\x8d\xf4\x81\x96"
- b"\xc7mmLpQ\x9e`\xa7\xbd")
- assert req.issuer_key_hash == (b"yu\xbb\x84:\xcb,\xdez\t\xbe1"
- b"\x1bC\xbc\x1c*MSX")
+ assert req.issuer_name_hash == (
+ b"8\xcaF\x8c\x07D\x8d\xf4\x81\x96" b"\xc7mmLpQ\x9e`\xa7\xbd"
+ )
+ assert req.issuer_key_hash == (
+ b"yu\xbb\x84:\xcb,\xdez\t\xbe1" b"\x1bC\xbc\x1c*MSX"
+ )
assert isinstance(req.hash_algorithm, hashes.SHA1)
assert req.serial_number == int(
"98D9E5C0B4C373552DF77C5D0F1EB5128E4945F9", 16
@@ -123,7 +126,7 @@
req_bytes = load_vectors_from_file(
filename=os.path.join("x509", "ocsp", "req-sha1.der"),
loader=lambda data: data.read(),
- mode="rb"
+ mode="rb",
)
req = ocsp.load_der_ocsp_request(req_bytes)
assert req.public_bytes(serialization.Encoding.DER) == req_bytes
@@ -194,16 +197,14 @@
[
[x509.OCSPNonce(b"0000"), False],
[x509.OCSPNonce(b"\x00\x01\x02"), True],
- ]
+ ],
)
def test_create_ocsp_request_with_extension(self, ext, critical):
cert, issuer = _cert_and_issuer()
builder = ocsp.OCSPRequestBuilder()
builder = builder.add_certificate(
cert, issuer, hashes.SHA1()
- ).add_extension(
- ext, critical
- )
+ ).add_extension(ext, critical)
req = builder.build()
assert len(req.extensions) == 1
assert req.extensions[0].value == ext
@@ -217,13 +218,25 @@
time = datetime.datetime.now()
builder = ocsp.OCSPResponseBuilder()
builder = builder.add_response(
- cert, issuer, hashes.SHA256(), ocsp.OCSPCertStatus.GOOD, time,
- time, None, None
+ cert,
+ issuer,
+ hashes.SHA256(),
+ ocsp.OCSPCertStatus.GOOD,
+ time,
+ time,
+ None,
+ None,
)
with pytest.raises(ValueError):
builder.add_response(
- cert, issuer, hashes.SHA256(), ocsp.OCSPCertStatus.GOOD, time,
- time, None, None
+ cert,
+ issuer,
+ hashes.SHA256(),
+ ocsp.OCSPCertStatus.GOOD,
+ time,
+ time,
+ None,
+ None,
)
def test_invalid_add_response(self):
@@ -233,28 +246,58 @@
builder = ocsp.OCSPResponseBuilder()
with pytest.raises(TypeError):
builder.add_response(
- 'bad', issuer, hashes.SHA256(), ocsp.OCSPCertStatus.GOOD,
- time, time, None, None
+ "bad",
+ issuer,
+ hashes.SHA256(),
+ ocsp.OCSPCertStatus.GOOD,
+ time,
+ time,
+ None,
+ None,
)
with pytest.raises(TypeError):
builder.add_response(
- cert, 'bad', hashes.SHA256(), ocsp.OCSPCertStatus.GOOD,
- time, time, None, None
+ cert,
+ "bad",
+ hashes.SHA256(),
+ ocsp.OCSPCertStatus.GOOD,
+ time,
+ time,
+ None,
+ None,
)
with pytest.raises(ValueError):
builder.add_response(
- cert, issuer, 'notahash', ocsp.OCSPCertStatus.GOOD,
- time, time, None, None
+ cert,
+ issuer,
+ "notahash",
+ ocsp.OCSPCertStatus.GOOD,
+ time,
+ time,
+ None,
+ None,
)
with pytest.raises(TypeError):
builder.add_response(
- cert, issuer, hashes.SHA256(), ocsp.OCSPCertStatus.GOOD,
- 'bad', time, None, None
+ cert,
+ issuer,
+ hashes.SHA256(),
+ ocsp.OCSPCertStatus.GOOD,
+ "bad",
+ time,
+ None,
+ None,
)
with pytest.raises(TypeError):
builder.add_response(
- cert, issuer, hashes.SHA256(), ocsp.OCSPCertStatus.GOOD,
- time, 'bad', None, None
+ cert,
+ issuer,
+ hashes.SHA256(),
+ ocsp.OCSPCertStatus.GOOD,
+ time,
+ "bad",
+ None,
+ None,
)
with pytest.raises(TypeError):
@@ -263,28 +306,58 @@
)
with pytest.raises(ValueError):
builder.add_response(
- cert, issuer, hashes.SHA256(), ocsp.OCSPCertStatus.GOOD,
- time, time, time, None
+ cert,
+ issuer,
+ hashes.SHA256(),
+ ocsp.OCSPCertStatus.GOOD,
+ time,
+ time,
+ time,
+ None,
)
with pytest.raises(ValueError):
builder.add_response(
- cert, issuer, hashes.SHA256(), ocsp.OCSPCertStatus.GOOD,
- time, time, None, reason
+ cert,
+ issuer,
+ hashes.SHA256(),
+ ocsp.OCSPCertStatus.GOOD,
+ time,
+ time,
+ None,
+ reason,
)
with pytest.raises(TypeError):
builder.add_response(
- cert, issuer, hashes.SHA256(), ocsp.OCSPCertStatus.REVOKED,
- time, time, None, reason
+ cert,
+ issuer,
+ hashes.SHA256(),
+ ocsp.OCSPCertStatus.REVOKED,
+ time,
+ time,
+ None,
+ reason,
)
with pytest.raises(TypeError):
builder.add_response(
- cert, issuer, hashes.SHA256(), ocsp.OCSPCertStatus.REVOKED,
- time, time, time, 0
+ cert,
+ issuer,
+ hashes.SHA256(),
+ ocsp.OCSPCertStatus.REVOKED,
+ time,
+ time,
+ time,
+ 0,
)
with pytest.raises(ValueError):
builder.add_response(
- cert, issuer, hashes.SHA256(), ocsp.OCSPCertStatus.REVOKED,
- time, time, time - datetime.timedelta(days=36500), None
+ cert,
+ issuer,
+ hashes.SHA256(),
+ ocsp.OCSPCertStatus.REVOKED,
+ time,
+ time,
+ time - datetime.timedelta(days=36500),
+ None,
)
def test_invalid_certificates(self):
@@ -292,9 +365,9 @@
with pytest.raises(ValueError):
builder.certificates([])
with pytest.raises(TypeError):
- builder.certificates(['notacert'])
+ builder.certificates(["notacert"])
with pytest.raises(TypeError):
- builder.certificates('invalid')
+ builder.certificates("invalid")
_, issuer = _cert_and_issuer()
builder = builder.certificates([issuer])
@@ -305,9 +378,9 @@
builder = ocsp.OCSPResponseBuilder()
cert, _ = _cert_and_issuer()
with pytest.raises(TypeError):
- builder.responder_id(ocsp.OCSPResponderEncoding.HASH, 'invalid')
+ builder.responder_id(ocsp.OCSPResponderEncoding.HASH, "invalid")
with pytest.raises(TypeError):
- builder.responder_id('notanenum', cert)
+ builder.responder_id("notanenum", cert)
builder = builder.responder_id(ocsp.OCSPResponderEncoding.NAME, cert)
with pytest.raises(ValueError):
@@ -335,8 +408,14 @@
this_update = current_time - datetime.timedelta(days=1)
next_update = this_update + datetime.timedelta(days=7)
builder = builder.add_response(
- cert, issuer, hashes.SHA1(), ocsp.OCSPCertStatus.GOOD, this_update,
- next_update, None, None
+ cert,
+ issuer,
+ hashes.SHA1(),
+ ocsp.OCSPCertStatus.GOOD,
+ this_update,
+ next_update,
+ None,
+ None,
)
with pytest.raises(ValueError):
builder.sign(private_key, hashes.SHA256())
@@ -351,11 +430,17 @@
builder = builder.responder_id(
ocsp.OCSPResponderEncoding.NAME, root_cert
).add_response(
- cert, issuer, hashes.SHA1(), ocsp.OCSPCertStatus.GOOD, this_update,
- next_update, None, None
+ cert,
+ issuer,
+ hashes.SHA1(),
+ ocsp.OCSPCertStatus.GOOD,
+ this_update,
+ next_update,
+ None,
+ None,
)
with pytest.raises(TypeError):
- builder.sign(private_key, 'notahash')
+ builder.sign(private_key, "notahash")
def test_sign_good_cert(self):
builder = ocsp.OCSPResponseBuilder()
@@ -367,15 +452,23 @@
builder = builder.responder_id(
ocsp.OCSPResponderEncoding.NAME, root_cert
).add_response(
- cert, issuer, hashes.SHA1(), ocsp.OCSPCertStatus.GOOD, this_update,
- next_update, None, None
+ cert,
+ issuer,
+ hashes.SHA1(),
+ ocsp.OCSPCertStatus.GOOD,
+ this_update,
+ next_update,
+ None,
+ None,
)
resp = builder.sign(private_key, hashes.SHA256())
assert resp.responder_name == root_cert.subject
assert resp.responder_key_hash is None
assert (current_time - resp.produced_at).total_seconds() < 10
- assert (resp.signature_algorithm_oid ==
- x509.SignatureAlgorithmOID.ECDSA_WITH_SHA256)
+ assert (
+ resp.signature_algorithm_oid
+ == x509.SignatureAlgorithmOID.ECDSA_WITH_SHA256
+ )
assert resp.certificate_status == ocsp.OCSPCertStatus.GOOD
assert resp.revocation_time is None
assert resp.revocation_reason is None
@@ -396,8 +489,14 @@
builder = builder.responder_id(
ocsp.OCSPResponderEncoding.NAME, root_cert
).add_response(
- cert, issuer, hashes.SHA1(), ocsp.OCSPCertStatus.REVOKED,
- this_update, next_update, revoked_date, None
+ cert,
+ issuer,
+ hashes.SHA1(),
+ ocsp.OCSPCertStatus.REVOKED,
+ this_update,
+ next_update,
+ revoked_date,
+ None,
)
resp = builder.sign(private_key, hashes.SHA256())
assert resp.certificate_status == ocsp.OCSPCertStatus.REVOKED
@@ -416,13 +515,19 @@
current_time = datetime.datetime.utcnow().replace(microsecond=0)
this_update = current_time - datetime.timedelta(days=1)
next_update = this_update + datetime.timedelta(days=7)
- builder = builder.responder_id(
- ocsp.OCSPResponderEncoding.NAME, root_cert
- ).add_response(
- cert, issuer, hashes.SHA1(), ocsp.OCSPCertStatus.GOOD, this_update,
- next_update, None, None
- ).certificates(
- [root_cert]
+ builder = (
+ builder.responder_id(ocsp.OCSPResponderEncoding.NAME, root_cert)
+ .add_response(
+ cert,
+ issuer,
+ hashes.SHA1(),
+ ocsp.OCSPCertStatus.GOOD,
+ this_update,
+ next_update,
+ None,
+ None,
+ )
+ .certificates([root_cert])
)
resp = builder.sign(private_key, hashes.SHA256())
assert resp.certificates == [root_cert]
@@ -437,8 +542,14 @@
builder = builder.responder_id(
ocsp.OCSPResponderEncoding.NAME, root_cert
).add_response(
- cert, issuer, hashes.SHA1(), ocsp.OCSPCertStatus.REVOKED,
- this_update, None, revoked_date, None
+ cert,
+ issuer,
+ hashes.SHA1(),
+ ocsp.OCSPCertStatus.REVOKED,
+ this_update,
+ None,
+ revoked_date,
+ None,
)
resp = builder.sign(private_key, hashes.SHA256())
assert resp.certificate_status == ocsp.OCSPCertStatus.REVOKED
@@ -461,9 +572,14 @@
builder = builder.responder_id(
ocsp.OCSPResponderEncoding.NAME, root_cert
).add_response(
- cert, issuer, hashes.SHA1(), ocsp.OCSPCertStatus.REVOKED,
- this_update, next_update, revoked_date,
- x509.ReasonFlags.key_compromise
+ cert,
+ issuer,
+ hashes.SHA1(),
+ ocsp.OCSPCertStatus.REVOKED,
+ this_update,
+ next_update,
+ revoked_date,
+ x509.ReasonFlags.key_compromise,
)
resp = builder.sign(private_key, hashes.SHA256())
assert resp.certificate_status == ocsp.OCSPCertStatus.REVOKED
@@ -485,13 +601,19 @@
builder = builder.responder_id(
ocsp.OCSPResponderEncoding.HASH, root_cert
).add_response(
- cert, issuer, hashes.SHA1(), ocsp.OCSPCertStatus.GOOD, this_update,
- next_update, None, None
+ cert,
+ issuer,
+ hashes.SHA1(),
+ ocsp.OCSPCertStatus.GOOD,
+ this_update,
+ next_update,
+ None,
+ None,
)
resp = builder.sign(private_key, hashes.SHA256())
assert resp.responder_name is None
assert resp.responder_key_hash == (
- b'\x8ca\x94\xe0\x948\xed\x89\xd8\xd4N\x89p\t\xd6\xf9^_\xec}'
+ b"\x8ca\x94\xe0\x948\xed\x89\xd8\xd4N\x89p\t\xd6\xf9^_\xec}"
)
private_key.public_key().verify(
resp.signature, resp.tbs_response_bytes, ec.ECDSA(hashes.SHA256())
@@ -507,10 +629,17 @@
builder = builder.responder_id(
ocsp.OCSPResponderEncoding.HASH, root_cert
).add_response(
- cert, issuer, hashes.SHA1(), ocsp.OCSPCertStatus.GOOD, this_update,
- next_update, None, None
+ cert,
+ issuer,
+ hashes.SHA1(),
+ ocsp.OCSPCertStatus.GOOD,
+ this_update,
+ next_update,
+ None,
+ None,
)
from cryptography.hazmat.backends.openssl.backend import backend
+
diff_key = ec.generate_private_key(ec.SECP256R1(), backend)
with pytest.raises(ValueError):
builder.sign(diff_key, hashes.SHA256())
@@ -522,13 +651,19 @@
current_time = datetime.datetime.utcnow().replace(microsecond=0)
this_update = current_time - datetime.timedelta(days=1)
next_update = this_update + datetime.timedelta(days=7)
- builder = builder.responder_id(
- ocsp.OCSPResponderEncoding.HASH, root_cert
- ).add_response(
- cert, issuer, hashes.SHA1(), ocsp.OCSPCertStatus.GOOD, this_update,
- next_update, None, None
- ).add_extension(
- x509.OCSPNonce(b"012345"), False
+ builder = (
+ builder.responder_id(ocsp.OCSPResponderEncoding.HASH, root_cert)
+ .add_response(
+ cert,
+ issuer,
+ hashes.SHA1(),
+ ocsp.OCSPCertStatus.GOOD,
+ this_update,
+ next_update,
+ None,
+ None,
+ )
+ .add_extension(x509.OCSPNonce(b"012345"), False)
)
resp = builder.sign(private_key, hashes.SHA256())
assert len(resp.extensions) == 1
@@ -546,7 +681,7 @@
(ocsp.OCSPResponseStatus.TRY_LATER, b"0\x03\n\x01\x03"),
(ocsp.OCSPResponseStatus.SIG_REQUIRED, b"0\x03\n\x01\x05"),
(ocsp.OCSPResponseStatus.UNAUTHORIZED, b"0\x03\n\x01\x06"),
- ]
+ ],
)
def test_build_non_successful_statuses(self, status, der):
resp = ocsp.OCSPResponseBuilder.build_unsuccessful(status)
@@ -564,6 +699,92 @@
)
+class TestSignedCertificateTimestampsExtension(object):
+ def test_init(self):
+ with pytest.raises(TypeError):
+ x509.SignedCertificateTimestamps([object()])
+
+ def test_repr(self):
+ assert repr(x509.SignedCertificateTimestamps([])) == (
+ "<SignedCertificateTimestamps([])>"
+ )
+
+ @pytest.mark.supported(
+ only_if=lambda backend: (backend._lib.Cryptography_HAS_SCT),
+ skip_message="Requires CT support",
+ )
+ def test_eq(self, backend):
+ sct1 = (
+ _load_data(
+ os.path.join("x509", "ocsp", "resp-sct-extension.der"),
+ ocsp.load_der_ocsp_response,
+ )
+ .single_extensions.get_extension_for_class(
+ x509.SignedCertificateTimestamps
+ )
+ .value
+ )
+ sct2 = (
+ _load_data(
+ os.path.join("x509", "ocsp", "resp-sct-extension.der"),
+ ocsp.load_der_ocsp_response,
+ )
+ .single_extensions.get_extension_for_class(
+ x509.SignedCertificateTimestamps
+ )
+ .value
+ )
+ assert sct1 == sct2
+
+ @pytest.mark.supported(
+ only_if=lambda backend: (backend._lib.Cryptography_HAS_SCT),
+ skip_message="Requires CT support",
+ )
+ def test_ne(self, backend):
+ sct1 = (
+ _load_data(
+ os.path.join("x509", "ocsp", "resp-sct-extension.der"),
+ ocsp.load_der_ocsp_response,
+ )
+ .single_extensions.get_extension_for_class(
+ x509.SignedCertificateTimestamps
+ )
+ .value
+ )
+ sct2 = x509.SignedCertificateTimestamps([])
+ assert sct1 != sct2
+ assert sct1 != object()
+
+ @pytest.mark.supported(
+ only_if=lambda backend: (backend._lib.Cryptography_HAS_SCT),
+ skip_message="Requires CT support",
+ )
+ def test_hash(self, backend):
+ sct1 = (
+ _load_data(
+ os.path.join("x509", "ocsp", "resp-sct-extension.der"),
+ ocsp.load_der_ocsp_response,
+ )
+ .single_extensions.get_extension_for_class(
+ x509.SignedCertificateTimestamps
+ )
+ .value
+ )
+ sct2 = (
+ _load_data(
+ os.path.join("x509", "ocsp", "resp-sct-extension.der"),
+ ocsp.load_der_ocsp_response,
+ )
+ .single_extensions.get_extension_for_class(
+ x509.SignedCertificateTimestamps
+ )
+ .value
+ )
+ sct3 = x509.SignedCertificateTimestamps([])
+ assert hash(sct1) == hash(sct2)
+ assert hash(sct1) != hash(sct3)
+
+
class TestOCSPResponse(object):
def test_bad_response(self):
with pytest.raises(ValueError):
@@ -575,14 +796,17 @@
ocsp.load_der_ocsp_response,
)
from cryptography.hazmat.backends.openssl.backend import backend
+
issuer = _load_cert(
os.path.join("x509", "letsencryptx3.pem"),
x509.load_pem_x509_certificate,
- backend
+ backend,
)
assert resp.response_status == ocsp.OCSPResponseStatus.SUCCESSFUL
- assert (resp.signature_algorithm_oid ==
- x509.SignatureAlgorithmOID.RSA_WITH_SHA256)
+ assert (
+ resp.signature_algorithm_oid
+ == x509.SignatureAlgorithmOID.RSA_WITH_SHA256
+ )
assert isinstance(resp.signature_hash_algorithm, hashes.SHA256)
assert resp.signature == base64.b64decode(
b"I9KUlyLV/2LbNCVu1BQphxdNlU/jBzXsPYVscPjW5E93pCrSO84GkIWoOJtqsnt"
@@ -603,7 +827,7 @@
resp.signature,
resp.tbs_response_bytes,
PKCS1v15(),
- resp.signature_hash_algorithm
+ resp.signature_hash_algorithm,
)
assert resp.certificates == []
assert resp.responder_key_hash is None
@@ -615,15 +839,22 @@
assert resp.this_update == datetime.datetime(2018, 8, 30, 11, 0)
assert resp.next_update == datetime.datetime(2018, 9, 6, 11, 0)
assert resp.issuer_key_hash == (
- b'\xa8Jjc\x04}\xdd\xba\xe6\xd19\xb7\xa6Ee\xef\xf3\xa8\xec\xa1'
+ b"\xa8Jjc\x04}\xdd\xba\xe6\xd19\xb7\xa6Ee\xef\xf3\xa8\xec\xa1"
)
assert resp.issuer_name_hash == (
- b'~\xe6j\xe7r\x9a\xb3\xfc\xf8\xa2 dl\x16\xa1-`q\x08]'
+ b"~\xe6j\xe7r\x9a\xb3\xfc\xf8\xa2 dl\x16\xa1-`q\x08]"
)
assert isinstance(resp.hash_algorithm, hashes.SHA1)
assert resp.serial_number == 271024907440004808294641238224534273948400
assert len(resp.extensions) == 0
+ def test_load_multi_valued_response(self):
+ with pytest.raises(ValueError):
+ _load_data(
+ os.path.join("x509", "ocsp", "ocsp-army.deps.mil-resp.der"),
+ ocsp.load_der_ocsp_response,
+ )
+
def test_load_unauthorized(self):
resp = _load_data(
os.path.join("x509", "ocsp", "resp-unauthorized.der"),
@@ -705,7 +936,7 @@
)
assert resp.responder_name is None
assert resp.responder_key_hash == (
- b'\x0f\x80a\x1c\x821a\xd5/(\xe7\x8dF8\xb4,\xe1\xc6\xd9\xe2'
+ b"\x0f\x80a\x1c\x821a\xd5/(\xe7\x8dF8\xb4,\xe1\xc6\xd9\xe2"
)
def test_load_revoked_reason(self):
@@ -739,7 +970,7 @@
resp_bytes = load_vectors_from_file(
filename=os.path.join("x509", "ocsp", "resp-revoked.der"),
loader=lambda data: data.read(),
- mode="rb"
+ mode="rb",
)
resp = ocsp.load_der_ocsp_response(resp_bytes)
assert resp.public_bytes(serialization.Encoding.DER) == resp_bytes
@@ -753,3 +984,161 @@
resp.public_bytes("invalid")
with pytest.raises(ValueError):
resp.public_bytes(serialization.Encoding.PEM)
+
+ @pytest.mark.supported(
+ only_if=lambda backend: (backend._lib.Cryptography_HAS_SCT),
+ skip_message="Requires CT support",
+ )
+ def test_single_extensions_sct(self, backend):
+ resp = _load_data(
+ os.path.join("x509", "ocsp", "resp-sct-extension.der"),
+ ocsp.load_der_ocsp_response,
+ )
+ assert len(resp.single_extensions) == 1
+ ext = resp.single_extensions[0]
+ assert ext.oid == x509.ObjectIdentifier("1.3.6.1.4.1.11129.2.4.5")
+ assert len(ext.value) == 4
+ log_ids = [base64.b64encode(sct.log_id) for sct in ext.value]
+ assert log_ids == [
+ b"RJRlLrDuzq/EQAfYqP4owNrmgr7YyzG1P9MzlrW2gag=",
+ b"b1N2rDHwMRnYmQCkURX/dxUcEdkCwQApBo2yCJo32RM=",
+ b"u9nfvB+KcbWTlCOXqpJ7RzhXlQqrUugakJZkNo4e0YU=",
+ b"7ku9t3XOYLrhQmkfq+GeZqMPfl+wctiDAMR7iXqo/cs=",
+ ]
+
+ @pytest.mark.supported(
+ only_if=lambda backend: (
+ not backend._lib.CRYPTOGRAPHY_OPENSSL_110F_OR_GREATER
+ ),
+ skip_message="Requires OpenSSL < 1.1.0f",
+ )
+ def test_skips_single_extensions_scts_if_unsupported(self, backend):
+ resp = _load_data(
+ os.path.join("x509", "ocsp", "resp-sct-extension.der"),
+ ocsp.load_der_ocsp_response,
+ )
+ with pytest.raises(x509.ExtensionNotFound):
+ resp.single_extensions.get_extension_for_class(
+ x509.SignedCertificateTimestamps
+ )
+
+ ext = resp.single_extensions.get_extension_for_oid(
+ x509.ExtensionOID.SIGNED_CERTIFICATE_TIMESTAMPS
+ )
+ assert isinstance(ext.value, x509.UnrecognizedExtension)
+
+ def test_single_extensions(self, backend):
+ resp = _load_data(
+ os.path.join("x509", "ocsp", "resp-single-extension-reason.der"),
+ ocsp.load_der_ocsp_response,
+ )
+ assert len(resp.single_extensions) == 1
+ ext = resp.single_extensions[0]
+ assert ext.oid == x509.CRLReason.oid
+ assert ext.value == x509.CRLReason(x509.ReasonFlags.unspecified)
+
+
+class TestOCSPEdDSA(object):
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.ed25519_supported(),
+ skip_message="Requires OpenSSL with Ed25519 support / OCSP",
+ )
+ def test_invalid_algorithm(self, backend):
+ builder = ocsp.OCSPResponseBuilder()
+ cert, issuer = _cert_and_issuer()
+ private_key = ed25519.Ed25519PrivateKey.generate()
+ root_cert, _ = _generate_root(private_key, None)
+ current_time = datetime.datetime.utcnow().replace(microsecond=0)
+ this_update = current_time - datetime.timedelta(days=1)
+ next_update = this_update + datetime.timedelta(days=7)
+ revoked_date = this_update - datetime.timedelta(days=300)
+ builder = builder.responder_id(
+ ocsp.OCSPResponderEncoding.NAME, root_cert
+ ).add_response(
+ cert,
+ issuer,
+ hashes.SHA1(),
+ ocsp.OCSPCertStatus.REVOKED,
+ this_update,
+ next_update,
+ revoked_date,
+ x509.ReasonFlags.key_compromise,
+ )
+ with pytest.raises(ValueError):
+ builder.sign(private_key, hashes.SHA256())
+
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.ed25519_supported(),
+ skip_message="Requires OpenSSL with Ed25519 support / OCSP",
+ )
+ def test_sign_ed25519(self, backend):
+ builder = ocsp.OCSPResponseBuilder()
+ cert, issuer = _cert_and_issuer()
+ private_key = ed25519.Ed25519PrivateKey.generate()
+ root_cert, _ = _generate_root(private_key, None)
+ current_time = datetime.datetime.utcnow().replace(microsecond=0)
+ this_update = current_time - datetime.timedelta(days=1)
+ next_update = this_update + datetime.timedelta(days=7)
+ revoked_date = this_update - datetime.timedelta(days=300)
+ builder = builder.responder_id(
+ ocsp.OCSPResponderEncoding.NAME, root_cert
+ ).add_response(
+ cert,
+ issuer,
+ hashes.SHA1(),
+ ocsp.OCSPCertStatus.REVOKED,
+ this_update,
+ next_update,
+ revoked_date,
+ x509.ReasonFlags.key_compromise,
+ )
+ resp = builder.sign(private_key, None)
+ assert resp.certificate_status == ocsp.OCSPCertStatus.REVOKED
+ assert resp.revocation_time == revoked_date
+ assert resp.revocation_reason is x509.ReasonFlags.key_compromise
+ assert resp.this_update == this_update
+ assert resp.next_update == next_update
+ assert resp.signature_hash_algorithm is None
+ assert (
+ resp.signature_algorithm_oid == x509.SignatureAlgorithmOID.ED25519
+ )
+ private_key.public_key().verify(
+ resp.signature, resp.tbs_response_bytes
+ )
+
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.ed448_supported(),
+ skip_message="Requires OpenSSL with Ed448 support / OCSP",
+ )
+ def test_sign_ed448(self, backend):
+ builder = ocsp.OCSPResponseBuilder()
+ cert, issuer = _cert_and_issuer()
+ private_key = ed448.Ed448PrivateKey.generate()
+ root_cert, _ = _generate_root(private_key, None)
+ current_time = datetime.datetime.utcnow().replace(microsecond=0)
+ this_update = current_time - datetime.timedelta(days=1)
+ next_update = this_update + datetime.timedelta(days=7)
+ revoked_date = this_update - datetime.timedelta(days=300)
+ builder = builder.responder_id(
+ ocsp.OCSPResponderEncoding.NAME, root_cert
+ ).add_response(
+ cert,
+ issuer,
+ hashes.SHA1(),
+ ocsp.OCSPCertStatus.REVOKED,
+ this_update,
+ next_update,
+ revoked_date,
+ x509.ReasonFlags.key_compromise,
+ )
+ resp = builder.sign(private_key, None)
+ assert resp.certificate_status == ocsp.OCSPCertStatus.REVOKED
+ assert resp.revocation_time == revoked_date
+ assert resp.revocation_reason is x509.ReasonFlags.key_compromise
+ assert resp.this_update == this_update
+ assert resp.next_update == next_update
+ assert resp.signature_hash_algorithm is None
+ assert resp.signature_algorithm_oid == x509.SignatureAlgorithmOID.ED448
+ private_key.public_key().verify(
+ resp.signature, resp.tbs_response_bytes
+ )