diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/_cffi_src/openssl/x509name.py | 10 | ||||
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/backend.py | 6 | ||||
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/decode_asn1.py | 16 | ||||
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/encode_asn1.py | 22 | ||||
-rw-r--r-- | src/cryptography/x509/name.py | 27 |
5 files changed, 58 insertions, 23 deletions
diff --git a/src/_cffi_src/openssl/x509name.py b/src/_cffi_src/openssl/x509name.py index 30acbdbb..0554a024 100644 --- a/src/_cffi_src/openssl/x509name.py +++ b/src/_cffi_src/openssl/x509name.py @@ -35,6 +35,7 @@ void X509_NAME_ENTRY_free(X509_NAME_ENTRY *); int X509_NAME_get_index_by_NID(X509_NAME *, int, int); int X509_NAME_cmp(const X509_NAME *, const X509_NAME *); X509_NAME *X509_NAME_dup(X509_NAME *); +int Cryptography_X509_NAME_ENTRY_set(X509_NAME_ENTRY *); """ MACROS = """ @@ -76,4 +77,13 @@ Cryptography_STACK_OF_X509_NAME_ENTRY *sk_X509_NAME_ENTRY_dup( """ CUSTOMIZATIONS = """ +#if CRYPTOGRAPHY_OPENSSL_110_OR_GREATER && !defined(LIBRESSL_VERSION_NUMBER) +int Cryptography_X509_NAME_ENTRY_set(X509_NAME_ENTRY *ne) { + return X509_NAME_ENTRY_set(ne); +} +#else +int Cryptography_X509_NAME_ENTRY_set(X509_NAME_ENTRY *ne) { + return ne->set; +} +#endif """ diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 7efab2be..41e7e773 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -820,7 +820,7 @@ class Backend(object): # Set the subject's name. res = self._lib.X509_set_subject_name( - x509_cert, _encode_name_gc(self, list(builder._subject_name)) + x509_cert, _encode_name_gc(self, builder._subject_name) ) self.openssl_assert(res == 1) @@ -860,7 +860,7 @@ class Backend(object): # Set the issuer name. res = self._lib.X509_set_issuer_name( - x509_cert, _encode_name_gc(self, list(builder._issuer_name)) + x509_cert, _encode_name_gc(self, builder._issuer_name) ) self.openssl_assert(res == 1) @@ -911,7 +911,7 @@ class Backend(object): # Set the issuer name. res = self._lib.X509_CRL_set_issuer_name( - x509_crl, _encode_name_gc(self, list(builder._issuer_name)) + x509_crl, _encode_name_gc(self, builder._issuer_name) ) self.openssl_assert(res == 1) diff --git a/src/cryptography/hazmat/backends/openssl/decode_asn1.py b/src/cryptography/hazmat/backends/openssl/decode_asn1.py index f8e8c95c..2cbc349e 100644 --- a/src/cryptography/hazmat/backends/openssl/decode_asn1.py +++ b/src/cryptography/hazmat/backends/openssl/decode_asn1.py @@ -45,11 +45,19 @@ def _decode_x509_name_entry(backend, x509_name_entry): def _decode_x509_name(backend, x509_name): count = backend._lib.X509_NAME_entry_count(x509_name) attributes = [] + prev_set_id = -1 for x in range(count): entry = backend._lib.X509_NAME_get_entry(x509_name, x) - attributes.append(_decode_x509_name_entry(backend, entry)) + attribute = _decode_x509_name_entry(backend, entry) + set_id = backend._lib.Cryptography_X509_NAME_ENTRY_set(entry) + if set_id != prev_set_id: + attributes.append(set([attribute])) + else: + # is in the same RDN a previous entry + attributes[-1].add(attribute) + prev_set_id = set_id - return x509.Name(attributes) + return x509.Name(x509.RelativeDistinguishedName(rdn) for rdn in attributes) def _decode_general_names(backend, gns): @@ -552,13 +560,13 @@ def _decode_crl_distribution_points(backend, cdps): else: rns = cdp.distpoint.name.relativename rnum = backend._lib.sk_X509_NAME_ENTRY_num(rns) - attributes = [] + attributes = set() for i in range(rnum): rn = backend._lib.sk_X509_NAME_ENTRY_value( rns, i ) backend.openssl_assert(rn != backend._ffi.NULL) - attributes.append( + attributes.add( _decode_x509_name_entry(backend, rn) ) diff --git a/src/cryptography/hazmat/backends/openssl/encode_asn1.py b/src/cryptography/hazmat/backends/openssl/encode_asn1.py index 284c760c..3b784861 100644 --- a/src/cryptography/hazmat/backends/openssl/encode_asn1.py +++ b/src/cryptography/hazmat/backends/openssl/encode_asn1.py @@ -79,19 +79,23 @@ def _encode_inhibit_any_policy(backend, inhibit_any_policy): return _encode_asn1_int_gc(backend, inhibit_any_policy.skip_certs) -def _encode_name(backend, attributes): +def _encode_name(backend, name): """ The X509_NAME created will not be gc'd. Use _encode_name_gc if needed. """ subject = backend._lib.X509_NAME_new() - for attribute in attributes: - name_entry = _encode_name_entry(backend, attribute) - # X509_NAME_add_entry dups the object so we need to gc this copy - name_entry = backend._ffi.gc( - name_entry, backend._lib.X509_NAME_ENTRY_free - ) - res = backend._lib.X509_NAME_add_entry(subject, name_entry, -1, 0) - backend.openssl_assert(res == 1) + for rdn in name.rdns: + set_flag = 0 # indicate whether to add to last RDN or create new RDN + for attribute in rdn: + name_entry = _encode_name_entry(backend, attribute) + # X509_NAME_add_entry dups the object so we need to gc this copy + name_entry = backend._ffi.gc( + name_entry, backend._lib.X509_NAME_ENTRY_free + ) + res = backend._lib.X509_NAME_add_entry( + subject, name_entry, -1, set_flag) + backend.openssl_assert(res == 1) + set_flag = -1 return subject diff --git a/src/cryptography/x509/name.py b/src/cryptography/x509/name.py index 7dc80646..fedfd78f 100644 --- a/src/cryptography/x509/name.py +++ b/src/cryptography/x509/name.py @@ -90,14 +90,25 @@ class RelativeDistinguishedName(object): class Name(object): def __init__(self, attributes): attributes = list(attributes) - if not all(isinstance(x, NameAttribute) for x in attributes): - raise TypeError("attributes must be a list of NameAttribute") - - self._attributes = attributes + if all(isinstance(x, NameAttribute) for x in attributes): + self._attributes = [ + RelativeDistinguishedName([x]) for x in attributes + ] + elif all(isinstance(x, RelativeDistinguishedName) for x in attributes): + self._attributes = attributes + else: + raise TypeError( + "attributes must be a list of NameAttribute" + " or a list RelativeDistinguishedName" + ) def get_attributes_for_oid(self, oid): return [i for i in self if i.oid == oid] + @property + def rdns(self): + return self._attributes + def __eq__(self, other): if not isinstance(other, Name): return NotImplemented @@ -113,10 +124,12 @@ class Name(object): return hash(tuple(self._attributes)) def __iter__(self): - return iter(self._attributes) + for rdn in self._attributes: + for ava in rdn: + yield ava def __len__(self): - return len(self._attributes) + return sum(len(rdn) for rdn in self._attributes) def __repr__(self): - return "<Name({0!r})>".format(self._attributes) + return "<Name({0!r})>".format(list(self)) |