From 8bfbacef9cb973115c0cf0f4185c8f47812c37bc Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 23 Jul 2015 19:10:28 +0100 Subject: when building a CSR adding > 1 extension would trigger a bug We were checking sk_X509_EXTENSION_push for a value == 1, but in reality it returns the number of extensions on the stack. We now assert >= 1 and added a test. --- src/cryptography/hazmat/backends/openssl/backend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 7ccb39a4..9cfe73c1 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -976,7 +976,7 @@ class Backend(object): ) assert extension != self._ffi.NULL res = self._lib.sk_X509_EXTENSION_push(extensions, extension) - assert res == 1 + assert res >= 1 res = self._lib.X509_REQ_add_extensions(x509_req, extensions) assert res == 1 -- cgit v1.2.3 From dce91f0b2923daf60a6fdfd811eb5b3d81ac7c88 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 23 Jul 2015 20:31:12 +0100 Subject: Support encoding KeyUsage into certificate signing requests --- src/_cffi_src/openssl/asn1.py | 2 ++ .../hazmat/backends/openssl/backend.py | 40 ++++++++++++++++++++++ src/cryptography/hazmat/backends/openssl/x509.py | 1 + src/cryptography/x509.py | 2 ++ 4 files changed, 45 insertions(+) (limited to 'src') diff --git a/src/_cffi_src/openssl/asn1.py b/src/_cffi_src/openssl/asn1.py index 5f8ca697..96eff7d3 100644 --- a/src/_cffi_src/openssl/asn1.py +++ b/src/_cffi_src/openssl/asn1.py @@ -125,7 +125,9 @@ int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *, int, int); """ MACROS = """ +ASN1_BIT_STRING *ASN1_BIT_STRING_new(void); void ASN1_BIT_STRING_free(ASN1_BIT_STRING *); +int i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *, unsigned char **); /* This is not a macro, but is const on some versions of OpenSSL */ int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *, int); ASN1_TIME *M_ASN1_TIME_dup(void *); diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 9cfe73c1..046a1739 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -131,6 +131,44 @@ def _txt2obj(backend, name): return obj +def _encode_key_usage(backend, key_usage): + set_bit = backend._lib.ASN1_BIT_STRING_set_bit + ku = backend._lib.ASN1_BIT_STRING_new() + ku = backend._ffi.gc(ku, backend._lib.ASN1_BIT_STRING_free) + res = set_bit(ku, 0, key_usage.digital_signature) + assert res == 1 + res = set_bit(ku, 1, key_usage.content_commitment) + assert res == 1 + res = set_bit(ku, 2, key_usage.key_encipherment) + assert res == 1 + res = set_bit(ku, 3, key_usage.data_encipherment) + assert res == 1 + res = set_bit(ku, 4, key_usage.key_agreement) + assert res == 1 + res = set_bit(ku, 5, key_usage.key_cert_sign) + assert res == 1 + res = set_bit(ku, 6, key_usage.crl_sign) + assert res == 1 + if key_usage.key_agreement: + res = set_bit(ku, 7, key_usage.encipher_only) + assert res == 1 + res = set_bit(ku, 8, key_usage.decipher_only) + assert res == 1 + else: + res = set_bit(ku, 7, 0) + assert res == 1 + res = set_bit(ku, 8, 0) + assert res == 1 + + pp = backend._ffi.new('unsigned char **') + r = backend._lib.i2d_ASN1_BIT_STRING(ku, pp) + assert r > 0 + pp = backend._ffi.gc( + pp, lambda pointer: backend._lib.OPENSSL_free(pointer[0]) + ) + return pp, r + + def _encode_basic_constraints(backend, basic_constraints): constraints = backend._lib.BASIC_CONSTRAINTS_new() constraints = backend._ffi.gc( @@ -964,6 +1002,8 @@ class Backend(object): pp, r = _encode_basic_constraints(self, extension.value) elif isinstance(extension.value, x509.SubjectAlternativeName): pp, r = _encode_subject_alt_name(self, extension.value) + elif isinstance(extension.value, x509.KeyUsage): + pp, r = _encode_key_usage(self, extension.value) else: raise NotImplementedError('Extension not yet supported.') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 472d8a70..943cfd78 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -816,6 +816,7 @@ _CSR_EXTENSION_PARSER = _X509ExtensionParser( get_ext=lambda backend, x, i: backend._lib.sk_X509_EXTENSION_value(x, i), handlers={ x509.OID_BASIC_CONSTRAINTS: _decode_basic_constraints, + x509.OID_KEY_USAGE: _decode_key_usage, x509.OID_SUBJECT_ALTERNATIVE_NAME: _decode_subject_alt_name, } ) diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 58e1a37c..5d108ee6 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -1577,6 +1577,8 @@ class CertificateSigningRequestBuilder(object): ) elif isinstance(extension, KeyUsage): extension = Extension(OID_KEY_USAGE, critical, extension) + elif isinstance(extension, InhibitAnyPolicy): + extension = Extension(OID_INHIBIT_ANY_POLICY, critical, extension) else: raise NotImplementedError('Unsupported X.509 extension.') # TODO: This is quadratic in the number of extensions -- cgit v1.2.3 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 From a5e8a75a0cd475877c3a8e8b07d00fd9f6dbb9e6 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 24 Jul 2015 16:05:23 +0100 Subject: refactor general name encoding to its own function --- .../hazmat/backends/openssl/backend.py | 171 +++++++++++---------- 1 file changed, 88 insertions(+), 83 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 64d518a1..2d2ecc81 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -203,89 +203,7 @@ def _encode_subject_alt_name(backend, san): ) for alt_name in san: - if isinstance(alt_name, x509.DNSName): - gn = backend._lib.GENERAL_NAME_new() - assert gn != backend._ffi.NULL - gn.type = backend._lib.GEN_DNS - - ia5 = backend._lib.ASN1_IA5STRING_new() - assert ia5 != backend._ffi.NULL - - if alt_name.value.startswith(u"*."): - value = b"*." + idna.encode(alt_name.value[2:]) - else: - value = idna.encode(alt_name.value) - - res = backend._lib.ASN1_STRING_set(ia5, value, len(value)) - assert res == 1 - gn.d.dNSName = ia5 - elif isinstance(alt_name, x509.RegisteredID): - gn = backend._lib.GENERAL_NAME_new() - assert gn != backend._ffi.NULL - gn.type = backend._lib.GEN_RID - obj = backend._lib.OBJ_txt2obj( - alt_name.value.dotted_string.encode('ascii'), 1 - ) - assert obj != backend._ffi.NULL - gn.d.registeredID = obj - elif isinstance(alt_name, x509.DirectoryName): - gn = backend._lib.GENERAL_NAME_new() - assert gn != backend._ffi.NULL - name = _encode_name(backend, alt_name.value) - gn.type = backend._lib.GEN_DIRNAME - gn.d.directoryName = name - elif isinstance(alt_name, x509.IPAddress): - gn = backend._lib.GENERAL_NAME_new() - assert gn != backend._ffi.NULL - ipaddr = _encode_asn1_str( - backend, alt_name.value.packed, len(alt_name.value.packed) - ) - gn.type = backend._lib.GEN_IPADD - gn.d.iPAddress = ipaddr - elif isinstance(alt_name, x509.OtherName): - gn = backend._lib.GENERAL_NAME_new() - assert gn != backend._ffi.NULL - other_name = backend._lib.OTHERNAME_new() - assert other_name != backend._ffi.NULL - - type_id = backend._lib.OBJ_txt2obj( - alt_name.type_id.dotted_string.encode('ascii'), 1 - ) - assert type_id != backend._ffi.NULL - data = backend._ffi.new("unsigned char[]", alt_name.value) - data_ptr_ptr = backend._ffi.new("unsigned char **") - data_ptr_ptr[0] = data - value = backend._lib.d2i_ASN1_TYPE( - backend._ffi.NULL, data_ptr_ptr, len(alt_name.value) - ) - if value == backend._ffi.NULL: - backend._consume_errors() - raise ValueError("Invalid ASN.1 data") - other_name.type_id = type_id - other_name.value = value - gn.type = backend._lib.GEN_OTHERNAME - gn.d.otherName = other_name - elif isinstance(alt_name, x509.RFC822Name): - gn = backend._lib.GENERAL_NAME_new() - assert gn != backend._ffi.NULL - asn1_str = _encode_asn1_str( - backend, alt_name._encoded, len(alt_name._encoded) - ) - gn.type = backend._lib.GEN_EMAIL - gn.d.rfc822Name = asn1_str - elif isinstance(alt_name, x509.UniformResourceIdentifier): - gn = backend._lib.GENERAL_NAME_new() - assert gn != backend._ffi.NULL - asn1_str = _encode_asn1_str( - backend, alt_name._encoded, len(alt_name._encoded) - ) - gn.type = backend._lib.GEN_URI - gn.d.uniformResourceIdentifier = asn1_str - else: - raise ValueError( - "{0} is an unknown GeneralName type".format(alt_name) - ) - + gn = _encode_general_name(backend, alt_name) res = backend._lib.sk_GENERAL_NAME_push(general_names, gn) assert res != 0 @@ -298,6 +216,93 @@ def _encode_subject_alt_name(backend, san): return pp, r +def _encode_general_name(backend, name): + if isinstance(name, x509.DNSName): + gn = backend._lib.GENERAL_NAME_new() + assert gn != backend._ffi.NULL + gn.type = backend._lib.GEN_DNS + + ia5 = backend._lib.ASN1_IA5STRING_new() + assert ia5 != backend._ffi.NULL + + if name.value.startswith(u"*."): + value = b"*." + idna.encode(name.value[2:]) + else: + value = idna.encode(name.value) + + res = backend._lib.ASN1_STRING_set(ia5, value, len(value)) + assert res == 1 + gn.d.dNSName = ia5 + elif isinstance(name, x509.RegisteredID): + gn = backend._lib.GENERAL_NAME_new() + assert gn != backend._ffi.NULL + gn.type = backend._lib.GEN_RID + obj = backend._lib.OBJ_txt2obj( + name.value.dotted_string.encode('ascii'), 1 + ) + assert obj != backend._ffi.NULL + gn.d.registeredID = obj + elif isinstance(name, x509.DirectoryName): + gn = backend._lib.GENERAL_NAME_new() + assert gn != backend._ffi.NULL + dir_name = _encode_name(backend, name.value) + gn.type = backend._lib.GEN_DIRNAME + gn.d.directoryName = dir_name + elif isinstance(name, x509.IPAddress): + gn = backend._lib.GENERAL_NAME_new() + assert gn != backend._ffi.NULL + ipaddr = _encode_asn1_str( + backend, name.value.packed, len(name.value.packed) + ) + gn.type = backend._lib.GEN_IPADD + gn.d.iPAddress = ipaddr + elif isinstance(name, x509.OtherName): + gn = backend._lib.GENERAL_NAME_new() + assert gn != backend._ffi.NULL + other_name = backend._lib.OTHERNAME_new() + assert other_name != backend._ffi.NULL + + type_id = backend._lib.OBJ_txt2obj( + name.type_id.dotted_string.encode('ascii'), 1 + ) + assert type_id != backend._ffi.NULL + data = backend._ffi.new("unsigned char[]", name.value) + data_ptr_ptr = backend._ffi.new("unsigned char **") + data_ptr_ptr[0] = data + value = backend._lib.d2i_ASN1_TYPE( + backend._ffi.NULL, data_ptr_ptr, len(name.value) + ) + if value == backend._ffi.NULL: + backend._consume_errors() + raise ValueError("Invalid ASN.1 data") + other_name.type_id = type_id + other_name.value = value + gn.type = backend._lib.GEN_OTHERNAME + gn.d.otherName = other_name + elif isinstance(name, x509.RFC822Name): + gn = backend._lib.GENERAL_NAME_new() + assert gn != backend._ffi.NULL + asn1_str = _encode_asn1_str( + backend, name._encoded, len(name._encoded) + ) + gn.type = backend._lib.GEN_EMAIL + gn.d.rfc822Name = asn1_str + elif isinstance(name, x509.UniformResourceIdentifier): + gn = backend._lib.GENERAL_NAME_new() + assert gn != backend._ffi.NULL + asn1_str = _encode_asn1_str( + backend, name._encoded, len(name._encoded) + ) + gn.type = backend._lib.GEN_URI + gn.d.uniformResourceIdentifier = asn1_str + else: + raise ValueError( + "{0} is an unknown GeneralName type".format(name) + ) + + return gn + + 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) -- cgit v1.2.3 From a34c0e858d1d5d0cb8bfc550841f476d926dce1c Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 24 Jul 2015 16:05:59 +0100 Subject: bindings for CRL encoding --- src/_cffi_src/openssl/x509v3.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/_cffi_src/openssl/x509v3.py b/src/_cffi_src/openssl/x509v3.py index 148cd64b..cb31ba1e 100644 --- a/src/_cffi_src/openssl/x509v3.py +++ b/src/_cffi_src/openssl/x509v3.py @@ -223,9 +223,11 @@ X509_EXTENSION *X509V3_EXT_conf_nid(Cryptography_LHASH_OF_CONF_VALUE *, const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *); const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int); +Cryptography_STACK_OF_DIST_POINT *sk_DIST_POINT_new_null(void); void sk_DIST_POINT_free(Cryptography_STACK_OF_DIST_POINT *); int sk_DIST_POINT_num(Cryptography_STACK_OF_DIST_POINT *); DIST_POINT *sk_DIST_POINT_value(Cryptography_STACK_OF_DIST_POINT *, int); +int sk_DIST_POINT_push(Cryptography_STACK_OF_DIST_POINT *, DIST_POINT *); void sk_POLICYINFO_free(Cryptography_STACK_OF_POLICYINFO *); int sk_POLICYINFO_num(Cryptography_STACK_OF_POLICYINFO *); @@ -249,6 +251,11 @@ int sk_ASN1_INTEGER_num(Cryptography_STACK_OF_ASN1_INTEGER *); ASN1_INTEGER *sk_ASN1_INTEGER_value(Cryptography_STACK_OF_ASN1_INTEGER *, int); X509_EXTENSION *X509V3_EXT_i2d(int, int, void *); + +DIST_POINT *DIST_POINT_new(void); +void DIST_POINT_free(DIST_POINT *); + +int i2d_CRL_DIST_POINTS(Cryptography_STACK_OF_DIST_POINT *, unsigned char **); """ CUSTOMIZATIONS = """ -- cgit v1.2.3 From eaac67b1bc25799102488f4a3338e9403ddde9d0 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 24 Jul 2015 20:15:33 +0100 Subject: let's also add the binding to make a new GENERAL_SUBTREE stack --- src/_cffi_src/openssl/x509v3.py | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/_cffi_src/openssl/x509v3.py b/src/_cffi_src/openssl/x509v3.py index cb31ba1e..d0a57349 100644 --- a/src/_cffi_src/openssl/x509v3.py +++ b/src/_cffi_src/openssl/x509v3.py @@ -238,6 +238,7 @@ int sk_POLICYQUALINFO_num(Cryptography_STACK_OF_POLICYQUALINFO *); POLICYQUALINFO *sk_POLICYQUALINFO_value(Cryptography_STACK_OF_POLICYQUALINFO *, int); +Cryptography_STACK_OF_GENERAL_SUBTREE *sk_GENERAL_SUBTREE_new_null(void); void sk_GENERAL_SUBTREE_free(Cryptography_STACK_OF_GENERAL_SUBTREE *); int sk_GENERAL_SUBTREE_num(Cryptography_STACK_OF_GENERAL_SUBTREE *); GENERAL_SUBTREE *sk_GENERAL_SUBTREE_value( -- cgit v1.2.3 From 6608b7e98e6669404c981ad981c277767998f129 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 24 Jul 2015 21:52:17 +0100 Subject: remove windows link type, update docs --- src/_cffi_src/build_openssl.py | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'src') diff --git a/src/_cffi_src/build_openssl.py b/src/_cffi_src/build_openssl.py index dac3e4d8..6a5bf2da 100644 --- a/src/_cffi_src/build_openssl.py +++ b/src/_cffi_src/build_openssl.py @@ -4,7 +4,6 @@ from __future__ import absolute_import, division, print_function -import os import sys from _cffi_src.utils import build_ffi_for_binding, extra_link_args @@ -19,20 +18,8 @@ def _get_openssl_libraries(platform): # (http://marc.info/?l=openssl-users&m=135361825921871) return ["ssl", "crypto"] else: - link_type = os.environ.get("PYCA_WINDOWS_LINK_TYPE", "static") - return _get_openssl_windows_libraries(link_type) - - -def _get_openssl_windows_libraries(link_type): - if link_type == "dynamic": - return ["libeay32", "ssleay32", "advapi32"] - elif link_type == "static" or link_type == "": - return ["libeay32mt", "ssleay32mt", "advapi32", + return ["libeay32", "ssleay32", "advapi32", "crypt32", "gdi32", "user32", "ws2_32"] - else: - raise ValueError( - "PYCA_WINDOWS_LINK_TYPE must be 'static' or 'dynamic'" - ) _OSX_PRE_INCLUDE = """ -- cgit v1.2.3 From 4e4a9ba524efe4963961c62c6da915a834ca185c Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 25 Jul 2015 18:49:35 +0100 Subject: handle RSA key too small and consume errors on CSR signature failure --- src/_cffi_src/openssl/err.py | 1 + src/cryptography/hazmat/backends/openssl/backend.py | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/_cffi_src/openssl/err.py b/src/_cffi_src/openssl/err.py index eebf19ba..73ce4e3c 100644 --- a/src/_cffi_src/openssl/err.py +++ b/src/_cffi_src/openssl/err.py @@ -230,6 +230,7 @@ static const int RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY; static const int RSA_R_BLOCK_TYPE_IS_NOT_01; static const int RSA_R_BLOCK_TYPE_IS_NOT_02; static const int RSA_R_PKCS_DECODING_ERROR; +static const int RSA_F_RSA_SIGN; """ FUNCTIONS = """ diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 2d2ecc81..dd89623e 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1055,7 +1055,16 @@ class Backend(object): res = self._lib.X509_REQ_sign( x509_req, private_key._evp_pkey, evp_md ) - assert res > 0 + if res == 0: + errors = self._consume_errors() + assert errors[0][1:] in ( + ( + self._lib.ERR_LIB_RSA, + self._lib.RSA_F_RSA_SIGN, + self._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY + ), + ) + raise ValueError("Digest too big for RSA key") return _CertificateSigningRequest(self, x509_req) -- cgit v1.2.3 From 28fae4e437a8487e6d5414ce5e3f7904f412995d Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 25 Jul 2015 19:07:21 +0100 Subject: == instead of in --- src/cryptography/hazmat/backends/openssl/backend.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index dd89623e..8b332c53 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1057,12 +1057,12 @@ class Backend(object): ) if res == 0: errors = self._consume_errors() - assert errors[0][1:] in ( + assert errors[0][1:] == ( ( self._lib.ERR_LIB_RSA, self._lib.RSA_F_RSA_SIGN, self._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY - ), + ) ) raise ValueError("Digest too big for RSA key") -- cgit v1.2.3 From 195a1ecb96d7ac7fc0d9ce39340e747531e5ad96 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 25 Jul 2015 19:12:19 +0100 Subject: extra parens --- src/cryptography/hazmat/backends/openssl/backend.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 8b332c53..76252404 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1058,11 +1058,9 @@ class Backend(object): if res == 0: errors = self._consume_errors() assert errors[0][1:] == ( - ( - self._lib.ERR_LIB_RSA, - self._lib.RSA_F_RSA_SIGN, - self._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY - ) + self._lib.ERR_LIB_RSA, + self._lib.RSA_F_RSA_SIGN, + self._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY ) raise ValueError("Digest too big for RSA key") -- cgit v1.2.3 From af57f7d2ce0b77a3e58a40d85b772ddd949f8e89 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 25 Jul 2015 20:04:11 +0100 Subject: openssl error codes are clearly not considered part of the api contract --- src/cryptography/hazmat/backends/openssl/backend.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 76252404..db4f963a 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1057,11 +1057,8 @@ class Backend(object): ) if res == 0: errors = self._consume_errors() - assert errors[0][1:] == ( - self._lib.ERR_LIB_RSA, - self._lib.RSA_F_RSA_SIGN, - self._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY - ) + assert errors[0][1] == self._lib.ERR_LIB_RSA + assert errors[0][3] == self._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY raise ValueError("Digest too big for RSA key") return _CertificateSigningRequest(self, x509_req) -- cgit v1.2.3 From b314a2359f9a6eb06afd5125f1176de30f1ef0fc Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 26 Jul 2015 22:30:12 +0100 Subject: add many bindings we'll need to encode a certificate policies extension --- src/_cffi_src/openssl/x509v3.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src') diff --git a/src/_cffi_src/openssl/x509v3.py b/src/_cffi_src/openssl/x509v3.py index d0a57349..a61ad321 100644 --- a/src/_cffi_src/openssl/x509v3.py +++ b/src/_cffi_src/openssl/x509v3.py @@ -232,11 +232,31 @@ int sk_DIST_POINT_push(Cryptography_STACK_OF_DIST_POINT *, DIST_POINT *); void sk_POLICYINFO_free(Cryptography_STACK_OF_POLICYINFO *); int sk_POLICYINFO_num(Cryptography_STACK_OF_POLICYINFO *); POLICYINFO *sk_POLICYINFO_value(Cryptography_STACK_OF_POLICYINFO *, int); +int sk_POLICYINFO_push(Cryptography_STACK_OF_POLICYINFO *, POLICYINFO *); +Cryptography_STACK_OF_POLICYINFO *sk_POLICYINFO_new_null(void); + +POLICYINFO *POLICYINFO_new(void); +void POLICYINFO_free(POLICYINFO *); + +POLICYQUALINFO *POLICYQUALINFO_new(void); +void POLICYQUALINFO_free(POLICYQUALINFO *); + +NOTICEREF *NOTICEREF_new(void); +void NOTICEREF_free(NOTICEREF *); + +USERNOTICE *USERNOTICE_new(void); +void USERNOTICE_free(USERNOTICE *); + +int i2d_CERTIFICATEPOLICIES(Cryptography_STACK_OF_POLICYINFO *, + unsigned char **); void sk_POLICYQUALINFO_free(Cryptography_STACK_OF_POLICYQUALINFO *); int sk_POLICYQUALINFO_num(Cryptography_STACK_OF_POLICYQUALINFO *); POLICYQUALINFO *sk_POLICYQUALINFO_value(Cryptography_STACK_OF_POLICYQUALINFO *, int); +int sk_POLICYQUALINFO_push(Cryptography_STACK_OF_POLICYQUALINFO *, + POLICYQUALINFO *); +Cryptography_STACK_OF_POLICYQUALINFO *sk_POLICYQUALINFO_new_null(void); Cryptography_STACK_OF_GENERAL_SUBTREE *sk_GENERAL_SUBTREE_new_null(void); void sk_GENERAL_SUBTREE_free(Cryptography_STACK_OF_GENERAL_SUBTREE *); @@ -250,6 +270,7 @@ int sk_GENERAL_SUBTREE_push(Cryptography_STACK_OF_GENERAL_SUBTREE *, void sk_ASN1_INTEGER_free(Cryptography_STACK_OF_ASN1_INTEGER *); int sk_ASN1_INTEGER_num(Cryptography_STACK_OF_ASN1_INTEGER *); ASN1_INTEGER *sk_ASN1_INTEGER_value(Cryptography_STACK_OF_ASN1_INTEGER *, int); +int sk_ASN1_INTEGER_push(Cryptography_STACK_OF_ASN1_INTEGER *, ASN1_INTEGER *); X509_EXTENSION *X509V3_EXT_i2d(int, int, void *); -- cgit v1.2.3 From bd16e4f7ed3f95cc0572c9ef48b7cae89c5c4707 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 1 Aug 2015 18:52:33 +0100 Subject: Remove elifs and replace with else + assert This is kind of ugly, but resolves many partial branch coverage issues. --- src/cryptography/hazmat/backends/openssl/backend.py | 20 +++++++++++++------- src/cryptography/hazmat/backends/openssl/rsa.py | 5 +++-- src/cryptography/hazmat/backends/openssl/x509.py | 3 ++- 3 files changed, 18 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index db4f963a..5ab46d44 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1577,13 +1577,15 @@ class Backend(object): if format is serialization.PrivateFormat.PKCS8: write_bio = self._lib.PEM_write_bio_PKCS8PrivateKey key = evp_pkey - elif format is serialization.PrivateFormat.TraditionalOpenSSL: + else: + assert format is serialization.PrivateFormat.TraditionalOpenSSL if evp_pkey.type == self._lib.EVP_PKEY_RSA: write_bio = self._lib.PEM_write_bio_RSAPrivateKey elif evp_pkey.type == self._lib.EVP_PKEY_DSA: write_bio = self._lib.PEM_write_bio_DSAPrivateKey - elif (self._lib.Cryptography_HAS_EC == 1 and - evp_pkey.type == self._lib.EVP_PKEY_EC): + else: + assert self._lib.Cryptography_HAS_EC == 1 + assert evp_pkey.type == self._lib.EVP_PKEY_EC write_bio = self._lib.PEM_write_bio_ECPrivateKey key = cdata @@ -1600,7 +1602,8 @@ class Backend(object): return self._private_key_bytes_traditional_der( evp_pkey.type, cdata ) - elif format is serialization.PrivateFormat.PKCS8: + else: + assert format is serialization.PrivateFormat.PKCS8 write_bio = self._lib.i2d_PKCS8PrivateKey_bio key = evp_pkey else: @@ -1625,7 +1628,8 @@ class Backend(object): elif (self._lib.Cryptography_HAS_EC == 1 and key_type == self._lib.EVP_PKEY_EC): write_bio = self._lib.i2d_ECPrivateKey_bio - elif key_type == self._lib.EVP_PKEY_DSA: + else: + assert key_type == self._lib.EVP_PKEY_DSA write_bio = self._lib.i2d_DSAPrivateKey_bio bio = self._create_mem_bio() @@ -1640,7 +1644,8 @@ class Backend(object): if format is serialization.PublicFormat.SubjectPublicKeyInfo: if encoding is serialization.Encoding.PEM: write_bio = self._lib.PEM_write_bio_PUBKEY - elif encoding is serialization.Encoding.DER: + else: + assert encoding is serialization.Encoding.DER write_bio = self._lib.i2d_PUBKEY_bio key = evp_pkey @@ -1649,7 +1654,8 @@ class Backend(object): assert evp_pkey.type == self._lib.EVP_PKEY_RSA if encoding is serialization.Encoding.PEM: write_bio = self._lib.PEM_write_bio_RSAPublicKey - elif encoding is serialization.Encoding.DER: + else: + assert encoding is serialization.Encoding.DER write_bio = self._lib.i2d_RSAPublicKey_bio key = cdata diff --git a/src/cryptography/hazmat/backends/openssl/rsa.py b/src/cryptography/hazmat/backends/openssl/rsa.py index 21414c05..822c7304 100644 --- a/src/cryptography/hazmat/backends/openssl/rsa.py +++ b/src/cryptography/hazmat/backends/openssl/rsa.py @@ -268,8 +268,9 @@ class _RSASignatureContext(object): self._backend._lib.RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE): reason = ("Salt length too long for key size. Try using " "MAX_LENGTH instead.") - elif (errors[0].reason == - self._backend._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY): + else: + assert (errors[0].reason == + self._backend._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY) reason = "Digest too large for key size. Use a larger key." assert reason is not None raise ValueError(reason) diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 493abc83..e7a9a792 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -386,7 +386,8 @@ def _decode_certificate_policies(backend, ext): pqi.d.cpsuri.data, pqi.d.cpsuri.length )[:].decode('ascii') qualifiers.append(cpsuri) - elif pqualid == x509.OID_CPS_USER_NOTICE: + else: + assert pqualid == x509.OID_CPS_USER_NOTICE user_notice = _decode_user_notice( backend, pqi.d.usernotice ) -- cgit v1.2.3 From e88c4318eabcc2c252a184df9a672161078fe911 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 1 Aug 2015 20:04:42 +0100 Subject: simplify x509 extension decoding --- src/cryptography/hazmat/backends/openssl/x509.py | 101 +++++++---------------- 1 file changed, 28 insertions(+), 73 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 493abc83..63e4a177 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -234,7 +234,9 @@ class _X509ExtensionParser(object): "{0} is not currently supported".format(oid), oid ) else: - value = handler(backend, ext) + d2i = backend._lib.X509V3_EXT_d2i(ext) + assert d2i != backend._ffi.NULL + value = handler(backend, d2i) extensions.append(x509.Extension(oid, critical, value)) seen_oids.add(oid) @@ -358,12 +360,8 @@ class _Certificate(object): return self._backend._read_mem_bio(bio) -def _decode_certificate_policies(backend, ext): - cp = backend._ffi.cast( - "Cryptography_STACK_OF_POLICYINFO *", - backend._lib.X509V3_EXT_d2i(ext) - ) - assert cp != backend._ffi.NULL +def _decode_certificate_policies(backend, cp): + cp = backend._ffi.cast("Cryptography_STACK_OF_POLICYINFO *", cp) cp = backend._ffi.gc(cp, backend._lib.sk_POLICYINFO_free) num = backend._lib.sk_POLICYINFO_num(cp) certificate_policies = [] @@ -431,12 +429,8 @@ def _decode_user_notice(backend, un): return x509.UserNotice(notice_reference, explicit_text) -def _decode_basic_constraints(backend, ext): - bc_st = backend._lib.X509V3_EXT_d2i(ext) - assert bc_st != backend._ffi.NULL - basic_constraints = backend._ffi.cast( - "BASIC_CONSTRAINTS *", bc_st - ) +def _decode_basic_constraints(backend, bc_st): + basic_constraints = backend._ffi.cast("BASIC_CONSTRAINTS *", bc_st) basic_constraints = backend._ffi.gc( basic_constraints, backend._lib.BASIC_CONSTRAINTS_free ) @@ -447,19 +441,13 @@ def _decode_basic_constraints(backend, ext): if basic_constraints.pathlen == backend._ffi.NULL: path_length = None else: - path_length = _asn1_integer_to_int( - backend, basic_constraints.pathlen - ) + path_length = _asn1_integer_to_int(backend, basic_constraints.pathlen) return x509.BasicConstraints(ca, path_length) -def _decode_subject_key_identifier(backend, ext): - asn1_string = backend._lib.X509V3_EXT_d2i(ext) - assert asn1_string != backend._ffi.NULL - asn1_string = backend._ffi.cast( - "ASN1_OCTET_STRING *", asn1_string - ) +def _decode_subject_key_identifier(backend, asn1_string): + asn1_string = backend._ffi.cast("ASN1_OCTET_STRING *", asn1_string) asn1_string = backend._ffi.gc( asn1_string, backend._lib.ASN1_OCTET_STRING_free ) @@ -468,13 +456,9 @@ def _decode_subject_key_identifier(backend, ext): ) -def _decode_authority_key_identifier(backend, ext): - akid = backend._lib.X509V3_EXT_d2i(ext) - assert akid != backend._ffi.NULL +def _decode_authority_key_identifier(backend, akid): akid = backend._ffi.cast("AUTHORITY_KEYID *", akid) - akid = backend._ffi.gc( - akid, backend._lib.AUTHORITY_KEYID_free - ) + akid = backend._ffi.gc(akid, backend._lib.AUTHORITY_KEYID_free) key_identifier = None authority_cert_issuer = None authority_cert_serial_number = None @@ -499,15 +483,9 @@ def _decode_authority_key_identifier(backend, ext): ) -def _decode_authority_information_access(backend, ext): - aia = backend._lib.X509V3_EXT_d2i(ext) - assert aia != backend._ffi.NULL - aia = backend._ffi.cast( - "Cryptography_STACK_OF_ACCESS_DESCRIPTION *", aia - ) - aia = backend._ffi.gc( - aia, backend._lib.sk_ACCESS_DESCRIPTION_free - ) +def _decode_authority_information_access(backend, aia): + aia = backend._ffi.cast("Cryptography_STACK_OF_ACCESS_DESCRIPTION *", aia) + aia = backend._ffi.gc(aia, backend._lib.sk_ACCESS_DESCRIPTION_free) num = backend._lib.sk_ACCESS_DESCRIPTION_num(aia) access_descriptions = [] for i in range(num): @@ -521,13 +499,9 @@ def _decode_authority_information_access(backend, ext): return x509.AuthorityInformationAccess(access_descriptions) -def _decode_key_usage(backend, ext): - bit_string = backend._lib.X509V3_EXT_d2i(ext) - assert bit_string != backend._ffi.NULL +def _decode_key_usage(backend, bit_string): bit_string = backend._ffi.cast("ASN1_BIT_STRING *", bit_string) - bit_string = backend._ffi.gc( - bit_string, backend._lib.ASN1_BIT_STRING_free - ) + bit_string = backend._ffi.gc(bit_string, backend._lib.ASN1_BIT_STRING_free) get_bit = backend._lib.ASN1_BIT_STRING_get_bit digital_signature = get_bit(bit_string, 0) == 1 content_commitment = get_bit(bit_string, 1) == 1 @@ -551,11 +525,8 @@ def _decode_key_usage(backend, ext): ) -def _decode_general_names_extension(backend, ext): - gns = backend._ffi.cast( - "GENERAL_NAMES *", backend._lib.X509V3_EXT_d2i(ext) - ) - assert gns != backend._ffi.NULL +def _decode_general_names_extension(backend, gns): + gns = backend._ffi.cast("GENERAL_NAMES *", gns) gns = backend._ffi.gc(gns, backend._lib.GENERAL_NAMES_free) general_names = _decode_general_names(backend, gns) return general_names @@ -573,11 +544,8 @@ def _decode_issuer_alt_name(backend, ext): ) -def _decode_name_constraints(backend, ext): - nc = backend._ffi.cast( - "NAME_CONSTRAINTS *", backend._lib.X509V3_EXT_d2i(ext) - ) - assert nc != backend._ffi.NULL +def _decode_name_constraints(backend, nc): + nc = backend._ffi.cast("NAME_CONSTRAINTS *", nc) nc = backend._ffi.gc(nc, backend._lib.NAME_CONSTRAINTS_free) permitted = _decode_general_subtrees(backend, nc.permittedSubtrees) excluded = _decode_general_subtrees(backend, nc.excludedSubtrees) @@ -602,12 +570,8 @@ def _decode_general_subtrees(backend, stack_subtrees): return subtrees -def _decode_extended_key_usage(backend, ext): - sk = backend._ffi.cast( - "Cryptography_STACK_OF_ASN1_OBJECT *", - backend._lib.X509V3_EXT_d2i(ext) - ) - assert sk != backend._ffi.NULL +def _decode_extended_key_usage(backend, sk): + sk = backend._ffi.cast("Cryptography_STACK_OF_ASN1_OBJECT *", sk) sk = backend._ffi.gc(sk, backend._lib.sk_ASN1_OBJECT_free) num = backend._lib.sk_ASN1_OBJECT_num(sk) ekus = [] @@ -621,14 +585,9 @@ def _decode_extended_key_usage(backend, ext): return x509.ExtendedKeyUsage(ekus) -def _decode_crl_distribution_points(backend, ext): - cdps = backend._ffi.cast( - "Cryptography_STACK_OF_DIST_POINT *", - backend._lib.X509V3_EXT_d2i(ext) - ) - assert cdps != backend._ffi.NULL - cdps = backend._ffi.gc( - cdps, backend._lib.sk_DIST_POINT_free) +def _decode_crl_distribution_points(backend, cdps): + cdps = backend._ffi.cast("Cryptography_STACK_OF_DIST_POINT *", cdps) + cdps = backend._ffi.gc(cdps, backend._lib.sk_DIST_POINT_free) num = backend._lib.sk_DIST_POINT_num(cdps) dist_points = [] @@ -716,12 +675,8 @@ def _decode_crl_distribution_points(backend, ext): return x509.CRLDistributionPoints(dist_points) -def _decode_inhibit_any_policy(backend, ext): - asn1_int = backend._ffi.cast( - "ASN1_INTEGER *", - backend._lib.X509V3_EXT_d2i(ext) - ) - assert asn1_int != backend._ffi.NULL +def _decode_inhibit_any_policy(backend, asn1_int): + asn1_int = backend._ffi.cast("ASN1_INTEGER *", asn1_int) asn1_int = backend._ffi.gc(asn1_int, backend._lib.ASN1_INTEGER_free) skip_certs = _asn1_integer_to_int(backend, asn1_int) return x509.InhibitAnyPolicy(skip_certs) -- cgit v1.2.3 From a08693f3a71a6537da9cfa7d9dda7781aef2bcdd Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 1 Aug 2015 20:45:21 +0100 Subject: check if the extension decoded to internal openssl repr ...and if not, raise an error (plus consume the error stack) --- src/cryptography/hazmat/backends/openssl/x509.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 63e4a177..1c0c3acf 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -235,7 +235,12 @@ class _X509ExtensionParser(object): ) else: d2i = backend._lib.X509V3_EXT_d2i(ext) - assert d2i != backend._ffi.NULL + if d2i == backend._ffi.NULL: + backend._consume_errors() + raise ValueError( + "The {0} extension appears to be corrupt".format(oid) + ) + value = handler(backend, d2i) extensions.append(x509.Extension(oid, critical, value)) -- cgit v1.2.3 From 1b7500f5f91a9ad07f5f15caf17264753173f8d8 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 1 Aug 2015 20:56:27 +0100 Subject: corrupt -> invalid --- src/cryptography/hazmat/backends/openssl/x509.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 1c0c3acf..2572cc41 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -238,7 +238,8 @@ class _X509ExtensionParser(object): if d2i == backend._ffi.NULL: backend._consume_errors() raise ValueError( - "The {0} extension appears to be corrupt".format(oid) + "The {0} extension is invalid and can't be " + "parsed".format(oid) ) value = handler(backend, d2i) -- cgit v1.2.3 From 33fc7dc0afa71e66b2a9e2d85ff0c090ffedbdc6 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 1 Aug 2015 21:23:22 +0100 Subject: allow certificate and CSR to both parse the same set of extensions --- src/cryptography/hazmat/backends/openssl/x509.py | 44 +++++++++++------------- 1 file changed, 21 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 63e4a177..eb0426e5 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -744,35 +744,33 @@ class _CertificateSigningRequest(object): return self._backend._read_mem_bio(bio) +_EXTENSION_HANDLERS = { + x509.OID_BASIC_CONSTRAINTS: _decode_basic_constraints, + x509.OID_SUBJECT_KEY_IDENTIFIER: _decode_subject_key_identifier, + 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, + x509.OID_AUTHORITY_KEY_IDENTIFIER: _decode_authority_key_identifier, + x509.OID_AUTHORITY_INFORMATION_ACCESS: ( + _decode_authority_information_access + ), + x509.OID_CERTIFICATE_POLICIES: _decode_certificate_policies, + x509.OID_CRL_DISTRIBUTION_POINTS: _decode_crl_distribution_points, + x509.OID_OCSP_NO_CHECK: _decode_ocsp_no_check, + x509.OID_INHIBIT_ANY_POLICY: _decode_inhibit_any_policy, + x509.OID_ISSUER_ALTERNATIVE_NAME: _decode_issuer_alt_name, + x509.OID_NAME_CONSTRAINTS: _decode_name_constraints, +} + + _CERTIFICATE_EXTENSION_PARSER = _X509ExtensionParser( ext_count=lambda backend, x: backend._lib.X509_get_ext_count(x), get_ext=lambda backend, x, i: backend._lib.X509_get_ext(x, i), - handlers={ - x509.OID_BASIC_CONSTRAINTS: _decode_basic_constraints, - x509.OID_SUBJECT_KEY_IDENTIFIER: _decode_subject_key_identifier, - 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, - x509.OID_AUTHORITY_KEY_IDENTIFIER: _decode_authority_key_identifier, - x509.OID_AUTHORITY_INFORMATION_ACCESS: ( - _decode_authority_information_access - ), - x509.OID_CERTIFICATE_POLICIES: _decode_certificate_policies, - x509.OID_CRL_DISTRIBUTION_POINTS: _decode_crl_distribution_points, - x509.OID_OCSP_NO_CHECK: _decode_ocsp_no_check, - x509.OID_INHIBIT_ANY_POLICY: _decode_inhibit_any_policy, - x509.OID_ISSUER_ALTERNATIVE_NAME: _decode_issuer_alt_name, - x509.OID_NAME_CONSTRAINTS: _decode_name_constraints, - } + handlers=_EXTENSION_HANDLERS ) _CSR_EXTENSION_PARSER = _X509ExtensionParser( ext_count=lambda backend, x: backend._lib.sk_X509_EXTENSION_num(x), get_ext=lambda backend, x, i: backend._lib.sk_X509_EXTENSION_value(x, i), - handlers={ - 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, - } + handlers=_EXTENSION_HANDLERS ) -- cgit v1.2.3