aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS.rst1
-rw-r--r--CHANGELOG.rst14
-rw-r--r--docs/hazmat/primitives/asymmetric/dsa.rst8
-rw-r--r--docs/hazmat/primitives/asymmetric/ec.rst8
-rw-r--r--docs/hazmat/primitives/asymmetric/utils.rst12
-rw-r--r--docs/x509/reference.rst463
-rw-r--r--docs/x509/tutorial.rst15
-rw-r--r--src/cryptography/__about__.py2
-rw-r--r--src/cryptography/hazmat/primitives/asymmetric/utils.py26
-rw-r--r--src/cryptography/utils.py1
-rw-r--r--src/cryptography/x509/__init__.py30
-rw-r--r--src/cryptography/x509/base.py771
-rw-r--r--src/cryptography/x509/extensions.py783
-rw-r--r--tests/hazmat/primitives/test_asym_utils.py50
-rw-r--r--tests/hazmat/primitives/test_dsa.py4
-rw-r--r--tests/test_x509.py32
-rw-r--r--tests/test_x509_ext.py89
-rw-r--r--vectors/cryptography_vectors/__about__.py2
18 files changed, 1221 insertions, 1090 deletions
diff --git a/AUTHORS.rst b/AUTHORS.rst
index 6f862b96..eaadd528 100644
--- a/AUTHORS.rst
+++ b/AUTHORS.rst
@@ -26,3 +26,4 @@ PGP key fingerprints are enclosed in parentheses.
* Andre Caron <andre.l.caron@gmail.com>
* Jiangge Zhang <tonyseek@gmail.com> (BBEC 782B 015F 71B1 5FF7 EACA 1A8C AA98 255F 5000)
* Major Hayden <major@mhtx.net> (1BF9 9264 9596 0033 698C 252B 7370 51E0 C101 1FB1)
+* Phoebe Queen <foibey@gmail.com> (10D4 7741 AB65 50F4 B264 3888 DA40 201A 072B C1FA)
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 8b0d9a3e..900a3365 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,11 +1,15 @@
Changelog
=========
-1.0 - `master`_
-~~~~~~~~~~~~~~~~
+1.1 - `master`_
+~~~~~~~~~~~~~~~
.. note:: This version is not yet released and is under active development.
+
+1.0 - 2015-08-12
+~~~~~~~~~~~~~~~~
+
* Switched to the new `cffi`_ ``set_source`` out-of-line API mode for
compilation. This results in significantly faster imports and lowered
memory consumption. Due to this change we no longer support PyPy releases
@@ -56,6 +60,12 @@ Changelog
* Add support for creating certificate signing requests with
:class:`~cryptography.x509.CertificateSigningRequestBuilder`. This includes
support for the same extensions supported in the ``CertificateBuilder``.
+* Deprecate ``encode_rfc6979_signature`` and ``decode_rfc6979_signature`` in
+ favor of
+ :func:`~cryptography.hazmat.primitives.asymmetric.utils.encode_dss_signature`
+ and
+ :func:`~cryptography.hazmat.primitives.asymmetric.utils.decode_dss_signature`.
+
0.9.3 - 2015-07-09
~~~~~~~~~~~~~~~~~~
diff --git a/docs/hazmat/primitives/asymmetric/dsa.rst b/docs/hazmat/primitives/asymmetric/dsa.rst
index 2ceb7d7d..4eb17e30 100644
--- a/docs/hazmat/primitives/asymmetric/dsa.rst
+++ b/docs/hazmat/primitives/asymmetric/dsa.rst
@@ -80,8 +80,8 @@ provider.
>>> signature = signer.finalize()
The ``signature`` is a ``bytes`` object, whose contents is DER encoded as
-described in :rfc:`6979`. This can be decoded using
-:func:`~cryptography.hazmat.primitives.asymmetric.utils.decode_rfc6979_signature`.
+described in :rfc:`3279`. This can be decoded using
+:func:`~cryptography.hazmat.primitives.asymmetric.utils.decode_dss_signature`.
Verification
~~~~~~~~~~~~
@@ -264,7 +264,7 @@ Key interfaces
Sign data which can be verified later by others using the public key.
The signature is formatted as DER-encoded bytes, as specified in
- :rfc:`6979`.
+ :rfc:`3279`.
:param algorithm: An instance of a
:class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`
@@ -354,7 +354,7 @@ Key interfaces
key.
:param bytes signature: The signature to verify. DER encoded as
- specified in :rfc:`6979`.
+ specified in :rfc:`3279`.
:param algorithm: An instance of a
:class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`
diff --git a/docs/hazmat/primitives/asymmetric/ec.rst b/docs/hazmat/primitives/asymmetric/ec.rst
index e0abe0ab..323f4c3f 100644
--- a/docs/hazmat/primitives/asymmetric/ec.rst
+++ b/docs/hazmat/primitives/asymmetric/ec.rst
@@ -49,8 +49,8 @@ Elliptic Curve Signature Algorithms
>>> signature = signer.finalize()
The ``signature`` is a ``bytes`` object, whose contents is DER encoded as
- described in :rfc:`6979`. This can be decoded using
- :func:`~cryptography.hazmat.primitives.asymmetric.utils.decode_rfc6979_signature`.
+ described in :rfc:`3279`. This can be decoded using
+ :func:`~cryptography.hazmat.primitives.asymmetric.utils.decode_dss_signature`.
@@ -306,7 +306,7 @@ Key Interfaces
Sign data which can be verified later by others using the public key.
The signature is formatted as DER-encoded bytes, as specified in
- :rfc:`6979`.
+ :rfc:`3279`.
:param signature_algorithm: An instance of a
:class:`EllipticCurveSignatureAlgorithm` provider.
@@ -372,7 +372,7 @@ Key Interfaces
key.
:param bytes signature: The signature to verify. DER encoded as
- specified in :rfc:`6979`.
+ specified in :rfc:`3279`.
:param signature_algorithm: An instance of a
:class:`EllipticCurveSignatureAlgorithm` provider.
diff --git a/docs/hazmat/primitives/asymmetric/utils.rst b/docs/hazmat/primitives/asymmetric/utils.rst
index 7380f0b5..07883598 100644
--- a/docs/hazmat/primitives/asymmetric/utils.rst
+++ b/docs/hazmat/primitives/asymmetric/utils.rst
@@ -6,10 +6,11 @@ Asymmetric Utilities
.. currentmodule:: cryptography.hazmat.primitives.asymmetric.utils
-.. function:: decode_rfc6979_signature(signature)
+.. function:: decode_dss_signature(signature)
- Takes in :rfc:`6979` signatures generated by the DSA/ECDSA signers and
- returns a tuple ``(r, s)``.
+ Takes in signatures generated by the DSA/ECDSA signers and returns a
+ tuple ``(r, s)``. These signatures are ASN.1 encoded ``Dss-Sig-Value``
+ sequences (as defined in :rfc:`3279`)
:param bytes signature: The signature to decode.
@@ -17,9 +18,10 @@ Asymmetric Utilities
:raises ValueError: Raised if the signature is malformed.
-.. function:: encode_rfc6979_signature(r, s)
+.. function:: encode_dss_signature(r, s)
- Creates an :rfc:`6979` byte string from raw signature values.
+ Creates an ASN.1 encoded ``Dss-Sig-Value`` (as defined in :rfc:`3279`) from
+ raw ``r`` and ``s`` values.
:param int r: The raw signature value ``r``.
diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst
index d86ebbe8..62bdb3a9 100644
--- a/docs/x509/reference.rst
+++ b/docs/x509/reference.rst
@@ -401,6 +401,7 @@ X.509 Certificate Builder
>>> from cryptography.hazmat.backends import default_backend
>>> from cryptography.hazmat.primitives import hashes
>>> from cryptography.hazmat.primitives.asymmetric import rsa
+ >>> from cryptography.x509.oid import NameOID
>>> import datetime
>>> import uuid
>>> one_day = datetime.timedelta(1, 0, 0)
@@ -416,10 +417,10 @@ X.509 Certificate Builder
... ).public_key()
>>> builder = x509.CertificateBuilder()
>>> builder = builder.subject_name(x509.Name([
- ... x509.NameAttribute(x509.OID_COMMON_NAME, u'cryptography.io'),
+ ... x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
... ]))
>>> builder = builder.issuer_name(x509.Name([
- ... x509.NameAttribute(x509.OID_COMMON_NAME, u'cryptography.io'),
+ ... x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
... ]))
>>> builder = builder.not_valid_before(datetime.datetime.today() - one_day)
>>> builder = builder.not_valid_after(datetime.datetime(2018, 8, 2))
@@ -634,6 +635,7 @@ X.509 CSR (Certificate Signing Request) Builder Object
>>> from cryptography.hazmat.backends import default_backend
>>> from cryptography.hazmat.primitives import hashes
>>> from cryptography.hazmat.primitives.asymmetric import rsa
+ >>> from cryptography.x509.oid import NameOID
>>> private_key = rsa.generate_private_key(
... public_exponent=65537,
... key_size=2048,
@@ -641,7 +643,7 @@ X.509 CSR (Certificate Signing Request) Builder Object
... )
>>> builder = x509.CertificateSigningRequestBuilder()
>>> builder = builder.subject_name(x509.Name([
- ... x509.NameAttribute(x509.OID_COMMON_NAME, u'cryptography.io'),
+ ... x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
... ]))
>>> builder = builder.add_extension(
... x509.BasicConstraints(ca=False, path_length=None), critical=True,
@@ -720,7 +722,7 @@ X.509 CSR (Certificate Signing Request) Builder Object
.. doctest::
- >>> cert.subject.get_attributes_for_oid(x509.OID_COMMON_NAME)
+ >>> cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME)
[<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commonName)>, value=u'Good CA')>]
.. class:: Version
@@ -883,7 +885,25 @@ X.509 Extensions
.. doctest::
- >>> cert.extensions.get_extension_for_oid(x509.OID_BASIC_CONSTRAINTS)
+ >>> from cryptography.x509.oid import ExtensionOID
+ >>> cert.extensions.get_extension_for_oid(ExtensionOID.BASIC_CONSTRAINTS)
+ <Extension(oid=<ObjectIdentifier(oid=2.5.29.19, name=basicConstraints)>, critical=True, value=<BasicConstraints(ca=True, path_length=None)>)>
+
+ .. method:: get_extension_for_class(extclass)
+
+ .. versionadded:: 1.1
+
+ :param extclass: An extension class.
+
+ :returns: An instance of the extension class.
+
+ :raises cryptography.x509.ExtensionNotFound: If the certificate does
+ not have the extension requested.
+
+ .. doctest::
+
+ >>> from cryptography import x509
+ >>> cert.extensions.get_extension_for_class(x509.BasicConstraints)
<Extension(oid=<ObjectIdentifier(oid=2.5.29.19, name=basicConstraints)>, critical=True, value=<BasicConstraints(ca=True, path_length=None)>)>
.. class:: Extension
@@ -894,7 +914,7 @@ X.509 Extensions
:type: :class:`ObjectIdentifier`
- The :ref:`extension OID <extension_oids>`.
+ One of the :class:`~cryptography.x509.oid.ExtensionOID` OIDs.
.. attribute:: critical
@@ -930,7 +950,7 @@ X.509 Extensions
:type: :class:`ObjectIdentifier`
- Returns :data:`OID_KEY_USAGE`.
+ Returns :attr:`~cryptography.x509.oid.ExtensionOID.KEY_USAGE`.
.. attribute:: digital_signature
@@ -1029,7 +1049,7 @@ X.509 Extensions
:type: :class:`ObjectIdentifier`
- Returns :data:`OID_BASIC_CONSTRAINTS`.
+ Returns :attr:`~cryptography.x509.oid.ExtensionOID.BASIC_CONSTRAINTS`.
.. attribute:: ca
@@ -1057,7 +1077,8 @@ X.509 Extensions
This extension indicates one or more purposes for which the certified
public key may be used, in addition to or in place of the basic
purposes indicated in the key usage extension. The object is
- iterable to obtain the list of :ref:`extended key usage OIDs <eku_oids>`.
+ iterable to obtain the list of
+ :class:`~cryptography.x509.oid.ExtendedKeyUsageOID` OIDs present.
.. attribute:: oid
@@ -1065,7 +1086,7 @@ X.509 Extensions
:type: :class:`ObjectIdentifier`
- Returns :data:`OID_EXTENDED_KEY_USAGE`.
+ Returns :attr:`~cryptography.x509.oid.ExtensionOID.EXTENDED_KEY_USAGE`.
.. class:: OCSPNoCheck
@@ -1087,7 +1108,7 @@ X.509 Extensions
:type: :class:`ObjectIdentifier`
- Returns :data:`OID_OCSP_NO_CHECK`.
+ Returns :attr:`~cryptography.x509.oid.ExtensionOID.OCSP_NO_CHECK`.
.. class:: NameConstraints
@@ -1104,7 +1125,7 @@ X.509 Extensions
:type: :class:`ObjectIdentifier`
- Returns :data:`OID_NAME_CONSTRAINTS`.
+ Returns :attr:`~cryptography.x509.oid.ExtensionOID.NAME_CONSTRAINTS`.
.. attribute:: permitted_subtrees
@@ -1139,7 +1160,8 @@ X.509 Extensions
:type: :class:`ObjectIdentifier`
- Returns :data:`OID_AUTHORITY_KEY_IDENTIFIER`.
+ Returns
+ :attr:`~cryptography.x509.oid.ExtensionOID.AUTHORITY_KEY_IDENTIFIER`.
.. attribute:: key_identifier
@@ -1204,7 +1226,8 @@ X.509 Extensions
:type: :class:`ObjectIdentifier`
- Returns :data:`OID_SUBJECT_KEY_IDENTIFIER`.
+ Returns
+ :attr:`~cryptography.x509.oid.ExtensionOID.SUBJECT_KEY_IDENTIFIER`.
.. attribute:: digest
@@ -1252,7 +1275,8 @@ X.509 Extensions
:type: :class:`ObjectIdentifier`
- Returns :data:`OID_SUBJECT_ALTERNATIVE_NAME`.
+ Returns
+ :attr:`~cryptography.x509.oid.ExtensionOID.SUBJECT_ALTERNATIVE_NAME`.
.. method:: get_values_for_type(type)
@@ -1269,7 +1293,7 @@ X.509 Extensions
>>> from cryptography.hazmat.primitives import hashes
>>> cert = x509.load_pem_x509_certificate(cryptography_cert_pem, default_backend())
>>> # Get the subjectAltName extension from the certificate
- >>> ext = cert.extensions.get_extension_for_oid(x509.OID_SUBJECT_ALTERNATIVE_NAME)
+ >>> ext = cert.extensions.get_extension_for_oid(ExtensionOID.SUBJECT_ALTERNATIVE_NAME)
>>> # Get the dNSName entries from the SAN extension
>>> ext.value.get_values_for_type(x509.DNSName)
[u'www.cryptography.io', u'cryptography.io']
@@ -1290,7 +1314,8 @@ X.509 Extensions
:type: :class:`ObjectIdentifier`
- Returns :data:`OID_ISSUER_ALTERNATIVE_NAME`.
+ Returns
+ :attr:`~cryptography.x509.oid.ExtensionOID.ISSUER_ALTERNATIVE_NAME`.
.. method:: get_values_for_type(type)
@@ -1308,7 +1333,8 @@ X.509 Extensions
information and services for the issuer of the certificate in which
the extension appears. Information and services may include online
validation services (such as OCSP) and issuer data. It is an iterable,
- containing one or more :class:`AccessDescription` instances.
+ containing one or more :class:`~cryptography.x509.AccessDescription`
+ instances.
.. attribute:: oid
@@ -1316,7 +1342,8 @@ X.509 Extensions
:type: :class:`ObjectIdentifier`
- Returns :data:`OID_AUTHORITY_INFORMATION_ACCESS`.
+ Returns
+ :attr:`~cryptography.x509.oid.ExtensionOID.AUTHORITY_INFORMATION_ACCESS`.
.. class:: AccessDescription
@@ -1328,11 +1355,16 @@ X.509 Extensions
:type: :class:`ObjectIdentifier`
The access method defines what the ``access_location`` means. It must
- be either :data:`OID_OCSP` or :data:`OID_CA_ISSUERS`. If it is
- :data:`OID_OCSP` the access location will be where to obtain OCSP
- information for the certificate. If it is :data:`OID_CA_ISSUERS` the
- access location will provide additional information about the issuing
- certificate.
+ be either
+ :attr:`~cryptography.x509.oid.AuthorityInformationAccessOID.OCSP` or
+ :attr:`~cryptography.x509.oid.AuthorityInformationAccessOID.CA_ISSUERS`.
+ If it is
+ :attr:`~cryptography.x509.oid.AuthorityInformationAccessOID.OCSP`
+ the access location will be where to obtain OCSP
+ information for the certificate. If it is
+ :attr:`~cryptography.x509.oid.AuthorityInformationAccessOID.CA_ISSUERS`
+ the access location will provide additional information about the
+ issuing certificate.
.. attribute:: access_location
@@ -1354,7 +1386,8 @@ X.509 Extensions
:type: :class:`ObjectIdentifier`
- Returns :data:`OID_CRL_DISTRIBUTION_POINTS`.
+ Returns
+ :attr:`~cryptography.x509.oid.ExtensionOID.CRL_DISTRIBUTION_POINTS`.
.. class:: DistributionPoint
@@ -1445,14 +1478,16 @@ X.509 Extensions
.. versionadded:: 1.0
The inhibit ``anyPolicy`` extension indicates that the special OID
- :data:`OID_ANY_POLICY`, is not considered an explicit match for other
- :class:`CertificatePolicies` except when it appears in an intermediate
- self-issued CA certificate. The value indicates the number of additional
- non-self-issued certificates that may appear in the path before
- :data:`OID_ANY_POLICY` is no longer permitted. For example, a value
- of one indicates that :data:`OID_ANY_POLICY` may be processed in
- certificates issued by the subject of this certificate, but not in
- additional certificates in the path.
+ :attr:`~cryptography.x509.oid.CertificatePoliciesOID.ANY_POLICY`, is not
+ considered an explicit match for other :class:`CertificatePolicies` except
+ when it appears in an intermediate self-issued CA certificate. The value
+ indicates the number of additional non-self-issued certificates that may
+ appear in the path before
+ :attr:`~cryptography.x509.oid.CertificatePoliciesOID.ANY_POLICY` is no
+ longer permitted. For example, a value of one indicates that
+ :attr:`~cryptography.x509.oid.CertificatePoliciesOID.ANY_POLICY` may be
+ processed in certificates issued by the subject of this certificate, but
+ not in additional certificates in the path.
.. attribute:: oid
@@ -1460,7 +1495,8 @@ X.509 Extensions
:type: :class:`ObjectIdentifier`
- Returns :data:`OID_INHIBIT_ANY_POLICY`.
+ Returns
+ :attr:`~cryptography.x509.oid.ExtensionOID.INHIBIT_ANY_POLICY`.
.. attribute:: skip_certs
@@ -1479,7 +1515,8 @@ X.509 Extensions
:type: :class:`ObjectIdentifier`
- Returns :data:`OID_CERTIFICATE_POLICIES`.
+ Returns
+ :attr:`~cryptography.x509.oid.ExtensionOID.CERTIFICATE_POLICIES`.
Certificate Policies Classes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1555,297 +1592,303 @@ Object Identifiers
X.509 elements are frequently identified by :class:`ObjectIdentifier`
instances. The following common OIDs are available as constants.
-Name OIDs
-~~~~~~~~~
+.. currentmodule:: cryptography.x509.oid
-.. data:: OID_COMMON_NAME
+.. class:: NameOID
- Corresponds to the dotted string ``"2.5.4.3"``. Historically the domain
- name would be encoded here for server certificates. :rfc:`2818` deprecates
- this practice and names of that type should now be located in a
- SubjectAlternativeName extension. This OID is typically seen in X.509 names.
+ These OIDs are typically seen in X.509 names.
-.. data:: OID_COUNTRY_NAME
+ .. versionadded:: 1.0
- Corresponds to the dotted string ``"2.5.4.6"``. This OID is typically seen
- in X.509 names.
+ .. attribute:: COMMON_NAME
-.. data:: OID_LOCALITY_NAME
+ Corresponds to the dotted string ``"2.5.4.3"``. Historically the domain
+ name would be encoded here for server certificates. :rfc:`2818`
+ deprecates this practice and names of that type should now be located
+ in a :class:`~cryptography.x509.SubjectAlternativeName` extension.
- Corresponds to the dotted string ``"2.5.4.7"``. This OID is typically seen
- in X.509 names.
+ .. attribute:: COUNTRY_NAME
-.. data:: OID_STATE_OR_PROVINCE_NAME
+ Corresponds to the dotted string ``"2.5.4.6"``.
- Corresponds to the dotted string ``"2.5.4.8"``. This OID is typically seen
- in X.509 names.
+ .. attribute:: LOCALITY_NAME
-.. data:: OID_ORGANIZATION_NAME
+ Corresponds to the dotted string ``"2.5.4.7"``.
- Corresponds to the dotted string ``"2.5.4.10"``. This OID is typically seen
- in X.509 names.
+ .. attribute:: STATE_OR_PROVINCE_NAME
-.. data:: OID_ORGANIZATIONAL_UNIT_NAME
+ Corresponds to the dotted string ``"2.5.4.8"``.
- Corresponds to the dotted string ``"2.5.4.11"``. This OID is typically seen
- in X.509 names.
+ .. attribute:: ORGANIZATION_NAME
-.. data:: OID_SERIAL_NUMBER
+ Corresponds to the dotted string ``"2.5.4.10"``.
- Corresponds to the dotted string ``"2.5.4.5"``. This is distinct from the
- serial number of the certificate itself (which can be obtained with
- :func:`Certificate.serial`). This OID is typically seen in X.509 names.
+ .. attribute:: ORGANIZATIONAL_UNIT_NAME
-.. data:: OID_SURNAME
+ Corresponds to the dotted string ``"2.5.4.11"``.
- Corresponds to the dotted string ``"2.5.4.4"``. This OID is typically seen
- in X.509 names.
+ .. attribute:: SERIAL_NUMBER
-.. data:: OID_GIVEN_NAME
+ Corresponds to the dotted string ``"2.5.4.5"``. This is distinct from
+ the serial number of the certificate itself (which can be obtained with
+ :func:`~cryptography.x509.Certificate.serial`).
- Corresponds to the dotted string ``"2.5.4.42"``. This OID is typically seen
- in X.509 names.
+ .. attribute:: SURNAME
-.. data:: OID_TITLE
+ Corresponds to the dotted string ``"2.5.4.4"``.
- Corresponds to the dotted string ``"2.5.4.12"``. This OID is typically seen
- in X.509 names.
+ .. attribute:: GIVEN_NAME
-.. data:: OID_GENERATION_QUALIFIER
+ Corresponds to the dotted string ``"2.5.4.42"``.
- Corresponds to the dotted string ``"2.5.4.44"``. This OID is typically seen
- in X.509 names.
+ .. attribute:: TITLE
-.. data:: OID_DN_QUALIFIER
+ Corresponds to the dotted string ``"2.5.4.12"``.
- Corresponds to the dotted string ``"2.5.4.46"``. This specifies
- disambiguating information to add to the relative distinguished name of an
- entry. See :rfc:`2256`. This OID is typically seen in X.509 names.
+ .. attribute:: GENERATION_QUALIFIER
-.. data:: OID_PSEUDONYM
+ Corresponds to the dotted string ``"2.5.4.44"``.
- Corresponds to the dotted string ``"2.5.4.65"``. This OID is typically seen
- in X.509 names.
+ .. attribute:: DN_QUALIFIER
-.. data:: OID_DOMAIN_COMPONENT
+ Corresponds to the dotted string ``"2.5.4.46"``. This specifies
+ disambiguating information to add to the relative distinguished name of an
+ entry. See :rfc:`2256`.
- Corresponds to the dotted string ``"0.9.2342.19200300.100.1.25"``. A string
- holding one component of a domain name. See :rfc:`4519`. This OID is
- typically seen in X.509 names.
+ .. attribute:: PSEUDONYM
-.. data:: OID_EMAIL_ADDRESS
+ Corresponds to the dotted string ``"2.5.4.65"``.
- Corresponds to the dotted string ``"1.2.840.113549.1.9.1"``. This OID is
- typically seen in X.509 names.
+ .. attribute:: DOMAIN_COMPONENT
-Signature Algorithm OIDs
-~~~~~~~~~~~~~~~~~~~~~~~~
+ Corresponds to the dotted string ``"0.9.2342.19200300.100.1.25"``. A string
+ holding one component of a domain name. See :rfc:`4519`.
-.. data:: OID_RSA_WITH_MD5
+ .. attribute:: EMAIL_ADDRESS
- Corresponds to the dotted string ``"1.2.840.113549.1.1.4"``. This is
- an MD5 digest signed by an RSA key.
+ Corresponds to the dotted string ``"1.2.840.113549.1.9.1"``.
-.. data:: OID_RSA_WITH_SHA1
- Corresponds to the dotted string ``"1.2.840.113549.1.1.5"``. This is
- a SHA1 digest signed by an RSA key.
+.. class:: SignatureAlgorithmOID
-.. data:: OID_RSA_WITH_SHA224
+ .. versionadded:: 1.0
- Corresponds to the dotted string ``"1.2.840.113549.1.1.14"``. This is
- a SHA224 digest signed by an RSA key.
+ .. attribute:: RSA_WITH_MD5
-.. data:: OID_RSA_WITH_SHA256
+ Corresponds to the dotted string ``"1.2.840.113549.1.1.4"``. This is
+ an MD5 digest signed by an RSA key.
- Corresponds to the dotted string ``"1.2.840.113549.1.1.11"``. This is
- a SHA256 digest signed by an RSA key.
+ .. attribute:: RSA_WITH_SHA1
-.. data:: OID_RSA_WITH_SHA384
+ Corresponds to the dotted string ``"1.2.840.113549.1.1.5"``. This is
+ a SHA1 digest signed by an RSA key.
- Corresponds to the dotted string ``"1.2.840.113549.1.1.12"``. This is
- a SHA384 digest signed by an RSA key.
+ .. attribute:: RSA_WITH_SHA224
-.. data:: OID_RSA_WITH_SHA512
+ Corresponds to the dotted string ``"1.2.840.113549.1.1.14"``. This is
+ a SHA224 digest signed by an RSA key.
- Corresponds to the dotted string ``"1.2.840.113549.1.1.13"``. This is
- a SHA512 digest signed by an RSA key.
+ .. attribute:: RSA_WITH_SHA256
-.. data:: OID_ECDSA_WITH_SHA1
+ Corresponds to the dotted string ``"1.2.840.113549.1.1.11"``. This is
+ a SHA256 digest signed by an RSA key.
- Corresponds to the dotted string ``"1.2.840.10045.4.1"``. This is a SHA1
- digest signed by an ECDSA key.
+ .. attribute:: RSA_WITH_SHA384
-.. data:: OID_ECDSA_WITH_SHA224
+ Corresponds to the dotted string ``"1.2.840.113549.1.1.12"``. This is
+ a SHA384 digest signed by an RSA key.
- Corresponds to the dotted string ``"1.2.840.10045.4.3.1"``. This is
- a SHA224 digest signed by an ECDSA key.
+ .. attribute:: RSA_WITH_SHA512
-.. data:: OID_ECDSA_WITH_SHA256
+ Corresponds to the dotted string ``"1.2.840.113549.1.1.13"``. This is
+ a SHA512 digest signed by an RSA key.
- Corresponds to the dotted string ``"1.2.840.10045.4.3.2"``. This is
- a SHA256 digest signed by an ECDSA key.
+ .. attribute:: ECDSA_WITH_SHA1
-.. data:: OID_ECDSA_WITH_SHA384
+ Corresponds to the dotted string ``"1.2.840.10045.4.1"``. This is a SHA1
+ digest signed by an ECDSA key.
- Corresponds to the dotted string ``"1.2.840.10045.4.3.3"``. This is
- a SHA384 digest signed by an ECDSA key.
+ .. attribute:: ECDSA_WITH_SHA224
-.. data:: OID_ECDSA_WITH_SHA512
+ Corresponds to the dotted string ``"1.2.840.10045.4.3.1"``. This is
+ a SHA224 digest signed by an ECDSA key.
- Corresponds to the dotted string ``"1.2.840.10045.4.3.4"``. This is
- a SHA512 digest signed by an ECDSA key.
+ .. attribute:: ECDSA_WITH_SHA256
-.. data:: OID_DSA_WITH_SHA1
+ Corresponds to the dotted string ``"1.2.840.10045.4.3.2"``. This is
+ a SHA256 digest signed by an ECDSA key.
- Corresponds to the dotted string ``"1.2.840.10040.4.3"``. This is
- a SHA1 digest signed by a DSA key.
+ .. attribute:: ECDSA_WITH_SHA384
-.. data:: OID_DSA_WITH_SHA224
+ Corresponds to the dotted string ``"1.2.840.10045.4.3.3"``. This is
+ a SHA384 digest signed by an ECDSA key.
- Corresponds to the dotted string ``"2.16.840.1.101.3.4.3.1"``. This is
- a SHA224 digest signed by a DSA key.
+ .. attribute:: ECDSA_WITH_SHA512
-.. data:: OID_DSA_WITH_SHA256
+ Corresponds to the dotted string ``"1.2.840.10045.4.3.4"``. This is
+ a SHA512 digest signed by an ECDSA key.
- Corresponds to the dotted string ``"2.16.840.1.101.3.4.3.2"``. This is
- a SHA256 digest signed by a DSA key.
+ .. attribute:: DSA_WITH_SHA1
-.. _eku_oids:
+ Corresponds to the dotted string ``"1.2.840.10040.4.3"``. This is
+ a SHA1 digest signed by a DSA key.
-Extended Key Usage OIDs
-~~~~~~~~~~~~~~~~~~~~~~~
+ .. attribute:: DSA_WITH_SHA224
-.. data:: OID_SERVER_AUTH
+ Corresponds to the dotted string ``"2.16.840.1.101.3.4.3.1"``. This is
+ a SHA224 digest signed by a DSA key.
- Corresponds to the dotted string ``"1.3.6.1.5.5.7.3.1"``. This is used to
- denote that a certificate may be used for TLS web server authentication.
+ .. attribute:: DSA_WITH_SHA256
-.. data:: OID_CLIENT_AUTH
+ Corresponds to the dotted string ``"2.16.840.1.101.3.4.3.2"``. This is
+ a SHA256 digest signed by a DSA key.
- Corresponds to the dotted string ``"1.3.6.1.5.5.7.3.2"``. This is used to
- denote that a certificate may be used for TLS web client authentication.
-.. data:: OID_CODE_SIGNING
+.. class:: ExtendedKeyUsageOID
- Corresponds to the dotted string ``"1.3.6.1.5.5.7.3.3"``. This is used to
- denote that a certificate may be used for code signing.
+ .. versionadded:: 1.0
+
+ .. attribute:: SERVER_AUTH
+
+ Corresponds to the dotted string ``"1.3.6.1.5.5.7.3.1"``. This is used
+ to denote that a certificate may be used for TLS web server
+ authentication.
+
+ .. attribute:: CLIENT_AUTH
+
+ Corresponds to the dotted string ``"1.3.6.1.5.5.7.3.2"``. This is used
+ to denote that a certificate may be used for TLS web client
+ authentication.
+
+ .. attribute:: CODE_SIGNING
+
+ Corresponds to the dotted string ``"1.3.6.1.5.5.7.3.3"``. This is used
+ to denote that a certificate may be used for code signing.
+
+ .. attribute:: EMAIL_PROTECTION
-.. data:: OID_EMAIL_PROTECTION
+ Corresponds to the dotted string ``"1.3.6.1.5.5.7.3.4"``. This is used
+ to denote that a certificate may be used for email protection.
- Corresponds to the dotted string ``"1.3.6.1.5.5.7.3.4"``. This is used to
- denote that a certificate may be used for email protection.
+ .. attribute:: TIME_STAMPING
-.. data:: OID_TIME_STAMPING
+ Corresponds to the dotted string ``"1.3.6.1.5.5.7.3.8"``. This is used
+ to denote that a certificate may be used for time stamping.
- Corresponds to the dotted string ``"1.3.6.1.5.5.7.3.8"``. This is used to
- denote that a certificate may be used for time stamping.
+ .. attribute:: OCSP_SIGNING
-.. data:: OID_OCSP_SIGNING
+ Corresponds to the dotted string ``"1.3.6.1.5.5.7.3.9"``. This is used
+ to denote that a certificate may be used for signing OCSP responses.
- Corresponds to the dotted string ``"1.3.6.1.5.5.7.3.9"``. This is used to
- denote that a certificate may be used for signing OCSP responses.
-Authority Information Access OIDs
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. class:: AuthorityInformationAccessOID
-.. data:: OID_OCSP
+ .. versionadded:: 1.0
+
+ .. attribute:: OCSP
+
+ Corresponds to the dotted string ``"1.3.6.1.5.5.7.48.1"``. Used as the
+ identifier for OCSP data in
+ :class:`~cryptography.x509.AccessDescription` objects.
+
+ .. attribute:: CA_ISSUERS
- Corresponds to the dotted string ``"1.3.6.1.5.5.7.48.1"``. Used as the
- identifier for OCSP data in :class:`AccessDescription` objects.
+ Corresponds to the dotted string ``"1.3.6.1.5.5.7.48.2"``. Used as the
+ identifier for CA issuer data in
+ :class:`~cryptography.x509.AccessDescription` objects.
-.. data:: OID_CA_ISSUERS
- Corresponds to the dotted string ``"1.3.6.1.5.5.7.48.2"``. Used as the
- identifier for CA issuer data in :class:`AccessDescription` objects.
+.. class:: CertificatePoliciesOID
-Policy Qualifier OIDs
-~~~~~~~~~~~~~~~~~~~~~
+ .. versionadded:: 1.0
+
+ .. attribute:: CPS_QUALIFIER
-.. data:: OID_CPS_QUALIFIER
+ Corresponds to the dotted string ``"1.3.6.1.5.5.7.2.1"``.
- Corresponds to the dotted string ``"1.3.6.1.5.5.7.2.1"``.
+ .. attribute:: CPS_USER_NOTICE
-.. data:: OID_CPS_USER_NOTICE
+ Corresponds to the dotted string ``"1.3.6.1.5.5.7.2.2"``.
- Corresponds to the dotted string ``"1.3.6.1.5.5.7.2.2"``.
+ .. attribute:: ANY_POLICY
-.. data:: OID_ANY_POLICY
+ Corresponds to the dotted string ``"2.5.29.32.0"``.
- Corresponds to the dotted string ``"2.5.29.32.0"``.
-.. _extension_oids:
+.. class:: ExtensionOID
-Extension OIDs
-~~~~~~~~~~~~~~
+ .. versionadded:: 1.0
-.. data:: OID_BASIC_CONSTRAINTS
+ .. attribute:: BASIC_CONSTRAINTS
- Corresponds to the dotted string ``"2.5.29.19"``. The identifier for the
- :class:`BasicConstraints` extension type.
+ Corresponds to the dotted string ``"2.5.29.19"``. The identifier for the
+ :class:`~cryptography.x509.BasicConstraints` extension type.
-.. data:: OID_KEY_USAGE
+ .. attribute:: KEY_USAGE
- Corresponds to the dotted string ``"2.5.29.15"``. The identifier for the
- :class:`KeyUsage` extension type.
+ Corresponds to the dotted string ``"2.5.29.15"``. The identifier for the
+ :class:`~cryptography.x509.KeyUsage` extension type.
-.. data:: OID_SUBJECT_ALTERNATIVE_NAME
+ .. attribute:: SUBJECT_ALTERNATIVE_NAME
- Corresponds to the dotted string ``"2.5.29.17"``. The identifier for the
- :class:`SubjectAlternativeName` extension type.
+ Corresponds to the dotted string ``"2.5.29.17"``. The identifier for the
+ :class:`~cryptography.x509.SubjectAlternativeName` extension type.
-.. data:: OID_ISSUER_ALTERNATIVE_NAME
+ .. attribute:: ISSUER_ALTERNATIVE_NAME
- Corresponds to the dotted string ``"2.5.29.18"``. The identifier for the
- :class:`IssuerAlternativeName` extension type.
+ Corresponds to the dotted string ``"2.5.29.18"``. The identifier for the
+ :class:`~cryptography.x509.IssuerAlternativeName` extension type.
-.. data:: OID_SUBJECT_KEY_IDENTIFIER
+ .. attribute:: SUBJECT_KEY_IDENTIFIER
- Corresponds to the dotted string ``"2.5.29.14"``. The identifier for the
- :class:`SubjectKeyIdentifier` extension type.
+ Corresponds to the dotted string ``"2.5.29.14"``. The identifier for the
+ :class:`~cryptography.x509.SubjectKeyIdentifier` extension type.
-.. data:: OID_NAME_CONSTRAINTS
+ .. attribute:: NAME_CONSTRAINTS
- Corresponds to the dotted string ``"2.5.29.30"``. The identifier for the
- :class:`NameConstraints` extension type.
+ Corresponds to the dotted string ``"2.5.29.30"``. The identifier for the
+ :class:`~cryptography.x509.NameConstraints` extension type.
-.. data:: OID_CRL_DISTRIBUTION_POINTS
+ .. attribute:: CRL_DISTRIBUTION_POINTS
- Corresponds to the dotted string ``"2.5.29.31"``. The identifier for the
- :class:`CRLDistributionPoints` extension type.
+ Corresponds to the dotted string ``"2.5.29.31"``. The identifier for the
+ :class:`~cryptography.x509.CRLDistributionPoints` extension type.
-.. data:: OID_CERTIFICATE_POLICIES
+ .. attribute:: CERTIFICATE_POLICIES
- Corresponds to the dotted string ``"2.5.29.32"``. The identifier for the
- :class:`CertificatePolicies` extension type.
+ Corresponds to the dotted string ``"2.5.29.32"``. The identifier for the
+ :class:`~cryptography.x509.CertificatePolicies` extension type.
-.. data:: OID_AUTHORITY_KEY_IDENTIFIER
+ .. attribute:: AUTHORITY_KEY_IDENTIFIER
- Corresponds to the dotted string ``"2.5.29.35"``. The identifier for the
- :class:`AuthorityKeyIdentifier` extension type.
+ Corresponds to the dotted string ``"2.5.29.35"``. The identifier for the
+ :class:`~cryptography.x509.AuthorityKeyIdentifier` extension type.
-.. data:: OID_EXTENDED_KEY_USAGE
+ .. attribute:: EXTENDED_KEY_USAGE
- Corresponds to the dotted string ``"2.5.29.37"``. The identifier for the
- :class:`ExtendedKeyUsage` extension type.
+ Corresponds to the dotted string ``"2.5.29.37"``. The identifier for the
+ :class:`~cryptography.x509.ExtendedKeyUsage` extension type.
-.. data:: OID_AUTHORITY_INFORMATION_ACCESS
+ .. attribute:: AUTHORITY_INFORMATION_ACCESS
- Corresponds to the dotted string ``"1.3.6.1.5.5.7.1.1"``. The identifier
- for the :class:`AuthorityInformationAccess` extension type.
+ Corresponds to the dotted string ``"1.3.6.1.5.5.7.1.1"``. The identifier
+ for the :class:`~cryptography.x509.AuthorityInformationAccess` extension
+ type.
-.. data:: OID_INHIBIT_ANY_POLICY
+ .. attribute:: INHIBIT_ANY_POLICY
- Corresponds to the dotted string ``"2.5.29.54"``. The identifier
- for the :class:`InhibitAnyPolicy` extension type.
+ Corresponds to the dotted string ``"2.5.29.54"``. The identifier
+ for the :class:`~cryptography.x509.InhibitAnyPolicy` extension type.
-.. data:: OID_OCSP_NO_CHECK
+ .. attribute:: OCSP_NO_CHECK
- Corresponds to the dotted string ``"1.3.6.1.5.5.7.48.1.5"``. The identifier
- for the :class:`OCSPNoCheck` extension type.
+ Corresponds to the dotted string ``"1.3.6.1.5.5.7.48.1.5"``. The
+ identifier for the :class:`~cryptography.x509.OCSPNoCheck` extension
+ type.
Exceptions
~~~~~~~~~~
+.. currentmodule:: cryptography.x509
.. class:: InvalidVersion
diff --git a/docs/x509/tutorial.rst b/docs/x509/tutorial.rst
index bcaec809..4caa90b5 100644
--- a/docs/x509/tutorial.rst
+++ b/docs/x509/tutorial.rst
@@ -37,7 +37,7 @@ are the most common types of keys on the web right now):
... backend=default_backend()
... )
>>> # Write our key to disk for safe keeping
- >>> with open("path/to/store/key.pem") as f:
+ >>> with open("path/to/store/key.pem", "w") as f:
... f.write(key.private_bytes(
... encoding=serialization.Encoding.PEM,
... format=serialization.PrivateFormat.TraditionalOpenSSL,
@@ -57,14 +57,15 @@ a few details:
.. code-block:: pycon
>>> from cryptography import x509
+ >>> from cryptography.x509.oid import NameOID
>>> # Generate a CSR
>>> csr = x509.CertificateSigningRequestBuilder().subject_name(x509.Name([
... # Provide various details about who we are.
- ... x509.NameAttribute(x509.OID_COUNTRY_NAME, u"US"),
- ... x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, u"CA"),
- ... x509.NameAttribute(x509.OID_LOCALITY_NAME, u"San Francisco"),
- ... x509.NameAttribute(x509.OID_ORGANIZATION_NAME, u"My Company"),
- ... x509.NameAttribute(x509.COMMON_NAME, u"mysite.com"),
+ ... x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
+ ... x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"CA"),
+ ... x509.NameAttribute(NameOID.LOCALITY_NAME, u"San Francisco"),
+ ... x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"My Company"),
+ ... x509.NameAttribute(NameOID.COMMON_NAME, u"mysite.com"),
... ])).add_extension(x509.SubjectAlternativeName([
... # Describe what sites we want this certificate for.
... x509.DNSName(u"mysite.com"),
@@ -73,7 +74,7 @@ a few details:
... # Sign the CSR with our private key.
... ])).sign(key, hashes.SHA256(), default_backend())
>>> # Write our CSR out to disk.
- >>> with open("path/to/csr.pem") as f:
+ >>> with open("path/to/csr.pem", "w") as f:
... f.write(csr.public_bytes(serialization.Encoding.PEM))
Now we can give our CSR to a CA, who will give a certificate to us in return.
diff --git a/src/cryptography/__about__.py b/src/cryptography/__about__.py
index 9c28be2e..d89a9fc7 100644
--- a/src/cryptography/__about__.py
+++ b/src/cryptography/__about__.py
@@ -14,7 +14,7 @@ __summary__ = ("cryptography is a package which provides cryptographic recipes"
" and primitives to Python developers.")
__uri__ = "https://github.com/pyca/cryptography"
-__version__ = "1.0.dev1"
+__version__ = "1.1.dev1"
__author__ = "The cryptography developers"
__email__ = "cryptography-dev@python.org"
diff --git a/src/cryptography/hazmat/primitives/asymmetric/utils.py b/src/cryptography/hazmat/primitives/asymmetric/utils.py
index a03025bb..bad9ab73 100644
--- a/src/cryptography/hazmat/primitives/asymmetric/utils.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/utils.py
@@ -4,12 +4,16 @@
from __future__ import absolute_import, division, print_function
+import warnings
+
from pyasn1.codec.der import decoder, encoder
from pyasn1.error import PyAsn1Error
from pyasn1.type import namedtype, univ
import six
+from cryptography import utils
+
class _DSSSigValue(univ.Sequence):
componentType = namedtype.NamedTypes(
@@ -19,6 +23,17 @@ class _DSSSigValue(univ.Sequence):
def decode_rfc6979_signature(signature):
+ warnings.warn(
+ "decode_rfc6979_signature is deprecated and will "
+ "be removed in a future version, use decode_dss_signature instead "
+ "instead.",
+ utils.DeprecatedIn10,
+ stacklevel=2
+ )
+ return decode_dss_signature(signature)
+
+
+def decode_dss_signature(signature):
try:
data, remaining = decoder.decode(signature, asn1Spec=_DSSSigValue())
except PyAsn1Error:
@@ -35,6 +50,17 @@ def decode_rfc6979_signature(signature):
def encode_rfc6979_signature(r, s):
+ warnings.warn(
+ "encode_rfc6979_signature is deprecated and will "
+ "be removed in a future version, use encode_dss_signature instead "
+ "instead.",
+ utils.DeprecatedIn10,
+ stacklevel=2
+ )
+ return encode_dss_signature(r, s)
+
+
+def encode_dss_signature(r, s):
if (
not isinstance(r, six.integer_types) or
not isinstance(s, six.integer_types)
diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py
index 993571bd..237d5968 100644
--- a/src/cryptography/utils.py
+++ b/src/cryptography/utils.py
@@ -13,6 +13,7 @@ import warnings
DeprecatedIn09 = DeprecationWarning
+DeprecatedIn10 = PendingDeprecationWarning
def read_only_property(name):
diff --git a/src/cryptography/x509/__init__.py b/src/cryptography/x509/__init__.py
index 389d737b..1aa2598b 100644
--- a/src/cryptography/x509/__init__.py
+++ b/src/cryptography/x509/__init__.py
@@ -5,21 +5,21 @@
from __future__ import absolute_import, division, print_function
from cryptography.x509.base import (
- AccessDescription, AuthorityInformationAccess,
- BasicConstraints, CRLDistributionPoints, Certificate, CertificateBuilder,
- CertificatePolicies, CertificateRevocationList, CertificateSigningRequest,
- CertificateSigningRequestBuilder, DistributionPoint,
- DuplicateExtension, ExtendedKeyUsage, Extension, ExtensionNotFound,
- ExtensionType, Extensions, GeneralNames, InhibitAnyPolicy,
- InvalidVersion, IssuerAlternativeName, KeyUsage, NameConstraints,
- NoticeReference, OCSPNoCheck, ObjectIdentifier,
- PolicyInformation, ReasonFlags,
- RevokedCertificate, SubjectAlternativeName,
- UnsupportedExtension, UserNotice, Version, load_der_x509_certificate,
- load_der_x509_csr, load_pem_x509_certificate, load_pem_x509_csr,
+ Certificate, CertificateBuilder, CertificateRevocationList,
+ CertificateSigningRequest, CertificateSigningRequestBuilder,
+ InvalidVersion, RevokedCertificate,
+ Version, load_der_x509_certificate, load_der_x509_csr,
+ load_pem_x509_certificate, load_pem_x509_csr,
)
from cryptography.x509.extensions import (
- AuthorityKeyIdentifier, SubjectKeyIdentifier
+ AccessDescription, AuthorityInformationAccess,
+ AuthorityKeyIdentifier, BasicConstraints, CRLDistributionPoints,
+ CertificatePolicies, DistributionPoint, DuplicateExtension,
+ ExtendedKeyUsage, Extension, ExtensionNotFound, ExtensionType, Extensions,
+ GeneralNames, InhibitAnyPolicy, IssuerAlternativeName, KeyUsage,
+ NameConstraints, NoticeReference, OCSPNoCheck, PolicyInformation,
+ ReasonFlags, SubjectAlternativeName, SubjectKeyIdentifier,
+ UnsupportedExtension, UserNotice
)
from cryptography.x509.general_name import (
DNSName, DirectoryName, GeneralName, IPAddress, OtherName, RFC822Name,
@@ -29,8 +29,8 @@ from cryptography.x509.general_name import (
from cryptography.x509.name import Name, NameAttribute
from cryptography.x509.oid import (
AuthorityInformationAccessOID, CRLExtensionOID, CertificatePoliciesOID,
- ExtendedKeyUsageOID, ExtensionOID, NameOID, SignatureAlgorithmOID,
- _SIG_OIDS_TO_HASH
+ ExtendedKeyUsageOID, ExtensionOID, NameOID, ObjectIdentifier,
+ SignatureAlgorithmOID, _SIG_OIDS_TO_HASH
)
diff --git a/src/cryptography/x509/base.py b/src/cryptography/x509/base.py
index b906c7a8..27eafac6 100644
--- a/src/cryptography/x509/base.py
+++ b/src/cryptography/x509/base.py
@@ -6,18 +6,14 @@ from __future__ import absolute_import, division, print_function
import abc
import datetime
-import ipaddress
from enum import Enum
import six
from cryptography import utils
from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa
-from cryptography.x509.general_name import GeneralName, IPAddress, OtherName
+from cryptography.x509.extensions import Extension, ExtensionType
from cryptography.x509.name import Name
-from cryptography.x509.oid import (
- AuthorityInformationAccessOID, ExtensionOID, ObjectIdentifier
-)
_UNIX_EPOCH = datetime.datetime(1970, 1, 1)
@@ -50,771 +46,6 @@ class InvalidVersion(Exception):
self.parsed_version = parsed_version
-class DuplicateExtension(Exception):
- def __init__(self, msg, oid):
- super(DuplicateExtension, self).__init__(msg)
- self.oid = oid
-
-
-class UnsupportedExtension(Exception):
- def __init__(self, msg, oid):
- super(UnsupportedExtension, self).__init__(msg)
- self.oid = oid
-
-
-class ExtensionNotFound(Exception):
- def __init__(self, msg, oid):
- super(ExtensionNotFound, self).__init__(msg)
- self.oid = oid
-
-
-class Extensions(object):
- def __init__(self, extensions):
- self._extensions = extensions
-
- def get_extension_for_oid(self, oid):
- for ext in self:
- if ext.oid == oid:
- return ext
-
- raise ExtensionNotFound("No {0} extension was found".format(oid), oid)
-
- def __iter__(self):
- return iter(self._extensions)
-
- def __len__(self):
- return len(self._extensions)
-
-
-class Extension(object):
- def __init__(self, oid, critical, value):
- if not isinstance(oid, ObjectIdentifier):
- raise TypeError(
- "oid argument must be an ObjectIdentifier instance."
- )
-
- if not isinstance(critical, bool):
- raise TypeError("critical must be a boolean value")
-
- self._oid = oid
- self._critical = critical
- self._value = value
-
- oid = utils.read_only_property("_oid")
- critical = utils.read_only_property("_critical")
- value = utils.read_only_property("_value")
-
- def __repr__(self):
- return ("<Extension(oid={0.oid}, critical={0.critical}, "
- "value={0.value})>").format(self)
-
- def __eq__(self, other):
- if not isinstance(other, Extension):
- return NotImplemented
-
- return (
- self.oid == other.oid and
- self.critical == other.critical and
- self.value == other.value
- )
-
- def __ne__(self, other):
- return not self == other
-
-
-@six.add_metaclass(abc.ABCMeta)
-class ExtensionType(object):
- @abc.abstractproperty
- def oid(self):
- """
- Returns the oid associated with the given extension type.
- """
-
-
-@utils.register_interface(ExtensionType)
-class ExtendedKeyUsage(object):
- oid = ExtensionOID.EXTENDED_KEY_USAGE
-
- def __init__(self, usages):
- if not all(isinstance(x, ObjectIdentifier) for x in usages):
- raise TypeError(
- "Every item in the usages list must be an ObjectIdentifier"
- )
-
- self._usages = usages
-
- def __iter__(self):
- return iter(self._usages)
-
- def __len__(self):
- return len(self._usages)
-
- def __repr__(self):
- return "<ExtendedKeyUsage({0})>".format(self._usages)
-
- def __eq__(self, other):
- if not isinstance(other, ExtendedKeyUsage):
- return NotImplemented
-
- return self._usages == other._usages
-
- def __ne__(self, other):
- return not self == other
-
-
-@utils.register_interface(ExtensionType)
-class OCSPNoCheck(object):
- oid = ExtensionOID.OCSP_NO_CHECK
-
-
-@utils.register_interface(ExtensionType)
-class BasicConstraints(object):
- oid = ExtensionOID.BASIC_CONSTRAINTS
-
- def __init__(self, ca, path_length):
- if not isinstance(ca, bool):
- raise TypeError("ca must be a boolean value")
-
- if path_length is not None and not ca:
- raise ValueError("path_length must be None when ca is False")
-
- if (
- path_length is not None and
- (not isinstance(path_length, six.integer_types) or path_length < 0)
- ):
- raise TypeError(
- "path_length must be a non-negative integer or None"
- )
-
- self._ca = ca
- self._path_length = path_length
-
- ca = utils.read_only_property("_ca")
- path_length = utils.read_only_property("_path_length")
-
- def __repr__(self):
- return ("<BasicConstraints(ca={0.ca}, "
- "path_length={0.path_length})>").format(self)
-
- def __eq__(self, other):
- if not isinstance(other, BasicConstraints):
- return NotImplemented
-
- return self.ca == other.ca and self.path_length == other.path_length
-
- def __ne__(self, other):
- return not self == other
-
-
-@utils.register_interface(ExtensionType)
-class KeyUsage(object):
- oid = ExtensionOID.KEY_USAGE
-
- def __init__(self, digital_signature, content_commitment, key_encipherment,
- data_encipherment, key_agreement, key_cert_sign, crl_sign,
- encipher_only, decipher_only):
- if not key_agreement and (encipher_only or decipher_only):
- raise ValueError(
- "encipher_only and decipher_only can only be true when "
- "key_agreement is true"
- )
-
- self._digital_signature = digital_signature
- self._content_commitment = content_commitment
- self._key_encipherment = key_encipherment
- self._data_encipherment = data_encipherment
- self._key_agreement = key_agreement
- self._key_cert_sign = key_cert_sign
- self._crl_sign = crl_sign
- self._encipher_only = encipher_only
- self._decipher_only = decipher_only
-
- digital_signature = utils.read_only_property("_digital_signature")
- content_commitment = utils.read_only_property("_content_commitment")
- key_encipherment = utils.read_only_property("_key_encipherment")
- data_encipherment = utils.read_only_property("_data_encipherment")
- key_agreement = utils.read_only_property("_key_agreement")
- key_cert_sign = utils.read_only_property("_key_cert_sign")
- crl_sign = utils.read_only_property("_crl_sign")
-
- @property
- def encipher_only(self):
- if not self.key_agreement:
- raise ValueError(
- "encipher_only is undefined unless key_agreement is true"
- )
- else:
- return self._encipher_only
-
- @property
- def decipher_only(self):
- if not self.key_agreement:
- raise ValueError(
- "decipher_only is undefined unless key_agreement is true"
- )
- else:
- return self._decipher_only
-
- def __repr__(self):
- try:
- encipher_only = self.encipher_only
- decipher_only = self.decipher_only
- except ValueError:
- encipher_only = None
- decipher_only = None
-
- return ("<KeyUsage(digital_signature={0.digital_signature}, "
- "content_commitment={0.content_commitment}, "
- "key_encipherment={0.key_encipherment}, "
- "data_encipherment={0.data_encipherment}, "
- "key_agreement={0.key_agreement}, "
- "key_cert_sign={0.key_cert_sign}, crl_sign={0.crl_sign}, "
- "encipher_only={1}, decipher_only={2})>").format(
- self, encipher_only, decipher_only)
-
- def __eq__(self, other):
- if not isinstance(other, KeyUsage):
- return NotImplemented
-
- return (
- self.digital_signature == other.digital_signature and
- self.content_commitment == other.content_commitment and
- self.key_encipherment == other.key_encipherment and
- self.data_encipherment == other.data_encipherment and
- self.key_agreement == other.key_agreement and
- self.key_cert_sign == other.key_cert_sign and
- self.crl_sign == other.crl_sign and
- self._encipher_only == other._encipher_only and
- self._decipher_only == other._decipher_only
- )
-
- def __ne__(self, other):
- return not self == other
-
-
-@utils.register_interface(ExtensionType)
-class AuthorityInformationAccess(object):
- oid = ExtensionOID.AUTHORITY_INFORMATION_ACCESS
-
- def __init__(self, descriptions):
- if not all(isinstance(x, AccessDescription) for x in descriptions):
- raise TypeError(
- "Every item in the descriptions list must be an "
- "AccessDescription"
- )
-
- self._descriptions = descriptions
-
- def __iter__(self):
- return iter(self._descriptions)
-
- def __len__(self):
- return len(self._descriptions)
-
- def __repr__(self):
- return "<AuthorityInformationAccess({0})>".format(self._descriptions)
-
- def __eq__(self, other):
- if not isinstance(other, AuthorityInformationAccess):
- return NotImplemented
-
- return self._descriptions == other._descriptions
-
- def __ne__(self, other):
- return not self == other
-
-
-class AccessDescription(object):
- def __init__(self, access_method, access_location):
- if not (access_method == AuthorityInformationAccessOID.OCSP or
- access_method == AuthorityInformationAccessOID.CA_ISSUERS):
- raise ValueError(
- "access_method must be OID_OCSP or OID_CA_ISSUERS"
- )
-
- if not isinstance(access_location, GeneralName):
- raise TypeError("access_location must be a GeneralName")
-
- self._access_method = access_method
- self._access_location = access_location
-
- def __repr__(self):
- return (
- "<AccessDescription(access_method={0.access_method}, access_locati"
- "on={0.access_location})>".format(self)
- )
-
- def __eq__(self, other):
- if not isinstance(other, AccessDescription):
- return NotImplemented
-
- return (
- self.access_method == other.access_method and
- self.access_location == other.access_location
- )
-
- def __ne__(self, other):
- return not self == other
-
- access_method = utils.read_only_property("_access_method")
- access_location = utils.read_only_property("_access_location")
-
-
-@utils.register_interface(ExtensionType)
-class CertificatePolicies(object):
- oid = ExtensionOID.CERTIFICATE_POLICIES
-
- def __init__(self, policies):
- if not all(isinstance(x, PolicyInformation) for x in policies):
- raise TypeError(
- "Every item in the policies list must be a "
- "PolicyInformation"
- )
-
- self._policies = policies
-
- def __iter__(self):
- return iter(self._policies)
-
- def __len__(self):
- return len(self._policies)
-
- def __repr__(self):
- return "<CertificatePolicies({0})>".format(self._policies)
-
- def __eq__(self, other):
- if not isinstance(other, CertificatePolicies):
- return NotImplemented
-
- return self._policies == other._policies
-
- def __ne__(self, other):
- return not self == other
-
-
-class PolicyInformation(object):
- def __init__(self, policy_identifier, policy_qualifiers):
- if not isinstance(policy_identifier, ObjectIdentifier):
- raise TypeError("policy_identifier must be an ObjectIdentifier")
-
- self._policy_identifier = policy_identifier
- if policy_qualifiers and not all(
- isinstance(
- x, (six.text_type, UserNotice)
- ) for x in policy_qualifiers
- ):
- raise TypeError(
- "policy_qualifiers must be a list of strings and/or UserNotice"
- " objects or None"
- )
-
- self._policy_qualifiers = policy_qualifiers
-
- def __repr__(self):
- return (
- "<PolicyInformation(policy_identifier={0.policy_identifier}, polic"
- "y_qualifiers={0.policy_qualifiers})>".format(self)
- )
-
- def __eq__(self, other):
- if not isinstance(other, PolicyInformation):
- return NotImplemented
-
- return (
- self.policy_identifier == other.policy_identifier and
- self.policy_qualifiers == other.policy_qualifiers
- )
-
- def __ne__(self, other):
- return not self == other
-
- policy_identifier = utils.read_only_property("_policy_identifier")
- policy_qualifiers = utils.read_only_property("_policy_qualifiers")
-
-
-class UserNotice(object):
- def __init__(self, notice_reference, explicit_text):
- if notice_reference and not isinstance(
- notice_reference, NoticeReference
- ):
- raise TypeError(
- "notice_reference must be None or a NoticeReference"
- )
-
- self._notice_reference = notice_reference
- self._explicit_text = explicit_text
-
- def __repr__(self):
- return (
- "<UserNotice(notice_reference={0.notice_reference}, explicit_text="
- "{0.explicit_text!r})>".format(self)
- )
-
- def __eq__(self, other):
- if not isinstance(other, UserNotice):
- return NotImplemented
-
- return (
- self.notice_reference == other.notice_reference and
- self.explicit_text == other.explicit_text
- )
-
- def __ne__(self, other):
- return not self == other
-
- notice_reference = utils.read_only_property("_notice_reference")
- explicit_text = utils.read_only_property("_explicit_text")
-
-
-class NoticeReference(object):
- def __init__(self, organization, notice_numbers):
- self._organization = organization
- if not isinstance(notice_numbers, list) or not all(
- isinstance(x, int) for x in notice_numbers
- ):
- raise TypeError(
- "notice_numbers must be a list of integers"
- )
-
- self._notice_numbers = notice_numbers
-
- def __repr__(self):
- return (
- "<NoticeReference(organization={0.organization!r}, notice_numbers="
- "{0.notice_numbers})>".format(self)
- )
-
- def __eq__(self, other):
- if not isinstance(other, NoticeReference):
- return NotImplemented
-
- return (
- self.organization == other.organization and
- self.notice_numbers == other.notice_numbers
- )
-
- def __ne__(self, other):
- return not self == other
-
- organization = utils.read_only_property("_organization")
- notice_numbers = utils.read_only_property("_notice_numbers")
-
-
-@utils.register_interface(ExtensionType)
-class NameConstraints(object):
- oid = ExtensionOID.NAME_CONSTRAINTS
-
- def __init__(self, permitted_subtrees, excluded_subtrees):
- if permitted_subtrees is not None:
- if not all(
- isinstance(x, GeneralName) for x in permitted_subtrees
- ):
- raise TypeError(
- "permitted_subtrees must be a list of GeneralName objects "
- "or None"
- )
-
- self._validate_ip_name(permitted_subtrees)
-
- if excluded_subtrees is not None:
- if not all(
- isinstance(x, GeneralName) for x in excluded_subtrees
- ):
- raise TypeError(
- "excluded_subtrees must be a list of GeneralName objects "
- "or None"
- )
-
- self._validate_ip_name(excluded_subtrees)
-
- if permitted_subtrees is None and excluded_subtrees is None:
- raise ValueError(
- "At least one of permitted_subtrees and excluded_subtrees "
- "must not be None"
- )
-
- self._permitted_subtrees = permitted_subtrees
- self._excluded_subtrees = excluded_subtrees
-
- def __eq__(self, other):
- if not isinstance(other, NameConstraints):
- return NotImplemented
-
- return (
- self.excluded_subtrees == other.excluded_subtrees and
- self.permitted_subtrees == other.permitted_subtrees
- )
-
- def __ne__(self, other):
- return not self == other
-
- def _validate_ip_name(self, tree):
- if any(isinstance(name, IPAddress) and not isinstance(
- name.value, (ipaddress.IPv4Network, ipaddress.IPv6Network)
- ) for name in tree):
- raise TypeError(
- "IPAddress name constraints must be an IPv4Network or"
- " IPv6Network object"
- )
-
- def __repr__(self):
- return (
- u"<NameConstraints(permitted_subtrees={0.permitted_subtrees}, "
- u"excluded_subtrees={0.excluded_subtrees})>".format(self)
- )
-
- permitted_subtrees = utils.read_only_property("_permitted_subtrees")
- excluded_subtrees = utils.read_only_property("_excluded_subtrees")
-
-
-@utils.register_interface(ExtensionType)
-class CRLDistributionPoints(object):
- oid = ExtensionOID.CRL_DISTRIBUTION_POINTS
-
- def __init__(self, distribution_points):
- if not all(
- isinstance(x, DistributionPoint) for x in distribution_points
- ):
- raise TypeError(
- "distribution_points must be a list of DistributionPoint "
- "objects"
- )
-
- self._distribution_points = distribution_points
-
- def __iter__(self):
- return iter(self._distribution_points)
-
- def __len__(self):
- return len(self._distribution_points)
-
- def __repr__(self):
- return "<CRLDistributionPoints({0})>".format(self._distribution_points)
-
- def __eq__(self, other):
- if not isinstance(other, CRLDistributionPoints):
- return NotImplemented
-
- return self._distribution_points == other._distribution_points
-
- def __ne__(self, other):
- return not self == other
-
-
-class DistributionPoint(object):
- def __init__(self, full_name, relative_name, reasons, crl_issuer):
- if full_name and relative_name:
- raise ValueError(
- "You cannot provide both full_name and relative_name, at "
- "least one must be None."
- )
-
- if full_name and not all(
- isinstance(x, GeneralName) for x in full_name
- ):
- raise TypeError(
- "full_name must be a list of GeneralName objects"
- )
-
- if relative_name and not isinstance(relative_name, Name):
- raise TypeError("relative_name must be a Name")
-
- if crl_issuer and not all(
- isinstance(x, GeneralName) for x in crl_issuer
- ):
- raise TypeError(
- "crl_issuer must be None or a list of general names"
- )
-
- if reasons and (not isinstance(reasons, frozenset) or not all(
- isinstance(x, ReasonFlags) for x in reasons
- )):
- raise TypeError("reasons must be None or frozenset of ReasonFlags")
-
- if reasons and (
- ReasonFlags.unspecified in reasons or
- ReasonFlags.remove_from_crl in reasons
- ):
- raise ValueError(
- "unspecified and remove_from_crl are not valid reasons in a "
- "DistributionPoint"
- )
-
- if reasons and not crl_issuer and not (full_name or relative_name):
- raise ValueError(
- "You must supply crl_issuer, full_name, or relative_name when "
- "reasons is not None"
- )
-
- self._full_name = full_name
- self._relative_name = relative_name
- self._reasons = reasons
- self._crl_issuer = crl_issuer
-
- def __repr__(self):
- return (
- "<DistributionPoint(full_name={0.full_name}, relative_name={0.rela"
- "tive_name}, reasons={0.reasons}, crl_issuer={0.crl_is"
- "suer})>".format(self)
- )
-
- def __eq__(self, other):
- if not isinstance(other, DistributionPoint):
- return NotImplemented
-
- return (
- self.full_name == other.full_name and
- self.relative_name == other.relative_name and
- self.reasons == other.reasons and
- self.crl_issuer == other.crl_issuer
- )
-
- def __ne__(self, other):
- return not self == other
-
- full_name = utils.read_only_property("_full_name")
- relative_name = utils.read_only_property("_relative_name")
- reasons = utils.read_only_property("_reasons")
- crl_issuer = utils.read_only_property("_crl_issuer")
-
-
-class ReasonFlags(Enum):
- unspecified = "unspecified"
- key_compromise = "keyCompromise"
- ca_compromise = "cACompromise"
- affiliation_changed = "affiliationChanged"
- superseded = "superseded"
- cessation_of_operation = "cessationOfOperation"
- certificate_hold = "certificateHold"
- privilege_withdrawn = "privilegeWithdrawn"
- aa_compromise = "aACompromise"
- remove_from_crl = "removeFromCRL"
-
-
-@utils.register_interface(ExtensionType)
-class InhibitAnyPolicy(object):
- oid = ExtensionOID.INHIBIT_ANY_POLICY
-
- def __init__(self, skip_certs):
- if not isinstance(skip_certs, six.integer_types):
- raise TypeError("skip_certs must be an integer")
-
- if skip_certs < 0:
- raise ValueError("skip_certs must be a non-negative integer")
-
- self._skip_certs = skip_certs
-
- def __repr__(self):
- return "<InhibitAnyPolicy(skip_certs={0.skip_certs})>".format(self)
-
- def __eq__(self, other):
- if not isinstance(other, InhibitAnyPolicy):
- return NotImplemented
-
- return self.skip_certs == other.skip_certs
-
- def __ne__(self, other):
- return not self == other
-
- skip_certs = utils.read_only_property("_skip_certs")
-
-
-class GeneralNames(object):
- def __init__(self, general_names):
- if not all(isinstance(x, GeneralName) for x in general_names):
- raise TypeError(
- "Every item in the general_names list must be an "
- "object conforming to the GeneralName interface"
- )
-
- self._general_names = general_names
-
- def __iter__(self):
- return iter(self._general_names)
-
- def __len__(self):
- return len(self._general_names)
-
- def get_values_for_type(self, type):
- # Return the value of each GeneralName, except for OtherName instances
- # which we return directly because it has two important properties not
- # just one value.
- objs = (i for i in self if isinstance(i, type))
- if type != OtherName:
- objs = (i.value for i in objs)
- return list(objs)
-
- def __repr__(self):
- return "<GeneralNames({0})>".format(self._general_names)
-
- def __eq__(self, other):
- if not isinstance(other, GeneralNames):
- return NotImplemented
-
- return self._general_names == other._general_names
-
- def __ne__(self, other):
- return not self == other
-
-
-@utils.register_interface(ExtensionType)
-class SubjectAlternativeName(object):
- oid = ExtensionOID.SUBJECT_ALTERNATIVE_NAME
-
- def __init__(self, general_names):
- self._general_names = GeneralNames(general_names)
-
- def __iter__(self):
- return iter(self._general_names)
-
- def __len__(self):
- return len(self._general_names)
-
- def get_values_for_type(self, type):
- return self._general_names.get_values_for_type(type)
-
- def __repr__(self):
- return "<SubjectAlternativeName({0})>".format(self._general_names)
-
- def __eq__(self, other):
- if not isinstance(other, SubjectAlternativeName):
- return NotImplemented
-
- return self._general_names == other._general_names
-
- def __ne__(self, other):
- return not self == other
-
-
-@utils.register_interface(ExtensionType)
-class IssuerAlternativeName(object):
- oid = ExtensionOID.ISSUER_ALTERNATIVE_NAME
-
- def __init__(self, general_names):
- self._general_names = GeneralNames(general_names)
-
- def __iter__(self):
- return iter(self._general_names)
-
- def __len__(self):
- return len(self._general_names)
-
- def get_values_for_type(self, type):
- return self._general_names.get_values_for_type(type)
-
- def __repr__(self):
- return "<IssuerAlternativeName({0})>".format(self._general_names)
-
- def __eq__(self, other):
- if not isinstance(other, IssuerAlternativeName):
- return NotImplemented
-
- return self._general_names == other._general_names
-
- def __ne__(self, other):
- return not self == other
-
-
@six.add_metaclass(abc.ABCMeta)
class Certificate(object):
@abc.abstractmethod
diff --git a/src/cryptography/x509/extensions.py b/src/cryptography/x509/extensions.py
index 38175531..803d7ec5 100644
--- a/src/cryptography/x509/extensions.py
+++ b/src/cryptography/x509/extensions.py
@@ -4,7 +4,10 @@
from __future__ import absolute_import, division, print_function
+import abc
import hashlib
+import ipaddress
+from enum import Enum
from pyasn1.codec.der import decoder
from pyasn1.type import namedtype, univ
@@ -13,10 +16,10 @@ import six
from cryptography import utils
from cryptography.hazmat.primitives import serialization
-from cryptography.x509.base import ExtensionType
-from cryptography.x509.general_name import GeneralName
+from cryptography.x509.general_name import GeneralName, IPAddress, OtherName
+from cryptography.x509.name import Name
from cryptography.x509.oid import (
- ExtensionOID
+ AuthorityInformationAccessOID, ExtensionOID, ObjectIdentifier
)
@@ -48,6 +51,60 @@ def _key_identifier_from_public_key(public_key):
return hashlib.sha1(data).digest()
+class DuplicateExtension(Exception):
+ def __init__(self, msg, oid):
+ super(DuplicateExtension, self).__init__(msg)
+ self.oid = oid
+
+
+class UnsupportedExtension(Exception):
+ def __init__(self, msg, oid):
+ super(UnsupportedExtension, self).__init__(msg)
+ self.oid = oid
+
+
+class ExtensionNotFound(Exception):
+ def __init__(self, msg, oid):
+ super(ExtensionNotFound, self).__init__(msg)
+ self.oid = oid
+
+
+@six.add_metaclass(abc.ABCMeta)
+class ExtensionType(object):
+ @abc.abstractproperty
+ def oid(self):
+ """
+ Returns the oid associated with the given extension type.
+ """
+
+
+class Extensions(object):
+ def __init__(self, extensions):
+ self._extensions = extensions
+
+ def get_extension_for_oid(self, oid):
+ for ext in self:
+ if ext.oid == oid:
+ return ext
+
+ raise ExtensionNotFound("No {0} extension was found".format(oid), oid)
+
+ def get_extension_for_class(self, extclass):
+ for ext in self:
+ if isinstance(ext.value, extclass):
+ return ext
+
+ raise ExtensionNotFound(
+ "No {0} extension was found".format(extclass), extclass.oid
+ )
+
+ def __iter__(self):
+ return iter(self._extensions)
+
+ def __len__(self):
+ return len(self._extensions)
+
+
@utils.register_interface(ExtensionType)
class AuthorityKeyIdentifier(object):
oid = ExtensionOID.AUTHORITY_KEY_IDENTIFIER
@@ -142,3 +199,723 @@ class SubjectKeyIdentifier(object):
def __ne__(self, other):
return not self == other
+
+
+@utils.register_interface(ExtensionType)
+class AuthorityInformationAccess(object):
+ oid = ExtensionOID.AUTHORITY_INFORMATION_ACCESS
+
+ def __init__(self, descriptions):
+ if not all(isinstance(x, AccessDescription) for x in descriptions):
+ raise TypeError(
+ "Every item in the descriptions list must be an "
+ "AccessDescription"
+ )
+
+ self._descriptions = descriptions
+
+ def __iter__(self):
+ return iter(self._descriptions)
+
+ def __len__(self):
+ return len(self._descriptions)
+
+ def __repr__(self):
+ return "<AuthorityInformationAccess({0})>".format(self._descriptions)
+
+ def __eq__(self, other):
+ if not isinstance(other, AuthorityInformationAccess):
+ return NotImplemented
+
+ return self._descriptions == other._descriptions
+
+ def __ne__(self, other):
+ return not self == other
+
+
+class AccessDescription(object):
+ def __init__(self, access_method, access_location):
+ if not (access_method == AuthorityInformationAccessOID.OCSP or
+ access_method == AuthorityInformationAccessOID.CA_ISSUERS):
+ raise ValueError(
+ "access_method must be OID_OCSP or OID_CA_ISSUERS"
+ )
+
+ if not isinstance(access_location, GeneralName):
+ raise TypeError("access_location must be a GeneralName")
+
+ self._access_method = access_method
+ self._access_location = access_location
+
+ def __repr__(self):
+ return (
+ "<AccessDescription(access_method={0.access_method}, access_locati"
+ "on={0.access_location})>".format(self)
+ )
+
+ def __eq__(self, other):
+ if not isinstance(other, AccessDescription):
+ return NotImplemented
+
+ return (
+ self.access_method == other.access_method and
+ self.access_location == other.access_location
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+ access_method = utils.read_only_property("_access_method")
+ access_location = utils.read_only_property("_access_location")
+
+
+@utils.register_interface(ExtensionType)
+class BasicConstraints(object):
+ oid = ExtensionOID.BASIC_CONSTRAINTS
+
+ def __init__(self, ca, path_length):
+ if not isinstance(ca, bool):
+ raise TypeError("ca must be a boolean value")
+
+ if path_length is not None and not ca:
+ raise ValueError("path_length must be None when ca is False")
+
+ if (
+ path_length is not None and
+ (not isinstance(path_length, six.integer_types) or path_length < 0)
+ ):
+ raise TypeError(
+ "path_length must be a non-negative integer or None"
+ )
+
+ self._ca = ca
+ self._path_length = path_length
+
+ ca = utils.read_only_property("_ca")
+ path_length = utils.read_only_property("_path_length")
+
+ def __repr__(self):
+ return ("<BasicConstraints(ca={0.ca}, "
+ "path_length={0.path_length})>").format(self)
+
+ def __eq__(self, other):
+ if not isinstance(other, BasicConstraints):
+ return NotImplemented
+
+ return self.ca == other.ca and self.path_length == other.path_length
+
+ def __ne__(self, other):
+ return not self == other
+
+
+@utils.register_interface(ExtensionType)
+class CRLDistributionPoints(object):
+ oid = ExtensionOID.CRL_DISTRIBUTION_POINTS
+
+ def __init__(self, distribution_points):
+ if not all(
+ isinstance(x, DistributionPoint) for x in distribution_points
+ ):
+ raise TypeError(
+ "distribution_points must be a list of DistributionPoint "
+ "objects"
+ )
+
+ self._distribution_points = distribution_points
+
+ def __iter__(self):
+ return iter(self._distribution_points)
+
+ def __len__(self):
+ return len(self._distribution_points)
+
+ def __repr__(self):
+ return "<CRLDistributionPoints({0})>".format(self._distribution_points)
+
+ def __eq__(self, other):
+ if not isinstance(other, CRLDistributionPoints):
+ return NotImplemented
+
+ return self._distribution_points == other._distribution_points
+
+ def __ne__(self, other):
+ return not self == other
+
+
+class DistributionPoint(object):
+ def __init__(self, full_name, relative_name, reasons, crl_issuer):
+ if full_name and relative_name:
+ raise ValueError(
+ "You cannot provide both full_name and relative_name, at "
+ "least one must be None."
+ )
+
+ if full_name and not all(
+ isinstance(x, GeneralName) for x in full_name
+ ):
+ raise TypeError(
+ "full_name must be a list of GeneralName objects"
+ )
+
+ if relative_name and not isinstance(relative_name, Name):
+ raise TypeError("relative_name must be a Name")
+
+ if crl_issuer and not all(
+ isinstance(x, GeneralName) for x in crl_issuer
+ ):
+ raise TypeError(
+ "crl_issuer must be None or a list of general names"
+ )
+
+ if reasons and (not isinstance(reasons, frozenset) or not all(
+ isinstance(x, ReasonFlags) for x in reasons
+ )):
+ raise TypeError("reasons must be None or frozenset of ReasonFlags")
+
+ if reasons and (
+ ReasonFlags.unspecified in reasons or
+ ReasonFlags.remove_from_crl in reasons
+ ):
+ raise ValueError(
+ "unspecified and remove_from_crl are not valid reasons in a "
+ "DistributionPoint"
+ )
+
+ if reasons and not crl_issuer and not (full_name or relative_name):
+ raise ValueError(
+ "You must supply crl_issuer, full_name, or relative_name when "
+ "reasons is not None"
+ )
+
+ self._full_name = full_name
+ self._relative_name = relative_name
+ self._reasons = reasons
+ self._crl_issuer = crl_issuer
+
+ def __repr__(self):
+ return (
+ "<DistributionPoint(full_name={0.full_name}, relative_name={0.rela"
+ "tive_name}, reasons={0.reasons}, crl_issuer={0.crl_is"
+ "suer})>".format(self)
+ )
+
+ def __eq__(self, other):
+ if not isinstance(other, DistributionPoint):
+ return NotImplemented
+
+ return (
+ self.full_name == other.full_name and
+ self.relative_name == other.relative_name and
+ self.reasons == other.reasons and
+ self.crl_issuer == other.crl_issuer
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+ full_name = utils.read_only_property("_full_name")
+ relative_name = utils.read_only_property("_relative_name")
+ reasons = utils.read_only_property("_reasons")
+ crl_issuer = utils.read_only_property("_crl_issuer")
+
+
+class ReasonFlags(Enum):
+ unspecified = "unspecified"
+ key_compromise = "keyCompromise"
+ ca_compromise = "cACompromise"
+ affiliation_changed = "affiliationChanged"
+ superseded = "superseded"
+ cessation_of_operation = "cessationOfOperation"
+ certificate_hold = "certificateHold"
+ privilege_withdrawn = "privilegeWithdrawn"
+ aa_compromise = "aACompromise"
+ remove_from_crl = "removeFromCRL"
+
+
+@utils.register_interface(ExtensionType)
+class CertificatePolicies(object):
+ oid = ExtensionOID.CERTIFICATE_POLICIES
+
+ def __init__(self, policies):
+ if not all(isinstance(x, PolicyInformation) for x in policies):
+ raise TypeError(
+ "Every item in the policies list must be a "
+ "PolicyInformation"
+ )
+
+ self._policies = policies
+
+ def __iter__(self):
+ return iter(self._policies)
+
+ def __len__(self):
+ return len(self._policies)
+
+ def __repr__(self):
+ return "<CertificatePolicies({0})>".format(self._policies)
+
+ def __eq__(self, other):
+ if not isinstance(other, CertificatePolicies):
+ return NotImplemented
+
+ return self._policies == other._policies
+
+ def __ne__(self, other):
+ return not self == other
+
+
+class PolicyInformation(object):
+ def __init__(self, policy_identifier, policy_qualifiers):
+ if not isinstance(policy_identifier, ObjectIdentifier):
+ raise TypeError("policy_identifier must be an ObjectIdentifier")
+
+ self._policy_identifier = policy_identifier
+ if policy_qualifiers and not all(
+ isinstance(
+ x, (six.text_type, UserNotice)
+ ) for x in policy_qualifiers
+ ):
+ raise TypeError(
+ "policy_qualifiers must be a list of strings and/or UserNotice"
+ " objects or None"
+ )
+
+ self._policy_qualifiers = policy_qualifiers
+
+ def __repr__(self):
+ return (
+ "<PolicyInformation(policy_identifier={0.policy_identifier}, polic"
+ "y_qualifiers={0.policy_qualifiers})>".format(self)
+ )
+
+ def __eq__(self, other):
+ if not isinstance(other, PolicyInformation):
+ return NotImplemented
+
+ return (
+ self.policy_identifier == other.policy_identifier and
+ self.policy_qualifiers == other.policy_qualifiers
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+ policy_identifier = utils.read_only_property("_policy_identifier")
+ policy_qualifiers = utils.read_only_property("_policy_qualifiers")
+
+
+class UserNotice(object):
+ def __init__(self, notice_reference, explicit_text):
+ if notice_reference and not isinstance(
+ notice_reference, NoticeReference
+ ):
+ raise TypeError(
+ "notice_reference must be None or a NoticeReference"
+ )
+
+ self._notice_reference = notice_reference
+ self._explicit_text = explicit_text
+
+ def __repr__(self):
+ return (
+ "<UserNotice(notice_reference={0.notice_reference}, explicit_text="
+ "{0.explicit_text!r})>".format(self)
+ )
+
+ def __eq__(self, other):
+ if not isinstance(other, UserNotice):
+ return NotImplemented
+
+ return (
+ self.notice_reference == other.notice_reference and
+ self.explicit_text == other.explicit_text
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+ notice_reference = utils.read_only_property("_notice_reference")
+ explicit_text = utils.read_only_property("_explicit_text")
+
+
+class NoticeReference(object):
+ def __init__(self, organization, notice_numbers):
+ self._organization = organization
+ if not isinstance(notice_numbers, list) or not all(
+ isinstance(x, int) for x in notice_numbers
+ ):
+ raise TypeError(
+ "notice_numbers must be a list of integers"
+ )
+
+ self._notice_numbers = notice_numbers
+
+ def __repr__(self):
+ return (
+ "<NoticeReference(organization={0.organization!r}, notice_numbers="
+ "{0.notice_numbers})>".format(self)
+ )
+
+ def __eq__(self, other):
+ if not isinstance(other, NoticeReference):
+ return NotImplemented
+
+ return (
+ self.organization == other.organization and
+ self.notice_numbers == other.notice_numbers
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+ organization = utils.read_only_property("_organization")
+ notice_numbers = utils.read_only_property("_notice_numbers")
+
+
+@utils.register_interface(ExtensionType)
+class ExtendedKeyUsage(object):
+ oid = ExtensionOID.EXTENDED_KEY_USAGE
+
+ def __init__(self, usages):
+ if not all(isinstance(x, ObjectIdentifier) for x in usages):
+ raise TypeError(
+ "Every item in the usages list must be an ObjectIdentifier"
+ )
+
+ self._usages = usages
+
+ def __iter__(self):
+ return iter(self._usages)
+
+ def __len__(self):
+ return len(self._usages)
+
+ def __repr__(self):
+ return "<ExtendedKeyUsage({0})>".format(self._usages)
+
+ def __eq__(self, other):
+ if not isinstance(other, ExtendedKeyUsage):
+ return NotImplemented
+
+ return self._usages == other._usages
+
+ def __ne__(self, other):
+ return not self == other
+
+
+@utils.register_interface(ExtensionType)
+class OCSPNoCheck(object):
+ oid = ExtensionOID.OCSP_NO_CHECK
+
+
+@utils.register_interface(ExtensionType)
+class InhibitAnyPolicy(object):
+ oid = ExtensionOID.INHIBIT_ANY_POLICY
+
+ def __init__(self, skip_certs):
+ if not isinstance(skip_certs, six.integer_types):
+ raise TypeError("skip_certs must be an integer")
+
+ if skip_certs < 0:
+ raise ValueError("skip_certs must be a non-negative integer")
+
+ self._skip_certs = skip_certs
+
+ def __repr__(self):
+ return "<InhibitAnyPolicy(skip_certs={0.skip_certs})>".format(self)
+
+ def __eq__(self, other):
+ if not isinstance(other, InhibitAnyPolicy):
+ return NotImplemented
+
+ return self.skip_certs == other.skip_certs
+
+ def __ne__(self, other):
+ return not self == other
+
+ skip_certs = utils.read_only_property("_skip_certs")
+
+
+@utils.register_interface(ExtensionType)
+class KeyUsage(object):
+ oid = ExtensionOID.KEY_USAGE
+
+ def __init__(self, digital_signature, content_commitment, key_encipherment,
+ data_encipherment, key_agreement, key_cert_sign, crl_sign,
+ encipher_only, decipher_only):
+ if not key_agreement and (encipher_only or decipher_only):
+ raise ValueError(
+ "encipher_only and decipher_only can only be true when "
+ "key_agreement is true"
+ )
+
+ self._digital_signature = digital_signature
+ self._content_commitment = content_commitment
+ self._key_encipherment = key_encipherment
+ self._data_encipherment = data_encipherment
+ self._key_agreement = key_agreement
+ self._key_cert_sign = key_cert_sign
+ self._crl_sign = crl_sign
+ self._encipher_only = encipher_only
+ self._decipher_only = decipher_only
+
+ digital_signature = utils.read_only_property("_digital_signature")
+ content_commitment = utils.read_only_property("_content_commitment")
+ key_encipherment = utils.read_only_property("_key_encipherment")
+ data_encipherment = utils.read_only_property("_data_encipherment")
+ key_agreement = utils.read_only_property("_key_agreement")
+ key_cert_sign = utils.read_only_property("_key_cert_sign")
+ crl_sign = utils.read_only_property("_crl_sign")
+
+ @property
+ def encipher_only(self):
+ if not self.key_agreement:
+ raise ValueError(
+ "encipher_only is undefined unless key_agreement is true"
+ )
+ else:
+ return self._encipher_only
+
+ @property
+ def decipher_only(self):
+ if not self.key_agreement:
+ raise ValueError(
+ "decipher_only is undefined unless key_agreement is true"
+ )
+ else:
+ return self._decipher_only
+
+ def __repr__(self):
+ try:
+ encipher_only = self.encipher_only
+ decipher_only = self.decipher_only
+ except ValueError:
+ encipher_only = None
+ decipher_only = None
+
+ return ("<KeyUsage(digital_signature={0.digital_signature}, "
+ "content_commitment={0.content_commitment}, "
+ "key_encipherment={0.key_encipherment}, "
+ "data_encipherment={0.data_encipherment}, "
+ "key_agreement={0.key_agreement}, "
+ "key_cert_sign={0.key_cert_sign}, crl_sign={0.crl_sign}, "
+ "encipher_only={1}, decipher_only={2})>").format(
+ self, encipher_only, decipher_only)
+
+ def __eq__(self, other):
+ if not isinstance(other, KeyUsage):
+ return NotImplemented
+
+ return (
+ self.digital_signature == other.digital_signature and
+ self.content_commitment == other.content_commitment and
+ self.key_encipherment == other.key_encipherment and
+ self.data_encipherment == other.data_encipherment and
+ self.key_agreement == other.key_agreement and
+ self.key_cert_sign == other.key_cert_sign and
+ self.crl_sign == other.crl_sign and
+ self._encipher_only == other._encipher_only and
+ self._decipher_only == other._decipher_only
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+
+@utils.register_interface(ExtensionType)
+class NameConstraints(object):
+ oid = ExtensionOID.NAME_CONSTRAINTS
+
+ def __init__(self, permitted_subtrees, excluded_subtrees):
+ if permitted_subtrees is not None:
+ if not all(
+ isinstance(x, GeneralName) for x in permitted_subtrees
+ ):
+ raise TypeError(
+ "permitted_subtrees must be a list of GeneralName objects "
+ "or None"
+ )
+
+ self._validate_ip_name(permitted_subtrees)
+
+ if excluded_subtrees is not None:
+ if not all(
+ isinstance(x, GeneralName) for x in excluded_subtrees
+ ):
+ raise TypeError(
+ "excluded_subtrees must be a list of GeneralName objects "
+ "or None"
+ )
+
+ self._validate_ip_name(excluded_subtrees)
+
+ if permitted_subtrees is None and excluded_subtrees is None:
+ raise ValueError(
+ "At least one of permitted_subtrees and excluded_subtrees "
+ "must not be None"
+ )
+
+ self._permitted_subtrees = permitted_subtrees
+ self._excluded_subtrees = excluded_subtrees
+
+ def __eq__(self, other):
+ if not isinstance(other, NameConstraints):
+ return NotImplemented
+
+ return (
+ self.excluded_subtrees == other.excluded_subtrees and
+ self.permitted_subtrees == other.permitted_subtrees
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+ def _validate_ip_name(self, tree):
+ if any(isinstance(name, IPAddress) and not isinstance(
+ name.value, (ipaddress.IPv4Network, ipaddress.IPv6Network)
+ ) for name in tree):
+ raise TypeError(
+ "IPAddress name constraints must be an IPv4Network or"
+ " IPv6Network object"
+ )
+
+ def __repr__(self):
+ return (
+ u"<NameConstraints(permitted_subtrees={0.permitted_subtrees}, "
+ u"excluded_subtrees={0.excluded_subtrees})>".format(self)
+ )
+
+ permitted_subtrees = utils.read_only_property("_permitted_subtrees")
+ excluded_subtrees = utils.read_only_property("_excluded_subtrees")
+
+
+class Extension(object):
+ def __init__(self, oid, critical, value):
+ if not isinstance(oid, ObjectIdentifier):
+ raise TypeError(
+ "oid argument must be an ObjectIdentifier instance."
+ )
+
+ if not isinstance(critical, bool):
+ raise TypeError("critical must be a boolean value")
+
+ self._oid = oid
+ self._critical = critical
+ self._value = value
+
+ oid = utils.read_only_property("_oid")
+ critical = utils.read_only_property("_critical")
+ value = utils.read_only_property("_value")
+
+ def __repr__(self):
+ return ("<Extension(oid={0.oid}, critical={0.critical}, "
+ "value={0.value})>").format(self)
+
+ def __eq__(self, other):
+ if not isinstance(other, Extension):
+ return NotImplemented
+
+ return (
+ self.oid == other.oid and
+ self.critical == other.critical and
+ self.value == other.value
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+
+class GeneralNames(object):
+ def __init__(self, general_names):
+ if not all(isinstance(x, GeneralName) for x in general_names):
+ raise TypeError(
+ "Every item in the general_names list must be an "
+ "object conforming to the GeneralName interface"
+ )
+
+ self._general_names = general_names
+
+ def __iter__(self):
+ return iter(self._general_names)
+
+ def __len__(self):
+ return len(self._general_names)
+
+ def get_values_for_type(self, type):
+ # Return the value of each GeneralName, except for OtherName instances
+ # which we return directly because it has two important properties not
+ # just one value.
+ objs = (i for i in self if isinstance(i, type))
+ if type != OtherName:
+ objs = (i.value for i in objs)
+ return list(objs)
+
+ def __repr__(self):
+ return "<GeneralNames({0})>".format(self._general_names)
+
+ def __eq__(self, other):
+ if not isinstance(other, GeneralNames):
+ return NotImplemented
+
+ return self._general_names == other._general_names
+
+ def __ne__(self, other):
+ return not self == other
+
+
+@utils.register_interface(ExtensionType)
+class SubjectAlternativeName(object):
+ oid = ExtensionOID.SUBJECT_ALTERNATIVE_NAME
+
+ def __init__(self, general_names):
+ self._general_names = GeneralNames(general_names)
+
+ def __iter__(self):
+ return iter(self._general_names)
+
+ def __len__(self):
+ return len(self._general_names)
+
+ def get_values_for_type(self, type):
+ return self._general_names.get_values_for_type(type)
+
+ def __repr__(self):
+ return "<SubjectAlternativeName({0})>".format(self._general_names)
+
+ def __eq__(self, other):
+ if not isinstance(other, SubjectAlternativeName):
+ return NotImplemented
+
+ return self._general_names == other._general_names
+
+ def __ne__(self, other):
+ return not self == other
+
+
+@utils.register_interface(ExtensionType)
+class IssuerAlternativeName(object):
+ oid = ExtensionOID.ISSUER_ALTERNATIVE_NAME
+
+ def __init__(self, general_names):
+ self._general_names = GeneralNames(general_names)
+
+ def __iter__(self):
+ return iter(self._general_names)
+
+ def __len__(self):
+ return len(self._general_names)
+
+ def get_values_for_type(self, type):
+ return self._general_names.get_values_for_type(type)
+
+ def __repr__(self):
+ return "<IssuerAlternativeName({0})>".format(self._general_names)
+
+ def __eq__(self, other):
+ if not isinstance(other, IssuerAlternativeName):
+ return NotImplemented
+
+ return self._general_names == other._general_names
+
+ def __ne__(self, other):
+ return not self == other
diff --git a/tests/hazmat/primitives/test_asym_utils.py b/tests/hazmat/primitives/test_asym_utils.py
index 35b77ca4..b9971137 100644
--- a/tests/hazmat/primitives/test_asym_utils.py
+++ b/tests/hazmat/primitives/test_asym_utils.py
@@ -7,64 +7,72 @@ from __future__ import absolute_import, division, print_function
import pytest
from cryptography.hazmat.primitives.asymmetric.utils import (
- decode_rfc6979_signature, encode_rfc6979_signature
+ decode_dss_signature, decode_rfc6979_signature,
+ encode_dss_signature, encode_rfc6979_signature
)
-def test_rfc6979_signature():
- sig = encode_rfc6979_signature(1, 1)
+def test_deprecated_rfc6979_signature():
+ sig = pytest.deprecated_call(encode_rfc6979_signature, 1, 1)
assert sig == b"0\x06\x02\x01\x01\x02\x01\x01"
- assert decode_rfc6979_signature(sig) == (1, 1)
+ decoded = pytest.deprecated_call(decode_rfc6979_signature, sig)
+ assert decoded == (1, 1)
+
+
+def test_dss_signature():
+ sig = encode_dss_signature(1, 1)
+ assert sig == b"0\x06\x02\x01\x01\x02\x01\x01"
+ assert decode_dss_signature(sig) == (1, 1)
r_s1 = (
1037234182290683143945502320610861668562885151617,
559776156650501990899426031439030258256861634312
)
- sig2 = encode_rfc6979_signature(*r_s1)
+ sig2 = encode_dss_signature(*r_s1)
assert sig2 == (
b'0-\x02\x15\x00\xb5\xaf0xg\xfb\x8bT9\x00\x13\xccg\x02\r\xdf\x1f,\x0b'
b'\x81\x02\x14b\r;"\xabP1D\x0c>5\xea\xb6\xf4\x81)\x8f\x9e\x9f\x08'
)
- assert decode_rfc6979_signature(sig2) == r_s1
+ assert decode_dss_signature(sig2) == r_s1
- sig3 = encode_rfc6979_signature(0, 0)
+ sig3 = encode_dss_signature(0, 0)
assert sig3 == b"0\x06\x02\x01\x00\x02\x01\x00"
- assert decode_rfc6979_signature(sig3) == (0, 0)
+ assert decode_dss_signature(sig3) == (0, 0)
- sig4 = encode_rfc6979_signature(-1, 0)
+ sig4 = encode_dss_signature(-1, 0)
assert sig4 == b"0\x06\x02\x01\xFF\x02\x01\x00"
- assert decode_rfc6979_signature(sig4) == (-1, 0)
+ assert decode_dss_signature(sig4) == (-1, 0)
-def test_encode_rfc6979_non_integer():
+def test_encode_dss_non_integer():
with pytest.raises(ValueError):
- encode_rfc6979_signature("h", 3)
+ encode_dss_signature("h", 3)
with pytest.raises(ValueError):
- encode_rfc6979_signature("3", "2")
+ encode_dss_signature("3", "2")
with pytest.raises(ValueError):
- encode_rfc6979_signature(3, "h")
+ encode_dss_signature(3, "h")
with pytest.raises(ValueError):
- encode_rfc6979_signature(3.3, 1.2)
+ encode_dss_signature(3.3, 1.2)
with pytest.raises(ValueError):
- encode_rfc6979_signature("hello", "world")
+ encode_dss_signature("hello", "world")
-def test_decode_rfc6979_trailing_bytes():
+def test_decode_dss_trailing_bytes():
with pytest.raises(ValueError):
- decode_rfc6979_signature(b"0\x06\x02\x01\x01\x02\x01\x01\x00\x00\x00")
+ decode_dss_signature(b"0\x06\x02\x01\x01\x02\x01\x01\x00\x00\x00")
-def test_decode_rfc6979_invalid_asn1():
+def test_decode_dss_invalid_asn1():
with pytest.raises(ValueError):
# This byte sequence has an invalid ASN.1 sequence length as well as
# an invalid integer length for the second integer.
- decode_rfc6979_signature(b"0\x07\x02\x01\x01\x02\x02\x01")
+ decode_dss_signature(b"0\x07\x02\x01\x01\x02\x02\x01")
with pytest.raises(ValueError):
# This is the BER "end-of-contents octets," which older versions of
# pyasn1 are wrongly willing to return from top-level DER decoding.
- decode_rfc6979_signature(b"\x00\x00")
+ decode_dss_signature(b"\x00\x00")
diff --git a/tests/hazmat/primitives/test_dsa.py b/tests/hazmat/primitives/test_dsa.py
index 53e41883..d1f8f341 100644
--- a/tests/hazmat/primitives/test_dsa.py
+++ b/tests/hazmat/primitives/test_dsa.py
@@ -17,7 +17,7 @@ from cryptography.hazmat.backends.interfaces import (
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import dsa
from cryptography.hazmat.primitives.asymmetric.utils import (
- encode_rfc6979_signature
+ encode_dss_signature
)
from cryptography.utils import bit_length
@@ -567,7 +567,7 @@ class TestDSAVerification(object):
),
y=vector['y']
).public_key(backend)
- sig = encode_rfc6979_signature(vector['r'], vector['s'])
+ sig = encode_dss_signature(vector['r'], vector['s'])
verifier = public_key.verifier(sig, algorithm())
verifier.update(vector['msg'])
if vector['result'] == "F":
diff --git a/tests/test_x509.py b/tests/test_x509.py
index 42f8f58d..b7602d18 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -20,7 +20,9 @@ from cryptography.hazmat.backends.interfaces import (
)
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa
-from cryptography.x509.oid import ExtensionOID, NameOID
+from cryptography.x509.oid import (
+ AuthorityInformationAccessOID, ExtendedKeyUsageOID, ExtensionOID, NameOID
+)
from .hazmat.primitives.fixtures_dsa import DSA_KEY_2048
from .hazmat.primitives.fixtures_rsa import RSA_KEY_2048, RSA_KEY_512
@@ -1503,9 +1505,9 @@ class TestCertificateBuilder(object):
123
).add_extension(
x509.ExtendedKeyUsage([
- x509.OID_CLIENT_AUTH,
- x509.OID_SERVER_AUTH,
- x509.OID_CODE_SIGNING,
+ ExtendedKeyUsageOID.CLIENT_AUTH,
+ ExtendedKeyUsageOID.SERVER_AUTH,
+ ExtendedKeyUsageOID.CODE_SIGNING,
]), critical=False
).sign(issuer_private_key, hashes.SHA256(), backend)
@@ -1514,9 +1516,9 @@ class TestCertificateBuilder(object):
)
assert eku.critical is False
assert eku.value == x509.ExtendedKeyUsage([
- x509.OID_CLIENT_AUTH,
- x509.OID_SERVER_AUTH,
- x509.OID_CODE_SIGNING,
+ ExtendedKeyUsageOID.CLIENT_AUTH,
+ ExtendedKeyUsageOID.SERVER_AUTH,
+ ExtendedKeyUsageOID.CODE_SIGNING,
])
@pytest.mark.requires_backend_interface(interface=RSABackend)
@@ -2011,9 +2013,9 @@ class TestCertificateSigningRequestBuilder(object):
x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
).add_extension(
x509.ExtendedKeyUsage([
- x509.OID_CLIENT_AUTH,
- x509.OID_SERVER_AUTH,
- x509.OID_CODE_SIGNING,
+ ExtendedKeyUsageOID.CLIENT_AUTH,
+ ExtendedKeyUsageOID.SERVER_AUTH,
+ ExtendedKeyUsageOID.CODE_SIGNING,
]), critical=False
).sign(private_key, hashes.SHA256(), backend)
@@ -2022,9 +2024,9 @@ class TestCertificateSigningRequestBuilder(object):
)
assert eku.critical is False
assert eku.value == x509.ExtendedKeyUsage([
- x509.OID_CLIENT_AUTH,
- x509.OID_SERVER_AUTH,
- x509.OID_CODE_SIGNING,
+ ExtendedKeyUsageOID.CLIENT_AUTH,
+ ExtendedKeyUsageOID.SERVER_AUTH,
+ ExtendedKeyUsageOID.CODE_SIGNING,
])
@pytest.mark.requires_backend_interface(interface=RSABackend)
@@ -2051,11 +2053,11 @@ class TestCertificateSigningRequestBuilder(object):
aia = x509.AuthorityInformationAccess([
x509.AccessDescription(
- x509.OID_OCSP,
+ AuthorityInformationAccessOID.OCSP,
x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
),
x509.AccessDescription(
- x509.OID_CA_ISSUERS,
+ AuthorityInformationAccessOID.CA_ISSUERS,
x509.UniformResourceIdentifier(u"http://domain.com/ca.crt")
)
])
diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py
index faf9086a..85373973 100644
--- a/tests/test_x509_ext.py
+++ b/tests/test_x509_ext.py
@@ -17,7 +17,9 @@ from cryptography.hazmat.backends.interfaces import (
DSABackend, EllipticCurveBackend, RSABackend, X509Backend
)
from cryptography.hazmat.primitives.asymmetric import ec
-from cryptography.x509.oid import ExtensionOID, NameOID
+from cryptography.x509.oid import (
+ AuthorityInformationAccessOID, ExtendedKeyUsageOID, ExtensionOID, NameOID
+)
from .hazmat.primitives.test_ec import _skip_curve_unsupported
from .test_x509 import _load_cert
@@ -731,8 +733,8 @@ class TestExtendedKeyUsage(object):
])
assert len(eku) == 2
assert list(eku) == [
- x509.OID_SERVER_AUTH,
- x509.OID_CLIENT_AUTH
+ ExtendedKeyUsageOID.SERVER_AUTH,
+ ExtendedKeyUsageOID.CLIENT_AUTH
]
def test_repr(self):
@@ -830,6 +832,31 @@ class TestExtensions(object):
extensions = cert.extensions
assert len(extensions) == 0
+ def test_no_extensions_get_for_class(self, backend):
+ cert = _load_cert(
+ os.path.join(
+ "x509", "cryptography.io.pem"
+ ),
+ x509.load_pem_x509_certificate,
+ backend
+ )
+ exts = cert.extensions
+ with pytest.raises(x509.ExtensionNotFound) as exc:
+ exts.get_extension_for_class(x509.IssuerAlternativeName)
+ assert exc.value.oid == ExtensionOID.ISSUER_ALTERNATIVE_NAME
+
+ def test_one_extension_get_for_class(self, backend):
+ cert = _load_cert(
+ os.path.join(
+ "x509", "custom", "basic_constraints_not_critical.pem"
+ ),
+ x509.load_pem_x509_certificate,
+ backend
+ )
+ ext = cert.extensions.get_extension_for_class(x509.BasicConstraints)
+ assert ext is not None
+ assert isinstance(ext.value, x509.BasicConstraints)
+
@pytest.mark.requires_backend_interface(interface=RSABackend)
@pytest.mark.requires_backend_interface(interface=X509Backend)
@@ -1797,11 +1824,13 @@ class TestAccessDescription(object):
def test_invalid_access_location(self):
with pytest.raises(TypeError):
- x509.AccessDescription(x509.OID_CA_ISSUERS, "invalid")
+ x509.AccessDescription(
+ AuthorityInformationAccessOID.CA_ISSUERS, "invalid"
+ )
def test_repr(self):
ad = x509.AccessDescription(
- x509.OID_OCSP,
+ AuthorityInformationAccessOID.OCSP,
x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
)
assert repr(ad) == (
@@ -1812,26 +1841,26 @@ class TestAccessDescription(object):
def test_eq(self):
ad = x509.AccessDescription(
- x509.OID_OCSP,
+ AuthorityInformationAccessOID.OCSP,
x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
)
ad2 = x509.AccessDescription(
- x509.OID_OCSP,
+ AuthorityInformationAccessOID.OCSP,
x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
)
assert ad == ad2
def test_ne(self):
ad = x509.AccessDescription(
- x509.OID_OCSP,
+ AuthorityInformationAccessOID.OCSP,
x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
)
ad2 = x509.AccessDescription(
- x509.OID_CA_ISSUERS,
+ AuthorityInformationAccessOID.CA_ISSUERS,
x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
)
ad3 = x509.AccessDescription(
- x509.OID_OCSP,
+ AuthorityInformationAccessOID.OCSP,
x509.UniformResourceIdentifier(u"http://notthesame")
)
assert ad != ad2
@@ -1847,22 +1876,22 @@ class TestAuthorityInformationAccess(object):
def test_iter_len(self):
aia = x509.AuthorityInformationAccess([
x509.AccessDescription(
- x509.OID_OCSP,
+ AuthorityInformationAccessOID.OCSP,
x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
),
x509.AccessDescription(
- x509.OID_CA_ISSUERS,
+ AuthorityInformationAccessOID.CA_ISSUERS,
x509.UniformResourceIdentifier(u"http://domain.com/ca.crt")
)
])
assert len(aia) == 2
assert list(aia) == [
x509.AccessDescription(
- x509.OID_OCSP,
+ AuthorityInformationAccessOID.OCSP,
x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
),
x509.AccessDescription(
- x509.OID_CA_ISSUERS,
+ AuthorityInformationAccessOID.CA_ISSUERS,
x509.UniformResourceIdentifier(u"http://domain.com/ca.crt")
)
]
@@ -1870,11 +1899,11 @@ class TestAuthorityInformationAccess(object):
def test_repr(self):
aia = x509.AuthorityInformationAccess([
x509.AccessDescription(
- x509.OID_OCSP,
+ AuthorityInformationAccessOID.OCSP,
x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
),
x509.AccessDescription(
- x509.OID_CA_ISSUERS,
+ AuthorityInformationAccessOID.CA_ISSUERS,
x509.UniformResourceIdentifier(u"http://domain.com/ca.crt")
)
])
@@ -1890,21 +1919,21 @@ class TestAuthorityInformationAccess(object):
def test_eq(self):
aia = x509.AuthorityInformationAccess([
x509.AccessDescription(
- x509.OID_OCSP,
+ AuthorityInformationAccessOID.OCSP,
x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
),
x509.AccessDescription(
- x509.OID_CA_ISSUERS,
+ AuthorityInformationAccessOID.CA_ISSUERS,
x509.UniformResourceIdentifier(u"http://domain.com/ca.crt")
)
])
aia2 = x509.AuthorityInformationAccess([
x509.AccessDescription(
- x509.OID_OCSP,
+ AuthorityInformationAccessOID.OCSP,
x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
),
x509.AccessDescription(
- x509.OID_CA_ISSUERS,
+ AuthorityInformationAccessOID.CA_ISSUERS,
x509.UniformResourceIdentifier(u"http://domain.com/ca.crt")
)
])
@@ -1913,17 +1942,17 @@ class TestAuthorityInformationAccess(object):
def test_ne(self):
aia = x509.AuthorityInformationAccess([
x509.AccessDescription(
- x509.OID_OCSP,
+ AuthorityInformationAccessOID.OCSP,
x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
),
x509.AccessDescription(
- x509.OID_CA_ISSUERS,
+ AuthorityInformationAccessOID.CA_ISSUERS,
x509.UniformResourceIdentifier(u"http://domain.com/ca.crt")
)
])
aia2 = x509.AuthorityInformationAccess([
x509.AccessDescription(
- x509.OID_OCSP,
+ AuthorityInformationAccessOID.OCSP,
x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
),
])
@@ -1949,11 +1978,11 @@ class TestAuthorityInformationAccessExtension(object):
assert ext.value == x509.AuthorityInformationAccess([
x509.AccessDescription(
- x509.OID_OCSP,
+ AuthorityInformationAccessOID.OCSP,
x509.UniformResourceIdentifier(u"http://gv.symcd.com")
),
x509.AccessDescription(
- x509.OID_CA_ISSUERS,
+ AuthorityInformationAccessOID.CA_ISSUERS,
x509.UniformResourceIdentifier(u"http://gv.symcb.com/gv.crt")
),
])
@@ -1972,15 +2001,15 @@ class TestAuthorityInformationAccessExtension(object):
assert ext.value == x509.AuthorityInformationAccess([
x509.AccessDescription(
- x509.OID_OCSP,
+ AuthorityInformationAccessOID.OCSP,
x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
),
x509.AccessDescription(
- x509.OID_OCSP,
+ AuthorityInformationAccessOID.OCSP,
x509.UniformResourceIdentifier(u"http://ocsp2.domain.com")
),
x509.AccessDescription(
- x509.OID_CA_ISSUERS,
+ AuthorityInformationAccessOID.CA_ISSUERS,
x509.DirectoryName(x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, u"myCN"),
x509.NameAttribute(NameOID.ORGANIZATION_NAME,
@@ -2003,7 +2032,7 @@ class TestAuthorityInformationAccessExtension(object):
assert ext.value == x509.AuthorityInformationAccess([
x509.AccessDescription(
- x509.OID_OCSP,
+ AuthorityInformationAccessOID.OCSP,
x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
),
])
@@ -2022,7 +2051,7 @@ class TestAuthorityInformationAccessExtension(object):
assert ext.value == x509.AuthorityInformationAccess([
x509.AccessDescription(
- x509.OID_CA_ISSUERS,
+ AuthorityInformationAccessOID.CA_ISSUERS,
x509.DirectoryName(x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, u"myCN"),
x509.NameAttribute(NameOID.ORGANIZATION_NAME,
diff --git a/vectors/cryptography_vectors/__about__.py b/vectors/cryptography_vectors/__about__.py
index a8199ced..e3553803 100644
--- a/vectors/cryptography_vectors/__about__.py
+++ b/vectors/cryptography_vectors/__about__.py
@@ -14,7 +14,7 @@ __summary__ = "Test vectors for the cryptography package."
__uri__ = "https://github.com/pyca/cryptography"
-__version__ = "1.0.dev1"
+__version__ = "1.1.dev1"
__author__ = "The cryptography developers"
__email__ = "cryptography-dev@python.org"