diff --git a/src/cryptography/hazmat/_oid.py b/src/cryptography/hazmat/_oid.py index 990df4b033d0..3d5f8e4773ca 100644 --- a/src/cryptography/hazmat/_oid.py +++ b/src/cryptography/hazmat/_oid.py @@ -274,6 +274,7 @@ class AttributeOID: ExtensionOID.SUBJECT_DIRECTORY_ATTRIBUTES: "subjectDirectoryAttributes", ExtensionOID.SUBJECT_KEY_IDENTIFIER: "subjectKeyIdentifier", ExtensionOID.KEY_USAGE: "keyUsage", + ExtensionOID.PRIVATE_KEY_USAGE_PERIOD: "privateKeyUsagePeriod", ExtensionOID.SUBJECT_ALTERNATIVE_NAME: "subjectAltName", ExtensionOID.ISSUER_ALTERNATIVE_NAME: "issuerAltName", ExtensionOID.BASIC_CONSTRAINTS: "basicConstraints", diff --git a/src/cryptography/x509/__init__.py b/src/cryptography/x509/__init__.py index 26c6444c511f..f88915edb491 100644 --- a/src/cryptography/x509/__init__.py +++ b/src/cryptography/x509/__init__.py @@ -63,6 +63,7 @@ PolicyInformation, PrecertificateSignedCertificateTimestamps, PrecertPoison, + PrivateKeyUsagePeriod, ReasonFlags, SignedCertificateTimestamps, SubjectAlternativeName, @@ -111,6 +112,7 @@ OID_INHIBIT_ANY_POLICY = ExtensionOID.INHIBIT_ANY_POLICY OID_ISSUER_ALTERNATIVE_NAME = ExtensionOID.ISSUER_ALTERNATIVE_NAME OID_KEY_USAGE = ExtensionOID.KEY_USAGE +OID_PRIVATE_KEY_USAGE_PERIOD = ExtensionOID.PRIVATE_KEY_USAGE_PERIOD OID_NAME_CONSTRAINTS = ExtensionOID.NAME_CONSTRAINTS OID_OCSP_NO_CHECK = ExtensionOID.OCSP_NO_CHECK OID_POLICY_CONSTRAINTS = ExtensionOID.POLICY_CONSTRAINTS @@ -226,6 +228,7 @@ "PolicyInformation", "PrecertPoison", "PrecertificateSignedCertificateTimestamps", + "PrivateKeyUsagePeriod", "PublicKeyAlgorithmOID", "RFC822Name", "ReasonFlags", diff --git a/src/rust/src/x509/certificate.rs b/src/rust/src/x509/certificate.rs index 2fb5d5af272e..c5b598075ce3 100644 --- a/src/rust/src/x509/certificate.rs +++ b/src/rust/src/x509/certificate.rs @@ -12,7 +12,7 @@ use cryptography_x509::extensions::{ DistributionPointName, DuplicateExtensionsError, IssuerAlternativeName, KeyUsage, MSCertificateTemplate, NameConstraints, PolicyConstraints, PolicyInformation, PolicyQualifierInfo, Qualifier, RawExtensions, SequenceOfAccessDescriptions, - SequenceOfSubtrees, UserNotice, + SequenceOfSubtrees, UserNotice, PrivateKeyUsagePeriod }; use cryptography_x509::extensions::{Extension, SubjectAlternativeName}; use cryptography_x509::{common, oid}; diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index a4368833ca3f..7e835ed7c3ec 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -4250,6 +4250,10 @@ def test_build_cert_with_rsa_key_too_small( encipher_only=False, decipher_only=False, ), + x509.PrivateKeyUsagePeriod( + not_before=datetime.datetime(2002, 1, 1, 12, 1), + not_after=datetime.datetime(2030, 12, 31, 8, 30), + ), x509.OCSPNoCheck(), x509.SubjectKeyIdentifier, ], diff --git a/tests/x509/test_x509_ext.py b/tests/x509/test_x509_ext.py index d11225fb3077..16913201749b 100644 --- a/tests/x509/test_x509_ext.py +++ b/tests/x509/test_x509_ext.py @@ -1876,6 +1876,65 @@ def test_key_cert_sign_crl_sign(self, backend): assert ku.crl_sign is True +class TestPrivateKeyUsagePeriodExtension: + def test_not_validity(self): + with pytest.raises(TypeError): + x509.PrivateKeyUsagePeriod("notvalidity") # type:ignore[arg-type] + + def test_repr(self): + period = x509.PrivateKeyUsagePeriod( + not_before=datetime.datetime(2012, 1, 1), + not_after=datetime.datetime(2013, 1, 1), + ) + ext = x509.Extension( + ExtensionOID.PRIVATE_KEY_USAGE_PERIOD, False, period + ) + assert repr(ext) == ( + ", " + "critical=False, value=)>" + ) + + def test_eq(self): + period = x509.PrivateKeyUsagePeriod( + not_before=datetime.datetime(2012, 1, 1), + not_after=datetime.datetime(2013, 1, 1), + ) + period2 = x509.PrivateKeyUsagePeriod( + not_before=datetime.datetime(2012, 1, 1), + not_after=datetime.datetime(2013, 1, 1), + ) + assert period == period2 + + def test_ne(self): + period = x509.PrivateKeyUsagePeriod( + not_before=datetime.datetime(2012, 1, 1), + not_after=datetime.datetime(2013, 1, 1), + ) + period2 = x509.PrivateKeyUsagePeriod( + not_before=datetime.datetime(2012, 1, 1), + not_after=datetime.datetime(2014, 1, 1), + ) + assert period != period2 + assert period != object() + + def test_hash(self): + period = x509.PrivateKeyUsagePeriod( + not_before=datetime.datetime(2012, 1, 1), + not_after=datetime.datetime(2013, 1, 1), + ) + period2 = x509.PrivateKeyUsagePeriod( + not_before=datetime.datetime(2012, 1, 1), + not_after=datetime.datetime(2013, 1, 1), + ) + period3 = x509.PrivateKeyUsagePeriod( + not_before=datetime.datetime(2012, 1, 1), + not_after=datetime.datetime(2014, 1, 1), + ) + assert hash(period) == hash(period2) + assert hash(period) != hash(period3) + + class TestDNSName: def test_non_a_label(self): with pytest.raises(ValueError): @@ -6320,6 +6379,7 @@ def test_all_extension_oid_members_have_names_defined(): for oid in dir(ExtensionOID): if oid.startswith("__"): continue + print(getattr(ExtensionOID, oid)) assert getattr(ExtensionOID, oid) in _OID_NAMES