aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlex Gaynor <alex.gaynor@gmail.com>2015-05-13 18:06:05 -0400
committerAlex Gaynor <alex.gaynor@gmail.com>2015-05-13 18:06:05 -0400
commit92fb53786baa78d1668fd14296450e32b8fdf21e (patch)
tree95f8d9c9f0a0ae48d867859e0a6c0c7312019080 /src
parent2c9ff679f79f919a965ee99e12dceea520abddfd (diff)
parent594a2edf1ead6b7ce3f4e217bada30f2f323dc36 (diff)
downloadcryptography-92fb53786baa78d1668fd14296450e32b8fdf21e.tar.gz
cryptography-92fb53786baa78d1668fd14296450e32b8fdf21e.tar.bz2
cryptography-92fb53786baa78d1668fd14296450e32b8fdf21e.zip
Merge pull request #1920 from reaperhulk/x509-ossl-cdp
support CRLDistributionPoints in the OpenSSL backend
Diffstat (limited to 'src')
-rw-r--r--src/cryptography/hazmat/backends/openssl/x509.py119
1 files changed, 108 insertions, 11 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index 9d70d72f..07e54baa 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -56,22 +56,23 @@ def _asn1_string_to_utf8(backend, asn1_string):
return backend._ffi.buffer(buf[0], res)[:].decode('utf8')
+def _build_x509_name_entry(backend, x509_name_entry):
+ obj = backend._lib.X509_NAME_ENTRY_get_object(x509_name_entry)
+ assert obj != backend._ffi.NULL
+ data = backend._lib.X509_NAME_ENTRY_get_data(x509_name_entry)
+ assert data != backend._ffi.NULL
+ value = _asn1_string_to_utf8(backend, data)
+ oid = _obj2txt(backend, obj)
+
+ return x509.NameAttribute(x509.ObjectIdentifier(oid), value)
+
+
def _build_x509_name(backend, x509_name):
count = backend._lib.X509_NAME_entry_count(x509_name)
attributes = []
for x in range(count):
entry = backend._lib.X509_NAME_get_entry(x509_name, x)
- obj = backend._lib.X509_NAME_ENTRY_get_object(entry)
- assert obj != backend._ffi.NULL
- data = backend._lib.X509_NAME_ENTRY_get_data(entry)
- assert data != backend._ffi.NULL
- value = _asn1_string_to_utf8(backend, data)
- oid = _obj2txt(backend, obj)
- attributes.append(
- x509.NameAttribute(
- x509.ObjectIdentifier(oid), value
- )
- )
+ attributes.append(_build_x509_name_entry(backend, entry))
return x509.Name(attributes)
@@ -292,6 +293,8 @@ class _Certificate(object):
value = self._build_authority_information_access(ext)
elif oid == x509.OID_CERTIFICATE_POLICIES:
value = self._build_certificate_policies(ext)
+ elif oid == x509.OID_CRL_DISTRIBUTION_POINTS:
+ value = self._build_crl_distribution_points(ext)
elif critical:
raise x509.UnsupportedExtension(
"{0} is not currently supported".format(oid), oid
@@ -518,6 +521,100 @@ class _Certificate(object):
return x509.ExtendedKeyUsage(ekus)
+ def _build_crl_distribution_points(self, ext):
+ cdps = self._backend._ffi.cast(
+ "Cryptography_STACK_OF_DIST_POINT *",
+ self._backend._lib.X509V3_EXT_d2i(ext)
+ )
+ assert cdps != self._backend._ffi.NULL
+ cdps = self._backend._ffi.gc(
+ cdps, self._backend._lib.sk_DIST_POINT_free)
+ num = self._backend._lib.sk_DIST_POINT_num(cdps)
+
+ dist_points = []
+ for i in range(num):
+ full_name = None
+ relative_name = None
+ crl_issuer = None
+ reasons = None
+ cdp = self._backend._lib.sk_DIST_POINT_value(cdps, i)
+ if cdp.reasons != self._backend._ffi.NULL:
+ # We will check each bit from RFC 5280
+ # ReasonFlags ::= BIT STRING {
+ # unused (0),
+ # keyCompromise (1),
+ # cACompromise (2),
+ # affiliationChanged (3),
+ # superseded (4),
+ # cessationOfOperation (5),
+ # certificateHold (6),
+ # privilegeWithdrawn (7),
+ # aACompromise (8) }
+ reasons = []
+ get_bit = self._backend._lib.ASN1_BIT_STRING_get_bit
+ if get_bit(cdp.reasons, 1):
+ reasons.append(x509.ReasonFlags.key_compromise)
+
+ if get_bit(cdp.reasons, 2):
+ reasons.append(x509.ReasonFlags.ca_compromise)
+
+ if get_bit(cdp.reasons, 3):
+ reasons.append(x509.ReasonFlags.affiliation_changed)
+
+ if get_bit(cdp.reasons, 4):
+ reasons.append(x509.ReasonFlags.superseded)
+
+ if get_bit(cdp.reasons, 5):
+ reasons.append(x509.ReasonFlags.cessation_of_operation)
+
+ if get_bit(cdp.reasons, 6):
+ reasons.append(x509.ReasonFlags.certificate_hold)
+
+ if get_bit(cdp.reasons, 7):
+ reasons.append(x509.ReasonFlags.privilege_withdrawn)
+
+ if get_bit(cdp.reasons, 8):
+ reasons.append(x509.ReasonFlags.aa_compromise)
+
+ reasons = frozenset(reasons)
+
+ if cdp.CRLissuer != self._backend._ffi.NULL:
+ crl_issuer = _build_general_names(self._backend, cdp.CRLissuer)
+
+ # Certificates may have a crl_issuer/reasons and no distribution
+ # point so make sure it's not null.
+ if cdp.distpoint != self._backend._ffi.NULL:
+ # Type 0 is fullName, there is no #define for it in the code.
+ if cdp.distpoint.type == 0:
+ full_name = _build_general_names(
+ self._backend, cdp.distpoint.name.fullname
+ )
+ # OpenSSL code doesn't test for a specific type for
+ # relativename, everything that isn't fullname is considered
+ # relativename.
+ else:
+ rns = cdp.distpoint.name.relativename
+ rnum = self._backend._lib.sk_X509_NAME_ENTRY_num(rns)
+ attributes = []
+ for i in range(rnum):
+ rn = self._backend._lib.sk_X509_NAME_ENTRY_value(
+ rns, i
+ )
+ assert rn != self._backend._ffi.NULL
+ attributes.append(
+ _build_x509_name_entry(self._backend, rn)
+ )
+
+ relative_name = x509.Name(attributes)
+
+ dist_points.append(
+ x509.DistributionPoint(
+ full_name, relative_name, reasons, crl_issuer
+ )
+ )
+
+ return x509.CRLDistributionPoints(dist_points)
+
@utils.register_interface(x509.CertificateSigningRequest)
class _CertificateSigningRequest(object):