diff options
author | Fraser Tweedale <frase@frase.id.au> | 2016-11-07 15:54:04 +1000 |
---|---|---|
committer | Paul Kehrer <paul.l.kehrer@gmail.com> | 2016-11-07 13:54:04 +0800 |
commit | 02467dda61be0413413bc88a85e0290ca7001847 (patch) | |
tree | 6c2a9db57e8e86c8c5325f53069a4a5ede8aa655 /src | |
parent | e51236d7c0b5432f3e79fc025de6c9c8eb28f210 (diff) | |
download | cryptography-02467dda61be0413413bc88a85e0290ca7001847.tar.gz cryptography-02467dda61be0413413bc88a85e0290ca7001847.tar.bz2 cryptography-02467dda61be0413413bc88a85e0290ca7001847.zip |
Make DistributionPoint relative_name a set of NameAttribute (#3210)
* Add RelativeDistinguishedName class
* Make relative_name a RelativeDistinguishedName
DistributionPoint relative_name is currently a Name but RFC 5280
defines it as RelativeDistinguishedName, i.e. a non-empty SET OF
name attributes. Change the DistributionPoint relative_name
attribute to be a RelativeDistinguishedName.
Diffstat (limited to 'src')
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/decode_asn1.py | 8 | ||||
-rw-r--r-- | src/cryptography/utils.py | 1 | ||||
-rw-r--r-- | src/cryptography/x509/__init__.py | 5 | ||||
-rw-r--r-- | src/cryptography/x509/extensions.py | 19 | ||||
-rw-r--r-- | src/cryptography/x509/name.py | 35 |
5 files changed, 62 insertions, 6 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/decode_asn1.py b/src/cryptography/hazmat/backends/openssl/decode_asn1.py index af9d3920..f8e8c95c 100644 --- a/src/cryptography/hazmat/backends/openssl/decode_asn1.py +++ b/src/cryptography/hazmat/backends/openssl/decode_asn1.py @@ -544,7 +544,11 @@ def _decode_crl_distribution_points(backend, cdps): ) # OpenSSL code doesn't test for a specific type for # relativename, everything that isn't fullname is considered - # relativename. + # relativename. Per RFC 5280: + # + # DistributionPointName ::= CHOICE { + # fullName [0] GeneralNames, + # nameRelativeToCRLIssuer [1] RelativeDistinguishedName } else: rns = cdp.distpoint.name.relativename rnum = backend._lib.sk_X509_NAME_ENTRY_num(rns) @@ -558,7 +562,7 @@ def _decode_crl_distribution_points(backend, cdps): _decode_x509_name_entry(backend, rn) ) - relative_name = x509.Name(attributes) + relative_name = x509.RelativeDistinguishedName(attributes) dist_points.append( x509.DistributionPoint( diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index 48ed449a..159d1ded 100644 --- a/src/cryptography/utils.py +++ b/src/cryptography/utils.py @@ -17,6 +17,7 @@ import warnings # ends. DeprecatedIn10 = DeprecationWarning DeprecatedIn14 = DeprecationWarning +DeprecatedIn16 = DeprecationWarning def read_only_property(name): diff --git a/src/cryptography/x509/__init__.py b/src/cryptography/x509/__init__.py index feab4497..51914e1e 100644 --- a/src/cryptography/x509/__init__.py +++ b/src/cryptography/x509/__init__.py @@ -30,7 +30,9 @@ from cryptography.x509.general_name import ( RegisteredID, UniformResourceIdentifier, UnsupportedGeneralNameType, _GENERAL_NAMES ) -from cryptography.x509.name import Name, NameAttribute +from cryptography.x509.name import ( + Name, NameAttribute, RelativeDistinguishedName +) from cryptography.x509.oid import ( AuthorityInformationAccessOID, CRLEntryExtensionOID, CertificatePoliciesOID, ExtendedKeyUsageOID, ExtensionOID, NameOID, @@ -122,6 +124,7 @@ __all__ = [ "UnsupportedGeneralNameType", "NameAttribute", "Name", + "RelativeDistinguishedName", "ObjectIdentifier", "ExtensionType", "Extensions", diff --git a/src/cryptography/x509/extensions.py b/src/cryptography/x509/extensions.py index c0705a3a..f7f6fcd3 100644 --- a/src/cryptography/x509/extensions.py +++ b/src/cryptography/x509/extensions.py @@ -8,6 +8,7 @@ import abc import datetime import hashlib import ipaddress +import warnings from enum import Enum from pyasn1.codec.der import decoder @@ -20,7 +21,7 @@ from cryptography.hazmat.primitives import constant_time, serialization from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePublicKey from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey from cryptography.x509.general_name import GeneralName, IPAddress, OtherName -from cryptography.x509.name import Name +from cryptography.x509.name import Name, RelativeDistinguishedName from cryptography.x509.oid import ( CRLEntryExtensionOID, ExtensionOID, ObjectIdentifier ) @@ -437,8 +438,20 @@ class DistributionPoint(object): "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 relative_name: + if isinstance(relative_name, Name): + warnings.warn( + "relative_name=<Name> is deprecated and will " + "be removed in a future version; use " + "<RelativeDistinguishedName> instead.", + utils.DeprecatedIn16, + stacklevel=2 + ) + relative_name = RelativeDistinguishedName(relative_name) + elif not isinstance(relative_name, RelativeDistinguishedName): + raise TypeError( + "relative_name must be a RelativeDistinguishedName" + ) if crl_issuer: crl_issuer = list(crl_issuer) diff --git a/src/cryptography/x509/name.py b/src/cryptography/x509/name.py index 7e55f6e3..7dc80646 100644 --- a/src/cryptography/x509/name.py +++ b/src/cryptography/x509/name.py @@ -52,6 +52,41 @@ class NameAttribute(object): return "<NameAttribute(oid={0.oid}, value={0.value!r})>".format(self) +class RelativeDistinguishedName(object): + def __init__(self, attributes): + attributes = frozenset(attributes) + if not attributes: + raise ValueError("a relative distinguished name cannot be empty") + if not all(isinstance(x, NameAttribute) for x in attributes): + raise TypeError("attributes must be an iterable of NameAttribute") + + self._attributes = attributes + + def get_attributes_for_oid(self, oid): + return [i for i in self if i.oid == oid] + + def __eq__(self, other): + if not isinstance(other, RelativeDistinguishedName): + return NotImplemented + + return self._attributes == other._attributes + + def __ne__(self, other): + return not self == other + + def __hash__(self): + return hash(self._attributes) + + def __iter__(self): + return iter(self._attributes) + + def __len__(self): + return len(self._attributes) + + def __repr__(self): + return "<RelativeDistinguishedName({0!r})>".format(list(self)) + + class Name(object): def __init__(self, attributes): attributes = list(attributes) |