From fbeaf2a7169efe9e83fac281948f5e5adcb2d03e Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 10 Aug 2015 23:52:10 -0500 Subject: move extension exceptions, NameConstraints, and KeyUsage --- src/cryptography/x509/__init__.py | 14 +-- src/cryptography/x509/base.py | 192 +----------------------------------- src/cryptography/x509/extensions.py | 192 +++++++++++++++++++++++++++++++++++- 3 files changed, 199 insertions(+), 199 deletions(-) (limited to 'src') diff --git a/src/cryptography/x509/__init__.py b/src/cryptography/x509/__init__.py index 8e345aee..a6d376b5 100644 --- a/src/cryptography/x509/__init__.py +++ b/src/cryptography/x509/__init__.py @@ -7,19 +7,19 @@ from __future__ import absolute_import, division, print_function from cryptography.x509.base import ( Certificate, CertificateBuilder, CertificateRevocationList, CertificateSigningRequest, CertificateSigningRequestBuilder, - DuplicateExtension, Extension, ExtensionNotFound, - ExtensionType, Extensions, GeneralNames, - InvalidVersion, IssuerAlternativeName, KeyUsage, NameConstraints, + Extension, ExtensionType, GeneralNames, + InvalidVersion, IssuerAlternativeName, ObjectIdentifier, RevokedCertificate, SubjectAlternativeName, - UnsupportedExtension, Version, load_der_x509_certificate, + Version, load_der_x509_certificate, load_der_x509_csr, load_pem_x509_certificate, load_pem_x509_csr, ) from cryptography.x509.extensions import ( AccessDescription, AuthorityInformationAccess, AuthorityKeyIdentifier, BasicConstraints, CRLDistributionPoints, - CertificatePolicies, DistributionPoint, ExtendedKeyUsage, - InhibitAnyPolicy, NoticeReference, OCSPNoCheck, PolicyInformation, - ReasonFlags, SubjectKeyIdentifier, UserNotice + CertificatePolicies, DistributionPoint, DuplicateExtension, + ExtendedKeyUsage, ExtensionNotFound, Extensions, InhibitAnyPolicy, + KeyUsage, NameConstraints, NoticeReference, OCSPNoCheck, PolicyInformation, + ReasonFlags, SubjectKeyIdentifier, UnsupportedExtension, UserNotice ) from cryptography.x509.general_name import ( DNSName, DirectoryName, GeneralName, IPAddress, OtherName, RFC822Name, diff --git a/src/cryptography/x509/base.py b/src/cryptography/x509/base.py index 2b4eeb56..312eea0c 100644 --- a/src/cryptography/x509/base.py +++ b/src/cryptography/x509/base.py @@ -6,14 +6,13 @@ 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.general_name import GeneralName, OtherName from cryptography.x509.name import Name from cryptography.x509.oid import ( ExtensionOID, ObjectIdentifier @@ -50,42 +49,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): @@ -131,159 +94,6 @@ class ExtensionType(object): """ -@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 ("").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"".format(self) - ) - - permitted_subtrees = utils.read_only_property("_permitted_subtrees") - excluded_subtrees = utils.read_only_property("_excluded_subtrees") - - class GeneralNames(object): def __init__(self, general_names): if not all(isinstance(x, GeneralName) for x in general_names): diff --git a/src/cryptography/x509/extensions.py b/src/cryptography/x509/extensions.py index f227dfe3..92a37357 100644 --- a/src/cryptography/x509/extensions.py +++ b/src/cryptography/x509/extensions.py @@ -5,6 +5,7 @@ from __future__ import absolute_import, division, print_function import hashlib +import ipaddress from enum import Enum from pyasn1.codec.der import decoder @@ -15,7 +16,7 @@ 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 from cryptography.x509.name import Name from cryptography.x509.oid import ( AuthorityInformationAccessOID, ExtensionOID, ObjectIdentifier @@ -50,6 +51,42 @@ 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 + + +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) + + @utils.register_interface(ExtensionType) class AuthorityKeyIdentifier(object): oid = ExtensionOID.AUTHORITY_KEY_IDENTIFIER @@ -579,3 +616,156 @@ class InhibitAnyPolicy(object): 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 ("").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"".format(self) + ) + + permitted_subtrees = utils.read_only_property("_permitted_subtrees") + excluded_subtrees = utils.read_only_property("_excluded_subtrees") -- cgit v1.2.3