aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2015-03-17 13:14:03 -0500
committerPaul Kehrer <paul.l.kehrer@gmail.com>2015-03-28 12:33:34 -0500
commitfa56a23061c8b3431aa32b7ffbd05a38fa6f77e4 (patch)
tree6c884d20d1f165cf7c42548d4877f9ed4e44cd79 /src
parent320050b92d98c9dd8f3949f04a13756a4018f85d (diff)
downloadcryptography-fa56a23061c8b3431aa32b7ffbd05a38fa6f77e4.tar.gz
cryptography-fa56a23061c8b3431aa32b7ffbd05a38fa6f77e4.tar.bz2
cryptography-fa56a23061c8b3431aa32b7ffbd05a38fa6f77e4.zip
basicConstraints support for OpenSSL X509 backend
Diffstat (limited to 'src')
-rw-r--r--src/cryptography/hazmat/backends/openssl/x509.py37
-rw-r--r--src/cryptography/x509.py13
2 files changed, 46 insertions, 4 deletions
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)