diff options
author | Adam Goodman <akgood@duosecurity.com> | 2014-07-23 15:11:46 -0400 |
---|---|---|
committer | Adam Goodman <akgood@duosecurity.com> | 2014-07-23 15:11:46 -0400 |
commit | e97ae127f9fc44098f2461a567aa6b9a61e37f5c (patch) | |
tree | 671df50035c3daadb26ddb081e36493c610828e5 /cryptography | |
parent | ab3093ffe7dcc058cbd1b22ecb32b715ca47d6d2 (diff) | |
parent | ad116e26d102651ab6dc2752ae21afb92b72ad6f (diff) | |
download | cryptography-e97ae127f9fc44098f2461a567aa6b9a61e37f5c.tar.gz cryptography-e97ae127f9fc44098f2461a567aa6b9a61e37f5c.tar.bz2 cryptography-e97ae127f9fc44098f2461a567aa6b9a61e37f5c.zip |
Merge branch 'master' into reorder_libs
Diffstat (limited to 'cryptography')
-rw-r--r-- | cryptography/hazmat/backends/interfaces.py | 70 | ||||
-rw-r--r-- | cryptography/hazmat/backends/multibackend.py | 27 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/backend.py | 53 | ||||
-rw-r--r-- | cryptography/hazmat/bindings/commoncrypto/secitem.py | 2 | ||||
-rw-r--r-- | cryptography/hazmat/bindings/openssl/nid.py | 1 | ||||
-rw-r--r-- | cryptography/hazmat/bindings/openssl/x509v3.py | 2 | ||||
-rw-r--r-- | cryptography/hazmat/primitives/asymmetric/rsa.py | 3 |
7 files changed, 97 insertions, 61 deletions
diff --git a/cryptography/hazmat/backends/interfaces.py b/cryptography/hazmat/backends/interfaces.py index 5ed49966..75d9af6d 100644 --- a/cryptography/hazmat/backends/interfaces.py +++ b/cryptography/hazmat/backends/interfaces.py @@ -71,6 +71,21 @@ class HMACBackend(object): @six.add_metaclass(abc.ABCMeta) +class CMACBackend(object): + @abc.abstractmethod + def cmac_algorithm_supported(self, algorithm): + """ + Returns True if the block cipher is supported for CMAC by this backend + """ + + @abc.abstractmethod + def create_cmac_ctx(self, algorithm): + """ + Create a CMACContext for calculating a message authentication code. + """ + + +@six.add_metaclass(abc.ABCMeta) class PBKDF2HMACBackend(object): @abc.abstractmethod def pbkdf2_hmac_supported(self, algorithm): @@ -222,41 +237,6 @@ class DSABackend(object): @six.add_metaclass(abc.ABCMeta) -class TraditionalOpenSSLSerializationBackend(object): - @abc.abstractmethod - def load_traditional_openssl_pem_private_key(self, data, password): - """ - Load a private key from PEM encoded data, using password if the data - is encrypted. - """ - - -@six.add_metaclass(abc.ABCMeta) -class PKCS8SerializationBackend(object): - @abc.abstractmethod - def load_pkcs8_pem_private_key(self, data, password): - """ - Load a private key from PEM encoded data, using password if the data - is encrypted. - """ - - -@six.add_metaclass(abc.ABCMeta) -class CMACBackend(object): - @abc.abstractmethod - def cmac_algorithm_supported(self, algorithm): - """ - Returns True if the block cipher is supported for CMAC by this backend - """ - - @abc.abstractmethod - def create_cmac_ctx(self, algorithm): - """ - Create a CMACContext for calculating a message authentication code. - """ - - -@six.add_metaclass(abc.ABCMeta) class EllipticCurveBackend(object): @abc.abstractmethod def elliptic_curve_signature_algorithm_supported( @@ -290,3 +270,23 @@ class EllipticCurveBackend(object): """ Return an EllipticCurvePublicKey provider using the given numbers. """ + + +@six.add_metaclass(abc.ABCMeta) +class TraditionalOpenSSLSerializationBackend(object): + @abc.abstractmethod + def load_traditional_openssl_pem_private_key(self, data, password): + """ + Load a private key from PEM encoded data, using password if the data + is encrypted. + """ + + +@six.add_metaclass(abc.ABCMeta) +class PKCS8SerializationBackend(object): + @abc.abstractmethod + def load_pkcs8_pem_private_key(self, data, password): + """ + Load a private key from PEM encoded data, using password if the data + is encrypted. + """ diff --git a/cryptography/hazmat/backends/multibackend.py b/cryptography/hazmat/backends/multibackend.py index 6741f045..6893cad6 100644 --- a/cryptography/hazmat/backends/multibackend.py +++ b/cryptography/hazmat/backends/multibackend.py @@ -17,7 +17,8 @@ from cryptography import utils from cryptography.exceptions import UnsupportedAlgorithm, _Reasons from cryptography.hazmat.backends.interfaces import ( CMACBackend, CipherBackend, DSABackend, EllipticCurveBackend, HMACBackend, - HashBackend, PBKDF2HMACBackend, PKCS8SerializationBackend, RSABackend + HashBackend, PBKDF2HMACBackend, PKCS8SerializationBackend, + RSABackend, TraditionalOpenSSLSerializationBackend ) @@ -28,6 +29,7 @@ from cryptography.hazmat.backends.interfaces import ( @utils.register_interface(PBKDF2HMACBackend) @utils.register_interface(PKCS8SerializationBackend) @utils.register_interface(RSABackend) +@utils.register_interface(TraditionalOpenSSLSerializationBackend) @utils.register_interface(DSABackend) @utils.register_interface(EllipticCurveBackend) class MultiBackend(object): @@ -237,6 +239,18 @@ class MultiBackend(object): raise UnsupportedAlgorithm("DSA is not supported by the backend.", _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + def load_dsa_public_numbers(self, numbers): + for b in self._filtered_backends(DSABackend): + return b.load_dsa_public_numbers(numbers) + raise UnsupportedAlgorithm("DSA is not supported by the backend.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + + def load_dsa_private_numbers(self, numbers): + for b in self._filtered_backends(DSABackend): + return b.load_dsa_private_numbers(numbers) + raise UnsupportedAlgorithm("DSA is not supported by the backend.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + def cmac_algorithm_supported(self, algorithm): return any( b.cmac_algorithm_supported(algorithm) @@ -312,3 +326,14 @@ class MultiBackend(object): "This backend does not support this key serialization.", _Reasons.UNSUPPORTED_SERIALIZATION ) + + def load_traditional_openssl_pem_private_key(self, data, password): + for b in self._filtered_backends( + TraditionalOpenSSLSerializationBackend + ): + return b.load_traditional_openssl_pem_private_key(data, password) + + raise UnsupportedAlgorithm( + "This backend does not support this key serialization.", + _Reasons.UNSUPPORTED_SERIALIZATION + ) diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index da52799c..01e61283 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -490,14 +490,24 @@ class Backend(object): def pem_password_cb(buf, size, writing, userdata): pem_password_cb.called += 1 - if not password or len(password) >= size: + if not password: + pem_password_cb.exception = TypeError( + "Password was not given but private key is encrypted." + ) return 0 - else: + elif len(password) < size: pw_buf = self._ffi.buffer(buf, size) pw_buf[:len(password)] = password return len(password) + else: + pem_password_cb.exception = ValueError( + "Passwords longer than {0} bytes are not supported " + "by this backend.".format(size - 1) + ) + return 0 pem_password_cb.called = 0 + pem_password_cb.exception = None return ( self._ffi.callback("int (char *, int, int, void *)", @@ -766,11 +776,19 @@ class Backend(object): return self.load_pkcs8_pem_private_key(data, password) def load_pkcs8_pem_private_key(self, data, password): + return self._load_key( + self._lib.PEM_read_bio_PrivateKey, + self._evp_pkey_to_private_key, + data, + password, + ) + + def _load_key(self, openssl_read_func, convert_func, data, password): mem_bio = self._bytes_to_bio(data) password_callback, password_func = self._pem_password_cb(password) - evp_pkey = self._lib.PEM_read_bio_PrivateKey( + evp_pkey = openssl_read_func( mem_bio.bio, self._ffi.NULL, password_callback, @@ -778,7 +796,12 @@ class Backend(object): ) if evp_pkey == self._ffi.NULL: - self._handle_key_loading_error(password) + if password_func.exception is not None: + errors = self._consume_errors() + assert errors + raise password_func.exception + else: + self._handle_key_loading_error() evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) @@ -791,30 +814,14 @@ class Backend(object): password is None ) - return self._evp_pkey_to_private_key(evp_pkey) + return convert_func(evp_pkey) - def _handle_key_loading_error(self, password): + def _handle_key_loading_error(self): errors = self._consume_errors() + if not errors: raise ValueError("Could not unserialize key data.") - if ( - errors[0][1:] == ( - self._lib.ERR_LIB_PEM, - self._lib.PEM_F_PEM_DO_HEADER, - self._lib.PEM_R_BAD_PASSWORD_READ - ) - ) or ( - errors[0][1:] == ( - self._lib.ERR_LIB_PEM, - self._lib.PEM_F_PEM_READ_BIO_PRIVATEKEY, - self._lib.PEM_R_BAD_PASSWORD_READ - ) - ): - assert not password - raise TypeError( - "Password was not given but private key is encrypted.") - elif errors[0][1:] == ( self._lib.ERR_LIB_EVP, self._lib.EVP_F_EVP_DECRYPTFINAL_EX, diff --git a/cryptography/hazmat/bindings/commoncrypto/secitem.py b/cryptography/hazmat/bindings/commoncrypto/secitem.py index 4d7710bd..ac3dad3f 100644 --- a/cryptography/hazmat/bindings/commoncrypto/secitem.py +++ b/cryptography/hazmat/bindings/commoncrypto/secitem.py @@ -23,8 +23,6 @@ const CFTypeRef kSecAttrKeySizeInBits; const CFTypeRef kSecAttrIsPermanent; const CFTypeRef kSecAttrKeyTypeRSA; const CFTypeRef kSecAttrKeyTypeDSA; -const CFTypeRef kSecAttrKeyTypeEC; -const CFTypeRef kSecAttrKeyTypeEC; const CFTypeRef kSecUseKeychain; """ diff --git a/cryptography/hazmat/bindings/openssl/nid.py b/cryptography/hazmat/bindings/openssl/nid.py index 7fa08660..133d2ca4 100644 --- a/cryptography/hazmat/bindings/openssl/nid.py +++ b/cryptography/hazmat/bindings/openssl/nid.py @@ -42,6 +42,7 @@ static const int NID_ecdsa_with_SHA512; static const int NID_crl_reason; static const int NID_pbe_WithSHA1And3_Key_TripleDES_CBC; static const int NID_subject_alt_name; +static const int NID_issuer_alt_name; static const int NID_X9_62_c2pnb163v1; static const int NID_X9_62_c2pnb163v2; static const int NID_X9_62_c2pnb163v3; diff --git a/cryptography/hazmat/bindings/openssl/x509v3.py b/cryptography/hazmat/bindings/openssl/x509v3.py index 02ec250a..cf4be1fe 100644 --- a/cryptography/hazmat/bindings/openssl/x509v3.py +++ b/cryptography/hazmat/bindings/openssl/x509v3.py @@ -82,6 +82,8 @@ FUNCTIONS = """ void X509V3_set_ctx(X509V3_CTX *, X509 *, X509 *, X509_REQ *, X509_CRL *, int); X509_EXTENSION *X509V3_EXT_nconf(CONF *, X509V3_CTX *, char *, char *); int GENERAL_NAME_print(BIO *, GENERAL_NAME *); +void GENERAL_NAMES_free(GENERAL_NAMES *); +void *X509V3_EXT_d2i(X509_EXTENSION *); """ MACROS = """ diff --git a/cryptography/hazmat/primitives/asymmetric/rsa.py b/cryptography/hazmat/primitives/asymmetric/rsa.py index 15ec52ac..398b3763 100644 --- a/cryptography/hazmat/primitives/asymmetric/rsa.py +++ b/cryptography/hazmat/primitives/asymmetric/rsa.py @@ -402,3 +402,6 @@ class RSAPublicNumbers(object): def public_key(self, backend): return backend.load_rsa_public_numbers(self) + + def __repr__(self): + return "<RSAPublicNumbers(e={0}, n={1})>".format(self._e, self._n) |