From fa56a23061c8b3431aa32b7ffbd05a38fa6f77e4 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 17 Mar 2015 13:14:03 -0500 Subject: basicConstraints support for OpenSSL X509 backend --- src/cryptography/hazmat/backends/openssl/x509.py | 37 +++++++++++++++++++++--- src/cryptography/x509.py | 13 +++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 3502d122..1c9cf5cf 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -168,13 +168,16 @@ class _Certificate(object): raise x509.DuplicateExtension( "Duplicate {0} extension found".format(oid), oid ) - elif oid == x509.OID_BASIC_CONSTRAINTS and critical: + elif oid == x509.OID_BASIC_CONSTRAINTS: + value = self._build_basic_constraints(ext) + elif oid == x509.OID_KEY_USAGE and critical: # TODO: remove this obviously. warnings.warn( - "Extension support is not fully implemented. A basic " - "constraints extension with the critical flag was seen and" - " IGNORED." + "Extension support is not fully implemented. A key usage " + "extension with the critical flag was seen and IGNORED." ) + seen_oids.add(oid) + continue elif critical: raise x509.UnsupportedExtension( "{0} is not currently supported".format(oid), oid @@ -185,5 +188,31 @@ class _Certificate(object): continue seen_oids.add(oid) + extensions.append(x509.Extension(oid, critical, value)) return x509.Extensions(extensions) + + def _build_basic_constraints(self, ext): + bc_st = self._backend._lib.X509V3_EXT_d2i(ext) + assert bc_st != self._backend._ffi.NULL + basic_constraints = self._backend._ffi.cast( + "BASIC_CONSTRAINTS *", bc_st + ) + basic_constraints = self._backend._ffi.gc( + basic_constraints, self._backend._lib.BASIC_CONSTRAINTS_free + ) + # The byte representation of an ASN.1 boolean true is \xff. OpenSSL + # chooses to just map this to its ordinal value, so true is 255 and + # false is 0. + ca = basic_constraints.ca == 255 + if basic_constraints.pathlen == self._backend._ffi.NULL: + path_length = None + else: + bn = self._backend._lib.ASN1_INTEGER_to_BN( + basic_constraints.pathlen, self._backend._ffi.NULL + ) + assert bn != self._backend._ffi.NULL + bn = self._backend._ffi.gc(bn, self._backend._lib.BN_free) + path_length = self._backend._bn_to_int(bn) + + return x509.BasicConstraints(ca, path_length) diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 29602b3e..864736e8 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -78,6 +78,12 @@ class UnsupportedExtension(Exception): self.oid = oid +class ExtensionNotFound(Exception): + def __init__(self, msg, oid): + super(ExtensionNotFound, self).__init__(msg) + self.oid = oid + + class NameAttribute(object): def __init__(self, oid, value): if not isinstance(oid, ObjectIdentifier): @@ -163,6 +169,13 @@ class Extensions(object): def __init__(self, extensions): self._extensions = extensions + def get_extension_for_oid(self, oid): + for ext in self: + if ext.oid == oid: + return ext + + raise ExtensionNotFound("No {0} extension was found".format(oid), oid) + def __iter__(self): return iter(self._extensions) -- cgit v1.2.3