aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/_cffi_src/openssl/x509name.py10
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py6
-rw-r--r--src/cryptography/hazmat/backends/openssl/decode_asn1.py16
-rw-r--r--src/cryptography/hazmat/backends/openssl/encode_asn1.py22
-rw-r--r--src/cryptography/x509/name.py27
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))