From 0b8f327f59b5a890f2d2ad9101391a0b818e186a Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 23 Jul 2015 21:46:21 +0100 Subject: Support encoding ExtendedKeyUsage into certificate signing requests --- src/_cffi_src/openssl/x509.py | 2 ++ src/_cffi_src/openssl/x509v3.py | 3 +++ .../hazmat/backends/openssl/backend.py | 30 ++++++++++++++++++++-- src/cryptography/hazmat/backends/openssl/x509.py | 1 + src/cryptography/x509.py | 2 ++ 5 files changed, 36 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/_cffi_src/openssl/x509.py b/src/_cffi_src/openssl/x509.py index 6bd117b0..bdcc1719 100644 --- a/src/_cffi_src/openssl/x509.py +++ b/src/_cffi_src/openssl/x509.py @@ -325,6 +325,8 @@ int i2o_ECPublicKey(EC_KEY *, unsigned char **); int sk_ASN1_OBJECT_num(Cryptography_STACK_OF_ASN1_OBJECT *); ASN1_OBJECT *sk_ASN1_OBJECT_value(Cryptography_STACK_OF_ASN1_OBJECT *, int); void sk_ASN1_OBJECT_free(Cryptography_STACK_OF_ASN1_OBJECT *); +Cryptography_STACK_OF_ASN1_OBJECT *sk_ASN1_OBJECT_new_null(void); +int sk_ASN1_OBJECT_push(Cryptography_STACK_OF_ASN1_OBJECT *, ASN1_OBJECT *); """ CUSTOMIZATIONS = """ diff --git a/src/_cffi_src/openssl/x509v3.py b/src/_cffi_src/openssl/x509v3.py index 8e42b65d..148cd64b 100644 --- a/src/_cffi_src/openssl/x509v3.py +++ b/src/_cffi_src/openssl/x509v3.py @@ -33,6 +33,7 @@ typedef ... Cryptography_STACK_OF_POLICYQUALINFO; typedef ... Cryptography_STACK_OF_POLICYINFO; typedef ... Cryptography_STACK_OF_ASN1_INTEGER; typedef ... Cryptography_STACK_OF_GENERAL_SUBTREE; +typedef ... EXTENDED_KEY_USAGE; typedef struct { X509 *issuer_cert; @@ -200,6 +201,8 @@ void *X509V3_set_ctx_nodb(X509V3_CTX *); int i2d_GENERAL_NAMES(GENERAL_NAMES *, unsigned char **); +int i2d_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE *, unsigned char **); + int sk_GENERAL_NAME_num(struct stack_st_GENERAL_NAME *); int sk_GENERAL_NAME_push(struct stack_st_GENERAL_NAME *, GENERAL_NAME *); GENERAL_NAME *sk_GENERAL_NAME_value(struct stack_st_GENERAL_NAME *, int); diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 046a1739..64d518a1 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -101,7 +101,7 @@ def _encode_name(backend, attributes): subject = backend._lib.X509_NAME_new() for attribute in attributes: value = attribute.value.encode('utf8') - obj = _txt2obj(backend, attribute.oid.dotted_string) + obj = _txt2obj_gc(backend, attribute.oid.dotted_string) res = backend._lib.X509_NAME_add_entry_by_OBJ( subject, obj, @@ -127,6 +127,11 @@ def _txt2obj(backend, name): name = name.encode('ascii') obj = backend._lib.OBJ_txt2obj(name, 1) assert obj != backend._ffi.NULL + return obj + + +def _txt2obj_gc(backend, name): + obj = _txt2obj(backend, name) obj = backend._ffi.gc(obj, backend._lib.ASN1_OBJECT_free) return obj @@ -293,6 +298,25 @@ def _encode_subject_alt_name(backend, san): return pp, r +def _encode_extended_key_usage(backend, extended_key_usage): + eku = backend._lib.sk_ASN1_OBJECT_new_null() + eku = backend._ffi.gc(eku, backend._lib.sk_ASN1_OBJECT_free) + for oid in extended_key_usage: + obj = _txt2obj(backend, oid.dotted_string) + res = backend._lib.sk_ASN1_OBJECT_push(eku, obj) + assert res >= 1 + + pp = backend._ffi.new('unsigned char **') + r = backend._lib.i2d_EXTENDED_KEY_USAGE( + backend._ffi.cast("EXTENDED_KEY_USAGE *", eku), pp + ) + assert r > 0 + pp = backend._ffi.gc( + pp, lambda pointer: backend._lib.OPENSSL_free(pointer[0]) + ) + return pp, r + + @utils.register_interface(CipherBackend) @utils.register_interface(CMACBackend) @utils.register_interface(DERSerializationBackend) @@ -1004,10 +1028,12 @@ class Backend(object): pp, r = _encode_subject_alt_name(self, extension.value) elif isinstance(extension.value, x509.KeyUsage): pp, r = _encode_key_usage(self, extension.value) + elif isinstance(extension.value, x509.ExtendedKeyUsage): + pp, r = _encode_extended_key_usage(self, extension.value) else: raise NotImplementedError('Extension not yet supported.') - obj = _txt2obj(self, extension.oid.dotted_string) + obj = _txt2obj_gc(self, extension.oid.dotted_string) extension = self._lib.X509_EXTENSION_create_by_OBJ( self._ffi.NULL, obj, diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 943cfd78..493abc83 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -818,5 +818,6 @@ _CSR_EXTENSION_PARSER = _X509ExtensionParser( x509.OID_BASIC_CONSTRAINTS: _decode_basic_constraints, x509.OID_KEY_USAGE: _decode_key_usage, x509.OID_SUBJECT_ALTERNATIVE_NAME: _decode_subject_alt_name, + x509.OID_EXTENDED_KEY_USAGE: _decode_extended_key_usage, } ) diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 5d108ee6..75552fc1 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -1571,6 +1571,8 @@ class CertificateSigningRequestBuilder(object): """ if isinstance(extension, BasicConstraints): extension = Extension(OID_BASIC_CONSTRAINTS, critical, extension) + elif isinstance(extension, ExtendedKeyUsage): + extension = Extension(OID_EXTENDED_KEY_USAGE, critical, extension) elif isinstance(extension, SubjectAlternativeName): extension = Extension( OID_SUBJECT_ALTERNATIVE_NAME, critical, extension -- cgit v1.2.3