diff options
author | Paul Kehrer <paul.l.kehrer@gmail.com> | 2018-11-29 11:51:38 +0800 |
---|---|---|
committer | Alex Gaynor <alex.gaynor@gmail.com> | 2018-11-28 22:51:38 -0500 |
commit | e4e7b89fb627b372cde4158ceb7078d8769497cb (patch) | |
tree | 9dc87beda0cf2d1a948feea01c87361feb1a32af /src | |
parent | 2f2f3d2e414a0167ae3a98b9b608904b2c76a35f (diff) | |
download | cryptography-e4e7b89fb627b372cde4158ceb7078d8769497cb.tar.gz cryptography-e4e7b89fb627b372cde4158ceb7078d8769497cb.tar.bz2 cryptography-e4e7b89fb627b372cde4158ceb7078d8769497cb.zip |
PKCS12 Basic Parsing (#4553)
* PKCS12 parsing support
* running all the tests is so gauche
* rename func
* various significant fixes
* dangerous idiot here
* move pkcs12
* docs updates
* a bit more prose
Diffstat (limited to 'src')
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/backend.py | 46 | ||||
-rw-r--r-- | src/cryptography/hazmat/primitives/serialization/pkcs12.py | 9 |
2 files changed, 55 insertions, 0 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 44c2e3cd..5a22a555 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -2129,6 +2129,52 @@ class Backend(object): self._lib.EVP_get_cipherbyname(cipher_name) != self._ffi.NULL ) + def load_key_and_certificates_from_pkcs12(self, data, password): + if password is None: + password = self._ffi.NULL + elif not isinstance(password, bytes): + raise TypeError("Password must be a byte string or None") + + bio = self._bytes_to_bio(data) + p12 = self._lib.d2i_PKCS12_bio(bio.bio, self._ffi.NULL) + if p12 == self._ffi.NULL: + self._consume_errors() + raise ValueError("Could not deserialize PKCS12 data") + + p12 = self._ffi.gc(p12, self._lib.PKCS12_free) + evp_pkey_ptr = self._ffi.new("EVP_PKEY **") + x509_ptr = self._ffi.new("X509 **") + sk_x509_ptr = self._ffi.new("Cryptography_STACK_OF_X509 **") + res = self._lib.PKCS12_parse( + p12, password, evp_pkey_ptr, x509_ptr, sk_x509_ptr + ) + if res == 0: + self._consume_errors() + raise ValueError("Invalid password or PKCS12 data") + + cert = None + key = None + additional_certificates = [] + + if evp_pkey_ptr[0] != self._ffi.NULL: + evp_pkey = self._ffi.gc(evp_pkey_ptr[0], self._lib.EVP_PKEY_free) + key = self._evp_pkey_to_private_key(evp_pkey) + + if x509_ptr[0] != self._ffi.NULL: + x509 = self._ffi.gc(x509_ptr[0], self._lib.X509_free) + cert = _Certificate(self, x509) + + if sk_x509_ptr[0] != self._ffi.NULL: + sk_x509 = self._ffi.gc(sk_x509_ptr[0], self._lib.sk_X509_free) + num = self._lib.sk_X509_num(sk_x509_ptr[0]) + for i in range(num): + x509 = self._lib.sk_X509_value(sk_x509, i) + x509 = self._ffi.gc(x509, self._lib.X509_free) + self.openssl_assert(x509 != self._ffi.NULL) + additional_certificates.append(_Certificate(self, x509)) + + return (key, cert, additional_certificates) + class GetCipherByName(object): def __init__(self, fmt): diff --git a/src/cryptography/hazmat/primitives/serialization/pkcs12.py b/src/cryptography/hazmat/primitives/serialization/pkcs12.py new file mode 100644 index 00000000..98161d57 --- /dev/null +++ b/src/cryptography/hazmat/primitives/serialization/pkcs12.py @@ -0,0 +1,9 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import absolute_import, division, print_function + + +def load_key_and_certificates(data, password, backend): + return backend.load_key_and_certificates_from_pkcs12(data, password) |