From 28d1dfaec4e39994340e156a387b7da90643f036 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 24 Dec 2015 21:38:37 -0600 Subject: refactor x509 extension creation to make it a bit more reusable Unfortunately X509 certs and CSRs add extensions differently, so we can't reuse quite as much as we'd like to... --- .../hazmat/backends/openssl/backend.py | 77 +++++++++++----------- 1 file changed, 39 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 6d19b806..0981b8e0 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1312,30 +1312,19 @@ class Backend(object): self.openssl_assert(res == 1) # Add extensions. - extensions = self._lib.sk_X509_EXTENSION_new_null() - self.openssl_assert(extensions != self._ffi.NULL) - extensions = self._ffi.gc( - extensions, - self._lib.sk_X509_EXTENSION_free, + extensions = self._create_x509_extensions( + builder._extensions, _EXTENSION_ENCODE_HANDLERS ) - for extension in builder._extensions: - try: - encode = _EXTENSION_ENCODE_HANDLERS[extension.oid] - except KeyError: - raise NotImplementedError('Extension not yet supported.') - - pp, r = encode(self, extension.value) - obj = _txt2obj_gc(self, extension.oid.dotted_string) - extension = self._lib.X509_EXTENSION_create_by_OBJ( - self._ffi.NULL, - obj, - 1 if extension.critical else 0, - _encode_asn1_str_gc(self, pp[0], r), - ) - self.openssl_assert(extension != self._ffi.NULL) - res = self._lib.sk_X509_EXTENSION_push(extensions, extension) + sk_extension = self._lib.sk_X509_EXTENSION_new_null() + self.openssl_assert(sk_extension != self._ffi.NULL) + sk_extension = self._ffi.gc( + sk_extension, self._lib.sk_X509_EXTENSION_free + ) + for extension in extensions: + res = self._lib.sk_X509_EXTENSION_push(sk_extension, extension) self.openssl_assert(res >= 1) - res = self._lib.X509_REQ_add_extensions(x509_req, extensions) + + res = self._lib.X509_REQ_add_extensions(x509_req, sk_extension) self.openssl_assert(res == 1) # Sign the request using the requester's private key. @@ -1416,22 +1405,10 @@ class Backend(object): self.openssl_assert(res != self._ffi.NULL) # Add extensions. - for i, extension in enumerate(builder._extensions): - try: - encode = _EXTENSION_ENCODE_HANDLERS[extension.oid] - except KeyError: - raise NotImplementedError('Extension not yet supported.') - - pp, r = encode(self, extension.value) - obj = _txt2obj_gc(self, extension.oid.dotted_string) - extension = self._lib.X509_EXTENSION_create_by_OBJ( - self._ffi.NULL, - obj, - 1 if extension.critical else 0, - _encode_asn1_str_gc(self, pp[0], r) - ) - self.openssl_assert(extension != self._ffi.NULL) - extension = self._ffi.gc(extension, self._lib.X509_EXTENSION_free) + extensions = self._create_x509_extensions( + builder._extensions, _EXTENSION_ENCODE_HANDLERS + ) + for i, extension in enumerate(extensions): res = self._lib.X509_add_ext(x509_cert, extension, i) self.openssl_assert(res == 1) @@ -1524,6 +1501,30 @@ class Backend(object): return _CertificateRevocationList(self, x509_crl) + def _create_x509_extensions(self, extensions, handlers): + x509_extensions = [] + for extension in extensions: + try: + encode = handlers[extension.oid] + except KeyError: + raise NotImplementedError( + 'Extension not supported: {0}'.format(extension.oid) + ) + + pp, r = encode(self, extension.value) + obj = _txt2obj_gc(self, extension.oid.dotted_string) + extension = self._lib.X509_EXTENSION_create_by_OBJ( + self._ffi.NULL, + obj, + 1 if extension.critical else 0, + _encode_asn1_str_gc(self, pp[0], r) + ) + self.openssl_assert(extension != self._ffi.NULL) + extension = self._ffi.gc(extension, self._lib.X509_EXTENSION_free) + x509_extensions.append(extension) + + return x509_extensions + def load_pem_private_key(self, data, password): return self._load_key( self._lib.PEM_read_bio_PrivateKey, -- cgit v1.2.3 From e7dc111a2fedbb42e008bb34a4e34835b3a63399 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 24 Dec 2015 21:44:57 -0600 Subject: don't reuse a variable, it's confusing --- src/cryptography/hazmat/backends/openssl/backend.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 0981b8e0..9ba0f3db 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1513,15 +1513,17 @@ class Backend(object): pp, r = encode(self, extension.value) obj = _txt2obj_gc(self, extension.oid.dotted_string) - extension = self._lib.X509_EXTENSION_create_by_OBJ( + x509_extension = self._lib.X509_EXTENSION_create_by_OBJ( self._ffi.NULL, obj, 1 if extension.critical else 0, _encode_asn1_str_gc(self, pp[0], r) ) - self.openssl_assert(extension != self._ffi.NULL) - extension = self._ffi.gc(extension, self._lib.X509_EXTENSION_free) - x509_extensions.append(extension) + self.openssl_assert(x509_extension != self._ffi.NULL) + x509_extension = self._ffi.gc( + x509_extension, self._lib.X509_EXTENSION_free + ) + x509_extensions.append(x509_extension) return x509_extensions -- cgit v1.2.3 From d58b57991f73581da951c7c98b808dad7875f9b1 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 24 Dec 2015 22:30:42 -0600 Subject: a different approach to refactoring the x509 extension addition --- src/_cffi_src/openssl/x509.py | 1 + .../hazmat/backends/openssl/backend.py | 45 ++++++++++++---------- 2 files changed, 25 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/_cffi_src/openssl/x509.py b/src/_cffi_src/openssl/x509.py index a08ef179..b58a1a27 100644 --- a/src/_cffi_src/openssl/x509.py +++ b/src/_cffi_src/openssl/x509.py @@ -292,6 +292,7 @@ X509_EXTENSIONS *sk_X509_EXTENSION_new_null(void); int sk_X509_EXTENSION_num(X509_EXTENSIONS *); X509_EXTENSION *sk_X509_EXTENSION_value(X509_EXTENSIONS *, int); int sk_X509_EXTENSION_push(X509_EXTENSIONS *, X509_EXTENSION *); +int sk_X509_EXTENSION_insert(X509_EXTENSIONS *, X509_EXTENSION *, int); X509_EXTENSION *sk_X509_EXTENSION_delete(X509_EXTENSIONS *, int); void sk_X509_EXTENSION_free(X509_EXTENSIONS *); diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 9ba0f3db..86c1a813 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1312,18 +1312,20 @@ class Backend(object): self.openssl_assert(res == 1) # Add extensions. - extensions = self._create_x509_extensions( - builder._extensions, _EXTENSION_ENCODE_HANDLERS - ) sk_extension = self._lib.sk_X509_EXTENSION_new_null() self.openssl_assert(sk_extension != self._ffi.NULL) sk_extension = self._ffi.gc( sk_extension, self._lib.sk_X509_EXTENSION_free ) - for extension in extensions: - res = self._lib.sk_X509_EXTENSION_push(sk_extension, extension) - self.openssl_assert(res >= 1) - + # gc is not necessary for CSRs, as sk_X509_EXTENSION_free + # will release all the X509_EXTENSIONs. + self._create_x509_extensions( + extensions=builder._extensions, + handlers=_EXTENSION_ENCODE_HANDLERS, + x509_obj=sk_extension, + add_func=self._lib.sk_X509_EXTENSION_insert, + gc=False + ) res = self._lib.X509_REQ_add_extensions(x509_req, sk_extension) self.openssl_assert(res == 1) @@ -1405,12 +1407,13 @@ class Backend(object): self.openssl_assert(res != self._ffi.NULL) # Add extensions. - extensions = self._create_x509_extensions( - builder._extensions, _EXTENSION_ENCODE_HANDLERS + self._create_x509_extensions( + extensions=builder._extensions, + handlers=_EXTENSION_ENCODE_HANDLERS, + x509_obj=x509_cert, + add_func=self._lib.X509_add_ext, + gc=True ) - for i, extension in enumerate(extensions): - res = self._lib.X509_add_ext(x509_cert, extension, i) - self.openssl_assert(res == 1) # Set the issuer name. res = self._lib.X509_set_issuer_name( @@ -1501,9 +1504,9 @@ class Backend(object): return _CertificateRevocationList(self, x509_crl) - def _create_x509_extensions(self, extensions, handlers): - x509_extensions = [] - for extension in extensions: + def _create_x509_extensions(self, extensions, handlers, x509_obj, + add_func, gc): + for i, extension in enumerate(extensions): try: encode = handlers[extension.oid] except KeyError: @@ -1520,12 +1523,12 @@ class Backend(object): _encode_asn1_str_gc(self, pp[0], r) ) self.openssl_assert(x509_extension != self._ffi.NULL) - x509_extension = self._ffi.gc( - x509_extension, self._lib.X509_EXTENSION_free - ) - x509_extensions.append(x509_extension) - - return x509_extensions + if gc: + x509_extension = self._ffi.gc( + x509_extension, self._lib.X509_EXTENSION_free + ) + res = add_func(x509_obj, x509_extension, i) + self.openssl_assert(res >= 1) def load_pem_private_key(self, data, password): return self._load_key( -- cgit v1.2.3