diff options
Diffstat (limited to 'cryptography/hazmat')
18 files changed, 593 insertions, 27 deletions
diff --git a/cryptography/hazmat/backends/__init__.py b/cryptography/hazmat/backends/__init__.py index 215aa4d3..cb1fee90 100644 --- a/cryptography/hazmat/backends/__init__.py +++ b/cryptography/hazmat/backends/__init__.py @@ -12,11 +12,15 @@ # limitations under the License. from cryptography.hazmat.backends import openssl +from cryptography.hazmat.bindings.commoncrypto.binding import ( + Binding as CCBinding +) +_ALL_BACKENDS = [openssl.backend] -_ALL_BACKENDS = [ - openssl.backend -] +if CCBinding.is_available(): + from cryptography.hazmat.backends import commoncrypto + _ALL_BACKENDS.append(commoncrypto.backend) def default_backend(): diff --git a/cryptography/hazmat/backends/commoncrypto/__init__.py b/cryptography/hazmat/backends/commoncrypto/__init__.py new file mode 100644 index 00000000..64a1c01c --- /dev/null +++ b/cryptography/hazmat/backends/commoncrypto/__init__.py @@ -0,0 +1,17 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from cryptography.hazmat.backends.commoncrypto.backend import backend + + +__all__ = ["backend"] diff --git a/cryptography/hazmat/backends/commoncrypto/backend.py b/cryptography/hazmat/backends/commoncrypto/backend.py new file mode 100644 index 00000000..603edc40 --- /dev/null +++ b/cryptography/hazmat/backends/commoncrypto/backend.py @@ -0,0 +1,186 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + +from collections import namedtuple + +from cryptography import utils +from cryptography.exceptions import UnsupportedAlgorithm +from cryptography.hazmat.backends.interfaces import ( + HashBackend, HMACBackend, +) +from cryptography.hazmat.bindings.commoncrypto.binding import Binding +from cryptography.hazmat.primitives import interfaces + + +HashMethods = namedtuple( + "HashMethods", ["ctx", "hash_init", "hash_update", "hash_final"] +) + + +@utils.register_interface(HashBackend) +@utils.register_interface(HMACBackend) +class Backend(object): + """ + CommonCrypto API wrapper. + """ + name = "commoncrypto" + + def __init__(self): + self._binding = Binding() + self._ffi = self._binding.ffi + self._lib = self._binding.lib + + self._hash_mapping = { + "md5": HashMethods( + "CC_MD5_CTX *", self._lib.CC_MD5_Init, + self._lib.CC_MD5_Update, self._lib.CC_MD5_Final + ), + "sha1": HashMethods( + "CC_SHA1_CTX *", self._lib.CC_SHA1_Init, + self._lib.CC_SHA1_Update, self._lib.CC_SHA1_Final + ), + "sha224": HashMethods( + "CC_SHA256_CTX *", self._lib.CC_SHA224_Init, + self._lib.CC_SHA224_Update, self._lib.CC_SHA224_Final + ), + "sha256": HashMethods( + "CC_SHA256_CTX *", self._lib.CC_SHA256_Init, + self._lib.CC_SHA256_Update, self._lib.CC_SHA256_Final + ), + "sha384": HashMethods( + "CC_SHA512_CTX *", self._lib.CC_SHA384_Init, + self._lib.CC_SHA384_Update, self._lib.CC_SHA384_Final + ), + "sha512": HashMethods( + "CC_SHA512_CTX *", self._lib.CC_SHA512_Init, + self._lib.CC_SHA512_Update, self._lib.CC_SHA512_Final + ), + } + + self._supported_hmac_algorithms = { + "md5": self._lib.kCCHmacAlgMD5, + "sha1": self._lib.kCCHmacAlgSHA1, + "sha224": self._lib.kCCHmacAlgSHA224, + "sha256": self._lib.kCCHmacAlgSHA256, + "sha384": self._lib.kCCHmacAlgSHA384, + "sha512": self._lib.kCCHmacAlgSHA512, + } + + def hash_supported(self, algorithm): + try: + self._hash_mapping[algorithm.name] + except KeyError: + return False + else: + return True + + def hmac_supported(self, algorithm): + try: + self._supported_hmac_algorithms[algorithm.name] + except KeyError: + return False + else: + return True + + def create_hash_ctx(self, algorithm): + return _HashContext(self, algorithm) + + def create_hmac_ctx(self, key, algorithm): + return _HMACContext(self, key, algorithm) + + +@utils.register_interface(interfaces.HashContext) +class _HashContext(object): + def __init__(self, backend, algorithm, ctx=None): + self.algorithm = algorithm + self._backend = backend + + if ctx is None: + try: + methods = self._backend._hash_mapping[self.algorithm.name] + except KeyError: + raise UnsupportedAlgorithm( + "{0} is not a supported hash on this backend".format( + algorithm.name) + ) + ctx = self._backend._ffi.new(methods.ctx) + res = methods.hash_init(ctx) + assert res == 1 + + self._ctx = ctx + + def copy(self): + methods = self._backend._hash_mapping[self.algorithm.name] + new_ctx = self._backend._ffi.new(methods.ctx) + # CommonCrypto has no APIs for copying hashes, so we have to copy the + # underlying struct. + new_ctx[0] = self._ctx[0] + + return _HashContext(self._backend, self.algorithm, ctx=new_ctx) + + def update(self, data): + methods = self._backend._hash_mapping[self.algorithm.name] + res = methods.hash_update(self._ctx, data, len(data)) + assert res == 1 + + def finalize(self): + methods = self._backend._hash_mapping[self.algorithm.name] + buf = self._backend._ffi.new("unsigned char[]", + self.algorithm.digest_size) + res = methods.hash_final(buf, self._ctx) + assert res == 1 + return self._backend._ffi.buffer(buf)[:] + + +@utils.register_interface(interfaces.HashContext) +class _HMACContext(object): + def __init__(self, backend, key, algorithm, ctx=None): + self.algorithm = algorithm + self._backend = backend + if ctx is None: + ctx = self._backend._ffi.new("CCHmacContext *") + try: + alg = self._backend._supported_hmac_algorithms[algorithm.name] + except KeyError: + raise UnsupportedAlgorithm( + "{0} is not a supported HMAC hash on this backend".format( + algorithm.name) + ) + + self._backend._lib.CCHmacInit(ctx, alg, key, len(key)) + + self._ctx = ctx + self._key = key + + def copy(self): + copied_ctx = self._backend._ffi.new("CCHmacContext *") + # CommonCrypto has no APIs for copying HMACs, so we have to copy the + # underlying struct. + copied_ctx[0] = self._ctx[0] + return _HMACContext( + self._backend, self._key, self.algorithm, ctx=copied_ctx + ) + + def update(self, data): + self._backend._lib.CCHmacUpdate(self._ctx, data, len(data)) + + def finalize(self): + buf = self._backend._ffi.new("unsigned char[]", + self.algorithm.digest_size) + self._backend._lib.CCHmacFinal(self._ctx, buf) + return self._backend._ffi.buffer(buf)[:] + + +backend = Backend() diff --git a/cryptography/hazmat/backends/interfaces.py b/cryptography/hazmat/backends/interfaces.py index 9a570968..4fbb3488 100644 --- a/cryptography/hazmat/backends/interfaces.py +++ b/cryptography/hazmat/backends/interfaces.py @@ -26,12 +26,6 @@ class CipherBackend(six.with_metaclass(abc.ABCMeta)): """ @abc.abstractmethod - def register_cipher_adapter(self, cipher, mode, adapter): - """ - Register an adapter for a cipher and mode to a backend specific object. - """ - - @abc.abstractmethod def create_symmetric_encryption_ctx(self, cipher, mode): """ Get a CipherContext that can be used for encryption. diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index ec2824d1..88afe997 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -37,6 +37,7 @@ class Backend(object): """ OpenSSL API binding interfaces. """ + name = "openssl" def __init__(self): self._binding = Binding() diff --git a/cryptography/hazmat/bindings/commoncrypto/binding.py b/cryptography/hazmat/bindings/commoncrypto/binding.py index 9c1af40a..a5a0dca8 100644 --- a/cryptography/hazmat/bindings/commoncrypto/binding.py +++ b/cryptography/hazmat/bindings/commoncrypto/binding.py @@ -26,6 +26,7 @@ class Binding(object): _modules = [ "common_digest", "common_hmac", + "common_cryptor", ] ffi = None diff --git a/cryptography/hazmat/bindings/commoncrypto/common_cryptor.py b/cryptography/hazmat/bindings/commoncrypto/common_cryptor.py new file mode 100644 index 00000000..ef0e7e10 --- /dev/null +++ b/cryptography/hazmat/bindings/commoncrypto/common_cryptor.py @@ -0,0 +1,94 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +INCLUDES = """ +#include <CommonCrypto/CommonCryptor.h> +""" + +TYPES = """ +enum { + kCCAlgorithmAES128 = 0, + kCCAlgorithmDES, + kCCAlgorithm3DES, + kCCAlgorithmCAST, + kCCAlgorithmRC4, + kCCAlgorithmRC2, + kCCAlgorithmBlowfish +}; +typedef uint32_t CCAlgorithm; +enum { + kCCSuccess = 0, + kCCParamError = -4300, + kCCBufferTooSmall = -4301, + kCCMemoryFailure = -4302, + kCCAlignmentError = -4303, + kCCDecodeError = -4304, + kCCUnimplemented = -4305 +}; +typedef int32_t CCCryptorStatus; +typedef uint32_t CCOptions; +enum { + kCCEncrypt = 0, + kCCDecrypt, +}; +typedef uint32_t CCOperation; +typedef ... *CCCryptorRef; + +enum { + kCCModeOptionCTR_LE = 0x0001, + kCCModeOptionCTR_BE = 0x0002 +}; + +typedef uint32_t CCModeOptions; + +enum { + kCCModeECB = 1, + kCCModeCBC = 2, + kCCModeCFB = 3, + kCCModeCTR = 4, + kCCModeF8 = 5, + kCCModeLRW = 6, + kCCModeOFB = 7, + kCCModeXTS = 8, + kCCModeRC4 = 9, + kCCModeCFB8 = 10, +}; +typedef uint32_t CCMode; +enum { + ccNoPadding = 0, + ccPKCS7Padding = 1, +}; +typedef uint32_t CCPadding; +""" + +FUNCTIONS = """ +CCCryptorStatus CCCryptorCreateWithMode(CCOperation, CCMode, CCAlgorithm, + CCPadding, const void *, const void *, + size_t, const void *, size_t, int, + CCModeOptions, CCCryptorRef *); +CCCryptorStatus CCCryptorCreate(CCOperation, CCAlgorithm, CCOptions, + const void *, size_t, const void *, + CCCryptorRef *); +CCCryptorStatus CCCryptorUpdate(CCCryptorRef, const void *, size_t, void *, + size_t, size_t *); +CCCryptorStatus CCCryptorFinal(CCCryptorRef, void *, size_t, size_t *); +CCCryptorStatus CCCryptorRelease(CCCryptorRef); +""" + +MACROS = """ +""" + +CUSTOMIZATIONS = """ +""" + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/bindings/openssl/bignum.py b/cryptography/hazmat/bindings/openssl/bignum.py index 59efd171..6545f329 100644 --- a/cryptography/hazmat/bindings/openssl/bignum.py +++ b/cryptography/hazmat/bindings/openssl/bignum.py @@ -47,6 +47,9 @@ char *BN_bn2hex(const BIGNUM *); int BN_hex2bn(BIGNUM **, const char *); int BN_dec2bn(BIGNUM **, const char *); +int BN_bn2bin(const BIGNUM *, unsigned char *); +BIGNUM *BN_bin2bn(const unsigned char *, int, BIGNUM *); + int BN_num_bits(const BIGNUM *); """ diff --git a/cryptography/hazmat/bindings/openssl/binding.py b/cryptography/hazmat/bindings/openssl/binding.py index 2419044f..261bbb8d 100644 --- a/cryptography/hazmat/bindings/openssl/binding.py +++ b/cryptography/hazmat/bindings/openssl/binding.py @@ -48,6 +48,7 @@ class Binding(object): "crypto", "dh", "dsa", + "ec", "engine", "err", "evp", diff --git a/cryptography/hazmat/bindings/openssl/crypto.py b/cryptography/hazmat/bindings/openssl/crypto.py index 189867bd..40d91bf2 100644 --- a/cryptography/hazmat/bindings/openssl/crypto.py +++ b/cryptography/hazmat/bindings/openssl/crypto.py @@ -16,6 +16,8 @@ INCLUDES = """ """ TYPES = """ +typedef ... CRYPTO_THREADID; + static const int SSLEAY_VERSION; static const int SSLEAY_CFLAGS; static const int SSLEAY_PLATFORM; diff --git a/cryptography/hazmat/bindings/openssl/dh.py b/cryptography/hazmat/bindings/openssl/dh.py index 3c12fbc6..ecc62e98 100644 --- a/cryptography/hazmat/bindings/openssl/dh.py +++ b/cryptography/hazmat/bindings/openssl/dh.py @@ -16,7 +16,17 @@ INCLUDES = """ """ TYPES = """ -typedef ... DH; +typedef struct dh_st { + // prime number (shared) + BIGNUM *p; + // generator of Z_p (shared) + BIGNUM *g; + // private DH value x + BIGNUM *priv_key; + // public DH value g^x + BIGNUM *pub_key; + ...; +} DH; """ FUNCTIONS = """ diff --git a/cryptography/hazmat/bindings/openssl/dsa.py b/cryptography/hazmat/bindings/openssl/dsa.py index 3b77d7ae..609a33bf 100644 --- a/cryptography/hazmat/bindings/openssl/dsa.py +++ b/cryptography/hazmat/bindings/openssl/dsa.py @@ -16,7 +16,19 @@ INCLUDES = """ """ TYPES = """ -typedef ... DSA; +typedef struct dsa_st { + // prime number (public) + BIGNUM *p; + // 160-bit subprime, q | p-1 (public) + BIGNUM *q; + // generator of subgroup (public) + BIGNUM *g; + // private key x + BIGNUM *priv_key; + // public key y = g^x + BIGNUM *pub_key; + ...; +} DSA; """ FUNCTIONS = """ diff --git a/cryptography/hazmat/bindings/openssl/ec.py b/cryptography/hazmat/bindings/openssl/ec.py new file mode 100644 index 00000000..9f10365a --- /dev/null +++ b/cryptography/hazmat/bindings/openssl/ec.py @@ -0,0 +1,56 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +INCLUDES = """ +#include <openssl/ec.h> +#include <openssl/obj_mac.h> +""" + +TYPES = """ +static const int Cryptography_HAS_EC; + +typedef ... EC_KEY; + +static const int NID_X9_62_prime192v1; +static const int NID_X9_62_prime192v2; +static const int NID_X9_62_prime192v3; +static const int NID_X9_62_prime239v1; +static const int NID_X9_62_prime239v2; +static const int NID_X9_62_prime239v3; +static const int NID_X9_62_prime256v1; +""" + +FUNCTIONS = """ +EC_KEY *EC_KEY_new_by_curve_name(int); +void EC_KEY_free(EC_KEY *); +""" + +MACROS = """ +""" + +CUSTOMIZATIONS = """ +#ifdef OPENSSL_NO_EC +static const long Cryptography_HAS_EC = 0; +EC_KEY* (*EC_KEY_new_by_curve_name)(int) = NULL; +void (*EC_KEY_free)(EC_KEY *) = NULL; +#else +static const long Cryptography_HAS_EC = 1; +#endif +""" + +CONDITIONAL_NAMES = { + "Cryptography_HAS_EC": [ + "EC_KEY_new_by_curve_name", + "EC_KEY_free", + ], +} diff --git a/cryptography/hazmat/bindings/openssl/engine.py b/cryptography/hazmat/bindings/openssl/engine.py index 390bfde1..77118e81 100644 --- a/cryptography/hazmat/bindings/openssl/engine.py +++ b/cryptography/hazmat/bindings/openssl/engine.py @@ -24,11 +24,11 @@ typedef ... ECDSA_METHOD; typedef ... DH_METHOD; typedef ... RAND_METHOD; typedef ... STORE_METHOD; -typedef ... ENGINE_GEN_INT_FUNC_PTR; -typedef ... ENGINE_CTRL_FUNC_PTR; -typedef ... ENGINE_LOAD_KEY_PTR; -typedef ... ENGINE_CIPHERS_PTR; -typedef ... ENGINE_DIGESTS_PTR; +typedef ... *ENGINE_GEN_INT_FUNC_PTR; +typedef ... *ENGINE_CTRL_FUNC_PTR; +typedef ... *ENGINE_LOAD_KEY_PTR; +typedef ... *ENGINE_CIPHERS_PTR; +typedef ... *ENGINE_DIGESTS_PTR; typedef ... ENGINE_CMD_DEFN; typedef ... UI_METHOD; diff --git a/cryptography/hazmat/bindings/openssl/err.py b/cryptography/hazmat/bindings/openssl/err.py index 1b66bd2a..ddb60ef7 100644 --- a/cryptography/hazmat/bindings/openssl/err.py +++ b/cryptography/hazmat/bindings/openssl/err.py @@ -16,24 +16,166 @@ INCLUDES = """ """ TYPES = """ +static const int Cryptography_HAS_REMOVE_THREAD_STATE; + struct ERR_string_data_st { unsigned long error; const char *string; }; typedef struct ERR_string_data_st ERR_STRING_DATA; -static const int ASN1_R_BAD_PASSWORD_READ; static const int ERR_LIB_EVP; static const int ERR_LIB_PEM; +static const int ERR_LIB_ASN1; + +static const int ASN1_F_ASN1_ENUMERATED_TO_BN; +static const int ASN1_F_ASN1_EX_C2I; +static const int ASN1_F_ASN1_FIND_END; +static const int ASN1_F_ASN1_GENERALIZEDTIME_SET; +static const int ASN1_F_ASN1_GENERATE_V3; +static const int ASN1_F_ASN1_GET_OBJECT; +static const int ASN1_F_ASN1_ITEM_I2D_FP; +static const int ASN1_F_ASN1_ITEM_PACK; +static const int ASN1_F_ASN1_ITEM_SIGN; +static const int ASN1_F_ASN1_ITEM_UNPACK; +static const int ASN1_F_ASN1_ITEM_VERIFY; +static const int ASN1_F_ASN1_MBSTRING_NCOPY; +static const int ASN1_F_ASN1_TEMPLATE_EX_D2I; +static const int ASN1_F_ASN1_TEMPLATE_NEW; +static const int ASN1_F_ASN1_TEMPLATE_NOEXP_D2I; +static const int ASN1_F_ASN1_TIME_SET; +static const int ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING; +static const int ASN1_F_ASN1_TYPE_GET_OCTETSTRING; +static const int ASN1_F_ASN1_UNPACK_STRING; +static const int ASN1_F_ASN1_UTCTIME_SET; +static const int ASN1_F_ASN1_VERIFY; +static const int ASN1_F_B64_READ_ASN1; +static const int ASN1_F_B64_WRITE_ASN1; +static const int ASN1_F_BITSTR_CB; +static const int ASN1_F_BN_TO_ASN1_ENUMERATED; +static const int ASN1_F_BN_TO_ASN1_INTEGER; +static const int ASN1_F_D2I_ASN1_TYPE_BYTES; +static const int ASN1_F_D2I_ASN1_UINTEGER; +static const int ASN1_F_D2I_ASN1_UTCTIME; +static const int ASN1_F_D2I_NETSCAPE_RSA; +static const int ASN1_F_D2I_NETSCAPE_RSA_2; +static const int ASN1_F_D2I_PRIVATEKEY; +static const int ASN1_F_D2I_X509; +static const int ASN1_F_D2I_X509_CINF; +static const int ASN1_F_D2I_X509_PKEY; +static const int ASN1_F_I2D_ASN1_SET; +static const int ASN1_F_I2D_ASN1_TIME; +static const int ASN1_F_I2D_DSA_PUBKEY; +static const int ASN1_F_LONG_C2I; +static const int ASN1_F_OID_MODULE_INIT; +static const int ASN1_F_PARSE_TAGGING; +static const int ASN1_F_PKCS5_PBE_SET; +static const int ASN1_F_SMIME_READ_ASN1; +static const int ASN1_F_SMIME_TEXT; +static const int ASN1_F_X509_CINF_NEW; +static const int ASN1_R_BOOLEAN_IS_WRONG_LENGTH; +static const int ASN1_R_BUFFER_TOO_SMALL; +static const int ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER; +static const int ASN1_R_DATA_IS_WRONG; +static const int ASN1_R_DECODE_ERROR; +static const int ASN1_R_DECODING_ERROR; +static const int ASN1_R_DEPTH_EXCEEDED; +static const int ASN1_R_ENCODE_ERROR; +static const int ASN1_R_ERROR_GETTING_TIME; +static const int ASN1_R_ERROR_LOADING_SECTION; +static const int ASN1_R_MSTRING_WRONG_TAG; +static const int ASN1_R_NESTED_ASN1_STRING; +static const int ASN1_R_NO_CONTENT_TYPE; +static const int ASN1_R_NO_MATCHING_CHOICE_TYPE; +static const int ASN1_R_NO_MULTIPART_BODY_FAILURE; +static const int ASN1_R_NO_MULTIPART_BOUNDARY; +static const int ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM; +static const int ASN1_R_UNKNOWN_OBJECT_TYPE; +static const int ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE; +static const int ASN1_R_UNKNOWN_TAG; +static const int ASN1_R_UNKOWN_FORMAT; +static const int ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE; +static const int ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM; +static const int ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE; +static const int ASN1_R_UNSUPPORTED_TYPE; +static const int ASN1_R_WRONG_TAG; +static const int ASN1_R_WRONG_TYPE; +static const int EVP_F_AES_INIT_KEY; +static const int EVP_F_CAMELLIA_INIT_KEY; +static const int EVP_F_D2I_PKEY; +static const int EVP_F_DSA_PKEY2PKCS8; +static const int EVP_F_DSAPKEY2PKCS8; +static const int EVP_F_ECDSA_PKEY2PKCS8; +static const int EVP_F_ECKEY_PKEY2PKCS8; +static const int EVP_F_EVP_CIPHER_CTX_CTRL; +static const int EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH; +static const int EVP_F_EVP_CIPHERINIT_EX; static const int EVP_F_EVP_DECRYPTFINAL_EX; +static const int EVP_F_EVP_DIGESTINIT_EX; static const int EVP_F_EVP_ENCRYPTFINAL_EX; - +static const int EVP_F_EVP_MD_CTX_COPY_EX; +static const int EVP_F_EVP_OPENINIT; +static const int EVP_F_EVP_PBE_ALG_ADD; +static const int EVP_F_EVP_PBE_CIPHERINIT; +static const int EVP_F_EVP_PKCS82PKEY; +static const int EVP_F_EVP_PKEY2PKCS8_BROKEN; +static const int EVP_F_EVP_PKEY_COPY_PARAMETERS; +static const int EVP_F_EVP_PKEY_DECRYPT; +static const int EVP_F_EVP_PKEY_ENCRYPT; +static const int EVP_F_EVP_PKEY_GET1_DH; +static const int EVP_F_EVP_PKEY_GET1_DSA; +static const int EVP_F_EVP_PKEY_GET1_ECDSA; +static const int EVP_F_EVP_PKEY_GET1_EC_KEY; +static const int EVP_F_EVP_PKEY_GET1_RSA; +static const int EVP_F_EVP_PKEY_NEW; +static const int EVP_F_EVP_RIJNDAEL; +static const int EVP_F_EVP_SIGNFINAL; +static const int EVP_F_EVP_VERIFYFINAL; +static const int EVP_F_PKCS5_PBE_KEYIVGEN; +static const int EVP_F_PKCS5_V2_PBE_KEYIVGEN; +static const int EVP_F_PKCS8_SET_BROKEN; +static const int EVP_F_RC2_MAGIC_TO_METH; +static const int EVP_F_RC5_CTRL; +static const int EVP_R_AES_KEY_SETUP_FAILED; +static const int EVP_R_ASN1_LIB; +static const int EVP_R_BAD_BLOCK_LENGTH; +static const int EVP_R_BAD_KEY_LENGTH; +static const int EVP_R_BN_DECODE_ERROR; +static const int EVP_R_BN_PUBKEY_ERROR; +static const int EVP_R_CAMELLIA_KEY_SETUP_FAILED; +static const int EVP_R_CIPHER_PARAMETER_ERROR; +static const int EVP_R_CTRL_NOT_IMPLEMENTED; +static const int EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED; static const int EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH; +static const int EVP_R_DECODE_ERROR; +static const int EVP_R_DIFFERENT_KEY_TYPES; +static const int EVP_R_DISABLED_FOR_FIPS; +static const int EVP_R_ENCODE_ERROR; +static const int EVP_R_INITIALIZATION_ERROR; +static const int EVP_R_INPUT_NOT_INITIALIZED; +static const int EVP_R_INVALID_KEY_LENGTH; +static const int EVP_R_IV_TOO_LARGE; +static const int EVP_R_KEYGEN_FAILURE; +static const int EVP_R_MISSING_PARAMETERS; +static const int EVP_R_NO_CIPHER_SET; +static const int EVP_R_NO_DIGEST_SET; +static const int EVP_R_NO_DSA_PARAMETERS; +static const int EVP_R_NO_SIGN_FUNCTION_CONFIGURED; +static const int EVP_R_NO_VERIFY_FUNCTION_CONFIGURED; +static const int EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE; +static const int EVP_R_PUBLIC_KEY_NOT_RSA; +static const int EVP_R_UNKNOWN_PBE_ALGORITHM; +static const int EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS; +static const int EVP_R_UNSUPPORTED_CIPHER; +static const int EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION; +static const int EVP_R_UNSUPPORTED_KEYLENGTH; +static const int EVP_R_UNSUPPORTED_SALT_TYPE; +static const int EVP_R_WRONG_FINAL_BLOCK_LENGTH; +static const int EVP_R_WRONG_PUBLIC_KEY_TYPE; static const int PEM_F_D2I_PKCS8PRIVATEKEY_BIO; -static const int PEM_F_D2I_PKCS8PRIVATEKEY_BIO; static const int PEM_F_D2I_PKCS8PRIVATEKEY_FP; static const int PEM_F_DO_PK8PKEY; static const int PEM_F_DO_PK8PKEY_FP; @@ -50,7 +192,6 @@ static const int PEM_F_PEM_PK8PKEY; static const int PEM_F_PEM_READ; static const int PEM_F_PEM_READ_BIO; static const int PEM_F_PEM_READ_BIO_PRIVATEKEY; -static const int PEM_F_PEM_READ_BIO_PRIVATEKEY; static const int PEM_F_PEM_READ_PRIVATEKEY; static const int PEM_F_PEM_SEALFINAL; static const int PEM_F_PEM_SEALINIT; @@ -66,12 +207,11 @@ static const int PEM_R_BAD_DECRYPT; static const int PEM_R_BAD_END_LINE; static const int PEM_R_BAD_IV_CHARS; static const int PEM_R_BAD_PASSWORD_READ; -static const int PEM_R_BAD_PASSWORD_READ; static const int PEM_R_ERROR_CONVERTING_PRIVATE_KEY; +static const int PEM_R_NO_START_LINE; static const int PEM_R_NOT_DEK_INFO; static const int PEM_R_NOT_ENCRYPTED; static const int PEM_R_NOT_PROC_TYPE; -static const int PEM_R_NO_START_LINE; static const int PEM_R_PROBLEMS_GETTING_PASSWORD; static const int PEM_R_PUBLIC_KEY_NO_RSA; static const int PEM_R_READ_KEY; @@ -114,9 +254,24 @@ int ERR_GET_LIB(unsigned long); int ERR_GET_FUNC(unsigned long); int ERR_GET_REASON(unsigned long); int ERR_FATAL_ERROR(unsigned long); +/* introduced in 1.0.0 so we have to handle this specially to continue + * supporting 0.9.8 + */ +void ERR_remove_thread_state(const CRYPTO_THREADID *); """ CUSTOMIZATIONS = """ +#if OPENSSL_VERSION_NUMBER >= 0x10000000L +static const long Cryptography_HAS_REMOVE_THREAD_STATE = 1; +#else +static const long Cryptography_HAS_REMOVE_THREAD_STATE = 0; +typedef uint32_t CRYPTO_THREADID; +void (*ERR_remove_thread_state)(const CRYPTO_THREADID *); +#endif """ -CONDITIONAL_NAMES = {} +CONDITIONAL_NAMES = { + "Cryptography_HAS_REMOVE_THREAD_STATE": [ + "ERR_remove_thread_state" + ], +} diff --git a/cryptography/hazmat/bindings/openssl/pem.py b/cryptography/hazmat/bindings/openssl/pem.py index ee5552c5..8b717c2d 100644 --- a/cryptography/hazmat/bindings/openssl/pem.py +++ b/cryptography/hazmat/bindings/openssl/pem.py @@ -27,7 +27,7 @@ int PEM_write_bio_PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *, unsigned char *, int, pem_password_cb *, void *); EVP_PKEY *PEM_read_bio_PrivateKey(BIO *, EVP_PKEY **, pem_password_cb *, - void *); + void *); int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *, char *, int, pem_password_cb *, void *); @@ -48,6 +48,29 @@ int PEM_write_bio_X509_CRL(BIO *, X509_CRL *); PKCS7 *PEM_read_bio_PKCS7(BIO *, PKCS7 **, pem_password_cb *, void *); DH *PEM_read_bio_DHparams(BIO *, DH **, pem_password_cb *, void *); + +DSA *PEM_read_bio_DSAPrivateKey(BIO *, DSA **, pem_password_cb *, void *); + +RSA *PEM_read_bio_RSAPrivateKey(BIO *, RSA **, pem_password_cb *, void *); + +int PEM_write_bio_DSAPrivateKey(BIO *, DSA *, const EVP_CIPHER *, + unsigned char *, int, + pem_password_cb *, void *); + +int PEM_write_bio_RSAPrivateKey(BIO *, RSA *, const EVP_CIPHER *, + unsigned char *, int, + pem_password_cb *, void *); + +DSA *PEM_read_bio_DSA_PUBKEY(BIO *, DSA **, pem_password_cb *, void *); + +RSA *PEM_read_bio_RSAPublicKey(BIO *, RSA **, pem_password_cb *, void *); + +int PEM_write_bio_DSA_PUBKEY(BIO *, DSA *); + +int PEM_write_bio_RSAPublicKey(BIO *, const RSA *); + +EVP_PKEY *PEM_read_bio_PUBKEY(BIO *, EVP_PKEY **, pem_password_cb *, void *); +int PEM_write_bio_PUBKEY(BIO *, EVP_PKEY *); """ MACROS = """ diff --git a/cryptography/hazmat/bindings/openssl/ssl.py b/cryptography/hazmat/bindings/openssl/ssl.py index d0d5ae2d..cd872d18 100644 --- a/cryptography/hazmat/bindings/openssl/ssl.py +++ b/cryptography/hazmat/bindings/openssl/ssl.py @@ -77,6 +77,7 @@ static const int SSL_OP_NO_QUERY_MTU; static const int SSL_OP_COOKIE_EXCHANGE; static const int SSL_OP_NO_TICKET; static const int SSL_OP_ALL; +static const int SSL_OP_SINGLE_ECDH_USE; static const int SSL_VERIFY_PEER; static const int SSL_VERIFY_FAIL_IF_NO_PEER_CERT; static const int SSL_VERIFY_CLIENT_ONCE; @@ -231,6 +232,7 @@ long SSL_CTX_get_mode(SSL_CTX *); long SSL_CTX_set_session_cache_mode(SSL_CTX *, long); long SSL_CTX_get_session_cache_mode(SSL_CTX *); long SSL_CTX_set_tmp_dh(SSL_CTX *, DH *); +long SSL_CTX_set_tmp_ecdh(SSL_CTX *, EC_KEY *); long SSL_CTX_add_extra_chain_cert(SSL_CTX *, X509 *); /*- These aren't macros these functions are all const X on openssl > 1.0.x -*/ @@ -345,6 +347,10 @@ static const long Cryptography_HAS_SSL_OP_MSIE_SSLV2_RSA_PADDING = 1; static const long Cryptography_HAS_SSL_OP_MSIE_SSLV2_RSA_PADDING = 0; const long SSL_OP_MSIE_SSLV2_RSA_PADDING = 0; #endif + +#ifdef OPENSSL_NO_EC +long (*SSL_CTX_set_tmp_ecdh)(SSL_CTX *, EC_KEY *) = NULL; +#endif """ CONDITIONAL_NAMES = { @@ -385,4 +391,8 @@ CONDITIONAL_NAMES = { "Cryptography_HAS_SSL_OP_MSIE_SSLV2_RSA_PADDING": [ "SSL_OP_MSIE_SSLV2_RSA_PADDING", ], + + "Cryptography_HAS_EC": [ + "EC_KEY_new_by_curve_name", + ] } diff --git a/cryptography/hazmat/bindings/utils.py b/cryptography/hazmat/bindings/utils.py index 9cc05506..b8253483 100644 --- a/cryptography/hazmat/bindings/utils.py +++ b/cryptography/hazmat/bindings/utils.py @@ -50,9 +50,6 @@ def build_ffi(module_prefix, modules, pre_include, post_include, libraries): includes.append(module.INCLUDES) customizations.append(module.CUSTOMIZATIONS) - # loop over the functions & macros after declaring all the types - # so we can set interdependent types in different files and still - # have them all defined before we parse the funcs & macros ffi.cdef("\n".join(types + functions + macros)) # We include functions here so that if we got any of their definitions |