From d3e84164d9932782beebfb997615bca6f6d30a8b Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 28 Jun 2015 10:14:55 -0400 Subject: Initial code to encode SANs --- src/_cffi_src/openssl/asn1.py | 5 ++- src/_cffi_src/openssl/x509v3.py | 6 +++ .../hazmat/backends/openssl/backend.py | 47 ++++++++++++++++++++++ tests/test_x509.py | 24 +++++++++++ 4 files changed, 81 insertions(+), 1 deletion(-) diff --git a/src/_cffi_src/openssl/asn1.py b/src/_cffi_src/openssl/asn1.py index c18708c5..5210c7c9 100644 --- a/src/_cffi_src/openssl/asn1.py +++ b/src/_cffi_src/openssl/asn1.py @@ -42,7 +42,7 @@ typedef struct asn1_string_st ASN1_OCTET_STRING; typedef struct asn1_string_st ASN1_IA5STRING; typedef ... ASN1_BIT_STRING; typedef ... ASN1_OBJECT; -typedef ... ASN1_STRING; +typedef struct asn1_string_st ASN1_STRING; typedef ... ASN1_TYPE; typedef ... ASN1_GENERALIZEDTIME; typedef ... ASN1_ENUMERATED; @@ -87,6 +87,9 @@ ASN1_OCTET_STRING *ASN1_OCTET_STRING_new(void); void ASN1_OCTET_STRING_free(ASN1_OCTET_STRING *); int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *, const unsigned char *, int); +/* ASN1 IA5STRING */ +ASN1_IA5STRING *ASN1_IA5STRING_new(void); + /* ASN1 INTEGER */ ASN1_INTEGER *ASN1_INTEGER_new(void); void ASN1_INTEGER_free(ASN1_INTEGER *); diff --git a/src/_cffi_src/openssl/x509v3.py b/src/_cffi_src/openssl/x509v3.py index 166fa59d..36d90911 100644 --- a/src/_cffi_src/openssl/x509v3.py +++ b/src/_cffi_src/openssl/x509v3.py @@ -172,7 +172,9 @@ FUNCTIONS = """ int X509V3_EXT_add_alias(int, int); void X509V3_set_ctx(X509V3_CTX *, X509 *, X509 *, X509_REQ *, X509_CRL *, int); X509_EXTENSION *X509V3_EXT_nconf(CONF *, X509V3_CTX *, char *, char *); +GENERAL_NAME *GENERAL_NAME_new(void); int GENERAL_NAME_print(BIO *, GENERAL_NAME *); +GENERAL_NAMES *GENERAL_NAMES_new(void); void GENERAL_NAMES_free(GENERAL_NAMES *); void *X509V3_EXT_d2i(X509_EXTENSION *); """ @@ -183,6 +185,7 @@ MACROS = """ int i2d_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS *, unsigned char **); BASIC_CONSTRAINTS *BASIC_CONSTRAINTS_new(void); void BASIC_CONSTRAINTS_free(BASIC_CONSTRAINTS *); + /* This is a macro defined by a call to DECLARE_ASN1_FUNCTIONS in the x509v3.h header. */ void AUTHORITY_KEYID_free(AUTHORITY_KEYID *); @@ -191,6 +194,9 @@ NAME_CONSTRAINTS *NAME_CONSTRAINTS_new(void); void NAME_CONSTRAINTS_free(NAME_CONSTRAINTS *); void *X509V3_set_ctx_nodb(X509V3_CTX *); + +int i2d_GENERAL_NAMES(GENERAL_NAMES *, 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 18faecb3..c2a3dc2d 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -146,6 +146,47 @@ def _encode_basic_constraints(backend, basic_constraints, critical): return extension +def _encode_subject_alt_name(backend, san, critical): + obj = _txt2obj(backend, x509.OID_SUBJECT_ALTERNATIVE_NAME.dotted_string) + assert obj is not None + + general_names = backend._lib.GENERAL_NAMES_new() + assert general_names != backend._ffi.NULL + # TODO: GC + + for alt_name in san: + assert 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 + gn.d.dNSName = ia5 + # TODO: idna + value = alt_name.value.encode("ascii") + res = backend._lib.ASN1_STRING_set(gn.d.dNSName, value, len(value)) + assert res == 1 + + res = backend._lib.sk_GENERAL_NAME_push(general_names, gn) + assert res == 1 + + pp = backend._ffi.new("unsigned char **") + r = backend._lib.i2d_GENERAL_NAMES(general_names, pp) + assert r > 0 + pp = backend._ffi.gc( + pp, lambda pointer: backend._lib.OPENSSL_free(pointer[0]) + ) + + extension = backend._lib.X509_EXTENSION_create_by_OBJ( + backend._ffi.NULL, + obj, + 1 if critical else 0, + _encode_asn1_str(backend, pp[0], r) + ) + assert extension != backend._ffi.NULL + return extension + + @utils.register_interface(CipherBackend) @utils.register_interface(CMACBackend) @utils.register_interface(DERSerializationBackend) @@ -857,6 +898,12 @@ class Backend(object): extension.value, extension.critical ) + elif isinstance(extension.value, x509.SubjectAlternativeName): + extension = _encode_subject_alt_name( + self, + extension.value, + extension.critical, + ) else: raise NotImplementedError('Extension not yet supported.') res = self._lib.sk_X509_EXTENSION_push(extensions, extension) diff --git a/tests/test_x509.py b/tests/test_x509.py index df315cc3..64a59237 100644 --- a/tests/test_x509.py +++ b/tests/test_x509.py @@ -884,6 +884,30 @@ class TestCertificateSigningRequestBuilder(object): ]) ) + def test_subject_alt_names(self, backend): + private_key = RSA_KEY_2048.private_key(backend) + + csr = x509.CertificateSigningRequestBuilder().subject_name( + x509.Name([ + x509.NameAttribute(x509.OID_COMMON_NAME, u"SAN"), + ]) + ).add_extension( + x509.SubjectAlternativeName([ + x509.DNSName(u"google.com"), + ]), + critical=False, + ).sign(private_key, hashes.SHA256(), backend) + + assert len(csr.extensions) == 1 + ext = csr.extensions.get_extension_for_oid( + x509.OID_SUBJECT_ALTERNATIVE_NAME + ) + assert not ext.critical + assert ext.oid == x509.OID_SUBJECT_ALTERNATIVE_NAME + assert list(ext.value) == [ + x509.DNSName(u"google.com"), + ] + @pytest.mark.requires_backend_interface(interface=DSABackend) @pytest.mark.requires_backend_interface(interface=X509Backend) -- cgit v1.2.3 From 6eeb877becb90f1a8209a8ac4db96e9b440265a6 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 28 Jun 2015 11:03:37 -0400 Subject: Clean up code and fix. --- .../hazmat/backends/openssl/backend.py | 54 ++++++++-------------- src/cryptography/hazmat/backends/openssl/x509.py | 2 + 2 files changed, 20 insertions(+), 36 deletions(-) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index c2a3dc2d..22179607 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -115,9 +115,7 @@ def _txt2obj(backend, name): return obj -def _encode_basic_constraints(backend, basic_constraints, critical): - obj = _txt2obj(backend, x509.OID_BASIC_CONSTRAINTS.dotted_string) - assert obj is not None +def _encode_basic_constraints(backend, basic_constraints): constraints = backend._lib.BASIC_CONSTRAINTS_new() constraints.ca = 255 if basic_constraints.ca else 0 if basic_constraints.ca: @@ -132,24 +130,10 @@ def _encode_basic_constraints(backend, basic_constraints, critical): pp = backend._ffi.gc( pp, lambda pointer: backend._lib.OPENSSL_free(pointer[0]) ) - - # Wrap that in an X509 extension object. - extension = backend._lib.X509_EXTENSION_create_by_OBJ( - backend._ffi.NULL, - obj, - 1 if critical else 0, - _encode_asn1_str(backend, pp[0], r), - ) - assert extension != backend._ffi.NULL - - # Return the wrapped extension. - return extension + return pp, r -def _encode_subject_alt_name(backend, san, critical): - obj = _txt2obj(backend, x509.OID_SUBJECT_ALTERNATIVE_NAME.dotted_string) - assert obj is not None - +def _encode_subject_alt_name(backend, san): general_names = backend._lib.GENERAL_NAMES_new() assert general_names != backend._ffi.NULL # TODO: GC @@ -176,15 +160,7 @@ def _encode_subject_alt_name(backend, san, critical): pp = backend._ffi.gc( pp, lambda pointer: backend._lib.OPENSSL_free(pointer[0]) ) - - extension = backend._lib.X509_EXTENSION_create_by_OBJ( - backend._ffi.NULL, - obj, - 1 if critical else 0, - _encode_asn1_str(backend, pp[0], r) - ) - assert extension != backend._ffi.NULL - return extension + return pp, r @utils.register_interface(CipherBackend) @@ -893,19 +869,25 @@ class Backend(object): ) for extension in builder._extensions: if isinstance(extension.value, x509.BasicConstraints): - extension = _encode_basic_constraints( - self, - extension.value, - extension.critical + pp, r = _encode_basic_constraints( + self, extension.value, ) elif isinstance(extension.value, x509.SubjectAlternativeName): - extension = _encode_subject_alt_name( - self, - extension.value, - extension.critical, + pp, r = _encode_subject_alt_name( + self, extension.value, ) else: raise NotImplementedError('Extension not yet supported.') + + obj = _txt2obj(self, extension.oid.dotted_string) + extension = backend._lib.X509_EXTENSION_create_by_OBJ( + backend._ffi.NULL, + obj, + 1 if extension.critical else 0, + _encode_asn1_str(backend, pp[0], r) + ) + assert extension != backend._ffi.NULL + res = self._lib.sk_X509_EXTENSION_push(extensions, extension) assert res == 1 res = self._lib.X509_REQ_add_extensions(x509_req, extensions) diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 8e361fa2..b387b9ee 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -720,6 +720,8 @@ class _CertificateSigningRequest(object): ) elif oid == x509.OID_BASIC_CONSTRAINTS: value = _decode_basic_constraints(self._backend, ext) + elif oid == x509.OID_SUBJECT_ALTERNATIVE_NAME: + value = _decode_subject_alt_name(self._backend, ext) elif critical: raise x509.UnsupportedExtension( "{0} is not currently supported".format(oid), oid -- cgit v1.2.3 From ac7f70a1dc284339238fcfbdfba4f76476ab3d29 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 28 Jun 2015 11:07:52 -0400 Subject: fix the not implemeneted test --- src/cryptography/x509.py | 4 ++++ tests/test_x509.py | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 668bc2ef..a091cd78 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -1472,6 +1472,10 @@ class CertificateSigningRequestBuilder(object): extension = Extension( OID_SUBJECT_ALTERNATIVE_NAME, critical, extension ) + elif isinstance(extension, KeyUsage): + extension = Extension( + OID_KEY_USAGE, critical, extension + ) else: raise NotImplementedError('Unsupported X.509 extension.') # TODO: This is quadratic in the number of extensions diff --git a/tests/test_x509.py b/tests/test_x509.py index 64a59237..133f0535 100644 --- a/tests/test_x509.py +++ b/tests/test_x509.py @@ -864,7 +864,17 @@ class TestCertificateSigningRequestBuilder(object): x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'), ]) ).add_extension( - x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]), + x509.KeyUsage( + digital_signature=True, + content_commitment=True, + key_encipherment=False, + data_encipherment=False, + key_agreement=False, + key_cert_sign=True, + crl_sign=False, + encipher_only=False, + decipher_only=False + ), critical=False, ) with pytest.raises(NotImplementedError): -- cgit v1.2.3 From d74e336fdad10333718d189da535ce47e147a967 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 3 Jul 2015 10:10:27 -0400 Subject: reduce diff with master --- src/_cffi_src/openssl/x509v3.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/_cffi_src/openssl/x509v3.py b/src/_cffi_src/openssl/x509v3.py index 36d90911..52287459 100644 --- a/src/_cffi_src/openssl/x509v3.py +++ b/src/_cffi_src/openssl/x509v3.py @@ -185,7 +185,6 @@ MACROS = """ int i2d_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS *, unsigned char **); BASIC_CONSTRAINTS *BASIC_CONSTRAINTS_new(void); void BASIC_CONSTRAINTS_free(BASIC_CONSTRAINTS *); - /* This is a macro defined by a call to DECLARE_ASN1_FUNCTIONS in the x509v3.h header. */ void AUTHORITY_KEYID_free(AUTHORITY_KEYID *); -- cgit v1.2.3 From e49351193d5027f212fd6a7677e7859cc71fe6d8 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 3 Jul 2015 10:29:49 -0400 Subject: fixed merge --- tests/test_x509.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/tests/test_x509.py b/tests/test_x509.py index 3491446d..fb74e3b1 100644 --- a/tests/test_x509.py +++ b/tests/test_x509.py @@ -863,19 +863,6 @@ class TestCertificateSigningRequestBuilder(object): x509.Name([ x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'), ]) - ).add_extension( - x509.KeyUsage( - digital_signature=True, - content_commitment=True, - key_encipherment=False, - data_encipherment=False, - key_agreement=False, - key_cert_sign=True, - crl_sign=False, - encipher_only=False, - decipher_only=False - ), - critical=False, ).add_extension( x509.KeyUsage( digital_signature=True, -- cgit v1.2.3 From 7583f7ff3a2d655aa1f58fde1fa13da7e8b40f57 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 3 Jul 2015 10:56:49 -0400 Subject: add this part of the test back --- tests/test_x509.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_x509.py b/tests/test_x509.py index 32f29ff5..3975d5b6 100644 --- a/tests/test_x509.py +++ b/tests/test_x509.py @@ -877,6 +877,9 @@ class TestCertificateSigningRequestBuilder(object): x509.Name([ x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'), ]) + ).add_extension( + x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]), + critical=False, ).add_extension( x509.KeyUsage( digital_signature=True, -- cgit v1.2.3 From d5f718c19c09f529ff34b319a1e2e0e7f1862a9a Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 5 Jul 2015 11:19:38 -0400 Subject: Organize code a bit better --- .../hazmat/backends/openssl/backend.py | 25 +++++++++++++--------- tests/test_x509.py | 18 ++++++++++++++++ 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index f05b0515..753cb50d 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -139,20 +139,25 @@ def _encode_basic_constraints(backend, basic_constraints): def _encode_subject_alt_name(backend, san): general_names = backend._lib.GENERAL_NAMES_new() assert general_names != backend._ffi.NULL - # TODO: GC + general_names = backend._ffi.gc( + general_names, backend._lib.GENERAL_NAMES_free + ) for alt_name in san: - assert 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 - gn.d.dNSName = ia5 - # TODO: idna - value = alt_name.value.encode("ascii") - res = backend._lib.ASN1_STRING_set(gn.d.dNSName, value, len(value)) - assert res == 1 + # TODO: GC? + if isinstance(alt_name, x509.DNSName): + gn.type = backend._lib.GEN_DNS + ia5 = backend._lib.ASN1_IA5STRING_new() + assert ia5 != backend._ffi.NULL + # TODO: idna + value = alt_name.value.encode("ascii") + res = backend._lib.ASN1_STRING_set(ia5, value, len(value)) + assert res == 1 + gn.d.dNSName = ia5 + else: + raise NotImplementedError("Only DNSNames are supported right now") res = backend._lib.sk_GENERAL_NAME_push(general_names, gn) assert res == 1 diff --git a/tests/test_x509.py b/tests/test_x509.py index 3975d5b6..6cc0fc48 100644 --- a/tests/test_x509.py +++ b/tests/test_x509.py @@ -935,6 +935,24 @@ class TestCertificateSigningRequestBuilder(object): x509.DNSName(u"google.com"), ] + def test_subject_alt_name_unsupported_general_name(self, backend): + private_key = RSA_KEY_2048.private_key(backend) + + builder = x509.CertificateSigningRequestBuilder().subject_name( + x509.Name([ + x509.NameAttribute(x509.OID_COMMON_NAME, u"SAN"), + ]) + ).add_extension( + x509.SubjectAlternativeName([ + x509.RFC822Name(u"test@example.com"), + ]), + critical=False, + ) + + with pytest.raises(NotImplementedError): + builder.sign(private_key, hashes.SHA256(), backend) + + @pytest.mark.requires_backend_interface(interface=DSABackend) @pytest.mark.requires_backend_interface(interface=X509Backend) -- cgit v1.2.3 From ba2abb102152a4b57f7661481c8bc53d473cbf09 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 5 Jul 2015 11:21:05 -0400 Subject: idna here --- src/cryptography/hazmat/backends/openssl/backend.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 753cb50d..52b5abcf 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -8,6 +8,8 @@ import collections import itertools from contextlib import contextmanager +import idna + import six from cryptography import utils, x509 @@ -151,8 +153,7 @@ def _encode_subject_alt_name(backend, san): gn.type = backend._lib.GEN_DNS ia5 = backend._lib.ASN1_IA5STRING_new() assert ia5 != backend._ffi.NULL - # TODO: idna - value = alt_name.value.encode("ascii") + value = idna.encode(alt_name.value) res = backend._lib.ASN1_STRING_set(ia5, value, len(value)) assert res == 1 gn.d.dNSName = ia5 -- cgit v1.2.3 From 4de08a2e1e85b7e16b78074c20cee840d315d637 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 5 Jul 2015 11:22:14 -0400 Subject: this needs to be freed as well --- src/cryptography/hazmat/backends/openssl/backend.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 52b5abcf..767605c0 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -153,6 +153,7 @@ def _encode_subject_alt_name(backend, san): gn.type = backend._lib.GEN_DNS ia5 = backend._lib.ASN1_IA5STRING_new() assert ia5 != backend._ffi.NULL + # TODO: GC? value = idna.encode(alt_name.value) res = backend._lib.ASN1_STRING_set(ia5, value, len(value)) assert res == 1 -- cgit v1.2.3 From 46501ce22c662600f45b3fadca54387a4520c119 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 5 Jul 2015 11:30:41 -0400 Subject: Paul says openssl just does the right thing here. --- src/cryptography/hazmat/backends/openssl/backend.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 767605c0..6f64613b 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -148,12 +148,10 @@ def _encode_subject_alt_name(backend, san): for alt_name in san: gn = backend._lib.GENERAL_NAME_new() assert gn != backend._ffi.NULL - # TODO: GC? if isinstance(alt_name, x509.DNSName): gn.type = backend._lib.GEN_DNS ia5 = backend._lib.ASN1_IA5STRING_new() assert ia5 != backend._ffi.NULL - # TODO: GC? value = idna.encode(alt_name.value) res = backend._lib.ASN1_STRING_set(ia5, value, len(value)) assert res == 1 -- cgit v1.2.3 From eae9560f6801e9c89381c2616b795b9037f2a6a9 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 5 Jul 2015 11:36:57 -0400 Subject: flake8 for the flkae8 god --- tests/test_x509.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_x509.py b/tests/test_x509.py index 6cc0fc48..b8c3b03a 100644 --- a/tests/test_x509.py +++ b/tests/test_x509.py @@ -953,7 +953,6 @@ class TestCertificateSigningRequestBuilder(object): builder.sign(private_key, hashes.SHA256(), backend) - @pytest.mark.requires_backend_interface(interface=DSABackend) @pytest.mark.requires_backend_interface(interface=X509Backend) class TestDSACertificate(object): -- cgit v1.2.3 From 6431d50831b8e4a4927f5e6619603eeac78ff489 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 5 Jul 2015 12:28:46 -0400 Subject: Wildcards. Also fixed a bug with multiple GNs --- src/cryptography/hazmat/backends/openssl/backend.py | 9 +++++++-- tests/test_x509.py | 6 ++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 6f64613b..ec692926 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -152,7 +152,12 @@ def _encode_subject_alt_name(backend, san): gn.type = backend._lib.GEN_DNS ia5 = backend._lib.ASN1_IA5STRING_new() assert ia5 != backend._ffi.NULL - value = idna.encode(alt_name.value) + + 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 @@ -160,7 +165,7 @@ def _encode_subject_alt_name(backend, san): raise NotImplementedError("Only DNSNames are supported right now") res = backend._lib.sk_GENERAL_NAME_push(general_names, gn) - assert res == 1 + assert res >= 0 pp = backend._ffi.new("unsigned char **") r = backend._lib.i2d_GENERAL_NAMES(general_names, pp) diff --git a/tests/test_x509.py b/tests/test_x509.py index b8c3b03a..78552978 100644 --- a/tests/test_x509.py +++ b/tests/test_x509.py @@ -920,7 +920,8 @@ class TestCertificateSigningRequestBuilder(object): ]) ).add_extension( x509.SubjectAlternativeName([ - x509.DNSName(u"google.com"), + x509.DNSName(u"example.com"), + x509.DNSName(u"*.example.com"), ]), critical=False, ).sign(private_key, hashes.SHA256(), backend) @@ -932,7 +933,8 @@ class TestCertificateSigningRequestBuilder(object): assert not ext.critical assert ext.oid == x509.OID_SUBJECT_ALTERNATIVE_NAME assert list(ext.value) == [ - x509.DNSName(u"google.com"), + x509.DNSName(u"example.com"), + x509.DNSName(u"*.example.com"), ] def test_subject_alt_name_unsupported_general_name(self, backend): -- cgit v1.2.3 From 8df780814d0f779dd80bf093ec8fcefc2071b248 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 5 Jul 2015 12:30:20 -0400 Subject: Make the error check match how the openssl codebase does it --- src/cryptography/hazmat/backends/openssl/backend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index ec692926..06801bc9 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -165,7 +165,7 @@ def _encode_subject_alt_name(backend, san): raise NotImplementedError("Only DNSNames are supported right now") res = backend._lib.sk_GENERAL_NAME_push(general_names, gn) - assert res >= 0 + assert res != 0 pp = backend._ffi.new("unsigned char **") r = backend._lib.i2d_GENERAL_NAMES(general_names, pp) -- cgit v1.2.3 From cc781e31f37d53c7d8ba0654db4e47e04c88f662 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 5 Jul 2015 12:43:20 -0400 Subject: fixed a leak in the event of non-DNS GN --- src/cryptography/hazmat/backends/openssl/backend.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 06801bc9..bbec6185 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -146,10 +146,11 @@ def _encode_subject_alt_name(backend, san): ) for alt_name in san: - gn = backend._lib.GENERAL_NAME_new() - assert gn != backend._ffi.NULL 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 -- cgit v1.2.3