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))
489'>489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642