__init__.py000064400000000000147205320040006640 0ustar00_libcrypto.py000064400000007312147205320040007264 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from .. import ffi from .._ffi import buffer_from_bytes, byte_string_from_buffer, null from .._types import str_cls if ffi() == 'cffi': from ._libcrypto_cffi import ( libcrypto, version as libcrypto_version, version_info as libcrypto_version_info ) else: from ._libcrypto_ctypes import ( libcrypto, version as libcrypto_version, version_info as libcrypto_version_info ) __all__ = [ 'handle_openssl_error', 'libcrypto', 'libcrypto_legacy_support', 'libcrypto_version', 'libcrypto_version_info', 'LibcryptoConst', 'peek_openssl_error', ] _encoding = 'utf-8' _fallback_encodings = ['utf-8', 'cp1252'] if libcrypto_version_info < (1, 1): libcrypto.ERR_load_crypto_strings() libcrypto.OPENSSL_config(null()) # This enables legacy algorithms in OpenSSL 3.0, such as RC2, etc # which are used by various tests and some old protocols and things # like PKCS12 libcrypto_legacy_support = True if libcrypto_version_info >= (3, ): if libcrypto.OSSL_PROVIDER_available(null(), "legacy".encode("ascii")): libcrypto.OSSL_PROVIDER_load(null(), "legacy".encode("ascii")) else: libcrypto_legacy_support = False def _try_decode(value): try: return str_cls(value, _encoding) # If the "correct" encoding did not work, try some defaults, and then just # obliterate characters that we can't seen to decode properly except (UnicodeDecodeError): for encoding in _fallback_encodings: try: return str_cls(value, encoding, errors='strict') except (UnicodeDecodeError): pass return str_cls(value, errors='replace') def handle_openssl_error(result, exception_class=None): """ Checks if an error occurred, and if so throws an OSError containing the last OpenSSL error message :param result: An integer result code - 1 or greater indicates success :param exception_class: The exception class to use for the exception if an error occurred :raises: OSError - when an OpenSSL error occurs """ if result > 0: return if exception_class is None: exception_class = OSError error_num = libcrypto.ERR_get_error() buffer = buffer_from_bytes(120) libcrypto.ERR_error_string(error_num, buffer) # Since we are dealing with a string, it is NULL terminated error_string = byte_string_from_buffer(buffer) raise exception_class(_try_decode(error_string)) def peek_openssl_error(): """ Peeks into the error stack and pulls out the lib, func and reason :return: A three-element tuple of integers (lib, func, reason) """ error = libcrypto.ERR_peek_error() if libcrypto_version_info < (3, 0): lib = int((error >> 24) & 0xff) func = int((error >> 12) & 0xfff) reason = int(error & 0xfff) else: lib = int((error >> 23) & 0xff) # OpenSSL 3.0 removed ERR_GET_FUNC() func = 0 reason = int(error & 0x7fffff) return (lib, func, reason) class LibcryptoConst(): EVP_CTRL_SET_RC2_KEY_BITS = 3 SSLEAY_VERSION = 0 RSA_PKCS1_PADDING = 1 RSA_NO_PADDING = 3 RSA_PKCS1_OAEP_PADDING = 4 # OpenSSL 0.9.x EVP_MD_CTX_FLAG_PSS_MDLEN = -1 # OpenSSL 1.x.x EVP_PKEY_CTRL_RSA_PADDING = 0x1001 RSA_PKCS1_PSS_PADDING = 6 EVP_PKEY_CTRL_RSA_PSS_SALTLEN = 0x1002 EVP_PKEY_RSA = 6 EVP_PKEY_OP_SIGN = 1 << 3 EVP_PKEY_OP_VERIFY = 1 << 4 NID_X9_62_prime256v1 = 415 NID_secp384r1 = 715 NID_secp521r1 = 716 OPENSSL_EC_NAMED_CURVE = 1 DH_GENERATOR_2 = 2 _libcrypto_cffi.py000064400000023311147205320040010250 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import re from .. import _backend_config from .._errors import pretty_message from .._ffi import get_library, register_ffi from ..errors import LibraryNotFoundError from cffi import FFI __all__ = [ 'is_libressl', 'libcrypto', 'libressl_version', 'libressl_version_info', 'version', 'version_info', ] libcrypto_path = _backend_config().get('libcrypto_path') if libcrypto_path is None: libcrypto_path = get_library('crypto', 'libcrypto.dylib', '42') if not libcrypto_path: raise LibraryNotFoundError('The library libcrypto could not be found') try: vffi = FFI() vffi.cdef("const char *SSLeay_version(int type);") version_string = vffi.string(vffi.dlopen(libcrypto_path).SSLeay_version(0)).decode('utf-8') except (AttributeError): vffi = FFI() vffi.cdef("const char *OpenSSL_version(int type);") version_string = vffi.string(vffi.dlopen(libcrypto_path).OpenSSL_version(0)).decode('utf-8') is_libressl = 'LibreSSL' in version_string version_match = re.search('\\b(\\d+\\.\\d+\\.\\d+[a-z]*)\\b', version_string) if not version_match: version_match = re.search('(?<=LibreSSL )(\\d+\\.\\d+(\\.\\d+)?)\\b', version_string) if not version_match: raise LibraryNotFoundError('Error detecting the version of libcrypto') version = version_match.group(1) version_parts = re.sub('(\\d+)([a-z]+)', '\\1.\\2', version).split('.') version_info = tuple(int(part) if part.isdigit() else part for part in version_parts) # LibreSSL is compatible with libcrypto from OpenSSL 1.0.1 libressl_version = '' libressl_version_info = tuple() if is_libressl: libressl_version = version libressl_version_info = version_info version = '1.0.1' version_info = (1, 0, 1) ffi = FFI() libcrypto = ffi.dlopen(libcrypto_path) register_ffi(libcrypto, ffi) if version_info < (0, 9, 8): raise LibraryNotFoundError(pretty_message( ''' OpenSSL versions older than 0.9.8 are not supported - found version %s ''', version )) if version_info < (1, 1): ffi.cdef(""" void ERR_load_crypto_strings(void); void ERR_free_strings(void); """) if version_info >= (3, ): ffi.cdef(""" typedef ... OSSL_LIB_CTX; typedef ... OSSL_PROVIDER; int OSSL_PROVIDER_available(OSSL_LIB_CTX *libctx, const char *name); OSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *libctx, const char *name); """) # The typedef uintptr_t lines here allow us to check for a NULL pointer, # without having to redefine the structs in our code. This is kind of a hack, # but it should cause problems since we treat these as opaque. ffi.cdef(""" typedef ... EVP_MD; typedef uintptr_t EVP_CIPHER_CTX; typedef ... EVP_CIPHER; typedef ... ENGINE; typedef uintptr_t EVP_PKEY; typedef uintptr_t X509; typedef uintptr_t DH; typedef uintptr_t RSA; typedef uintptr_t DSA; typedef uintptr_t EC_KEY; typedef ... EVP_MD_CTX; typedef ... EVP_PKEY_CTX; typedef ... BN_GENCB; typedef ... BIGNUM; unsigned long ERR_get_error(void); char *ERR_error_string(unsigned long e, char *buf); unsigned long ERR_peek_error(void); void OPENSSL_config(const char *config_name); EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx); int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen); int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *x, int padding); int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); const EVP_CIPHER *EVP_aes_128_cbc(void); const EVP_CIPHER *EVP_aes_192_cbc(void); const EVP_CIPHER *EVP_aes_256_cbc(void); const EVP_CIPHER *EVP_des_cbc(void); const EVP_CIPHER *EVP_des_ede_cbc(void); const EVP_CIPHER *EVP_des_ede3_cbc(void); const EVP_CIPHER *EVP_rc4(void); const EVP_CIPHER *EVP_rc2_cbc(void); int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, const char *key, const char *iv); int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, char *out, int *outl, const char *in, int inl); int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, char *out, int *outl); int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, const char *key, const char *iv); int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, char *out, int *outl, const char *in, int inl); int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, char *out, int *outl); EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const char **pp, long length); EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const char **pp, long length); int i2d_PUBKEY(EVP_PKEY *a, char **pp); void EVP_PKEY_free(EVP_PKEY *key); X509 *d2i_X509(X509 **px, const char **in, int len); int i2d_X509(X509 *x, char **out); EVP_PKEY *X509_get_pubkey(X509 *x); void X509_free(X509 *a); RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey); void RSA_free(RSA *r); int RSA_public_encrypt(int flen, const char *from, char *to, RSA *rsa, int padding); int RSA_private_encrypt(int flen, const char *from, char *to, RSA *rsa, int padding); int RSA_public_decrypt(int flen, const char *from, char *to, RSA *rsa, int padding); int RSA_private_decrypt(int flen, const char *from, char *to, RSA *rsa, int padding); int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt); const EVP_MD *EVP_md5(void); const EVP_MD *EVP_sha1(void); const EVP_MD *EVP_sha224(void); const EVP_MD *EVP_sha256(void); const EVP_MD *EVP_sha384(void); const EVP_MD *EVP_sha512(void); int PKCS12_key_gen_uni(char *pass, int passlen, char *salt, int saltlen, int id, int iter, int n, char *out, const EVP_MD *md_type); void BN_free(BIGNUM *a); int BN_dec2bn(BIGNUM **a, const char *str); DH *DH_new(void); int DH_generate_parameters_ex(DH *dh, int prime_len, int generator, BN_GENCB *cb); int i2d_DHparams(const DH *a, char **pp); void DH_free(DH *dh); RSA *RSA_new(void); int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); int i2d_RSAPublicKey(RSA *a, char **pp); int i2d_RSAPrivateKey(RSA *a, char **pp); DSA *DSA_new(void); int DSA_generate_parameters_ex(DSA *dsa, int bits, const char *seed, int seed_len, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); int DSA_generate_key(DSA *a); int i2d_DSA_PUBKEY(const DSA *a, char **pp); int i2d_DSAPrivateKey(const DSA *a, char **pp); void DSA_free(DSA *dsa); EC_KEY *EC_KEY_new_by_curve_name(int nid); int EC_KEY_generate_key(EC_KEY *key); void EC_KEY_set_asn1_flag(EC_KEY *, int); int i2d_ECPrivateKey(EC_KEY *key, char **out); int i2o_ECPublicKey(EC_KEY *key, char **out); void EC_KEY_free(EC_KEY *key); """) if version_info < (3, ): ffi.cdef(""" int EVP_PKEY_size(EVP_PKEY *pkey); """) else: ffi.cdef(""" int EVP_PKEY_get_size(EVP_PKEY *pkey); """) if version_info < (1, 1): ffi.cdef(""" EVP_MD_CTX *EVP_MD_CTX_create(void); void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); """) else: ffi.cdef(""" EVP_MD_CTX *EVP_MD_CTX_new(void); void EVP_MD_CTX_free(EVP_MD_CTX *ctx); """) if version_info < (1,): ffi.cdef(""" typedef ... *DSA_SIG; typedef ... *ECDSA_SIG; DSA_SIG *DSA_do_sign(const char *dgst, int dlen, DSA *dsa); ECDSA_SIG *ECDSA_do_sign(const char *dgst, int dgst_len, EC_KEY *eckey); DSA_SIG *d2i_DSA_SIG(DSA_SIG **v, const char **pp, long length); ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **v, const char **pp, long len); int i2d_DSA_SIG(const DSA_SIG *a, char **pp); int i2d_ECDSA_SIG(const ECDSA_SIG *a, char **pp); int DSA_do_verify(const char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa); int ECDSA_do_verify(const char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY *eckey); void DSA_SIG_free(DSA_SIG *a); void ECDSA_SIG_free(ECDSA_SIG *a); DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey); EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); int RSA_verify_PKCS1_PSS(RSA *rsa, const char *mHash, const EVP_MD *Hash, const char *EM, int sLen); int RSA_padding_add_PKCS1_PSS(RSA *rsa, char *EM, const char *mHash, const EVP_MD *Hash, int sLen); int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); int EVP_SignFinal(EVP_MD_CTX *ctx, char *sig, unsigned int *s, EVP_PKEY *pkey); int EVP_VerifyFinal(EVP_MD_CTX *ctx, char *sigbuf, unsigned int siglen, EVP_PKEY *pkey); void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); """) else: ffi.cdef(""" int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const char *salt, int saltlen, int iter, const EVP_MD *digest, int keylen, char *out); int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); int EVP_DigestSignFinal(EVP_MD_CTX *ctx, char *sig, size_t *siglen); int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const char *sig, size_t siglen); int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2); """) _libcrypto_ctypes.py000064400000042415147205320040010656 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import re from ctypes import CDLL, c_void_p, c_char_p, c_int, c_ulong, c_uint, c_long, c_size_t, POINTER from .. import _backend_config from .._errors import pretty_message from .._ffi import FFIEngineError, get_library from ..errors import LibraryNotFoundError __all__ = [ 'is_libressl', 'libcrypto', 'libressl_version', 'libressl_version_info', 'version', 'version_info', ] libcrypto_path = _backend_config().get('libcrypto_path') if libcrypto_path is None: libcrypto_path = get_library('crypto', 'libcrypto.dylib', '42') if not libcrypto_path: raise LibraryNotFoundError('The library libcrypto could not be found') libcrypto = CDLL(libcrypto_path, use_errno=True) try: libcrypto.SSLeay_version.argtypes = [c_int] libcrypto.SSLeay_version.restype = c_char_p version_string = libcrypto.SSLeay_version(0).decode('utf-8') except (AttributeError): libcrypto.OpenSSL_version.argtypes = [c_int] libcrypto.OpenSSL_version.restype = c_char_p version_string = libcrypto.OpenSSL_version(0).decode('utf-8') is_libressl = 'LibreSSL' in version_string version_match = re.search('\\b(\\d+\\.\\d+\\.\\d+[a-z]*)\\b', version_string) if not version_match: version_match = re.search('(?<=LibreSSL )(\\d+\\.\\d+(\\.\\d+)?)\\b', version_string) if not version_match: raise LibraryNotFoundError('Error detecting the version of libcrypto') version = version_match.group(1) version_parts = re.sub('(\\d+)([a-z]+)', '\\1.\\2', version).split('.') version_info = tuple(int(part) if part.isdigit() else part for part in version_parts) # LibreSSL is compatible with libcrypto from OpenSSL 1.0.1 libressl_version = '' libressl_version_info = tuple() if is_libressl: libressl_version = version libressl_version_info = version_info version = '1.0.1' version_info = (1, 0, 1) if version_info < (0, 9, 8): raise LibraryNotFoundError(pretty_message( ''' OpenSSL versions older than 0.9.8 are not supported - found version %s ''', version )) P_EVP_CIPHER_CTX = c_void_p P_EVP_CIPHER = c_void_p P_EVP_MD_CTX = c_void_p P_EVP_MD = c_void_p P_ENGINE = c_void_p OSSL_PROVIDER = c_void_p OSSL_LIB_CTX = c_void_p P_EVP_PKEY = c_void_p EVP_PKEY_CTX = c_void_p P_EVP_PKEY_CTX = POINTER(c_void_p) P_X509 = POINTER(c_void_p) P_DH = c_void_p P_RSA = c_void_p P_DSA = c_void_p P_EC_KEY = c_void_p P_BN_GENCB = c_void_p BIGNUM = c_void_p P_BIGNUM = POINTER(BIGNUM) p_int = POINTER(c_int) p_uint = POINTER(c_uint) try: if version_info < (1, 1): libcrypto.ERR_load_crypto_strings.argtypes = [] libcrypto.ERR_load_crypto_strings.restype = None libcrypto.ERR_free_strings.argtypes = [] libcrypto.ERR_free_strings.restype = None if version_info >= (3, ): libcrypto.OSSL_PROVIDER_available.argtypes = [OSSL_LIB_CTX, c_char_p] libcrypto.OSSL_PROVIDER_available.restype = c_int libcrypto.OSSL_PROVIDER_load.argtypes = [OSSL_LIB_CTX, c_char_p] libcrypto.OSSL_PROVIDER_load.restype = POINTER(OSSL_PROVIDER) libcrypto.ERR_get_error.argtypes = [] libcrypto.ERR_get_error.restype = c_ulong libcrypto.ERR_peek_error.argtypes = [] libcrypto.ERR_peek_error.restype = c_ulong libcrypto.ERR_error_string.argtypes = [ c_ulong, c_char_p ] libcrypto.ERR_error_string.restype = c_char_p libcrypto.OPENSSL_config.argtypes = [ c_char_p ] libcrypto.OPENSSL_config.restype = None # This allocates the memory and inits libcrypto.EVP_CIPHER_CTX_new.argtype = [] libcrypto.EVP_CIPHER_CTX_new.restype = P_EVP_CIPHER_CTX libcrypto.EVP_CIPHER_CTX_set_key_length.argtypes = [ P_EVP_CIPHER_CTX, c_int ] libcrypto.EVP_CIPHER_CTX_set_key_length.restype = c_int libcrypto.EVP_CIPHER_CTX_set_padding.argtypes = [ P_EVP_CIPHER_CTX, c_int ] libcrypto.EVP_CIPHER_CTX_set_padding.restype = c_int libcrypto.EVP_CIPHER_CTX_ctrl.argtypes = [ P_EVP_CIPHER_CTX, c_int, c_int, c_void_p ] libcrypto.EVP_CIPHER_CTX_ctrl.restype = c_int # This cleans up and frees libcrypto.EVP_CIPHER_CTX_free.argtypes = [ P_EVP_CIPHER_CTX ] libcrypto.EVP_CIPHER_CTX_free.restype = None libcrypto.EVP_aes_128_cbc.argtypes = [] libcrypto.EVP_aes_128_cbc.restype = P_EVP_CIPHER libcrypto.EVP_aes_192_cbc.argtypes = [] libcrypto.EVP_aes_192_cbc.restype = P_EVP_CIPHER libcrypto.EVP_aes_256_cbc.argtypes = [] libcrypto.EVP_aes_256_cbc.restype = P_EVP_CIPHER libcrypto.EVP_des_cbc.argtypes = [] libcrypto.EVP_des_cbc.restype = P_EVP_CIPHER libcrypto.EVP_des_ede_cbc.argtypes = [] libcrypto.EVP_des_ede_cbc.restype = P_EVP_CIPHER libcrypto.EVP_des_ede3_cbc.argtypes = [] libcrypto.EVP_des_ede3_cbc.restype = P_EVP_CIPHER libcrypto.EVP_rc4.argtypes = [] libcrypto.EVP_rc4.restype = P_EVP_CIPHER libcrypto.EVP_rc2_cbc.argtypes = [] libcrypto.EVP_rc2_cbc.restype = P_EVP_CIPHER libcrypto.EVP_EncryptInit_ex.argtypes = [ P_EVP_CIPHER_CTX, P_EVP_CIPHER, P_ENGINE, c_char_p, c_char_p ] libcrypto.EVP_EncryptInit_ex.restype = c_int libcrypto.EVP_EncryptUpdate.argtypes = [ P_EVP_CIPHER_CTX, c_char_p, p_int, c_char_p, c_int ] libcrypto.EVP_EncryptUpdate.restype = c_int libcrypto.EVP_EncryptFinal_ex.argtypes = [ P_EVP_CIPHER_CTX, c_char_p, p_int ] libcrypto.EVP_EncryptFinal_ex.restype = c_int libcrypto.EVP_DecryptInit_ex.argtypes = [ P_EVP_CIPHER_CTX, P_EVP_CIPHER, P_ENGINE, c_char_p, c_char_p ] libcrypto.EVP_DecryptInit_ex.restype = c_int libcrypto.EVP_DecryptUpdate.argtypes = [ P_EVP_CIPHER_CTX, c_char_p, p_int, c_char_p, c_int ] libcrypto.EVP_DecryptUpdate.restype = c_int libcrypto.EVP_DecryptFinal_ex.argtypes = [ P_EVP_CIPHER_CTX, c_char_p, p_int ] libcrypto.EVP_DecryptFinal_ex.restype = c_int libcrypto.d2i_AutoPrivateKey.argtypes = [ POINTER(P_EVP_PKEY), POINTER(c_char_p), c_int ] libcrypto.d2i_AutoPrivateKey.restype = P_EVP_PKEY libcrypto.d2i_PUBKEY.argtypes = [ POINTER(P_EVP_PKEY), POINTER(c_char_p), c_int ] libcrypto.d2i_PUBKEY.restype = P_EVP_PKEY libcrypto.i2d_PUBKEY.argtypes = [ P_EVP_PKEY, POINTER(c_char_p) ] libcrypto.i2d_PUBKEY.restype = c_int libcrypto.d2i_X509.argtypes = [ POINTER(P_X509), POINTER(c_char_p), c_int ] libcrypto.d2i_X509.restype = P_X509 libcrypto.i2d_X509.argtypes = [ P_X509, POINTER(c_char_p) ] libcrypto.i2d_X509.restype = c_int libcrypto.X509_get_pubkey.argtypes = [ P_X509 ] libcrypto.X509_get_pubkey.restype = P_EVP_PKEY libcrypto.X509_free.argtypes = [ P_X509 ] libcrypto.X509_free.restype = None libcrypto.EVP_PKEY_free.argtypes = [ P_EVP_PKEY ] libcrypto.EVP_PKEY_free.restype = None if version_info < (1, 1): libcrypto.EVP_MD_CTX_create.argtypes = [] libcrypto.EVP_MD_CTX_create.restype = P_EVP_MD_CTX libcrypto.EVP_MD_CTX_destroy.argtypes = [ P_EVP_MD_CTX ] libcrypto.EVP_MD_CTX_destroy.restype = None else: libcrypto.EVP_MD_CTX_new.argtypes = [] libcrypto.EVP_MD_CTX_new.restype = P_EVP_MD_CTX libcrypto.EVP_MD_CTX_free.argtypes = [ P_EVP_MD_CTX ] libcrypto.EVP_MD_CTX_free.restype = None libcrypto.EVP_md5.argtypes = [] libcrypto.EVP_md5.restype = P_EVP_MD libcrypto.EVP_sha1.argtypes = [] libcrypto.EVP_sha1.restype = P_EVP_MD libcrypto.EVP_sha224.argtypes = [] libcrypto.EVP_sha224.restype = P_EVP_MD libcrypto.EVP_sha256.argtypes = [] libcrypto.EVP_sha256.restype = P_EVP_MD libcrypto.EVP_sha384.argtypes = [] libcrypto.EVP_sha384.restype = P_EVP_MD libcrypto.EVP_sha512.argtypes = [] libcrypto.EVP_sha512.restype = P_EVP_MD if version_info < (3, 0): libcrypto.EVP_PKEY_size.argtypes = [ P_EVP_PKEY ] libcrypto.EVP_PKEY_size.restype = c_int else: libcrypto.EVP_PKEY_get_size.argtypes = [ P_EVP_PKEY ] libcrypto.EVP_PKEY_get_size.restype = c_int libcrypto.EVP_PKEY_get1_RSA.argtypes = [ P_EVP_PKEY ] libcrypto.EVP_PKEY_get1_RSA.restype = P_RSA libcrypto.RSA_free.argtypes = [ P_RSA ] libcrypto.RSA_free.restype = None libcrypto.RSA_public_encrypt.argtypes = [ c_int, c_char_p, c_char_p, P_RSA, c_int ] libcrypto.RSA_public_encrypt.restype = c_int libcrypto.RSA_private_encrypt.argtypes = [ c_int, c_char_p, c_char_p, P_RSA, c_int ] libcrypto.RSA_private_encrypt.restype = c_int libcrypto.RSA_public_decrypt.argtypes = [ c_int, c_char_p, c_char_p, P_RSA, c_int ] libcrypto.RSA_public_decrypt.restype = c_int libcrypto.RSA_private_decrypt.argtypes = [ c_int, c_char_p, c_char_p, P_RSA, c_int ] libcrypto.RSA_private_decrypt.restype = c_int libcrypto.EVP_DigestUpdate.argtypes = [ P_EVP_MD_CTX, c_char_p, c_uint ] libcrypto.EVP_DigestUpdate.restype = c_int libcrypto.PKCS12_key_gen_uni.argtypes = [ c_char_p, c_int, c_char_p, c_int, c_int, c_int, c_int, c_char_p, c_void_p ] libcrypto.PKCS12_key_gen_uni.restype = c_int libcrypto.BN_free.argtypes = [ P_BIGNUM ] libcrypto.BN_free.restype = None libcrypto.BN_dec2bn.argtypes = [ POINTER(P_BIGNUM), c_char_p ] libcrypto.BN_dec2bn.restype = c_int libcrypto.DH_new.argtypes = [] libcrypto.DH_new.restype = P_DH libcrypto.DH_generate_parameters_ex.argtypes = [ P_DH, c_int, c_int, P_BN_GENCB ] libcrypto.DH_generate_parameters_ex.restype = c_int libcrypto.i2d_DHparams.argtypes = [ P_DH, POINTER(c_char_p) ] libcrypto.i2d_DHparams.restype = c_int libcrypto.DH_free.argtypes = [ P_DH ] libcrypto.DH_free.restype = None libcrypto.RSA_new.argtypes = [] libcrypto.RSA_new.restype = P_RSA libcrypto.RSA_generate_key_ex.argtypes = [ P_RSA, c_int, P_BIGNUM, P_BN_GENCB ] libcrypto.RSA_generate_key_ex.restype = c_int libcrypto.i2d_RSAPublicKey.argtypes = [ P_RSA, POINTER(c_char_p) ] libcrypto.i2d_RSAPublicKey.restype = c_int libcrypto.i2d_RSAPrivateKey.argtypes = [ P_RSA, POINTER(c_char_p) ] libcrypto.i2d_RSAPrivateKey.restype = c_int libcrypto.RSA_free.argtypes = [ P_RSA ] libcrypto.RSA_free.restype = None libcrypto.DSA_new.argtypes = [] libcrypto.DSA_new.restype = P_DSA libcrypto.DSA_generate_parameters_ex.argtypes = [ P_DSA, c_int, c_char_p, c_int, POINTER(c_int), POINTER(c_ulong), P_BN_GENCB ] libcrypto.DSA_generate_parameters_ex.restype = c_int libcrypto.DSA_generate_key.argtypes = [ P_DSA ] libcrypto.DSA_generate_key.restype = c_int libcrypto.i2d_DSA_PUBKEY.argtypes = [ P_DSA, POINTER(c_char_p) ] libcrypto.i2d_DSA_PUBKEY.restype = c_int libcrypto.i2d_DSAPrivateKey.argtypes = [ P_DSA, POINTER(c_char_p) ] libcrypto.i2d_DSAPrivateKey.restype = c_int libcrypto.DSA_free.argtypes = [ P_DSA ] libcrypto.DSA_free.restype = None libcrypto.EC_KEY_new_by_curve_name.argtypes = [ c_int ] libcrypto.EC_KEY_new_by_curve_name.restype = P_EC_KEY libcrypto.EC_KEY_generate_key.argtypes = [ P_EC_KEY ] libcrypto.EC_KEY_generate_key.restype = c_int libcrypto.EC_KEY_set_asn1_flag.argtypes = [ P_EC_KEY, c_int ] libcrypto.EC_KEY_set_asn1_flag.restype = None libcrypto.i2d_ECPrivateKey.argtypes = [ P_EC_KEY, POINTER(c_char_p) ] libcrypto.i2d_ECPrivateKey.restype = c_int libcrypto.i2o_ECPublicKey.argtypes = [ P_EC_KEY, POINTER(c_char_p) ] libcrypto.i2o_ECPublicKey.restype = c_int libcrypto.EC_KEY_free.argtypes = [ P_EC_KEY ] libcrypto.EC_KEY_free.restype = None if version_info < (1,): P_DSA_SIG = c_void_p P_ECDSA_SIG = c_void_p libcrypto.DSA_do_sign.argtypes = [ c_char_p, c_int, P_DSA ] libcrypto.DSA_do_sign.restype = P_DSA_SIG libcrypto.ECDSA_do_sign.argtypes = [ c_char_p, c_int, P_EC_KEY ] libcrypto.ECDSA_do_sign.restype = P_ECDSA_SIG libcrypto.d2i_DSA_SIG.argtypes = [ POINTER(P_DSA_SIG), POINTER(c_char_p), c_long ] libcrypto.d2i_DSA_SIG.restype = P_DSA_SIG libcrypto.d2i_ECDSA_SIG.argtypes = [ POINTER(P_ECDSA_SIG), POINTER(c_char_p), c_long ] libcrypto.d2i_ECDSA_SIG.restype = P_ECDSA_SIG libcrypto.i2d_DSA_SIG.argtypes = [ P_DSA_SIG, POINTER(c_char_p) ] libcrypto.i2d_DSA_SIG.restype = c_int libcrypto.i2d_ECDSA_SIG.argtypes = [ P_ECDSA_SIG, POINTER(c_char_p) ] libcrypto.i2d_ECDSA_SIG.restype = c_int libcrypto.DSA_do_verify.argtypes = [ c_char_p, c_int, P_DSA_SIG, P_DSA ] libcrypto.DSA_do_verify.restype = c_int libcrypto.ECDSA_do_verify.argtypes = [ c_char_p, c_int, P_ECDSA_SIG, P_EC_KEY ] libcrypto.ECDSA_do_verify.restype = c_int libcrypto.DSA_SIG_free.argtypes = [ P_DSA_SIG ] libcrypto.DSA_SIG_free.restype = None libcrypto.ECDSA_SIG_free.argtypes = [ P_ECDSA_SIG ] libcrypto.ECDSA_SIG_free.restype = None libcrypto.EVP_PKEY_get1_DSA.argtypes = [ P_EVP_PKEY ] libcrypto.EVP_PKEY_get1_DSA.restype = P_DSA libcrypto.EVP_PKEY_get1_EC_KEY.argtypes = [ P_EVP_PKEY ] libcrypto.EVP_PKEY_get1_EC_KEY.restype = P_EC_KEY libcrypto.RSA_verify_PKCS1_PSS.argtypes = [ P_RSA, c_char_p, P_EVP_MD, c_char_p, c_int ] libcrypto.RSA_verify_PKCS1_PSS.restype = c_int libcrypto.RSA_padding_add_PKCS1_PSS.argtypes = [ P_RSA, c_char_p, c_char_p, P_EVP_MD, c_int ] libcrypto.RSA_padding_add_PKCS1_PSS.restype = c_int libcrypto.EVP_DigestInit_ex.argtypes = [ P_EVP_MD_CTX, P_EVP_MD, P_ENGINE ] libcrypto.EVP_DigestInit_ex.restype = c_int libcrypto.EVP_SignFinal.argtypes = [ P_EVP_MD_CTX, c_char_p, p_uint, P_EVP_PKEY ] libcrypto.EVP_SignFinal.restype = c_int libcrypto.EVP_VerifyFinal.argtypes = [ P_EVP_MD_CTX, c_char_p, c_uint, P_EVP_PKEY ] libcrypto.EVP_VerifyFinal.restype = c_int libcrypto.EVP_MD_CTX_set_flags.argtypes = [ P_EVP_MD_CTX, c_int ] libcrypto.EVP_MD_CTX_set_flags.restype = None else: libcrypto.PKCS5_PBKDF2_HMAC.argtypes = [ c_char_p, c_int, c_char_p, c_int, c_int, P_EVP_MD, c_int, c_char_p ] libcrypto.PKCS5_PBKDF2_HMAC.restype = c_int libcrypto.EVP_DigestSignInit.argtypes = [ P_EVP_MD_CTX, POINTER(P_EVP_PKEY_CTX), P_EVP_MD, P_ENGINE, P_EVP_PKEY ] libcrypto.EVP_DigestSignInit.restype = c_int libcrypto.EVP_DigestSignFinal.argtypes = [ P_EVP_MD_CTX, c_char_p, POINTER(c_size_t) ] libcrypto.EVP_DigestSignFinal.restype = c_int libcrypto.EVP_DigestVerifyInit.argtypes = [ P_EVP_MD_CTX, POINTER(P_EVP_PKEY_CTX), P_EVP_MD, P_ENGINE, P_EVP_PKEY ] libcrypto.EVP_DigestVerifyInit.restype = c_int libcrypto.EVP_DigestVerifyFinal.argtypes = [ P_EVP_MD_CTX, c_char_p, c_size_t ] libcrypto.EVP_DigestVerifyFinal.restype = c_int libcrypto.EVP_PKEY_CTX_ctrl.argtypes = [ P_EVP_PKEY_CTX, c_int, c_int, c_int, c_int, c_void_p ] libcrypto.EVP_PKEY_CTX_ctrl.restype = c_int except (AttributeError): raise FFIEngineError('Error initializing ctypes') setattr(libcrypto, 'EVP_PKEY_CTX', EVP_PKEY_CTX) setattr(libcrypto, 'BIGNUM', BIGNUM) _libssl.py000064400000004163147205320040006546 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from .. import ffi # Initialize OpenSSL from ._libcrypto import libcrypto_version_info if ffi() == 'cffi': from ._libssl_cffi import libssl else: from ._libssl_ctypes import libssl __all__ = [ 'libssl', 'LibsslConst', ] if libcrypto_version_info < (1, 1): libssl.SSL_library_init() # Enables SHA2 algorithms on 0.9.8n and older if libcrypto_version_info < (1, 0): libssl.OPENSSL_add_all_algorithms_noconf() class LibsslConst(): ERR_LIB_ASN1 = 13 ERR_LIB_SSL = 20 SSL_CTRL_OPTIONS = 32 SSL_CTRL_SET_SESS_CACHE_MODE = 44 SSL_VERIFY_NONE = 0 SSL_VERIFY_PEER = 1 SSL_ST_OK = 3 SSL_ERROR_WANT_READ = 2 SSL_ERROR_WANT_WRITE = 3 SSL_ERROR_ZERO_RETURN = 6 SSL_OP_NO_SSLv2 = 0x01000000 SSL_OP_NO_SSLv3 = 0x02000000 SSL_OP_NO_TLSv1 = 0x04000000 SSL_OP_NO_TLSv1_2 = 0x08000000 SSL_OP_NO_TLSv1_1 = 0x10000000 SSL_SESS_CACHE_CLIENT = 0x0001 SSL_R_NO_SHARED_CIPHER = 193 SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM = 130 SSL_F_SSL3_GET_KEY_EXCHANGE = 141 SSL_F_SSL3_GET_SERVER_CERTIFICATE = 144 SSL_R_BAD_DH_P_LENGTH = 110 SSL_R_CERTIFICATE_VERIFY_FAILED = 134 SSL_R_UNKNOWN_PROTOCOL = 252 SSL_R_DH_KEY_TOO_SMALL = 372 # OpenSSL 1.1.0 SSL_F_TLS_PROCESS_SKE_DHE = 419 SSL_F_SSL3_GET_RECORD = 143 SSL_R_WRONG_VERSION_NUMBER = 267 SSL_F_TLS_PROCESS_SERVER_CERTIFICATE = 367 # OpenSSL < 1.1.0 SSL_F_SSL23_GET_SERVER_HELLO = 119 SSL_F_SSL3_READ_BYTES = 148 SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE = 1040 SSL_R_TLSV1_ALERT_PROTOCOL_VERSION = 1070 SSL_CTRL_SET_TLSEXT_HOSTNAME = 55 TLSEXT_NAMETYPE_host_name = 0 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY = 20 X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN = 19 X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT = 18 X509_V_ERR_CERT_NOT_YET_VALID = 9 X509_V_ERR_CERT_HAS_EXPIRED = 10 ASN1_F_ASN1_ITEM_VERIFY = 197 ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM = 161 if libcrypto_version_info >= (1, 1, 0): LibsslConst.SSL_R_DH_KEY_TOO_SMALL = 394 _libssl_cffi.py000064400000005761147205320040007542 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from .. import _backend_config from .._ffi import get_library, register_ffi from ..errors import LibraryNotFoundError from ._libcrypto import libcrypto_version_info from cffi import FFI __all__ = [ 'libssl', ] ffi = FFI() libssl_path = _backend_config().get('libssl_path') if libssl_path is None: libssl_path = get_library('ssl', 'libssl', '44') if not libssl_path: raise LibraryNotFoundError('The library libssl could not be found') libssl = ffi.dlopen(libssl_path) register_ffi(libssl, ffi) ffi.cdef(""" typedef ... SSL_METHOD; typedef uintptr_t SSL_CTX; typedef ... SSL_SESSION; typedef uintptr_t SSL; typedef ... BIO_METHOD; typedef uintptr_t BIO; typedef uintptr_t X509; typedef ... X509_STORE; typedef ... X509_STORE_CTX; typedef uintptr_t _STACK; BIO_METHOD *BIO_s_mem(void); BIO *BIO_new(BIO_METHOD *type); int BIO_free(BIO *a); int BIO_read(BIO *b, void *buf, int len); int BIO_write(BIO *b, const void *buf, int len); size_t BIO_ctrl_pending(BIO *b); SSL_CTX *SSL_CTX_new(const SSL_METHOD *method); long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath); long SSL_get_verify_result(const SSL *ssl); X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx); int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str); long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg); void SSL_CTX_free(SSL_CTX *a); SSL *SSL_new(SSL_CTX *ctx); void SSL_free(SSL *ssl); void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio); long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg); _STACK *SSL_get_peer_cert_chain(const SSL *s); SSL_SESSION *SSL_get1_session(const SSL *ssl); int SSL_set_session(SSL *ssl, SSL_SESSION *session); void SSL_SESSION_free(SSL_SESSION *session); void SSL_set_connect_state(SSL *ssl); int SSL_do_handshake(SSL *ssl); int SSL_get_error(const SSL *ssl, int ret); const char *SSL_get_version(const SSL *ssl); int SSL_read(SSL *ssl, void *buf, int num); int SSL_write(SSL *ssl, const void *buf, int num); int SSL_pending(const SSL *ssl); int SSL_shutdown(SSL *ssl); """) if libcrypto_version_info < (1, 1): ffi.cdef(""" int sk_num(const _STACK *); X509 *sk_value(const _STACK *, int); int SSL_library_init(void); void OPENSSL_add_all_algorithms_noconf(void); SSL_METHOD *SSLv23_method(void); """) else: ffi.cdef(""" int OPENSSL_sk_num(const _STACK *); X509 *OPENSSL_sk_value(const _STACK *, int); SSL_METHOD *TLS_method(void); """) _libssl_ctypes.py000064400000013612147205320040010134 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from ctypes import CDLL, CFUNCTYPE, POINTER, c_void_p, c_char_p, c_int, c_size_t, c_long from .. import _backend_config from .._ffi import FFIEngineError, get_library from ..errors import LibraryNotFoundError from ._libcrypto import libcrypto_version_info __all__ = [ 'libssl', ] libssl_path = _backend_config().get('libssl_path') if libssl_path is None: libssl_path = get_library('ssl', 'libssl', '44') if not libssl_path: raise LibraryNotFoundError('The library libssl could not be found') libssl = CDLL(libssl_path, use_errno=True) P_SSL_METHOD = POINTER(c_void_p) P_SSL_CTX = POINTER(c_void_p) P_SSL_SESSION = POINTER(c_void_p) P_SSL = POINTER(c_void_p) P_BIO_METHOD = POINTER(c_void_p) P_BIO = POINTER(c_void_p) X509 = c_void_p P_X509 = POINTER(X509) P_X509_STORE = POINTER(c_void_p) P_X509_STORE_CTX = POINTER(c_void_p) _STACK = c_void_p P_STACK = POINTER(_STACK) try: if libcrypto_version_info < (1, 1): libssl.sk_num.argtypes = [P_STACK] libssl.sk_num.restype = c_int libssl.sk_value.argtypes = [P_STACK, c_int] libssl.sk_value.restype = P_X509 libssl.SSL_library_init.argtypes = [] libssl.SSL_library_init.restype = c_int libssl.OPENSSL_add_all_algorithms_noconf.argtypes = [] libssl.OPENSSL_add_all_algorithms_noconf.restype = None libssl.SSLv23_method.argtypes = [] libssl.SSLv23_method.restype = P_SSL_METHOD else: libssl.OPENSSL_sk_num.argtypes = [P_STACK] libssl.OPENSSL_sk_num.restype = c_int libssl.OPENSSL_sk_value.argtypes = [P_STACK, c_int] libssl.OPENSSL_sk_value.restype = P_X509 libssl.TLS_method.argtypes = [] libssl.TLS_method.restype = P_SSL_METHOD libssl.BIO_s_mem.argtypes = [] libssl.BIO_s_mem.restype = P_BIO_METHOD libssl.BIO_new.argtypes = [ P_BIO_METHOD ] libssl.BIO_new.restype = P_BIO libssl.BIO_free.argtypes = [ P_BIO ] libssl.BIO_free.restype = c_int libssl.BIO_read.argtypes = [ P_BIO, c_char_p, c_int ] libssl.BIO_read.restype = c_int libssl.BIO_write.argtypes = [ P_BIO, c_char_p, c_int ] libssl.BIO_write.restype = c_int libssl.BIO_ctrl_pending.argtypes = [ P_BIO ] libssl.BIO_ctrl_pending.restype = c_size_t libssl.SSL_CTX_new.argtypes = [ P_SSL_METHOD ] libssl.SSL_CTX_new.restype = P_SSL_CTX libssl.SSL_CTX_set_timeout.argtypes = [ P_SSL_CTX, c_long ] libssl.SSL_CTX_set_timeout.restype = c_long verify_callback = CFUNCTYPE(c_int, c_int, P_X509_STORE_CTX) setattr(libssl, 'verify_callback', verify_callback) libssl.SSL_CTX_set_verify.argtypes = [ P_SSL_CTX, c_int, POINTER(verify_callback) ] libssl.SSL_CTX_set_verify.restype = None libssl.SSL_CTX_set_default_verify_paths.argtypes = [ P_SSL_CTX ] libssl.SSL_CTX_set_default_verify_paths.restype = c_int libssl.SSL_CTX_load_verify_locations.argtypes = [ P_SSL_CTX, c_char_p, c_char_p ] libssl.SSL_CTX_load_verify_locations.restype = c_int libssl.SSL_get_verify_result.argtypes = [ P_SSL ] libssl.SSL_get_verify_result.restype = c_long libssl.SSL_CTX_get_cert_store.argtypes = [ P_SSL_CTX ] libssl.SSL_CTX_get_cert_store.restype = P_X509_STORE libssl.X509_STORE_add_cert.argtypes = [ P_X509_STORE, P_X509 ] libssl.X509_STORE_add_cert.restype = c_int libssl.SSL_CTX_set_cipher_list.argtypes = [ P_SSL_CTX, c_char_p ] libssl.SSL_CTX_set_cipher_list.restype = c_int libssl.SSL_CTX_ctrl.arg_types = [ P_SSL_CTX, c_int, c_long, c_void_p ] libssl.SSL_CTX_ctrl.restype = c_long libssl.SSL_CTX_free.argtypes = [ P_SSL_CTX ] libssl.SSL_CTX_free.restype = None libssl.SSL_new.argtypes = [ P_SSL_CTX ] libssl.SSL_new.restype = P_SSL libssl.SSL_free.argtypes = [ P_SSL ] libssl.SSL_free.restype = None libssl.SSL_set_bio.argtypes = [ P_SSL, P_BIO, P_BIO ] libssl.SSL_set_bio.restype = None libssl.SSL_ctrl.arg_types = [ P_SSL, c_int, c_long, c_void_p ] libssl.SSL_ctrl.restype = c_long libssl.SSL_get_peer_cert_chain.argtypes = [ P_SSL ] libssl.SSL_get_peer_cert_chain.restype = P_STACK libssl.SSL_get1_session.argtypes = [ P_SSL ] libssl.SSL_get1_session.restype = P_SSL_SESSION libssl.SSL_set_session.argtypes = [ P_SSL, P_SSL_SESSION ] libssl.SSL_set_session.restype = c_int libssl.SSL_SESSION_free.argtypes = [ P_SSL_SESSION ] libssl.SSL_SESSION_free.restype = None libssl.SSL_set_connect_state.argtypes = [ P_SSL ] libssl.SSL_set_connect_state.restype = None libssl.SSL_do_handshake.argtypes = [ P_SSL ] libssl.SSL_do_handshake.restype = c_int libssl.SSL_get_error.argtypes = [ P_SSL, c_int ] libssl.SSL_get_error.restype = c_int libssl.SSL_get_version.argtypes = [ P_SSL ] libssl.SSL_get_version.restype = c_char_p libssl.SSL_read.argtypes = [ P_SSL, c_char_p, c_int ] libssl.SSL_read.restype = c_int libssl.SSL_write.argtypes = [ P_SSL, c_char_p, c_int ] libssl.SSL_write.restype = c_int libssl.SSL_pending.argtypes = [ P_SSL ] libssl.SSL_pending.restype = c_int libssl.SSL_shutdown.argtypes = [ P_SSL ] libssl.SSL_shutdown.restype = c_int except (AttributeError): raise FFIEngineError('Error initializing ctypes') setattr(libssl, '_STACK', _STACK) setattr(libssl, 'X509', X509) asymmetric.py000064400000173073147205320040007303 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import hashlib from .._asn1 import ( Certificate as Asn1Certificate, DHParameters, ECDomainParameters, PrivateKeyInfo, PublicKeyAlgorithm, PublicKeyInfo, ) from .._asymmetric import ( _CertificateBase, _fingerprint, _parse_pkcs12, _PrivateKeyBase, _PublicKeyBase, _unwrap_private_key_info, parse_certificate, parse_private, parse_public, ) from .._errors import pretty_message from .._ffi import ( buffer_from_bytes, buffer_pointer, bytes_from_buffer, deref, is_null, new, null, unwrap, write_to_buffer, ) from ._libcrypto import libcrypto, LibcryptoConst, libcrypto_version_info, handle_openssl_error from ..errors import AsymmetricKeyError, IncompleteAsymmetricKeyError, SignatureError from .._types import type_name, str_cls, byte_cls, int_types from ..util import constant_compare __all__ = [ 'Certificate', 'dsa_sign', 'dsa_verify', 'ecdsa_sign', 'ecdsa_verify', 'generate_pair', 'load_certificate', 'load_pkcs12', 'load_private_key', 'load_public_key', 'parse_pkcs12', 'PrivateKey', 'PublicKey', 'rsa_oaep_decrypt', 'rsa_oaep_encrypt', 'rsa_pkcs1v15_decrypt', 'rsa_pkcs1v15_encrypt', 'rsa_pkcs1v15_sign', 'rsa_pkcs1v15_verify', 'rsa_pss_sign', 'rsa_pss_verify', ] class PrivateKey(_PrivateKeyBase): """ Container for the OpenSSL representation of a private key """ evp_pkey = None _public_key = None # A reference to the library used in the destructor to make sure it hasn't # been garbage collected by the time this object is garbage collected _lib = None def __init__(self, evp_pkey, asn1): """ :param evp_pkey: An OpenSSL EVP_PKEY value from loading/importing the key :param asn1: An asn1crypto.keys.PrivateKeyInfo object """ self.evp_pkey = evp_pkey self.asn1 = asn1 self._lib = libcrypto @property def public_key(self): """ :return: A PublicKey object corresponding to this private key. """ if self._public_key is None: buffer_size = libcrypto.i2d_PUBKEY(self.evp_pkey, null()) pubkey_buffer = buffer_from_bytes(buffer_size) pubkey_pointer = buffer_pointer(pubkey_buffer) pubkey_length = libcrypto.i2d_PUBKEY(self.evp_pkey, pubkey_pointer) handle_openssl_error(pubkey_length) pubkey_data = bytes_from_buffer(pubkey_buffer, pubkey_length) asn1 = PublicKeyInfo.load(pubkey_data) # OpenSSL 1.x suffers from issues trying to use RSASSA-PSS keys, so we # masquerade it as a normal RSA key so the OID checks work if libcrypto_version_info < (3,) and asn1.algorithm == 'rsassa_pss': temp_asn1 = asn1.copy() temp_asn1['algorithm']['algorithm'] = 'rsa' temp_data = temp_asn1.dump() write_to_buffer(pubkey_buffer, temp_data) pubkey_length = len(temp_data) pub_evp_pkey = libcrypto.d2i_PUBKEY(null(), buffer_pointer(pubkey_buffer), pubkey_length) if is_null(pub_evp_pkey): handle_openssl_error(0) self._public_key = PublicKey(pub_evp_pkey, asn1) return self._public_key @property def fingerprint(self): """ Creates a fingerprint that can be compared with a public key to see if the two form a pair. This fingerprint is not compatible with fingerprints generated by any other software. :return: A byte string that is a sha256 hash of selected components (based on the key type) """ if self._fingerprint is None: self._fingerprint = _fingerprint(self.asn1, load_private_key) return self._fingerprint def __del__(self): if self.evp_pkey: self._lib.EVP_PKEY_free(self.evp_pkey) self._lib = None self.evp_pkey = None class PublicKey(_PublicKeyBase): """ Container for the OpenSSL representation of a public key """ evp_pkey = None # A reference to the library used in the destructor to make sure it hasn't # been garbage collected by the time this object is garbage collected _lib = None def __init__(self, evp_pkey, asn1): """ :param evp_pkey: An OpenSSL EVP_PKEY value from loading/importing the key :param asn1: An asn1crypto.keys.PublicKeyInfo object """ self.evp_pkey = evp_pkey self.asn1 = asn1 self._lib = libcrypto def __del__(self): if self.evp_pkey: self._lib.EVP_PKEY_free(self.evp_pkey) self._lib = None self.evp_pkey = None class Certificate(_CertificateBase): """ Container for the OpenSSL representation of a certificate """ x509 = None _public_key = None _self_signed = None # A reference to the library used in the destructor to make sure it hasn't # been garbage collected by the time this object is garbage collected _lib = None def __init__(self, x509, asn1): """ :param x509: An OpenSSL X509 value from loading/importing the certificate :param asn1: An asn1crypto.x509.Certificate object """ self.x509 = x509 self.asn1 = asn1 self._lib = libcrypto @property def evp_pkey(self): """ :return: The EVP_PKEY of the public key this certificate contains """ return self.public_key.evp_pkey @property def public_key(self): """ :return: The PublicKey object for the public key this certificate contains """ if not self._public_key and self.x509: # OpenSSL 1.x suffers from issues trying to use RSASSA-PSS keys, so we # masquerade it as a normal RSA key so the OID checks work if libcrypto_version_info < (3,) and self.asn1.public_key.algorithm == 'rsassa_pss': self._public_key = load_public_key(self.asn1.public_key) else: evp_pkey = libcrypto.X509_get_pubkey(self.x509) self._public_key = PublicKey(evp_pkey, self.asn1.public_key) return self._public_key @property def self_signed(self): """ :return: A boolean - if the certificate is self-signed """ if self._self_signed is None: self._self_signed = False if self.asn1.self_signed in set(['yes', 'maybe']): signature_algo = self.asn1['signature_algorithm'].signature_algo hash_algo = self.asn1['signature_algorithm'].hash_algo if signature_algo == 'rsassa_pkcs1v15': verify_func = rsa_pkcs1v15_verify elif signature_algo == 'rsassa_pss': verify_func = rsa_pss_verify elif signature_algo == 'dsa': verify_func = dsa_verify elif signature_algo == 'ecdsa': verify_func = ecdsa_verify else: raise OSError(pretty_message( ''' Unable to verify the signature of the certificate since it uses the unsupported algorithm %s ''', signature_algo )) try: verify_func( self.public_key, self.asn1['signature_value'].native, self.asn1['tbs_certificate'].dump(), hash_algo ) self._self_signed = True except (SignatureError): pass return self._self_signed def __del__(self): if self._public_key: self._public_key.__del__() self._public_key = None if self.x509: self._lib.X509_free(self.x509) self._lib = None self.x509 = None def generate_pair(algorithm, bit_size=None, curve=None): """ Generates a public/private key pair :param algorithm: The key algorithm - "rsa", "dsa" or "ec" :param bit_size: An integer - used for "rsa" and "dsa". For "rsa" the value maye be 1024, 2048, 3072 or 4096. For "dsa" the value may be 1024, plus 2048 or 3072 if OpenSSL 1.0.0 or newer is available. :param curve: A unicode string - used for "ec" keys. Valid values include "secp256r1", "secp384r1" and "secp521r1". :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A 2-element tuple of (PublicKey, PrivateKey). The contents of each key may be saved by calling .asn1.dump(). """ if algorithm not in set(['rsa', 'dsa', 'ec']): raise ValueError(pretty_message( ''' algorithm must be one of "rsa", "dsa", "ec", not %s ''', repr(algorithm) )) if algorithm == 'rsa': if bit_size not in set([1024, 2048, 3072, 4096]): raise ValueError(pretty_message( ''' bit_size must be one of 1024, 2048, 3072, 4096, not %s ''', repr(bit_size) )) elif algorithm == 'dsa': if libcrypto_version_info < (1,): if bit_size != 1024: raise ValueError(pretty_message( ''' bit_size must be 1024, not %s ''', repr(bit_size) )) else: if bit_size not in set([1024, 2048, 3072]): raise ValueError(pretty_message( ''' bit_size must be one of 1024, 2048, 3072, not %s ''', repr(bit_size) )) elif algorithm == 'ec': if curve not in set(['secp256r1', 'secp384r1', 'secp521r1']): raise ValueError(pretty_message( ''' curve must be one of "secp256r1", "secp384r1", "secp521r1", not %s ''', repr(curve) )) if algorithm == 'rsa': rsa = None exponent = None try: rsa = libcrypto.RSA_new() if is_null(rsa): handle_openssl_error(0) exponent_pointer = new(libcrypto, 'BIGNUM **') result = libcrypto.BN_dec2bn(exponent_pointer, b'65537') handle_openssl_error(result) exponent = unwrap(exponent_pointer) result = libcrypto.RSA_generate_key_ex(rsa, bit_size, exponent, null()) handle_openssl_error(result) buffer_length = libcrypto.i2d_RSAPublicKey(rsa, null()) if buffer_length < 0: handle_openssl_error(buffer_length) buffer = buffer_from_bytes(buffer_length) result = libcrypto.i2d_RSAPublicKey(rsa, buffer_pointer(buffer)) if result < 0: handle_openssl_error(result) public_key_bytes = bytes_from_buffer(buffer, buffer_length) buffer_length = libcrypto.i2d_RSAPrivateKey(rsa, null()) if buffer_length < 0: handle_openssl_error(buffer_length) buffer = buffer_from_bytes(buffer_length) result = libcrypto.i2d_RSAPrivateKey(rsa, buffer_pointer(buffer)) if result < 0: handle_openssl_error(result) private_key_bytes = bytes_from_buffer(buffer, buffer_length) finally: if rsa: libcrypto.RSA_free(rsa) if exponent: libcrypto.BN_free(exponent) elif algorithm == 'dsa': dsa = None try: dsa = libcrypto.DSA_new() if is_null(dsa): handle_openssl_error(0) result = libcrypto.DSA_generate_parameters_ex(dsa, bit_size, null(), 0, null(), null(), null()) handle_openssl_error(result) result = libcrypto.DSA_generate_key(dsa) handle_openssl_error(result) buffer_length = libcrypto.i2d_DSA_PUBKEY(dsa, null()) if buffer_length < 0: handle_openssl_error(buffer_length) buffer = buffer_from_bytes(buffer_length) result = libcrypto.i2d_DSA_PUBKEY(dsa, buffer_pointer(buffer)) if result < 0: handle_openssl_error(result) public_key_bytes = bytes_from_buffer(buffer, buffer_length) buffer_length = libcrypto.i2d_DSAPrivateKey(dsa, null()) if buffer_length < 0: handle_openssl_error(buffer_length) buffer = buffer_from_bytes(buffer_length) result = libcrypto.i2d_DSAPrivateKey(dsa, buffer_pointer(buffer)) if result < 0: handle_openssl_error(result) private_key_bytes = bytes_from_buffer(buffer, buffer_length) finally: if dsa: libcrypto.DSA_free(dsa) elif algorithm == 'ec': ec_key = None try: curve_id = { 'secp256r1': LibcryptoConst.NID_X9_62_prime256v1, 'secp384r1': LibcryptoConst.NID_secp384r1, 'secp521r1': LibcryptoConst.NID_secp521r1, }[curve] ec_key = libcrypto.EC_KEY_new_by_curve_name(curve_id) if is_null(ec_key): handle_openssl_error(0) result = libcrypto.EC_KEY_generate_key(ec_key) handle_openssl_error(result) libcrypto.EC_KEY_set_asn1_flag(ec_key, LibcryptoConst.OPENSSL_EC_NAMED_CURVE) buffer_length = libcrypto.i2o_ECPublicKey(ec_key, null()) if buffer_length < 0: handle_openssl_error(buffer_length) buffer = buffer_from_bytes(buffer_length) result = libcrypto.i2o_ECPublicKey(ec_key, buffer_pointer(buffer)) if result < 0: handle_openssl_error(result) public_key_point_bytes = bytes_from_buffer(buffer, buffer_length) # i2o_ECPublicKey only returns the ECPoint bytes, so we have to # manually wrap it in a PublicKeyInfo structure to get it to parse public_key = PublicKeyInfo({ 'algorithm': PublicKeyAlgorithm({ 'algorithm': 'ec', 'parameters': ECDomainParameters( name='named', value=curve ) }), 'public_key': public_key_point_bytes }) public_key_bytes = public_key.dump() buffer_length = libcrypto.i2d_ECPrivateKey(ec_key, null()) if buffer_length < 0: handle_openssl_error(buffer_length) buffer = buffer_from_bytes(buffer_length) result = libcrypto.i2d_ECPrivateKey(ec_key, buffer_pointer(buffer)) if result < 0: handle_openssl_error(result) private_key_bytes = bytes_from_buffer(buffer, buffer_length) finally: if ec_key: libcrypto.EC_KEY_free(ec_key) return (load_public_key(public_key_bytes), load_private_key(private_key_bytes)) def generate_dh_parameters(bit_size): """ Generates DH parameters for use with Diffie-Hellman key exchange. Returns a structure in the format of DHParameter defined in PKCS#3, which is also used by the OpenSSL dhparam tool. THIS CAN BE VERY TIME CONSUMING! :param bit_size: The integer bit size of the parameters to generate. Must be between 512 and 4096, and divisible by 64. Recommended secure value as of early 2016 is 2048, with an absolute minimum of 1024. :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: An asn1crypto.algos.DHParameters object. Use oscrypto.asymmetric.dump_dh_parameters() to save to disk for usage with web servers. """ if not isinstance(bit_size, int_types): raise TypeError(pretty_message( ''' bit_size must be an integer, not %s ''', type_name(bit_size) )) if bit_size < 512: raise ValueError('bit_size must be greater than or equal to 512') if bit_size > 4096: raise ValueError('bit_size must be less than or equal to 4096') if bit_size % 64 != 0: raise ValueError('bit_size must be a multiple of 64') dh = None try: dh = libcrypto.DH_new() if is_null(dh): handle_openssl_error(0) result = libcrypto.DH_generate_parameters_ex(dh, bit_size, LibcryptoConst.DH_GENERATOR_2, null()) handle_openssl_error(result) buffer_length = libcrypto.i2d_DHparams(dh, null()) if buffer_length < 0: handle_openssl_error(buffer_length) buffer = buffer_from_bytes(buffer_length) result = libcrypto.i2d_DHparams(dh, buffer_pointer(buffer)) if result < 0: handle_openssl_error(result) dh_params_bytes = bytes_from_buffer(buffer, buffer_length) return DHParameters.load(dh_params_bytes) finally: if dh: libcrypto.DH_free(dh) def load_certificate(source): """ Loads an x509 certificate into a Certificate object :param source: A byte string of file contents, a unicode string filename or an asn1crypto.x509.Certificate object :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A Certificate object """ if isinstance(source, Asn1Certificate): certificate = source elif isinstance(source, byte_cls): certificate = parse_certificate(source) elif isinstance(source, str_cls): with open(source, 'rb') as f: certificate = parse_certificate(f.read()) else: raise TypeError(pretty_message( ''' source must be a byte string, unicode string or asn1crypto.x509.Certificate object, not %s ''', type_name(source) )) return _load_x509(certificate) def _load_x509(certificate): """ Loads an ASN.1 object of an x509 certificate into a Certificate object :param certificate: An asn1crypto.x509.Certificate object :return: A Certificate object """ source = certificate.dump() buffer = buffer_from_bytes(source) evp_pkey = libcrypto.d2i_X509(null(), buffer_pointer(buffer), len(source)) if is_null(evp_pkey): handle_openssl_error(0) return Certificate(evp_pkey, certificate) def load_private_key(source, password=None): """ Loads a private key into a PrivateKey object :param source: A byte string of file contents, a unicode string filename or an asn1crypto.keys.PrivateKeyInfo object :param password: A byte or unicode string to decrypt the private key file. Unicode strings will be encoded using UTF-8. Not used is the source is a PrivateKeyInfo object. :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type oscrypto.errors.AsymmetricKeyError - when the private key is incompatible with the OS crypto library OSError - when an error is returned by the OS crypto library :return: A PrivateKey object """ if isinstance(source, PrivateKeyInfo): private_object = source else: if password is not None: if isinstance(password, str_cls): password = password.encode('utf-8') if not isinstance(password, byte_cls): raise TypeError(pretty_message( ''' password must be a byte string, not %s ''', type_name(password) )) if isinstance(source, str_cls): with open(source, 'rb') as f: source = f.read() elif not isinstance(source, byte_cls): raise TypeError(pretty_message( ''' source must be a byte string, unicode string or asn1crypto.keys.PrivateKeyInfo object, not %s ''', type_name(source) )) private_object = parse_private(source, password) return _load_key(private_object) def load_public_key(source): """ Loads a public key into a PublicKey object :param source: A byte string of file contents, a unicode string filename or an asn1crypto.keys.PublicKeyInfo object :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type oscrypto.errors.AsymmetricKeyError - when the public key is incompatible with the OS crypto library OSError - when an error is returned by the OS crypto library :return: A PublicKey object """ if isinstance(source, PublicKeyInfo): public_key = source elif isinstance(source, byte_cls): public_key = parse_public(source) elif isinstance(source, str_cls): with open(source, 'rb') as f: public_key = parse_public(f.read()) else: raise TypeError(pretty_message( ''' source must be a byte string, unicode string or asn1crypto.keys.PublicKeyInfo object, not %s ''', type_name(source) )) if public_key.algorithm == 'dsa': if libcrypto_version_info < (1,) and public_key.hash_algo == 'sha2': raise AsymmetricKeyError(pretty_message( ''' OpenSSL 0.9.8 only supports DSA keys based on SHA1 (2048 bits or less) - this key is based on SHA2 and is %s bits ''', public_key.bit_size )) elif public_key.hash_algo is None: raise IncompleteAsymmetricKeyError(pretty_message( ''' The DSA key does not contain the necessary p, q and g parameters and can not be used ''' )) # OpenSSL 1.x suffers from issues trying to use RSASSA-PSS keys, so we # masquerade it as a normal RSA key so the OID checks work if libcrypto_version_info < (3,) and public_key.algorithm == 'rsassa_pss': temp_key = public_key.copy() temp_key['algorithm']['algorithm'] = 'rsa' data = temp_key.dump() else: data = public_key.dump() buffer = buffer_from_bytes(data) evp_pkey = libcrypto.d2i_PUBKEY(null(), buffer_pointer(buffer), len(data)) if is_null(evp_pkey): handle_openssl_error(0) return PublicKey(evp_pkey, public_key) def _load_key(private_object): """ Loads a private key into a PrivateKey object :param private_object: An asn1crypto.keys.PrivateKeyInfo object :return: A PrivateKey object """ if libcrypto_version_info < (1,) and private_object.algorithm == 'dsa' and private_object.hash_algo == 'sha2': raise AsymmetricKeyError(pretty_message( ''' OpenSSL 0.9.8 only supports DSA keys based on SHA1 (2048 bits or less) - this key is based on SHA2 and is %s bits ''', private_object.bit_size )) source = _unwrap_private_key_info(private_object).dump() buffer = buffer_from_bytes(source) evp_pkey = libcrypto.d2i_AutoPrivateKey(null(), buffer_pointer(buffer), len(source)) if is_null(evp_pkey): handle_openssl_error(0) return PrivateKey(evp_pkey, private_object) def parse_pkcs12(data, password=None): """ Parses a PKCS#12 ANS.1 DER-encoded structure and extracts certs and keys :param data: A byte string of a DER-encoded PKCS#12 file :param password: A byte string of the password to any encrypted data :raises: ValueError - when any of the parameters are of the wrong type or value OSError - when an error is returned by one of the OS decryption functions :return: A three-element tuple of: 1. An asn1crypto.keys.PrivateKeyInfo object 2. An asn1crypto.x509.Certificate object 3. A list of zero or more asn1crypto.x509.Certificate objects that are "extra" certificates, possibly intermediates from the cert chain """ return _parse_pkcs12(data, password, load_private_key) def load_pkcs12(source, password=None): """ Loads a .p12 or .pfx file into a PrivateKey object and one or more Certificates objects :param source: A byte string of file contents or a unicode string filename :param password: A byte or unicode string to decrypt the PKCS12 file. Unicode strings will be encoded using UTF-8. :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type oscrypto.errors.AsymmetricKeyError - when a contained key is incompatible with the OS crypto library OSError - when an error is returned by the OS crypto library :return: A three-element tuple containing (PrivateKey, Certificate, [Certificate, ...]) """ if password is not None: if isinstance(password, str_cls): password = password.encode('utf-8') if not isinstance(password, byte_cls): raise TypeError(pretty_message( ''' password must be a byte string, not %s ''', type_name(password) )) if isinstance(source, str_cls): with open(source, 'rb') as f: source = f.read() elif not isinstance(source, byte_cls): raise TypeError(pretty_message( ''' source must be a byte string or a unicode string, not %s ''', type_name(source) )) key_info, cert_info, extra_certs_info = parse_pkcs12(source, password) key = None cert = None if key_info: key = _load_key(key_info) if cert_info: cert = _load_x509(cert_info) extra_certs = [_load_x509(info) for info in extra_certs_info] return (key, cert, extra_certs) def rsa_pkcs1v15_encrypt(certificate_or_public_key, data): """ Encrypts a byte string using an RSA public key or certificate. Uses PKCS#1 v1.5 padding. :param certificate_or_public_key: A PublicKey or Certificate object :param data: A byte string, with a maximum length 11 bytes less than the key length (in bytes) :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the encrypted data """ return _encrypt(certificate_or_public_key, data, LibcryptoConst.RSA_PKCS1_PADDING) def rsa_pkcs1v15_decrypt(private_key, ciphertext): """ Decrypts a byte string using an RSA private key. Uses PKCS#1 v1.5 padding. :param private_key: A PrivateKey object :param ciphertext: A byte string of the encrypted data :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the original plaintext """ return _decrypt(private_key, ciphertext, LibcryptoConst.RSA_PKCS1_PADDING) def rsa_oaep_encrypt(certificate_or_public_key, data): """ Encrypts a byte string using an RSA public key or certificate. Uses PKCS#1 OAEP padding with SHA1. :param certificate_or_public_key: A PublicKey or Certificate object :param data: A byte string, with a maximum length 41 bytes (or more) less than the key length (in bytes) :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the encrypted data """ return _encrypt(certificate_or_public_key, data, LibcryptoConst.RSA_PKCS1_OAEP_PADDING) def rsa_oaep_decrypt(private_key, ciphertext): """ Decrypts a byte string using an RSA private key. Uses PKCS#1 OAEP padding with SHA1. :param private_key: A PrivateKey object :param ciphertext: A byte string of the encrypted data :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the original plaintext """ return _decrypt(private_key, ciphertext, LibcryptoConst.RSA_PKCS1_OAEP_PADDING) def _evp_pkey_get_size(evp_pkey): """ Handles the function name change from OpenSSL 1.1 -> 3.0 :param evp_pkey: The EVP_PKEY of the Certificte or PublicKey to get the size of :return: An int of the number of bytes necessary for the key """ if libcrypto_version_info < (3, ): return libcrypto.EVP_PKEY_size(evp_pkey) return libcrypto.EVP_PKEY_get_size(evp_pkey) def _encrypt(certificate_or_public_key, data, padding): """ Encrypts plaintext using an RSA public key or certificate :param certificate_or_public_key: A PublicKey, Certificate or PrivateKey object :param data: The byte string to encrypt :param padding: The padding mode to use :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the encrypted data """ if not isinstance(certificate_or_public_key, (Certificate, PublicKey)): raise TypeError(pretty_message( ''' certificate_or_public_key must be an instance of the Certificate or PublicKey class, not %s ''', type_name(certificate_or_public_key) )) if not isinstance(data, byte_cls): raise TypeError(pretty_message( ''' data must be a byte string, not %s ''', type_name(data) )) rsa = None try: buffer_size = _evp_pkey_get_size(certificate_or_public_key.evp_pkey) buffer = buffer_from_bytes(buffer_size) rsa = libcrypto.EVP_PKEY_get1_RSA(certificate_or_public_key.evp_pkey) res = libcrypto.RSA_public_encrypt(len(data), data, buffer, rsa, padding) handle_openssl_error(res) return bytes_from_buffer(buffer, res) finally: if rsa: libcrypto.RSA_free(rsa) def _decrypt(private_key, ciphertext, padding): """ Decrypts RSA ciphertext using a private key :param private_key: A PrivateKey object :param ciphertext: The ciphertext - a byte string :param padding: The padding mode to use :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the plaintext """ if not isinstance(private_key, PrivateKey): raise TypeError(pretty_message( ''' private_key must be an instance of the PrivateKey class, not %s ''', type_name(private_key) )) if not isinstance(ciphertext, byte_cls): raise TypeError(pretty_message( ''' ciphertext must be a byte string, not %s ''', type_name(ciphertext) )) rsa = None try: buffer_size = _evp_pkey_get_size(private_key.evp_pkey) buffer = buffer_from_bytes(buffer_size) rsa = libcrypto.EVP_PKEY_get1_RSA(private_key.evp_pkey) res = libcrypto.RSA_private_decrypt(len(ciphertext), ciphertext, buffer, rsa, padding) handle_openssl_error(res) return bytes_from_buffer(buffer, res) finally: if rsa: libcrypto.RSA_free(rsa) def rsa_pkcs1v15_verify(certificate_or_public_key, signature, data, hash_algorithm): """ Verifies an RSASSA-PKCS-v1.5 signature. When the hash_algorithm is "raw", the operation is identical to RSA public key decryption. That is: the data is not hashed and no ASN.1 structure with an algorithm identifier of the hash algorithm is placed in the encrypted byte string. :param certificate_or_public_key: A Certificate or PublicKey instance to verify the signature with :param signature: A byte string of the signature to verify :param data: A byte string of the data the signature is for :param hash_algorithm: A unicode string of "md5", "sha1", "sha224", "sha256", "sha384", "sha512" or "raw" :raises: oscrypto.errors.SignatureError - when the signature is determined to be invalid ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library """ if certificate_or_public_key.algorithm != 'rsa': raise ValueError(pretty_message( ''' The key specified is not an RSA public key, but %s ''', certificate_or_public_key.algorithm.upper() )) return _verify(certificate_or_public_key, signature, data, hash_algorithm) def rsa_pss_verify(certificate_or_public_key, signature, data, hash_algorithm): """ Verifies an RSASSA-PSS signature. For the PSS padding the mask gen algorithm will be mgf1 using the same hash algorithm as the signature. The salt length with be the length of the hash algorithm, and the trailer field with be the standard 0xBC byte. :param certificate_or_public_key: A Certificate or PublicKey instance to verify the signature with :param signature: A byte string of the signature to verify :param data: A byte string of the data the signature is for :param hash_algorithm: A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512" :raises: oscrypto.errors.SignatureError - when the signature is determined to be invalid ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library """ cp_alg = certificate_or_public_key.algorithm if cp_alg != 'rsa' and cp_alg != 'rsassa_pss': raise ValueError(pretty_message( ''' The key specified is not an RSA public key, but %s ''', certificate_or_public_key.algorithm.upper() )) return _verify(certificate_or_public_key, signature, data, hash_algorithm, rsa_pss_padding=True) def dsa_verify(certificate_or_public_key, signature, data, hash_algorithm): """ Verifies a DSA signature :param certificate_or_public_key: A Certificate or PublicKey instance to verify the signature with :param signature: A byte string of the signature to verify :param data: A byte string of the data the signature is for :param hash_algorithm: A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512" :raises: oscrypto.errors.SignatureError - when the signature is determined to be invalid ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library """ if certificate_or_public_key.algorithm != 'dsa': raise ValueError(pretty_message( ''' The key specified is not a DSA public key, but %s ''', certificate_or_public_key.algorithm.upper() )) return _verify(certificate_or_public_key, signature, data, hash_algorithm) def ecdsa_verify(certificate_or_public_key, signature, data, hash_algorithm): """ Verifies an ECDSA signature :param certificate_or_public_key: A Certificate or PublicKey instance to verify the signature with :param signature: A byte string of the signature to verify :param data: A byte string of the data the signature is for :param hash_algorithm: A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512" :raises: oscrypto.errors.SignatureError - when the signature is determined to be invalid ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library """ if certificate_or_public_key.algorithm != 'ec': raise ValueError(pretty_message( ''' The key specified is not an EC public key, but %s ''', certificate_or_public_key.algorithm.upper() )) return _verify(certificate_or_public_key, signature, data, hash_algorithm) def _verify(certificate_or_public_key, signature, data, hash_algorithm, rsa_pss_padding=False): """ Verifies an RSA, DSA or ECDSA signature :param certificate_or_public_key: A Certificate or PublicKey instance to verify the signature with :param signature: A byte string of the signature to verify :param data: A byte string of the data the signature is for :param hash_algorithm: A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512" :param rsa_pss_padding: If the certificate_or_public_key is an RSA key, this enables PSS padding :raises: oscrypto.errors.SignatureError - when the signature is determined to be invalid ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library """ if not isinstance(certificate_or_public_key, (Certificate, PublicKey)): raise TypeError(pretty_message( ''' certificate_or_public_key must be an instance of the Certificate or PublicKey class, not %s ''', type_name(certificate_or_public_key) )) if not isinstance(signature, byte_cls): raise TypeError(pretty_message( ''' signature must be a byte string, not %s ''', type_name(signature) )) if not isinstance(data, byte_cls): raise TypeError(pretty_message( ''' data must be a byte string, not %s ''', type_name(data) )) cp_alg = certificate_or_public_key.algorithm cp_is_rsa = cp_alg == 'rsa' or cp_alg == 'rsassa_pss' valid_hash_algorithms = set(['md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512']) if cp_is_rsa and not rsa_pss_padding: valid_hash_algorithms |= set(['raw']) if hash_algorithm not in valid_hash_algorithms: valid_hash_algorithms_error = '"md5", "sha1", "sha224", "sha256", "sha384", "sha512"' if cp_is_rsa and not rsa_pss_padding: valid_hash_algorithms_error += ', "raw"' raise ValueError(pretty_message( ''' hash_algorithm must be one of %s, not %s ''', valid_hash_algorithms_error, repr(hash_algorithm) )) if not cp_is_rsa and rsa_pss_padding: raise ValueError(pretty_message( ''' PSS padding can only be used with RSA keys - the key provided is a %s key ''', cp_alg.upper() )) if cp_is_rsa and hash_algorithm == 'raw': if len(data) > certificate_or_public_key.byte_size - 11: raise ValueError(pretty_message( ''' data must be 11 bytes shorter than the key size when hash_algorithm is "raw" - key size is %s bytes, but data is %s bytes long ''', certificate_or_public_key.byte_size, len(data) )) rsa = None try: rsa = libcrypto.EVP_PKEY_get1_RSA(certificate_or_public_key.evp_pkey) if is_null(rsa): handle_openssl_error(0) buffer_size = _evp_pkey_get_size(certificate_or_public_key.evp_pkey) decrypted_buffer = buffer_from_bytes(buffer_size) decrypted_length = libcrypto.RSA_public_decrypt( len(signature), signature, decrypted_buffer, rsa, LibcryptoConst.RSA_PKCS1_PADDING ) handle_openssl_error(decrypted_length) decrypted_bytes = bytes_from_buffer(decrypted_buffer, decrypted_length) if not constant_compare(data, decrypted_bytes): raise SignatureError('Signature is invalid') return finally: if rsa: libcrypto.RSA_free(rsa) evp_md_ctx = None rsa = None dsa = None dsa_sig = None ec_key = None ecdsa_sig = None try: if libcrypto_version_info < (1, 1): evp_md_ctx = libcrypto.EVP_MD_CTX_create() else: evp_md_ctx = libcrypto.EVP_MD_CTX_new() evp_md = { 'md5': libcrypto.EVP_md5, 'sha1': libcrypto.EVP_sha1, 'sha224': libcrypto.EVP_sha224, 'sha256': libcrypto.EVP_sha256, 'sha384': libcrypto.EVP_sha384, 'sha512': libcrypto.EVP_sha512 }[hash_algorithm]() if libcrypto_version_info < (1,): if cp_is_rsa and rsa_pss_padding: digest = getattr(hashlib, hash_algorithm)(data).digest() rsa = libcrypto.EVP_PKEY_get1_RSA(certificate_or_public_key.evp_pkey) if is_null(rsa): handle_openssl_error(0) buffer_size = _evp_pkey_get_size(certificate_or_public_key.evp_pkey) decoded_buffer = buffer_from_bytes(buffer_size) decoded_length = libcrypto.RSA_public_decrypt( len(signature), signature, decoded_buffer, rsa, LibcryptoConst.RSA_NO_PADDING ) handle_openssl_error(decoded_length) res = libcrypto.RSA_verify_PKCS1_PSS( rsa, digest, evp_md, decoded_buffer, LibcryptoConst.EVP_MD_CTX_FLAG_PSS_MDLEN ) elif cp_is_rsa: res = libcrypto.EVP_DigestInit_ex(evp_md_ctx, evp_md, null()) handle_openssl_error(res) res = libcrypto.EVP_DigestUpdate(evp_md_ctx, data, len(data)) handle_openssl_error(res) res = libcrypto.EVP_VerifyFinal( evp_md_ctx, signature, len(signature), certificate_or_public_key.evp_pkey ) elif cp_alg == 'dsa': digest = getattr(hashlib, hash_algorithm)(data).digest() signature_buffer = buffer_from_bytes(signature) signature_pointer = buffer_pointer(signature_buffer) dsa_sig = libcrypto.d2i_DSA_SIG(null(), signature_pointer, len(signature)) if is_null(dsa_sig): raise SignatureError('Signature is invalid') dsa = libcrypto.EVP_PKEY_get1_DSA(certificate_or_public_key.evp_pkey) if is_null(dsa): handle_openssl_error(0) res = libcrypto.DSA_do_verify(digest, len(digest), dsa_sig, dsa) elif cp_alg == 'ec': digest = getattr(hashlib, hash_algorithm)(data).digest() signature_buffer = buffer_from_bytes(signature) signature_pointer = buffer_pointer(signature_buffer) ecdsa_sig = libcrypto.d2i_ECDSA_SIG(null(), signature_pointer, len(signature)) if is_null(ecdsa_sig): raise SignatureError('Signature is invalid') ec_key = libcrypto.EVP_PKEY_get1_EC_KEY(certificate_or_public_key.evp_pkey) if is_null(ec_key): handle_openssl_error(0) res = libcrypto.ECDSA_do_verify(digest, len(digest), ecdsa_sig, ec_key) else: evp_pkey_ctx_pointer_pointer = new(libcrypto, 'EVP_PKEY_CTX **') res = libcrypto.EVP_DigestVerifyInit( evp_md_ctx, evp_pkey_ctx_pointer_pointer, evp_md, null(), certificate_or_public_key.evp_pkey ) handle_openssl_error(res) evp_pkey_ctx_pointer = unwrap(evp_pkey_ctx_pointer_pointer) if rsa_pss_padding: # Enable PSS padding res = libcrypto.EVP_PKEY_CTX_ctrl( evp_pkey_ctx_pointer, LibcryptoConst.EVP_PKEY_RSA, -1, # All operations LibcryptoConst.EVP_PKEY_CTRL_RSA_PADDING, LibcryptoConst.RSA_PKCS1_PSS_PADDING, null() ) handle_openssl_error(res) # Use the hash algorithm output length as the salt length if libcrypto_version_info < (3, 0): res = libcrypto.EVP_PKEY_CTX_ctrl( evp_pkey_ctx_pointer, LibcryptoConst.EVP_PKEY_RSA, LibcryptoConst.EVP_PKEY_OP_SIGN | LibcryptoConst.EVP_PKEY_OP_VERIFY, LibcryptoConst.EVP_PKEY_CTRL_RSA_PSS_SALTLEN, -1, null() ) handle_openssl_error(res) res = libcrypto.EVP_DigestUpdate(evp_md_ctx, data, len(data)) handle_openssl_error(res) res = libcrypto.EVP_DigestVerifyFinal(evp_md_ctx, signature, len(signature)) if res < 1: raise SignatureError('Signature is invalid') handle_openssl_error(res) finally: if evp_md_ctx: if libcrypto_version_info < (1, 1): libcrypto.EVP_MD_CTX_destroy(evp_md_ctx) else: libcrypto.EVP_MD_CTX_free(evp_md_ctx) if rsa: libcrypto.RSA_free(rsa) if dsa: libcrypto.DSA_free(dsa) if dsa_sig: libcrypto.DSA_SIG_free(dsa_sig) if ec_key: libcrypto.EC_KEY_free(ec_key) if ecdsa_sig: libcrypto.ECDSA_SIG_free(ecdsa_sig) def rsa_pkcs1v15_sign(private_key, data, hash_algorithm): """ Generates an RSASSA-PKCS-v1.5 signature. When the hash_algorithm is "raw", the operation is identical to RSA private key encryption. That is: the data is not hashed and no ASN.1 structure with an algorithm identifier of the hash algorithm is placed in the encrypted byte string. :param private_key: The PrivateKey to generate the signature with :param data: A byte string of the data the signature is for :param hash_algorithm: A unicode string of "md5", "sha1", "sha224", "sha256", "sha384", "sha512" or "raw" :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the signature """ if private_key.algorithm != 'rsa': raise ValueError(pretty_message( ''' The key specified is not an RSA private key, but %s ''', private_key.algorithm.upper() )) return _sign(private_key, data, hash_algorithm) def rsa_pss_sign(private_key, data, hash_algorithm): """ Generates an RSASSA-PSS signature. For the PSS padding the mask gen algorithm will be mgf1 using the same hash algorithm as the signature. The salt length with be the length of the hash algorithm, and the trailer field with be the standard 0xBC byte. :param private_key: The PrivateKey to generate the signature with :param data: A byte string of the data the signature is for :param hash_algorithm: A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512" :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the signature """ pkey_alg = private_key.algorithm if pkey_alg != 'rsa' and pkey_alg != 'rsassa_pss': raise ValueError(pretty_message( ''' The key specified is not an RSA private key, but %s ''', pkey_alg.upper() )) return _sign(private_key, data, hash_algorithm, rsa_pss_padding=True) def dsa_sign(private_key, data, hash_algorithm): """ Generates a DSA signature :param private_key: The PrivateKey to generate the signature with :param data: A byte string of the data the signature is for :param hash_algorithm: A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512" :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the signature """ if private_key.algorithm != 'dsa': raise ValueError(pretty_message( ''' The key specified is not a DSA private key, but %s ''', private_key.algorithm.upper() )) return _sign(private_key, data, hash_algorithm) def ecdsa_sign(private_key, data, hash_algorithm): """ Generates an ECDSA signature :param private_key: The PrivateKey to generate the signature with :param data: A byte string of the data the signature is for :param hash_algorithm: A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512" :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the signature """ if private_key.algorithm != 'ec': raise ValueError(pretty_message( ''' The key specified is not an EC private key, but %s ''', private_key.algorithm.upper() )) return _sign(private_key, data, hash_algorithm) def _sign(private_key, data, hash_algorithm, rsa_pss_padding=False): """ Generates an RSA, DSA or ECDSA signature :param private_key: The PrivateKey to generate the signature with :param data: A byte string of the data the signature is for :param hash_algorithm: A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512" :param rsa_pss_padding: If the private_key is an RSA key, this enables PSS padding :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the signature """ if not isinstance(private_key, PrivateKey): raise TypeError(pretty_message( ''' private_key must be an instance of PrivateKey, not %s ''', type_name(private_key) )) if not isinstance(data, byte_cls): raise TypeError(pretty_message( ''' data must be a byte string, not %s ''', type_name(data) )) pkey_alg = private_key.algorithm pkey_is_rsa = pkey_alg == 'rsa' or pkey_alg == 'rsassa_pss' valid_hash_algorithms = set(['md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512']) if pkey_alg == 'rsa' and not rsa_pss_padding: valid_hash_algorithms |= set(['raw']) if hash_algorithm not in valid_hash_algorithms: valid_hash_algorithms_error = '"md5", "sha1", "sha224", "sha256", "sha384", "sha512"' if pkey_is_rsa and not rsa_pss_padding: valid_hash_algorithms_error += ', "raw"' raise ValueError(pretty_message( ''' hash_algorithm must be one of %s, not %s ''', valid_hash_algorithms_error, repr(hash_algorithm) )) if not pkey_is_rsa and rsa_pss_padding: raise ValueError(pretty_message( ''' PSS padding can only be used with RSA keys - the key provided is a %s key ''', pkey_alg.upper() )) if pkey_is_rsa and hash_algorithm == 'raw': if len(data) > private_key.byte_size - 11: raise ValueError(pretty_message( ''' data must be 11 bytes shorter than the key size when hash_algorithm is "raw" - key size is %s bytes, but data is %s bytes long ''', private_key.byte_size, len(data) )) rsa = None try: rsa = libcrypto.EVP_PKEY_get1_RSA(private_key.evp_pkey) if is_null(rsa): handle_openssl_error(0) buffer_size = _evp_pkey_get_size(private_key.evp_pkey) signature_buffer = buffer_from_bytes(buffer_size) signature_length = libcrypto.RSA_private_encrypt( len(data), data, signature_buffer, rsa, LibcryptoConst.RSA_PKCS1_PADDING ) handle_openssl_error(signature_length) return bytes_from_buffer(signature_buffer, signature_length) finally: if rsa: libcrypto.RSA_free(rsa) evp_md_ctx = None rsa = None dsa = None dsa_sig = None ec_key = None ecdsa_sig = None try: if libcrypto_version_info < (1, 1): evp_md_ctx = libcrypto.EVP_MD_CTX_create() else: evp_md_ctx = libcrypto.EVP_MD_CTX_new() evp_md = { 'md5': libcrypto.EVP_md5, 'sha1': libcrypto.EVP_sha1, 'sha224': libcrypto.EVP_sha224, 'sha256': libcrypto.EVP_sha256, 'sha384': libcrypto.EVP_sha384, 'sha512': libcrypto.EVP_sha512 }[hash_algorithm]() if libcrypto_version_info < (1,): if pkey_is_rsa and rsa_pss_padding: digest = getattr(hashlib, hash_algorithm)(data).digest() rsa = libcrypto.EVP_PKEY_get1_RSA(private_key.evp_pkey) if is_null(rsa): handle_openssl_error(0) buffer_size = _evp_pkey_get_size(private_key.evp_pkey) em_buffer = buffer_from_bytes(buffer_size) res = libcrypto.RSA_padding_add_PKCS1_PSS( rsa, em_buffer, digest, evp_md, LibcryptoConst.EVP_MD_CTX_FLAG_PSS_MDLEN ) handle_openssl_error(res) signature_buffer = buffer_from_bytes(buffer_size) signature_length = libcrypto.RSA_private_encrypt( buffer_size, em_buffer, signature_buffer, rsa, LibcryptoConst.RSA_NO_PADDING ) handle_openssl_error(signature_length) elif pkey_is_rsa: buffer_size = _evp_pkey_get_size(private_key.evp_pkey) signature_buffer = buffer_from_bytes(buffer_size) signature_length = new(libcrypto, 'unsigned int *') res = libcrypto.EVP_DigestInit_ex(evp_md_ctx, evp_md, null()) handle_openssl_error(res) res = libcrypto.EVP_DigestUpdate(evp_md_ctx, data, len(data)) handle_openssl_error(res) res = libcrypto.EVP_SignFinal( evp_md_ctx, signature_buffer, signature_length, private_key.evp_pkey ) handle_openssl_error(res) signature_length = deref(signature_length) elif pkey_alg == 'dsa': digest = getattr(hashlib, hash_algorithm)(data).digest() dsa = libcrypto.EVP_PKEY_get1_DSA(private_key.evp_pkey) if is_null(dsa): handle_openssl_error(0) dsa_sig = libcrypto.DSA_do_sign(digest, len(digest), dsa) if is_null(dsa_sig): handle_openssl_error(0) buffer_size = libcrypto.i2d_DSA_SIG(dsa_sig, null()) signature_buffer = buffer_from_bytes(buffer_size) signature_pointer = buffer_pointer(signature_buffer) signature_length = libcrypto.i2d_DSA_SIG(dsa_sig, signature_pointer) handle_openssl_error(signature_length) elif pkey_alg == 'ec': digest = getattr(hashlib, hash_algorithm)(data).digest() ec_key = libcrypto.EVP_PKEY_get1_EC_KEY(private_key.evp_pkey) if is_null(ec_key): handle_openssl_error(0) ecdsa_sig = libcrypto.ECDSA_do_sign(digest, len(digest), ec_key) if is_null(ecdsa_sig): handle_openssl_error(0) buffer_size = libcrypto.i2d_ECDSA_SIG(ecdsa_sig, null()) signature_buffer = buffer_from_bytes(buffer_size) signature_pointer = buffer_pointer(signature_buffer) signature_length = libcrypto.i2d_ECDSA_SIG(ecdsa_sig, signature_pointer) handle_openssl_error(signature_length) else: buffer_size = _evp_pkey_get_size(private_key.evp_pkey) signature_buffer = buffer_from_bytes(buffer_size) signature_length = new(libcrypto, 'size_t *', buffer_size) evp_pkey_ctx_pointer_pointer = new(libcrypto, 'EVP_PKEY_CTX **') res = libcrypto.EVP_DigestSignInit( evp_md_ctx, evp_pkey_ctx_pointer_pointer, evp_md, null(), private_key.evp_pkey ) handle_openssl_error(res) evp_pkey_ctx_pointer = unwrap(evp_pkey_ctx_pointer_pointer) if rsa_pss_padding: # Enable PSS padding res = libcrypto.EVP_PKEY_CTX_ctrl( evp_pkey_ctx_pointer, LibcryptoConst.EVP_PKEY_RSA, -1, # All operations LibcryptoConst.EVP_PKEY_CTRL_RSA_PADDING, LibcryptoConst.RSA_PKCS1_PSS_PADDING, null() ) handle_openssl_error(res) # Use the hash algorithm output length as the salt length if libcrypto_version_info < (3, 0): res = libcrypto.EVP_PKEY_CTX_ctrl( evp_pkey_ctx_pointer, LibcryptoConst.EVP_PKEY_RSA, LibcryptoConst.EVP_PKEY_OP_SIGN | LibcryptoConst.EVP_PKEY_OP_VERIFY, LibcryptoConst.EVP_PKEY_CTRL_RSA_PSS_SALTLEN, -1, null() ) handle_openssl_error(res) res = libcrypto.EVP_DigestUpdate(evp_md_ctx, data, len(data)) handle_openssl_error(res) res = libcrypto.EVP_DigestSignFinal(evp_md_ctx, signature_buffer, signature_length) handle_openssl_error(res) signature_length = deref(signature_length) return bytes_from_buffer(signature_buffer, signature_length) finally: if evp_md_ctx: if libcrypto_version_info < (1, 1): libcrypto.EVP_MD_CTX_destroy(evp_md_ctx) else: libcrypto.EVP_MD_CTX_free(evp_md_ctx) if rsa: libcrypto.RSA_free(rsa) if dsa: libcrypto.DSA_free(dsa) if dsa_sig: libcrypto.DSA_SIG_free(dsa_sig) if ec_key: libcrypto.EC_KEY_free(ec_key) if ecdsa_sig: libcrypto.ECDSA_SIG_free(ecdsa_sig) symmetric.py000064400000055630147205320040007140 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import math from .._errors import pretty_message from .._ffi import new, null, is_null, buffer_from_bytes, bytes_from_buffer, deref from ._libcrypto import libcrypto, libcrypto_legacy_support, LibcryptoConst, handle_openssl_error from ..util import rand_bytes from .._types import type_name, byte_cls __all__ = [ 'aes_cbc_no_padding_decrypt', 'aes_cbc_no_padding_encrypt', 'aes_cbc_pkcs7_decrypt', 'aes_cbc_pkcs7_encrypt', 'des_cbc_pkcs5_decrypt', 'des_cbc_pkcs5_encrypt', 'rc2_cbc_pkcs5_decrypt', 'rc2_cbc_pkcs5_encrypt', 'rc4_decrypt', 'rc4_encrypt', 'tripledes_cbc_pkcs5_decrypt', 'tripledes_cbc_pkcs5_encrypt', ] def aes_cbc_no_padding_encrypt(key, data, iv): """ Encrypts plaintext using AES in CBC mode with a 128, 192 or 256 bit key and no padding. This means the ciphertext must be an exact multiple of 16 bytes long. :param key: The encryption key - a byte string either 16, 24 or 32 bytes long :param data: The plaintext - a byte string :param iv: The initialization vector - either a byte string 16-bytes long or None to generate an IV :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A tuple of two byte strings (iv, ciphertext) """ cipher = _calculate_aes_cipher(key) if not iv: iv = rand_bytes(16) elif len(iv) != 16: raise ValueError(pretty_message( ''' iv must be 16 bytes long - is %s ''', len(iv) )) if len(data) % 16 != 0: raise ValueError(pretty_message( ''' data must be a multiple of 16 bytes long - is %s ''', len(data) )) return (iv, _encrypt(cipher, key, data, iv, False)) def aes_cbc_no_padding_decrypt(key, data, iv): """ Decrypts AES ciphertext in CBC mode using a 128, 192 or 256 bit key and no padding. :param key: The encryption key - a byte string either 16, 24 or 32 bytes long :param data: The ciphertext - a byte string :param iv: The initialization vector - a byte string 16-bytes long :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A byte string of the plaintext """ cipher = _calculate_aes_cipher(key) if len(iv) != 16: raise ValueError(pretty_message( ''' iv must be 16 bytes long - is %s ''', len(iv) )) return _decrypt(cipher, key, data, iv, False) def aes_cbc_pkcs7_encrypt(key, data, iv): """ Encrypts plaintext using AES in CBC mode with a 128, 192 or 256 bit key and PKCS#7 padding. :param key: The encryption key - a byte string either 16, 24 or 32 bytes long :param data: The plaintext - a byte string :param iv: The initialization vector - either a byte string 16-bytes long or None to generate an IV :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A tuple of two byte strings (iv, ciphertext) """ cipher = _calculate_aes_cipher(key) if not iv: iv = rand_bytes(16) elif len(iv) != 16: raise ValueError(pretty_message( ''' iv must be 16 bytes long - is %s ''', len(iv) )) return (iv, _encrypt(cipher, key, data, iv, True)) def aes_cbc_pkcs7_decrypt(key, data, iv): """ Decrypts AES ciphertext in CBC mode using a 128, 192 or 256 bit key :param key: The encryption key - a byte string either 16, 24 or 32 bytes long :param data: The ciphertext - a byte string :param iv: The initialization vector - a byte string 16-bytes long :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A byte string of the plaintext """ cipher = _calculate_aes_cipher(key) if len(iv) != 16: raise ValueError(pretty_message( ''' iv must be 16 bytes long - is %s ''', len(iv) )) return _decrypt(cipher, key, data, iv, True) def _calculate_aes_cipher(key): """ Determines if the key is a valid AES 128, 192 or 256 key :param key: A byte string of the key to use :raises: ValueError - when an invalid key is provided :return: A unicode string of the AES variation - "aes128", "aes192" or "aes256" """ if len(key) not in [16, 24, 32]: raise ValueError(pretty_message( ''' key must be either 16, 24 or 32 bytes (128, 192 or 256 bits) long - is %s ''', len(key) )) if len(key) == 16: cipher = 'aes128' elif len(key) == 24: cipher = 'aes192' elif len(key) == 32: cipher = 'aes256' return cipher def rc4_encrypt(key, data): """ Encrypts plaintext using RC4 with a 40-128 bit key :param key: The encryption key - a byte string 5-16 bytes long :param data: The plaintext - a byte string :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A byte string of the ciphertext """ if not libcrypto_legacy_support: raise EnvironmentError('OpenSSL has been compiled without RC4 support') if len(key) < 5 or len(key) > 16: raise ValueError(pretty_message( ''' key must be 5 to 16 bytes (40 to 128 bits) long - is %s ''', len(key) )) return _encrypt('rc4', key, data, None, None) def rc4_decrypt(key, data): """ Decrypts RC4 ciphertext using a 40-128 bit key :param key: The encryption key - a byte string 5-16 bytes long :param data: The ciphertext - a byte string :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A byte string of the plaintext """ if not libcrypto_legacy_support: raise EnvironmentError('OpenSSL has been compiled without RC4 support') if len(key) < 5 or len(key) > 16: raise ValueError(pretty_message( ''' key must be 5 to 16 bytes (40 to 128 bits) long - is %s ''', len(key) )) return _decrypt('rc4', key, data, None, None) def rc2_cbc_pkcs5_encrypt(key, data, iv): """ Encrypts plaintext using RC2 in CBC mode with a 40-128 bit key and PKCS#5 padding. :param key: The encryption key - a byte string 8 bytes long :param data: The plaintext - a byte string :param iv: The initialization vector - a byte string 8-bytes long or None to generate an IV :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A tuple of two byte strings (iv, ciphertext) """ if not libcrypto_legacy_support: raise EnvironmentError('OpenSSL has been compiled without RC2 support') if len(key) < 5 or len(key) > 16: raise ValueError(pretty_message( ''' key must be 5 to 16 bytes (40 to 128 bits) long - is %s ''', len(key) )) if not iv: iv = rand_bytes(8) elif len(iv) != 8: raise ValueError(pretty_message( ''' iv must be 8 bytes long - is %s ''', len(iv) )) return (iv, _encrypt('rc2', key, data, iv, True)) def rc2_cbc_pkcs5_decrypt(key, data, iv): """ Decrypts RC2 ciphertext ib CBC mode using a 40-128 bit key and PKCS#5 padding. :param key: The encryption key - a byte string 8 bytes long :param data: The ciphertext - a byte string :param iv: The initialization vector - a byte string 8 bytes long :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A byte string of the plaintext """ if not libcrypto_legacy_support: raise EnvironmentError('OpenSSL has been compiled without RC2 support') if len(key) < 5 or len(key) > 16: raise ValueError(pretty_message( ''' key must be 5 to 16 bytes (40 to 128 bits) long - is %s ''', len(key) )) if len(iv) != 8: raise ValueError(pretty_message( ''' iv must be 8 bytes long - is %s ''', len(iv) )) return _decrypt('rc2', key, data, iv, True) def tripledes_cbc_pkcs5_encrypt(key, data, iv): """ Encrypts plaintext using 3DES in CBC mode using either the 2 or 3 key variant (16 or 24 byte long key) and PKCS#5 padding. :param key: The encryption key - a byte string 16 or 24 bytes long (2 or 3 key mode) :param data: The plaintext - a byte string :param iv: The initialization vector - a byte string 8-bytes long or None to generate an IV :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A tuple of two byte strings (iv, ciphertext) """ if len(key) != 16 and len(key) != 24: raise ValueError(pretty_message( ''' key must be 16 bytes (2 key) or 24 bytes (3 key) long - %s ''', len(key) )) if not iv: iv = rand_bytes(8) elif len(iv) != 8: raise ValueError(pretty_message( ''' iv must be 8 bytes long - %s ''', len(iv) )) cipher = 'tripledes_3key' # Expand 2-key to actual 24 byte byte string used by cipher if len(key) == 16: key = key + key[0:8] cipher = 'tripledes_2key' return (iv, _encrypt(cipher, key, data, iv, True)) def tripledes_cbc_pkcs5_decrypt(key, data, iv): """ Decrypts 3DES ciphertext in CBC mode using either the 2 or 3 key variant (16 or 24 byte long key) and PKCS#5 padding. :param key: The encryption key - a byte string 16 or 24 bytes long (2 or 3 key mode) :param data: The ciphertext - a byte string :param iv: The initialization vector - a byte string 8-bytes long :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A byte string of the plaintext """ if len(key) != 16 and len(key) != 24: raise ValueError(pretty_message( ''' key must be 16 bytes (2 key) or 24 bytes (3 key) long - is %s ''', len(key) )) if len(iv) != 8: raise ValueError(pretty_message( ''' iv must be 8 bytes long - is %s ''', len(iv) )) cipher = 'tripledes_3key' # Expand 2-key to actual 24 byte byte string used by cipher if len(key) == 16: key = key + key[0:8] cipher = 'tripledes_2key' return _decrypt(cipher, key, data, iv, True) def des_cbc_pkcs5_encrypt(key, data, iv): """ Encrypts plaintext using DES in CBC mode with a 56 bit key and PKCS#5 padding. :param key: The encryption key - a byte string 8 bytes long (includes error correction bits) :param data: The plaintext - a byte string :param iv: The initialization vector - a byte string 8-bytes long or None to generate an IV :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A tuple of two byte strings (iv, ciphertext) """ if not libcrypto_legacy_support: raise EnvironmentError('OpenSSL has been compiled without DES support') if len(key) != 8: raise ValueError(pretty_message( ''' key must be 8 bytes (56 bits + 8 parity bits) long - is %s ''', len(key) )) if not iv: iv = rand_bytes(8) elif len(iv) != 8: raise ValueError(pretty_message( ''' iv must be 8 bytes long - is %s ''', len(iv) )) return (iv, _encrypt('des', key, data, iv, True)) def des_cbc_pkcs5_decrypt(key, data, iv): """ Decrypts DES ciphertext in CBC mode using a 56 bit key and PKCS#5 padding. :param key: The encryption key - a byte string 8 bytes long (includes error correction bits) :param data: The ciphertext - a byte string :param iv: The initialization vector - a byte string 8-bytes long :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A byte string of the plaintext """ if not libcrypto_legacy_support: raise EnvironmentError('OpenSSL has been compiled without DES support') if len(key) != 8: raise ValueError(pretty_message( ''' key must be 8 bytes (56 bits + 8 parity bits) long - is %s ''', len(key) )) if len(iv) != 8: raise ValueError(pretty_message( ''' iv must be 8 bytes long - is %s ''', len(iv) )) return _decrypt('des', key, data, iv, True) def _encrypt(cipher, key, data, iv, padding): """ Encrypts plaintext :param cipher: A unicode string of "aes128", "aes192", "aes256", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: The encryption key - a byte string 5-32 bytes long :param data: The plaintext - a byte string :param iv: The initialization vector - a byte string - unused for RC4 :param padding: Boolean, if padding should be used - unused for RC4 :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A byte string of the ciphertext """ if not isinstance(key, byte_cls): raise TypeError(pretty_message( ''' key must be a byte string, not %s ''', type_name(key) )) if not isinstance(data, byte_cls): raise TypeError(pretty_message( ''' data must be a byte string, not %s ''', type_name(data) )) if cipher != 'rc4' and not isinstance(iv, byte_cls): raise TypeError(pretty_message( ''' iv must be a byte string, not %s ''', type_name(iv) )) if cipher != 'rc4' and not padding: # AES in CBC mode can be allowed with no padding if # the data is an exact multiple of the block size is_aes = cipher in set(['aes128', 'aes192', 'aes256']) if not is_aes or (is_aes and (len(data) % 16) != 0): raise ValueError('padding must be specified') evp_cipher_ctx = None try: evp_cipher_ctx = libcrypto.EVP_CIPHER_CTX_new() if is_null(evp_cipher_ctx): handle_openssl_error(0) evp_cipher, buffer_size = _setup_evp_encrypt_decrypt(cipher, data) if iv is None: iv = null() if cipher in set(['rc2', 'rc4']): res = libcrypto.EVP_EncryptInit_ex(evp_cipher_ctx, evp_cipher, null(), null(), null()) handle_openssl_error(res) res = libcrypto.EVP_CIPHER_CTX_set_key_length(evp_cipher_ctx, len(key)) handle_openssl_error(res) if cipher == 'rc2': res = libcrypto.EVP_CIPHER_CTX_ctrl( evp_cipher_ctx, LibcryptoConst.EVP_CTRL_SET_RC2_KEY_BITS, len(key) * 8, null() ) handle_openssl_error(res) evp_cipher = null() res = libcrypto.EVP_EncryptInit_ex(evp_cipher_ctx, evp_cipher, null(), key, iv) handle_openssl_error(res) if padding is not None: res = libcrypto.EVP_CIPHER_CTX_set_padding(evp_cipher_ctx, int(padding)) handle_openssl_error(res) buffer = buffer_from_bytes(buffer_size) output_length = new(libcrypto, 'int *') res = libcrypto.EVP_EncryptUpdate(evp_cipher_ctx, buffer, output_length, data, len(data)) handle_openssl_error(res) output = bytes_from_buffer(buffer, deref(output_length)) res = libcrypto.EVP_EncryptFinal_ex(evp_cipher_ctx, buffer, output_length) handle_openssl_error(res) output += bytes_from_buffer(buffer, deref(output_length)) return output finally: if evp_cipher_ctx: libcrypto.EVP_CIPHER_CTX_free(evp_cipher_ctx) def _decrypt(cipher, key, data, iv, padding): """ Decrypts AES/RC4/RC2/3DES/DES ciphertext :param cipher: A unicode string of "aes128", "aes192", "aes256", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: The encryption key - a byte string 5-32 bytes long :param data: The ciphertext - a byte string :param iv: The initialization vector - a byte string - unused for RC4 :param padding: Boolean, if padding should be used - unused for RC4 :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A byte string of the plaintext """ if not isinstance(key, byte_cls): raise TypeError(pretty_message( ''' key must be a byte string, not %s ''', type_name(key) )) if not isinstance(data, byte_cls): raise TypeError(pretty_message( ''' data must be a byte string, not %s ''', type_name(data) )) if cipher != 'rc4' and not isinstance(iv, byte_cls): raise TypeError(pretty_message( ''' iv must be a byte string, not %s ''', type_name(iv) )) if cipher not in set(['rc4', 'aes128', 'aes192', 'aes256']) and not padding: raise ValueError('padding must be specified') evp_cipher_ctx = None try: evp_cipher_ctx = libcrypto.EVP_CIPHER_CTX_new() if is_null(evp_cipher_ctx): handle_openssl_error(0) evp_cipher, buffer_size = _setup_evp_encrypt_decrypt(cipher, data) if iv is None: iv = null() if cipher in set(['rc2', 'rc4']): res = libcrypto.EVP_DecryptInit_ex(evp_cipher_ctx, evp_cipher, null(), null(), null()) handle_openssl_error(res) res = libcrypto.EVP_CIPHER_CTX_set_key_length(evp_cipher_ctx, len(key)) handle_openssl_error(res) if cipher == 'rc2': res = libcrypto.EVP_CIPHER_CTX_ctrl( evp_cipher_ctx, LibcryptoConst.EVP_CTRL_SET_RC2_KEY_BITS, len(key) * 8, null() ) handle_openssl_error(res) evp_cipher = null() res = libcrypto.EVP_DecryptInit_ex(evp_cipher_ctx, evp_cipher, null(), key, iv) handle_openssl_error(res) if padding is not None: res = libcrypto.EVP_CIPHER_CTX_set_padding(evp_cipher_ctx, int(padding)) handle_openssl_error(res) buffer = buffer_from_bytes(buffer_size) output_length = new(libcrypto, 'int *') res = libcrypto.EVP_DecryptUpdate(evp_cipher_ctx, buffer, output_length, data, len(data)) handle_openssl_error(res) output = bytes_from_buffer(buffer, deref(output_length)) res = libcrypto.EVP_DecryptFinal_ex(evp_cipher_ctx, buffer, output_length) handle_openssl_error(res) output += bytes_from_buffer(buffer, deref(output_length)) return output finally: if evp_cipher_ctx: libcrypto.EVP_CIPHER_CTX_free(evp_cipher_ctx) def _setup_evp_encrypt_decrypt(cipher, data): """ Creates an EVP_CIPHER pointer object and determines the buffer size necessary for the parameter specified. :param evp_cipher_ctx: An EVP_CIPHER_CTX pointer :param cipher: A unicode string of "aes128", "aes192", "aes256", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: The key byte string :param data: The plaintext or ciphertext as a byte string :param padding: If padding is to be used :return: A 2-element tuple with the first element being an EVP_CIPHER pointer and the second being an integer that is the required buffer size """ evp_cipher = { 'aes128': libcrypto.EVP_aes_128_cbc, 'aes192': libcrypto.EVP_aes_192_cbc, 'aes256': libcrypto.EVP_aes_256_cbc, 'rc2': libcrypto.EVP_rc2_cbc, 'rc4': libcrypto.EVP_rc4, 'des': libcrypto.EVP_des_cbc, 'tripledes_2key': libcrypto.EVP_des_ede_cbc, 'tripledes_3key': libcrypto.EVP_des_ede3_cbc, }[cipher]() if cipher == 'rc4': buffer_size = len(data) else: block_size = { 'aes128': 16, 'aes192': 16, 'aes256': 16, 'rc2': 8, 'des': 8, 'tripledes_2key': 8, 'tripledes_3key': 8, }[cipher] buffer_size = block_size * int(math.ceil(len(data) / block_size)) return (evp_cipher, buffer_size) tls.py000064400000126601147205320040005723 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import sys import re import socket as socket_ import select import numbers from ._libssl import libssl, LibsslConst from ._libcrypto import libcrypto, libcrypto_version_info, handle_openssl_error, peek_openssl_error from .. import _backend_config from .._asn1 import Certificate as Asn1Certificate from .._errors import pretty_message from .._ffi import null, bytes_from_buffer, buffer_from_bytes, is_null, buffer_pointer from .._types import type_name, str_cls, byte_cls, int_types from ..errors import TLSError, TLSDisconnectError, TLSGracefulDisconnectError from .._tls import ( detect_client_auth_request, extract_chain, get_dh_params_length, parse_session_info, raise_client_auth, raise_dh_params, raise_disconnection, raise_expired_not_yet_valid, raise_handshake, raise_hostname, raise_no_issuer, raise_protocol_error, raise_protocol_version, raise_self_signed, raise_verification, raise_weak_signature, parse_tls_records, parse_handshake_messages, ) from .asymmetric import load_certificate, Certificate from ..keys import parse_certificate from ..trust_list import get_path if sys.version_info < (3,): range = xrange # noqa if sys.version_info < (3, 7): Pattern = re._pattern_type else: Pattern = re.Pattern __all__ = [ 'TLSSession', 'TLSSocket', ] _trust_list_path = _backend_config().get('trust_list_path') _line_regex = re.compile(b'(\r\n|\r|\n)') _PROTOCOL_MAP = { 'SSLv2': LibsslConst.SSL_OP_NO_SSLv2, 'SSLv3': LibsslConst.SSL_OP_NO_SSLv3, 'TLSv1': LibsslConst.SSL_OP_NO_TLSv1, 'TLSv1.1': LibsslConst.SSL_OP_NO_TLSv1_1, 'TLSv1.2': LibsslConst.SSL_OP_NO_TLSv1_2, } def _homogenize_openssl3_error(error_tuple): """ Takes a 3-element tuple from peek_openssl_error() and modifies it to handle the changes in OpenSSL 3.0. That release removed the concept of an error function, meaning the second item in the tuple will always be 0. :param error_tuple: A 3-element tuple of integers :return: A 3-element tuple of integers """ if libcrypto_version_info < (3,): return error_tuple return (error_tuple[0], 0, error_tuple[2]) class TLSSession(object): """ A TLS session object that multiple TLSSocket objects can share for the sake of session reuse """ _protocols = None _ciphers = None _manual_validation = None _extra_trust_roots = None _ssl_ctx = None _ssl_session = None def __init__(self, protocol=None, manual_validation=False, extra_trust_roots=None): """ :param protocol: A unicode string or set of unicode strings representing allowable protocols to negotiate with the server: - "TLSv1.2" - "TLSv1.1" - "TLSv1" - "SSLv3" Default is: {"TLSv1", "TLSv1.1", "TLSv1.2"} :param manual_validation: If certificate and certificate path validation should be skipped and left to the developer to implement :param extra_trust_roots: A list containing one or more certificates to be treated as trust roots, in one of the following formats: - A byte string of the DER encoded certificate - A unicode string of the certificate filename - An asn1crypto.x509.Certificate object - An oscrypto.asymmetric.Certificate object :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library """ if not isinstance(manual_validation, bool): raise TypeError(pretty_message( ''' manual_validation must be a boolean, not %s ''', type_name(manual_validation) )) self._manual_validation = manual_validation if protocol is None: protocol = set(['TLSv1', 'TLSv1.1', 'TLSv1.2']) if isinstance(protocol, str_cls): protocol = set([protocol]) elif not isinstance(protocol, set): raise TypeError(pretty_message( ''' protocol must be a unicode string or set of unicode strings, not %s ''', type_name(protocol) )) valid_protocols = set(['SSLv3', 'TLSv1', 'TLSv1.1', 'TLSv1.2']) unsupported_protocols = protocol - valid_protocols if unsupported_protocols: raise ValueError(pretty_message( ''' protocol must contain only the unicode strings "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2", not %s ''', repr(unsupported_protocols) )) self._protocols = protocol self._extra_trust_roots = [] if extra_trust_roots: for extra_trust_root in extra_trust_roots: if isinstance(extra_trust_root, Certificate): extra_trust_root = extra_trust_root.asn1 elif isinstance(extra_trust_root, byte_cls): extra_trust_root = parse_certificate(extra_trust_root) elif isinstance(extra_trust_root, str_cls): with open(extra_trust_root, 'rb') as f: extra_trust_root = parse_certificate(f.read()) elif not isinstance(extra_trust_root, Asn1Certificate): raise TypeError(pretty_message( ''' extra_trust_roots must be a list of byte strings, unicode strings, asn1crypto.x509.Certificate objects or oscrypto.asymmetric.Certificate objects, not %s ''', type_name(extra_trust_root) )) self._extra_trust_roots.append(extra_trust_root) ssl_ctx = None try: if libcrypto_version_info < (1, 1): method = libssl.SSLv23_method() else: method = libssl.TLS_method() ssl_ctx = libssl.SSL_CTX_new(method) if is_null(ssl_ctx): handle_openssl_error(0) self._ssl_ctx = ssl_ctx libssl.SSL_CTX_set_timeout(ssl_ctx, 600) # Allow caching SSL sessions libssl.SSL_CTX_ctrl( ssl_ctx, LibsslConst.SSL_CTRL_SET_SESS_CACHE_MODE, LibsslConst.SSL_SESS_CACHE_CLIENT, null() ) if sys.platform in set(['win32', 'darwin']): trust_list_path = _trust_list_path if trust_list_path is None: trust_list_path = get_path() if sys.platform == 'win32': path_encoding = 'mbcs' else: path_encoding = 'utf-8' result = libssl.SSL_CTX_load_verify_locations( ssl_ctx, trust_list_path.encode(path_encoding), null() ) else: result = libssl.SSL_CTX_set_default_verify_paths(ssl_ctx) handle_openssl_error(result) verify_mode = LibsslConst.SSL_VERIFY_NONE if manual_validation else LibsslConst.SSL_VERIFY_PEER libssl.SSL_CTX_set_verify(ssl_ctx, verify_mode, null()) # Modern cipher suite list from https://wiki.mozilla.org/Security/Server_Side_TLS late August 2015 result = libssl.SSL_CTX_set_cipher_list( ssl_ctx, ( b'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:' b'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:' b'DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:' b'kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:' b'ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:' b'ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:' b'DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:' b'DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:' b'AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:' b'AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:' b'!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:' b'!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA' ) ) handle_openssl_error(result) disabled_protocols = set(['SSLv2']) disabled_protocols |= (valid_protocols - self._protocols) for disabled_protocol in disabled_protocols: libssl.SSL_CTX_ctrl( ssl_ctx, LibsslConst.SSL_CTRL_OPTIONS, _PROTOCOL_MAP[disabled_protocol], null() ) if self._extra_trust_roots: x509_store = libssl.SSL_CTX_get_cert_store(ssl_ctx) for cert in self._extra_trust_roots: oscrypto_cert = load_certificate(cert) result = libssl.X509_STORE_add_cert( x509_store, oscrypto_cert.x509 ) handle_openssl_error(result) except (Exception): if ssl_ctx: libssl.SSL_CTX_free(ssl_ctx) self._ssl_ctx = None raise def __del__(self): if self._ssl_ctx: libssl.SSL_CTX_free(self._ssl_ctx) self._ssl_ctx = None if self._ssl_session: libssl.SSL_SESSION_free(self._ssl_session) self._ssl_session = None class TLSSocket(object): """ A wrapper around a socket.socket that adds TLS """ _socket = None # An oscrypto.tls.TLSSession object _session = None # An OpenSSL SSL struct pointer _ssl = None # OpenSSL memory bios used for reading/writing data to and # from the socket _rbio = None _wbio = None # Size of _bio_write_buffer and _read_buffer _buffer_size = 8192 # A buffer used to pull bytes out of the _wbio memory bio to # be written to the socket _bio_write_buffer = None # A buffer used to push bytes into the _rbio memory bio to # be decrypted by OpenSSL _read_buffer = None # Raw ciphertext from the socker that hasn't need fed to OpenSSL yet _raw_bytes = None # Plaintext that has been decrypted, but not asked for yet _decrypted_bytes = None _hostname = None _certificate = None _intermediates = None _protocol = None _cipher_suite = None _compression = None _session_id = None _session_ticket = None # If we explicitly asked for the connection to be closed _local_closed = False _gracefully_closed = False @classmethod def wrap(cls, socket, hostname, session=None): """ Takes an existing socket and adds TLS :param socket: A socket.socket object to wrap with TLS :param hostname: A unicode string of the hostname or IP the socket is connected to :param session: An existing TLSSession object to allow for session reuse, specific protocol or manual certificate validation :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library """ if not isinstance(socket, socket_.socket): raise TypeError(pretty_message( ''' socket must be an instance of socket.socket, not %s ''', type_name(socket) )) if not isinstance(hostname, str_cls): raise TypeError(pretty_message( ''' hostname must be a unicode string, not %s ''', type_name(hostname) )) if session is not None and not isinstance(session, TLSSession): raise TypeError(pretty_message( ''' session must be an instance of oscrypto.tls.TLSSession, not %s ''', type_name(session) )) new_socket = cls(None, None, session=session) new_socket._socket = socket new_socket._hostname = hostname new_socket._handshake() return new_socket def __init__(self, address, port, timeout=10, session=None): """ :param address: A unicode string of the domain name or IP address to connect to :param port: An integer of the port number to connect to :param timeout: An integer timeout to use for the socket :param session: An oscrypto.tls.TLSSession object to allow for session reuse and controlling the protocols and validation performed """ self._raw_bytes = b'' self._decrypted_bytes = b'' if address is None and port is None: self._socket = None else: if not isinstance(address, str_cls): raise TypeError(pretty_message( ''' address must be a unicode string, not %s ''', type_name(address) )) if not isinstance(port, int_types): raise TypeError(pretty_message( ''' port must be an integer, not %s ''', type_name(port) )) if timeout is not None and not isinstance(timeout, numbers.Number): raise TypeError(pretty_message( ''' timeout must be a number, not %s ''', type_name(timeout) )) self._socket = socket_.create_connection((address, port), timeout) self._socket.settimeout(timeout) if session is None: session = TLSSession() elif not isinstance(session, TLSSession): raise TypeError(pretty_message( ''' session must be an instance of oscrypto.tls.TLSSession, not %s ''', type_name(session) )) self._session = session if self._socket: self._hostname = address self._handshake() def _handshake(self): """ Perform an initial TLS handshake """ self._ssl = None self._rbio = None self._wbio = None try: self._ssl = libssl.SSL_new(self._session._ssl_ctx) if is_null(self._ssl): self._ssl = None handle_openssl_error(0) mem_bio = libssl.BIO_s_mem() self._rbio = libssl.BIO_new(mem_bio) if is_null(self._rbio): handle_openssl_error(0) self._wbio = libssl.BIO_new(mem_bio) if is_null(self._wbio): handle_openssl_error(0) libssl.SSL_set_bio(self._ssl, self._rbio, self._wbio) utf8_domain = self._hostname.encode('utf-8') libssl.SSL_ctrl( self._ssl, LibsslConst.SSL_CTRL_SET_TLSEXT_HOSTNAME, LibsslConst.TLSEXT_NAMETYPE_host_name, utf8_domain ) libssl.SSL_set_connect_state(self._ssl) if self._session._ssl_session: libssl.SSL_set_session(self._ssl, self._session._ssl_session) self._bio_write_buffer = buffer_from_bytes(self._buffer_size) self._read_buffer = buffer_from_bytes(self._buffer_size) handshake_server_bytes = b'' handshake_client_bytes = b'' while True: result = libssl.SSL_do_handshake(self._ssl) handshake_client_bytes += self._raw_write() if result == 1: break error = libssl.SSL_get_error(self._ssl, result) if error == LibsslConst.SSL_ERROR_WANT_READ: chunk = self._raw_read() if chunk == b'': if handshake_server_bytes == b'': raise_disconnection() if detect_client_auth_request(handshake_server_bytes): raise_client_auth() raise_protocol_error(handshake_server_bytes) handshake_server_bytes += chunk elif error == LibsslConst.SSL_ERROR_WANT_WRITE: handshake_client_bytes += self._raw_write() elif error == LibsslConst.SSL_ERROR_ZERO_RETURN: self._gracefully_closed = True self._shutdown(False) self._raise_closed() else: info = peek_openssl_error() dh_key_info_1 = ( LibsslConst.ERR_LIB_SSL, LibsslConst.SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, LibsslConst.SSL_R_DH_KEY_TOO_SMALL ) dh_key_info_1 = _homogenize_openssl3_error(dh_key_info_1) dh_key_info_2 = ( LibsslConst.ERR_LIB_SSL, LibsslConst.SSL_F_TLS_PROCESS_SKE_DHE, LibsslConst.SSL_R_DH_KEY_TOO_SMALL ) dh_key_info_2 = _homogenize_openssl3_error(dh_key_info_2) dh_key_info_3 = ( LibsslConst.ERR_LIB_SSL, LibsslConst.SSL_F_SSL3_GET_KEY_EXCHANGE, LibsslConst.SSL_R_BAD_DH_P_LENGTH ) dh_key_info_3 = _homogenize_openssl3_error(dh_key_info_3) if info == dh_key_info_1 or info == dh_key_info_2 or info == dh_key_info_3: raise_dh_params() if libcrypto_version_info < (1, 1): unknown_protocol_info = ( LibsslConst.ERR_LIB_SSL, LibsslConst.SSL_F_SSL23_GET_SERVER_HELLO, LibsslConst.SSL_R_UNKNOWN_PROTOCOL ) else: unknown_protocol_info = ( LibsslConst.ERR_LIB_SSL, LibsslConst.SSL_F_SSL3_GET_RECORD, LibsslConst.SSL_R_WRONG_VERSION_NUMBER ) unknown_protocol_info = _homogenize_openssl3_error(unknown_protocol_info) if info == unknown_protocol_info: raise_protocol_error(handshake_server_bytes) tls_version_info_error = ( LibsslConst.ERR_LIB_SSL, LibsslConst.SSL_F_SSL23_GET_SERVER_HELLO, LibsslConst.SSL_R_TLSV1_ALERT_PROTOCOL_VERSION ) tls_version_info_error = _homogenize_openssl3_error(tls_version_info_error) if info == tls_version_info_error: raise_protocol_version() handshake_error_info = ( LibsslConst.ERR_LIB_SSL, LibsslConst.SSL_F_SSL23_GET_SERVER_HELLO, LibsslConst.SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE ) # OpenSSL 3.0 no longer has func codes, so this can be confused # with the following handler which needs to check for client auth if libcrypto_version_info < (3, ) and info == handshake_error_info: raise_handshake() handshake_failure_info = ( LibsslConst.ERR_LIB_SSL, LibsslConst.SSL_F_SSL3_READ_BYTES, LibsslConst.SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE ) handshake_failure_info = _homogenize_openssl3_error(handshake_failure_info) if info == handshake_failure_info: saw_client_auth = False for record_type, _, record_data in parse_tls_records(handshake_server_bytes): if record_type != b'\x16': continue for message_type, message_data in parse_handshake_messages(record_data): if message_type == b'\x0d': saw_client_auth = True break if saw_client_auth: raise_client_auth() raise_handshake() if libcrypto_version_info < (1, 1): cert_verify_failed_info = ( LibsslConst.ERR_LIB_SSL, LibsslConst.SSL_F_SSL3_GET_SERVER_CERTIFICATE, LibsslConst.SSL_R_CERTIFICATE_VERIFY_FAILED ) else: cert_verify_failed_info = ( LibsslConst.ERR_LIB_SSL, LibsslConst.SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, LibsslConst.SSL_R_CERTIFICATE_VERIFY_FAILED ) cert_verify_failed_info = _homogenize_openssl3_error(cert_verify_failed_info) # It would appear that some versions of OpenSSL (such as on Fedora 30) # don't even have the MD5 digest algorithm included any longer? To # give a more useful error message we handle this specifically. unknown_hash_algo_info = ( LibsslConst.ERR_LIB_ASN1, LibsslConst.ASN1_F_ASN1_ITEM_VERIFY, LibsslConst.ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM ) unknown_hash_algo_info = _homogenize_openssl3_error(unknown_hash_algo_info) if info == unknown_hash_algo_info: chain = extract_chain(handshake_server_bytes) if chain: cert = chain[0] oscrypto_cert = load_certificate(cert) if oscrypto_cert.asn1.hash_algo in set(['md5', 'md2']): raise_weak_signature(oscrypto_cert) if info == cert_verify_failed_info: verify_result = libssl.SSL_get_verify_result(self._ssl) chain = extract_chain(handshake_server_bytes) self_signed = False time_invalid = False no_issuer = False cert = None oscrypto_cert = None if chain: cert = chain[0] oscrypto_cert = load_certificate(cert) self_signed = oscrypto_cert.self_signed issuer_error_codes = set([ LibsslConst.X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT, LibsslConst.X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN, LibsslConst.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY ]) if verify_result in issuer_error_codes: no_issuer = not self_signed time_error_codes = set([ LibsslConst.X509_V_ERR_CERT_HAS_EXPIRED, LibsslConst.X509_V_ERR_CERT_NOT_YET_VALID ]) time_invalid = verify_result in time_error_codes if time_invalid: raise_expired_not_yet_valid(cert) if no_issuer: raise_no_issuer(cert) if self_signed: raise_self_signed(cert) if oscrypto_cert and oscrypto_cert.asn1.hash_algo in set(['md5', 'md2']): raise_weak_signature(oscrypto_cert) raise_verification(cert) handle_openssl_error(0, TLSError) session_info = parse_session_info( handshake_server_bytes, handshake_client_bytes ) self._protocol = session_info['protocol'] self._cipher_suite = session_info['cipher_suite'] self._compression = session_info['compression'] self._session_id = session_info['session_id'] self._session_ticket = session_info['session_ticket'] if self._cipher_suite.find('_DHE_') != -1: dh_params_length = get_dh_params_length(handshake_server_bytes) if dh_params_length < 1024: self.close() raise_dh_params() # When saving the session for future requests, we use # SSL_get1_session() variant to increase the reference count. This # prevents the session from being freed when one connection closes # before another is opened. However, since we increase the ref # count, we also have to explicitly free any previous session. if self._session_id == 'new' or self._session_ticket == 'new': if self._session._ssl_session: libssl.SSL_SESSION_free(self._session._ssl_session) self._session._ssl_session = libssl.SSL_get1_session(self._ssl) if not self._session._manual_validation: if self.certificate.hash_algo in set(['md5', 'md2']): raise_weak_signature(self.certificate) # OpenSSL does not do hostname or IP address checking in the end # entity certificate, so we must perform that check if not self.certificate.is_valid_domain_ip(self._hostname): raise_hostname(self.certificate, self._hostname) except (OSError, socket_.error): if self._ssl: libssl.SSL_free(self._ssl) self._ssl = None self._rbio = None self._wbio = None # The BIOs are freed by SSL_free(), so we only need to free # them if for some reason SSL_free() was not called else: if self._rbio: libssl.BIO_free(self._rbio) self._rbio = None if self._wbio: libssl.BIO_free(self._wbio) self._wbio = None self.close() raise def _raw_read(self): """ Reads data from the socket and writes it to the memory bio used by libssl to decrypt the data. Returns the unencrypted data for the purpose of debugging handshakes. :return: A byte string of ciphertext from the socket. Used for debugging the handshake only. """ data = self._raw_bytes try: data += self._socket.recv(8192) except (socket_.error): pass output = data written = libssl.BIO_write(self._rbio, data, len(data)) self._raw_bytes = data[written:] return output def _raw_write(self): """ Takes ciphertext from the memory bio and writes it to the socket. :return: A byte string of ciphertext going to the socket. Used for debugging the handshake only. """ data_available = libssl.BIO_ctrl_pending(self._wbio) if data_available == 0: return b'' to_read = min(self._buffer_size, data_available) read = libssl.BIO_read(self._wbio, self._bio_write_buffer, to_read) to_write = bytes_from_buffer(self._bio_write_buffer, read) output = to_write while len(to_write): raise_disconnect = False try: sent = self._socket.send(to_write) except (socket_.error) as e: # Handle ECONNRESET and EPIPE if e.errno == 104 or e.errno == 32: raise_disconnect = True # Handle EPROTOTYPE. Newer versions of macOS will return this # if we try to call send() while the socket is being torn down elif sys.platform == 'darwin' and e.errno == 41: raise_disconnect = True else: raise if raise_disconnect: raise_disconnection() to_write = to_write[sent:] if len(to_write): self.select_write() return output def read(self, max_length): """ Reads data from the TLS-wrapped socket :param max_length: The number of bytes to read - output may be less than this :raises: socket.socket - when a non-TLS socket error occurs oscrypto.errors.TLSError - when a TLS-related error occurs ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the data read """ if not isinstance(max_length, int_types): raise TypeError(pretty_message( ''' max_length must be an integer, not %s ''', type_name(max_length) )) buffered_length = len(self._decrypted_bytes) # If we already have enough buffered data, just use that if buffered_length >= max_length: output = self._decrypted_bytes[0:max_length] self._decrypted_bytes = self._decrypted_bytes[max_length:] return output if self._ssl is None: self._raise_closed() # Don't block if we have buffered data available, since it is ok to # return less than the max_length if buffered_length > 0 and not self.select_read(0): output = self._decrypted_bytes self._decrypted_bytes = b'' return output # Only read enough to get the requested amount when # combined with buffered data to_read = min(self._buffer_size, max_length - buffered_length) output = self._decrypted_bytes # The SSL_read() loop handles renegotiations, so we need to handle # requests for both reads and writes again = True while again: again = False result = libssl.SSL_read(self._ssl, self._read_buffer, to_read) self._raw_write() if result <= 0: error = libssl.SSL_get_error(self._ssl, result) if error == LibsslConst.SSL_ERROR_WANT_READ: if self._raw_read() != b'': again = True continue raise_disconnection() elif error == LibsslConst.SSL_ERROR_WANT_WRITE: self._raw_write() again = True continue elif error == LibsslConst.SSL_ERROR_ZERO_RETURN: self._gracefully_closed = True self._shutdown(False) break else: handle_openssl_error(0, TLSError) output += bytes_from_buffer(self._read_buffer, result) if self._gracefully_closed and len(output) == 0: self._raise_closed() self._decrypted_bytes = output[max_length:] return output[0:max_length] def select_read(self, timeout=None): """ Blocks until the socket is ready to be read from, or the timeout is hit :param timeout: A float - the period of time to wait for data to be read. None for no time limit. :return: A boolean - if data is ready to be read. Will only be False if timeout is not None. """ # If we have buffered data, we consider a read possible if len(self._decrypted_bytes) > 0: return True read_ready, _, _ = select.select([self._socket], [], [], timeout) return len(read_ready) > 0 def read_until(self, marker): """ Reads data from the socket until a marker is found. Data read includes the marker. :param marker: A byte string or regex object from re.compile(). Used to determine when to stop reading. Regex objects are more inefficient since they must scan the entire byte string of read data each time data is read off the socket. :return: A byte string of the data read, including the marker """ if not isinstance(marker, byte_cls) and not isinstance(marker, Pattern): raise TypeError(pretty_message( ''' marker must be a byte string or compiled regex object, not %s ''', type_name(marker) )) output = b'' is_regex = isinstance(marker, Pattern) while True: if len(self._decrypted_bytes) > 0: chunk = self._decrypted_bytes self._decrypted_bytes = b'' else: if self._ssl is None: self._raise_closed() to_read = libssl.SSL_pending(self._ssl) or 8192 chunk = self.read(to_read) offset = len(output) output += chunk if is_regex: match = marker.search(output) if match is not None: end = match.end() break else: # If the marker was not found last time, we have to start # at a position where the marker would have its final char # in the newly read chunk start = max(0, offset - len(marker) - 1) match = output.find(marker, start) if match != -1: end = match + len(marker) break self._decrypted_bytes = output[end:] + self._decrypted_bytes return output[0:end] def read_line(self): r""" Reads a line from the socket, including the line ending of "\r\n", "\r", or "\n" :return: A byte string of the next line from the socket """ return self.read_until(_line_regex) def read_exactly(self, num_bytes): """ Reads exactly the specified number of bytes from the socket :param num_bytes: An integer - the exact number of bytes to read :return: A byte string of the data that was read """ output = b'' remaining = num_bytes while remaining > 0: output += self.read(remaining) remaining = num_bytes - len(output) return output def write(self, data): """ Writes data to the TLS-wrapped socket :param data: A byte string to write to the socket :raises: socket.socket - when a non-TLS socket error occurs oscrypto.errors.TLSError - when a TLS-related error occurs ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library """ data_len = len(data) while data_len: if self._ssl is None: self._raise_closed() result = libssl.SSL_write(self._ssl, data, data_len) self._raw_write() if result <= 0: error = libssl.SSL_get_error(self._ssl, result) if error == LibsslConst.SSL_ERROR_WANT_READ: if self._raw_read() != b'': continue raise_disconnection() elif error == LibsslConst.SSL_ERROR_WANT_WRITE: self._raw_write() continue elif error == LibsslConst.SSL_ERROR_ZERO_RETURN: self._gracefully_closed = True self._shutdown(False) self._raise_closed() else: handle_openssl_error(0, TLSError) data = data[result:] data_len = len(data) def select_write(self, timeout=None): """ Blocks until the socket is ready to be written to, or the timeout is hit :param timeout: A float - the period of time to wait for the socket to be ready to written to. None for no time limit. :return: A boolean - if the socket is ready for writing. Will only be False if timeout is not None. """ _, write_ready, _ = select.select([], [self._socket], [], timeout) return len(write_ready) > 0 def _shutdown(self, manual): """ Shuts down the TLS session and then shuts down the underlying socket :param manual: A boolean if the connection was manually shutdown """ if self._ssl is None: return while True: result = libssl.SSL_shutdown(self._ssl) # Don't be noisy if the socket is already closed try: self._raw_write() except (TLSDisconnectError): pass if result >= 0: break if result < 0: error = libssl.SSL_get_error(self._ssl, result) if error == LibsslConst.SSL_ERROR_WANT_READ: if self._raw_read() != b'': continue else: break elif error == LibsslConst.SSL_ERROR_WANT_WRITE: self._raw_write() continue else: handle_openssl_error(0, TLSError) if manual: self._local_closed = True libssl.SSL_free(self._ssl) self._ssl = None # BIOs are freed by SSL_free() self._rbio = None self._wbio = None try: self._socket.shutdown(socket_.SHUT_RDWR) except (socket_.error): pass def shutdown(self): """ Shuts down the TLS session and then shuts down the underlying socket """ self._shutdown(True) def close(self): """ Shuts down the TLS session and socket and forcibly closes it """ try: self.shutdown() finally: if self._socket: try: self._socket.close() except (socket_.error): pass self._socket = None def _read_certificates(self): """ Reads end-entity and intermediate certificate information from the TLS session """ stack_pointer = libssl.SSL_get_peer_cert_chain(self._ssl) if is_null(stack_pointer): handle_openssl_error(0, TLSError) if libcrypto_version_info < (1, 1): number_certs = libssl.sk_num(stack_pointer) else: number_certs = libssl.OPENSSL_sk_num(stack_pointer) self._intermediates = [] for index in range(0, number_certs): if libcrypto_version_info < (1, 1): x509_ = libssl.sk_value(stack_pointer, index) else: x509_ = libssl.OPENSSL_sk_value(stack_pointer, index) buffer_size = libcrypto.i2d_X509(x509_, null()) cert_buffer = buffer_from_bytes(buffer_size) cert_pointer = buffer_pointer(cert_buffer) cert_length = libcrypto.i2d_X509(x509_, cert_pointer) handle_openssl_error(cert_length) cert_data = bytes_from_buffer(cert_buffer, cert_length) cert = Asn1Certificate.load(cert_data) if index == 0: self._certificate = cert else: self._intermediates.append(cert) def _raise_closed(self): """ Raises an exception describing if the local or remote end closed the connection """ if self._local_closed: raise TLSDisconnectError('The connection was already closed') elif self._gracefully_closed: raise TLSGracefulDisconnectError('The remote end closed the connection') else: raise TLSDisconnectError('The connection was closed') @property def certificate(self): """ An asn1crypto.x509.Certificate object of the end-entity certificate presented by the server """ if self._ssl is None: self._raise_closed() if self._certificate is None: self._read_certificates() return self._certificate @property def intermediates(self): """ A list of asn1crypto.x509.Certificate objects that were presented as intermediates by the server """ if self._ssl is None: self._raise_closed() if self._certificate is None: self._read_certificates() return self._intermediates @property def cipher_suite(self): """ A unicode string of the IANA cipher suite name of the negotiated cipher suite """ return self._cipher_suite @property def protocol(self): """ A unicode string of: "TLSv1.2", "TLSv1.1", "TLSv1", "SSLv3" """ return self._protocol @property def compression(self): """ A boolean if compression is enabled """ return self._compression @property def session_id(self): """ A unicode string of "new" or "reused" or None for no ticket """ return self._session_id @property def session_ticket(self): """ A unicode string of "new" or "reused" or None for no ticket """ return self._session_ticket @property def session(self): """ The oscrypto.tls.TLSSession object used for this connection """ return self._session @property def hostname(self): """ A unicode string of the TLS server domain name or IP address """ return self._hostname @property def port(self): """ An integer of the port number the socket is connected to """ return self.socket.getpeername()[1] @property def socket(self): """ The underlying socket.socket connection """ if self._ssl is None: self._raise_closed() return self._socket def __del__(self): self.close() util.py000064400000015346147205320040006101 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from .._errors import pretty_message from .._ffi import buffer_from_bytes, bytes_from_buffer from ._libcrypto import libcrypto, libcrypto_version_info, handle_openssl_error from .._rand import rand_bytes from .._types import type_name, byte_cls, int_types __all__ = [ 'pbkdf2', 'pkcs12_kdf', 'rand_bytes', ] # OpenSSL 0.9.8 does not include PBKDF2 if libcrypto_version_info < (1,): from .._pkcs5 import pbkdf2 else: def pbkdf2(hash_algorithm, password, salt, iterations, key_length): """ PBKDF2 from PKCS#5 :param hash_algorithm: The string name of the hash algorithm to use: "sha1", "sha224", "sha256", "sha384", "sha512" :param password: A byte string of the password to use an input to the KDF :param salt: A cryptographic random byte string :param iterations: The numbers of iterations to use when deriving the key :param key_length: The length of the desired key in bytes :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type :return: The derived key as a byte string """ if not isinstance(password, byte_cls): raise TypeError(pretty_message( ''' password must be a byte string, not %s ''', type_name(password) )) if not isinstance(salt, byte_cls): raise TypeError(pretty_message( ''' salt must be a byte string, not %s ''', type_name(salt) )) if not isinstance(iterations, int_types): raise TypeError(pretty_message( ''' iterations must be an integer, not %s ''', type_name(iterations) )) if iterations < 1: raise ValueError('iterations must be greater than 0') if not isinstance(key_length, int_types): raise TypeError(pretty_message( ''' key_length must be an integer, not %s ''', type_name(key_length) )) if key_length < 1: raise ValueError('key_length must be greater than 0') if hash_algorithm not in set(['sha1', 'sha224', 'sha256', 'sha384', 'sha512']): raise ValueError(pretty_message( ''' hash_algorithm must be one of "sha1", "sha224", "sha256", "sha384", "sha512", not %s ''', repr(hash_algorithm) )) evp_md = { 'sha1': libcrypto.EVP_sha1, 'sha224': libcrypto.EVP_sha224, 'sha256': libcrypto.EVP_sha256, 'sha384': libcrypto.EVP_sha384, 'sha512': libcrypto.EVP_sha512 }[hash_algorithm]() output_buffer = buffer_from_bytes(key_length) result = libcrypto.PKCS5_PBKDF2_HMAC( password, len(password), salt, len(salt), iterations, evp_md, key_length, output_buffer ) handle_openssl_error(result) return bytes_from_buffer(output_buffer) pbkdf2.pure_python = False def pkcs12_kdf(hash_algorithm, password, salt, iterations, key_length, id_): """ KDF from RFC7292 appendix B.2 - https://tools.ietf.org/html/rfc7292#page-19 :param hash_algorithm: The string name of the hash algorithm to use: "md5", "sha1", "sha224", "sha256", "sha384", "sha512" :param password: A byte string of the password to use an input to the KDF :param salt: A cryptographic random byte string :param iterations: The numbers of iterations to use when deriving the key :param key_length: The length of the desired key in bytes :param id_: The ID of the usage - 1 for key, 2 for iv, 3 for mac :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type :return: The derived key as a byte string """ if not isinstance(password, byte_cls): raise TypeError(pretty_message( ''' password must be a byte string, not %s ''', type_name(password) )) if not isinstance(salt, byte_cls): raise TypeError(pretty_message( ''' salt must be a byte string, not %s ''', type_name(salt) )) if not isinstance(iterations, int_types): raise TypeError(pretty_message( ''' iterations must be an integer, not %s ''', type_name(iterations) )) if iterations < 1: raise ValueError(pretty_message( ''' iterations must be greater than 0 - is %s ''', repr(iterations) )) if not isinstance(key_length, int_types): raise TypeError(pretty_message( ''' key_length must be an integer, not %s ''', type_name(key_length) )) if key_length < 1: raise ValueError(pretty_message( ''' key_length must be greater than 0 - is %s ''', repr(key_length) )) if hash_algorithm not in set(['md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512']): raise ValueError(pretty_message( ''' hash_algorithm must be one of "md5", "sha1", "sha224", "sha256", "sha384", "sha512", not %s ''', repr(hash_algorithm) )) if id_ not in set([1, 2, 3]): raise ValueError(pretty_message( ''' id_ must be one of 1, 2, 3, not %s ''', repr(id_) )) utf16_password = password.decode('utf-8').encode('utf-16be') + b'\x00\x00' digest_type = { 'md5': libcrypto.EVP_md5, 'sha1': libcrypto.EVP_sha1, 'sha224': libcrypto.EVP_sha224, 'sha256': libcrypto.EVP_sha256, 'sha384': libcrypto.EVP_sha384, 'sha512': libcrypto.EVP_sha512, }[hash_algorithm]() output_buffer = buffer_from_bytes(key_length) result = libcrypto.PKCS12_key_gen_uni( utf16_password, len(utf16_password), salt, len(salt), id_, iterations, key_length, output_buffer, digest_type ) handle_openssl_error(result) return bytes_from_buffer(output_buffer) __pycache__/__init__.cpython-38.pyc000064400000000246147205320040013142 0ustar00U af@sdS)NrrrK/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_openssl/__init__.py__pycache__/_libcrypto.cpython-38.pyc000064400000006170147205320040013553 0ustar00U af@sddlmZmZmZmZddlmZddlmZm Z m Z ddl m Z edkrdddl mZmZmZnddlmZmZmZd d d d d ddgZdZddgZedkreee dZedkree ddree ddndZddZddd ZddZGdddZ dS))unicode_literalsdivisionabsolute_importprint_function)ffi)buffer_from_bytesbyte_string_from_buffernull)str_clsZcffi) libcryptoversion version_infohandle_openssl_errorr libcrypto_legacy_supportlibcrypto_versionlibcrypto_version_infoLibcryptoConstpeek_openssl_errorzutf-8cp1252)r r T)legacyasciiFc Csfz t|tWStk rXtD]2}zt||ddWYStk rPYq Xq YnXt|ddS)Nstrict)errorsreplace)r _encodingUnicodeDecodeError_fallback_encodings)valueencodingr"M/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_openssl/_libcrypto.py _try_decode5s r$NcCsL|dkr dS|dkrt}t}td}t||t|}|t|dS)ah Checks if an error occurred, and if so throws an OSError containing the last OpenSSL error message :param result: An integer result code - 1 or greater indicates success :param exception_class: The exception class to use for the exception if an error occurred :raises: OSError - when an OpenSSL error occurs rNx)OSErrorr Z ERR_get_errorrZERR_error_stringr r$)resultZexception_classZ error_numbufferZ error_stringr"r"r#rFs cCsht}tdkr>t|d?d@}t|d?d@}t|d@}n t|d?d@}d}t|d@}|||fS) z Peeks into the error stack and pulls out the lib, func and reason :return: A three-element tuple of integers (lib, func, reason) )rr iri)r ZERR_peek_errorrint)errorlibfuncreasonr"r"r#res c@sPeZdZdZdZdZdZdZdZdZ dZ dZ dZ d Z d Zd Zd Zd ZdZdZdS)rrrr iiiiirN)__name__ __module__ __qualname__ZEVP_CTRL_SET_RC2_KEY_BITSZSSLEAY_VERSIONZRSA_PKCS1_PADDINGZRSA_NO_PADDINGZRSA_PKCS1_OAEP_PADDINGZEVP_MD_CTX_FLAG_PSS_MDLENZEVP_PKEY_CTRL_RSA_PADDINGZRSA_PKCS1_PSS_PADDINGZEVP_PKEY_CTRL_RSA_PSS_SALTLENZ EVP_PKEY_RSAZEVP_PKEY_OP_SIGNZEVP_PKEY_OP_VERIFYZNID_X9_62_prime256v1Z NID_secp384r1Z NID_secp521r1ZOPENSSL_EC_NAMED_CURVEZDH_GENERATOR_2r"r"r"r#r{s")N)! __future__rrrrrZ_ffirr r _typesr Z_libcrypto_cffir rrrrZ_libcrypto_ctypes__all__rrZERR_load_crypto_stringsZOPENSSL_configrZOSSL_PROVIDER_availableencodeZOSSL_PROVIDER_loadr$rrrr"r"r"r#s8      __pycache__/_libcrypto_cffi.cpython-38.pyc000064400000022252147205320040014541 0ustar00U af&@s\ddlmZmZmZmZddlZddlmZddlm Z ddl m Z m Z ddl mZddlmZd d d d d dgZedZedkre dddZesedz0eZedeeeddZWnBek reZedeeeddZYnXdekZedeZes6edeZesDede dZ!e"dde!#dZ$e%dd e$DZ&d!Z'e%Z(ere!Z'e&Z(d"Z!d#Z&eZ)e)eZ*e e*e)e&d$kree d%e!e&d&kre)d'e&d(kre)d)e)d*e&d(kre)d+n e)d,e&d&kr.e)d-n e)d.e&d/krNe)d0n e)d1dS)2)unicode_literalsdivisionabsolute_importprint_functionN)_backend_config)pretty_message) get_library register_ffi)LibraryNotFoundError)FFI is_libressl libcryptolibressl_versionlibressl_version_infoversion version_infolibcrypto_pathZcryptozlibcrypto.dylibZ42z(The library libcrypto could not be foundz%const char *SSLeay_version(int type);zutf-8z&const char *OpenSSL_version(int type);ZLibreSSLz\b(\d+\.\d+\.\d+[a-z]*)\bz"(?<=LibreSSL )(\d+\.\d+(\.\d+)?)\bz(Error detecting the version of libcryptoz (\d+)([a-z]+)z\1.\2.ccs"|]}|rt|n|VqdS)N)isdigitint).0partrR/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_openssl/_libcrypto_cffi.py /srz1.0.1)rrr)r zX OpenSSL versions older than 0.9.8 are not supported - found version %s )rrzV void ERR_load_crypto_strings(void); void ERR_free_strings(void); )z typedef ... OSSL_LIB_CTX; typedef ... OSSL_PROVIDER; int OSSL_PROVIDER_available(OSSL_LIB_CTX *libctx, const char *name); OSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *libctx, const char *name); aP typedef ... EVP_MD; typedef uintptr_t EVP_CIPHER_CTX; typedef ... EVP_CIPHER; typedef ... ENGINE; typedef uintptr_t EVP_PKEY; typedef uintptr_t X509; typedef uintptr_t DH; typedef uintptr_t RSA; typedef uintptr_t DSA; typedef uintptr_t EC_KEY; typedef ... EVP_MD_CTX; typedef ... EVP_PKEY_CTX; typedef ... BN_GENCB; typedef ... BIGNUM; unsigned long ERR_get_error(void); char *ERR_error_string(unsigned long e, char *buf); unsigned long ERR_peek_error(void); void OPENSSL_config(const char *config_name); EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx); int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen); int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *x, int padding); int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); const EVP_CIPHER *EVP_aes_128_cbc(void); const EVP_CIPHER *EVP_aes_192_cbc(void); const EVP_CIPHER *EVP_aes_256_cbc(void); const EVP_CIPHER *EVP_des_cbc(void); const EVP_CIPHER *EVP_des_ede_cbc(void); const EVP_CIPHER *EVP_des_ede3_cbc(void); const EVP_CIPHER *EVP_rc4(void); const EVP_CIPHER *EVP_rc2_cbc(void); int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, const char *key, const char *iv); int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, char *out, int *outl, const char *in, int inl); int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, char *out, int *outl); int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, const char *key, const char *iv); int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, char *out, int *outl, const char *in, int inl); int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, char *out, int *outl); EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const char **pp, long length); EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const char **pp, long length); int i2d_PUBKEY(EVP_PKEY *a, char **pp); void EVP_PKEY_free(EVP_PKEY *key); X509 *d2i_X509(X509 **px, const char **in, int len); int i2d_X509(X509 *x, char **out); EVP_PKEY *X509_get_pubkey(X509 *x); void X509_free(X509 *a); RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey); void RSA_free(RSA *r); int RSA_public_encrypt(int flen, const char *from, char *to, RSA *rsa, int padding); int RSA_private_encrypt(int flen, const char *from, char *to, RSA *rsa, int padding); int RSA_public_decrypt(int flen, const char *from, char *to, RSA *rsa, int padding); int RSA_private_decrypt(int flen, const char *from, char *to, RSA *rsa, int padding); int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt); const EVP_MD *EVP_md5(void); const EVP_MD *EVP_sha1(void); const EVP_MD *EVP_sha224(void); const EVP_MD *EVP_sha256(void); const EVP_MD *EVP_sha384(void); const EVP_MD *EVP_sha512(void); int PKCS12_key_gen_uni(char *pass, int passlen, char *salt, int saltlen, int id, int iter, int n, char *out, const EVP_MD *md_type); void BN_free(BIGNUM *a); int BN_dec2bn(BIGNUM **a, const char *str); DH *DH_new(void); int DH_generate_parameters_ex(DH *dh, int prime_len, int generator, BN_GENCB *cb); int i2d_DHparams(const DH *a, char **pp); void DH_free(DH *dh); RSA *RSA_new(void); int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); int i2d_RSAPublicKey(RSA *a, char **pp); int i2d_RSAPrivateKey(RSA *a, char **pp); DSA *DSA_new(void); int DSA_generate_parameters_ex(DSA *dsa, int bits, const char *seed, int seed_len, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); int DSA_generate_key(DSA *a); int i2d_DSA_PUBKEY(const DSA *a, char **pp); int i2d_DSAPrivateKey(const DSA *a, char **pp); void DSA_free(DSA *dsa); EC_KEY *EC_KEY_new_by_curve_name(int nid); int EC_KEY_generate_key(EC_KEY *key); void EC_KEY_set_asn1_flag(EC_KEY *, int); int i2d_ECPrivateKey(EC_KEY *key, char **out); int i2o_ECPublicKey(EC_KEY *key, char **out); void EC_KEY_free(EC_KEY *key); z0 int EVP_PKEY_size(EVP_PKEY *pkey); z4 int EVP_PKEY_get_size(EVP_PKEY *pkey); zd EVP_MD_CTX *EVP_MD_CTX_create(void); void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); z^ EVP_MD_CTX *EVP_MD_CTX_new(void); void EVP_MD_CTX_free(EVP_MD_CTX *ctx); )ra typedef ... *DSA_SIG; typedef ... *ECDSA_SIG; DSA_SIG *DSA_do_sign(const char *dgst, int dlen, DSA *dsa); ECDSA_SIG *ECDSA_do_sign(const char *dgst, int dgst_len, EC_KEY *eckey); DSA_SIG *d2i_DSA_SIG(DSA_SIG **v, const char **pp, long length); ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **v, const char **pp, long len); int i2d_DSA_SIG(const DSA_SIG *a, char **pp); int i2d_ECDSA_SIG(const ECDSA_SIG *a, char **pp); int DSA_do_verify(const char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa); int ECDSA_do_verify(const char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY *eckey); void DSA_SIG_free(DSA_SIG *a); void ECDSA_SIG_free(ECDSA_SIG *a); DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey); EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); int RSA_verify_PKCS1_PSS(RSA *rsa, const char *mHash, const EVP_MD *Hash, const char *EM, int sLen); int RSA_padding_add_PKCS1_PSS(RSA *rsa, char *EM, const char *mHash, const EVP_MD *Hash, int sLen); int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); int EVP_SignFinal(EVP_MD_CTX *ctx, char *sig, unsigned int *s, EVP_PKEY *pkey); int EVP_VerifyFinal(EVP_MD_CTX *ctx, char *sigbuf, unsigned int siglen, EVP_PKEY *pkey); void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); a int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const char *salt, int saltlen, int iter, const EVP_MD *digest, int keylen, char *out); int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); int EVP_DigestSignFinal(EVP_MD_CTX *ctx, char *sig, size_t *siglen); int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const char *sig, size_t siglen); int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2); )+ __future__rrrrrerr_errorsrZ_ffir r errorsr Zcffir __all__getrZvffiZcdefstringdlopenZSSLeay_versiondecodeversion_stringAttributeErrorZOpenSSL_versionr searchZ version_matchgrouprsubsplit version_partstuplerrrffirrrrrs         "          v        $__pycache__/_libcrypto_ctypes.cpython-38.pyc000064400000016212147205320040015140 0ustar00U af E @s. ddlmZmZmZmZddlZddlmZmZm Z m Z m Z m Z m Z mZmZddlmZddlmZddlmZmZddlmZd d d d d dgZedZedkredddZesedeeddZz&e gej_e ej_ed dZ!Wn8e"k r&e gej#_e ej#_e#d dZ!YnXde!kZ$e%de!Z&e&sNe%de!Z&e&s\ede&'dZ(e)dde(*dZ+e,dd e+DZ-d!Z.e,Z/e$re(Z.e-Z/d"Z(d#Z-e-d$kreed%e(eZ0eZ1eZ2eZ3eZ4eZ5eZ6eZ7eZ8eeZ9eeZ:eZ;eZeZ?eZ@ee@ZAee ZBee ZCze-d&krVgejD_dejD_gejE_dejE_e-d'kre6e gejF_e ejF_e6e gejG_ee5ejG_gejH_e ejH_gejI_e ejI_e e gejJ_e ejJ_e gejK_dejK_gejL_Me0ejL_e0e gejN_e ejN_e0e gejO_e ejO_e0e e egejP_e ejP_e0gejQ_dejQ_gejR_e1ejR_gejS_e1ejS_gejT_e1ejT_gejU_e1ejU_gejV_e1ejV_gejW_e1ejW_gejX_e1ejX_gejY_e1ejY_e0e1e4e e gejZ_e ejZ_e0e eBe e gej[_e ej[_e0e eBgej\_e ej\_e0e1e4e e gej]_e ej]_e0e eBe e gej^_e ej^_e0e eBgej__e ej__ee7ee e gej`_e7ej`_ee7ee e geja_e7eja_e7ee gejb_e ejb_ee:ee e gejc_e:ejc_e:ee gejd_e ejd_e:geje_e7eje_e:gejf_dejf_e7gejg_dejg_e-d&kr6gejh_e2ejh_e2geji_deji_n"gejj_e2ejj_e2gejk_dejk_gejl_e3ejl_gejm_e3ejm_gejn_e3ejn_gejo_e3ejo_gejp_e3ejp_gejq_e3ejq_e-d(kre7gejr_e ejr_ne7gejs_e ejs_e7gejt_eej_e>gej_e ej_e>e gej_dej_e>ee gej_e ej_e>ee gej_e ej_e>gej_dej_e-d)k rHeZeZe e e=gej_eej_e e e>gej_eej_eeee e gej_eej_eeee e gej_eej_eee gej_e ej_eee gej_e ej_e e ee=gej_e ej_e e ee>gej_e ej_egej_dej_egej_dej_e7gej_e=ej_e7gej_e>ej_e2sr%z1.0.1)rrr)r zX OpenSSL versions older than 0.9.8 are not supported - found version %s )rr))r)r)rzError initializing ctypes EVP_PKEY_CTXBIGNUM) __future__rrrrrectypesrrrr r r r r rr&r_errorsrZ_ffirrerrorsr__all__getrrZSSLeay_versionargtypesrestypedecodeversion_stringAttributeErrorZOpenSSL_versionrsearchZ version_matchgrouprsubsplit version_partstuplerrrZP_EVP_CIPHER_CTXZ P_EVP_CIPHERZ P_EVP_MD_CTXZP_EVP_MDZP_ENGINEZ OSSL_PROVIDERZ OSSL_LIB_CTXZ P_EVP_PKEYr*ZP_EVP_PKEY_CTXZP_X509ZP_DHZP_RSAZP_DSAZP_EC_KEYZ P_BN_GENCBr+ZP_BIGNUMZp_intZp_uintZERR_load_crypto_stringsZERR_free_stringsZOSSL_PROVIDER_availableZOSSL_PROVIDER_loadZ ERR_get_errorZERR_peek_errorZERR_error_stringZOPENSSL_configZEVP_CIPHER_CTX_newZargtypeZEVP_CIPHER_CTX_set_key_lengthZEVP_CIPHER_CTX_set_paddingZEVP_CIPHER_CTX_ctrlZEVP_CIPHER_CTX_freeZEVP_aes_128_cbcZEVP_aes_192_cbcZEVP_aes_256_cbcZ EVP_des_cbcZEVP_des_ede_cbcZEVP_des_ede3_cbcZEVP_rc4Z EVP_rc2_cbcZEVP_EncryptInit_exZEVP_EncryptUpdateZEVP_EncryptFinal_exZEVP_DecryptInit_exZEVP_DecryptUpdateZEVP_DecryptFinal_exZd2i_AutoPrivateKeyZ d2i_PUBKEYZ i2d_PUBKEYZd2i_X509Zi2d_X509ZX509_get_pubkeyZ X509_freeZ EVP_PKEY_freeZEVP_MD_CTX_createZEVP_MD_CTX_destroyZEVP_MD_CTX_newZEVP_MD_CTX_freeZEVP_md5ZEVP_sha1Z EVP_sha224Z EVP_sha256Z EVP_sha384Z EVP_sha512Z EVP_PKEY_sizeZEVP_PKEY_get_sizeZEVP_PKEY_get1_RSAZRSA_freeZRSA_public_encryptZRSA_private_encryptZRSA_public_decryptZRSA_private_decryptZEVP_DigestUpdateZPKCS12_key_gen_uniZBN_freeZ BN_dec2bnZDH_newZDH_generate_parameters_exZ i2d_DHparamsZDH_freeZRSA_newZRSA_generate_key_exZi2d_RSAPublicKeyZi2d_RSAPrivateKeyZDSA_newZDSA_generate_parameters_exZDSA_generate_keyZi2d_DSA_PUBKEYZi2d_DSAPrivateKeyZDSA_freeZEC_KEY_new_by_curve_nameZEC_KEY_generate_keyZEC_KEY_set_asn1_flagZi2d_ECPrivateKeyZi2o_ECPublicKeyZ EC_KEY_freeZ P_DSA_SIGZ P_ECDSA_SIGZ DSA_do_signZ ECDSA_do_signZ d2i_DSA_SIGZ d2i_ECDSA_SIGZ i2d_DSA_SIGZ i2d_ECDSA_SIGZ DSA_do_verifyZECDSA_do_verifyZ DSA_SIG_freeZECDSA_SIG_freeZEVP_PKEY_get1_DSAZEVP_PKEY_get1_EC_KEYZRSA_verify_PKCS1_PSSZRSA_padding_add_PKCS1_PSSZEVP_DigestInit_exZ EVP_SignFinalZEVP_VerifyFinalZEVP_MD_CTX_set_flagsZPKCS5_PBKDF2_HMACZEVP_DigestSignInitZEVP_DigestSignFinalZEVP_DigestVerifyInitZEVP_DigestVerifyFinalZEVP_PKEY_CTX_ctrlsetattrr#r#r#r$s,                            __pycache__/_libssl.cpython-38.pyc000064400000004427147205320040013037 0ustar00U afs@sddlmZmZmZmZddlmZddlmZedkrHddl m Z n ddl m Z dd gZ ed krle ed kr|e Gd d d Zed krde_dS))unicode_literalsdivisionabsolute_importprint_function)ffi)libcrypto_version_infoZcffi)libsslr LibsslConst)rr)rrc@seZdZdZdZdZdZdZdZdZ dZ dZ d Z d Z d Zd Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#dZ$dZ%d Z&d!Z'd"Z(d#Z)d$Z*d%Z+d&S)'r  ,rrriiiiinitii iowii.7 N),__name__ __module__ __qualname__Z ERR_LIB_ASN1Z ERR_LIB_SSLZSSL_CTRL_OPTIONSZSSL_CTRL_SET_SESS_CACHE_MODEZSSL_VERIFY_NONEZSSL_VERIFY_PEERZ SSL_ST_OKSSL_ERROR_WANT_READSSL_ERROR_WANT_WRITESSL_ERROR_ZERO_RETURNZSSL_OP_NO_SSLv2ZSSL_OP_NO_SSLv3ZSSL_OP_NO_TLSv1ZSSL_OP_NO_TLSv1_2ZSSL_OP_NO_TLSv1_1ZSSL_SESS_CACHE_CLIENTZSSL_R_NO_SHARED_CIPHERZ#SSL_F_SSL3_CHECK_CERT_AND_ALGORITHMZSSL_F_SSL3_GET_KEY_EXCHANGEZ!SSL_F_SSL3_GET_SERVER_CERTIFICATEZSSL_R_BAD_DH_P_LENGTHZSSL_R_CERTIFICATE_VERIFY_FAILEDZSSL_R_UNKNOWN_PROTOCOLSSL_R_DH_KEY_TOO_SMALLZSSL_F_TLS_PROCESS_SKE_DHEZSSL_F_SSL3_GET_RECORDZSSL_R_WRONG_VERSION_NUMBERZ$SSL_F_TLS_PROCESS_SERVER_CERTIFICATEZSSL_F_SSL23_GET_SERVER_HELLOZSSL_F_SSL3_READ_BYTESZ#SSL_R_SSLV3_ALERT_HANDSHAKE_FAILUREZ"SSL_R_TLSV1_ALERT_PROTOCOL_VERSIONZSSL_CTRL_SET_TLSEXT_HOSTNAMEZTLSEXT_NAMETYPE_host_nameZ,X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLYZ$X509_V_ERR_SELF_SIGNED_CERT_IN_CHAINZ&X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERTZX509_V_ERR_CERT_NOT_YET_VALIDZX509_V_ERR_CERT_HAS_EXPIREDZASN1_F_ASN1_ITEM_VERIFYZ'ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHMr*r*J/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_openssl/_libssl.pyr sR)rrriN) __future__rrrrrZ _libcryptor Z _libssl_cffir Z_libssl_ctypes__all__ZSSL_library_initZ!OPENSSL_add_all_algorithms_noconfr r)r*r*r*r+s    <__pycache__/_libssl_cffi.cpython-38.pyc000064400000006133147205320040014022 0ustar00U af @sddlmZmZmZmZddlmZddlmZm Z ddl m Z ddl m Z ddlmZd gZeZed Zed kred d d Zese deeZe eeede dkredn edd S))unicode_literalsdivisionabsolute_importprint_function)_backend_config) get_library register_ffi)LibraryNotFoundError)libcrypto_version_info)FFIlibssl libssl_pathNsslZ44z%The library libssl could not be founda typedef ... SSL_METHOD; typedef uintptr_t SSL_CTX; typedef ... SSL_SESSION; typedef uintptr_t SSL; typedef ... BIO_METHOD; typedef uintptr_t BIO; typedef uintptr_t X509; typedef ... X509_STORE; typedef ... X509_STORE_CTX; typedef uintptr_t _STACK; BIO_METHOD *BIO_s_mem(void); BIO *BIO_new(BIO_METHOD *type); int BIO_free(BIO *a); int BIO_read(BIO *b, void *buf, int len); int BIO_write(BIO *b, const void *buf, int len); size_t BIO_ctrl_pending(BIO *b); SSL_CTX *SSL_CTX_new(const SSL_METHOD *method); long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath); long SSL_get_verify_result(const SSL *ssl); X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx); int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str); long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg); void SSL_CTX_free(SSL_CTX *a); SSL *SSL_new(SSL_CTX *ctx); void SSL_free(SSL *ssl); void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio); long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg); _STACK *SSL_get_peer_cert_chain(const SSL *s); SSL_SESSION *SSL_get1_session(const SSL *ssl); int SSL_set_session(SSL *ssl, SSL_SESSION *session); void SSL_SESSION_free(SSL_SESSION *session); void SSL_set_connect_state(SSL *ssl); int SSL_do_handshake(SSL *ssl); int SSL_get_error(const SSL *ssl, int ret); const char *SSL_get_version(const SSL *ssl); int SSL_read(SSL *ssl, void *buf, int num); int SSL_write(SSL *ssl, const void *buf, int num); int SSL_pending(const SSL *ssl); int SSL_shutdown(SSL *ssl); )r r z int sk_num(const _STACK *); X509 *sk_value(const _STACK *, int); int SSL_library_init(void); void OPENSSL_add_all_algorithms_noconf(void); SSL_METHOD *SSLv23_method(void); z int OPENSSL_sk_num(const _STACK *); X509 *OPENSSL_sk_value(const _STACK *, int); SSL_METHOD *TLS_method(void); ) __future__rrrrrZ_ffirr errorsr Z _libcryptor Zcffir __all__ffigetrdlopenrZcdefrrO/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_openssl/_libssl_cffi.pys&         7 __pycache__/_libssl_ctypes.cpython-38.pyc000064400000006025147205320040014422 0ustar00U af@sddlmZmZmZmZddlmZmZmZm Z m Z m Z m Z m Z ddlmZddlmZmZddlmZddlmZd gZed Zed kred d d ZesedeeddZee Zee Zee Zee Zee Zee Z e Z!ee!Z"ee Z#ee Z$e Z%ee%Z&z:edkrpe&gej'_(e ej'_)e&e gej*_(e"ej*_)gej+_(e ej+_)gej,_(d ej,_)gej-_(eej-_)n6e&gej._(e ej._)e&e gej/_(e"ej/_)gej0_(eej0_)gej1_(eej1_)egej2_(e ej2_)e gej3_(e ej3_)e e e gej4_(e ej4_)e e e gej5_(e ej5_)e gej6_(e ej6_)egej7_(eej7_)ee gej8_(e ej8_)ee e e$Z9e:ede9ee ee9gej;_(d ej;_)egej<_(e ej<_)ee e gej=_(e ej=_)egej>_(e ej>_)egej?_(e#ej?_)e#e"gej@_(e ej@_)ee gejA_(e ejA_)ee e e gejB_Ce ejB_)egejD_(d ejD_)egejE_(eejE_)egejF_(d ejF_)ee e gejG_(d ejG_)ee e e gejH_Ce ejH_)egejI_(e&ejI_)egejJ_(eejJ_)eegejK_(e ejK_)egejL_(d ejL_)egejM_(d ejM_)egejN_(e ejN_)ee gejO_(e ejO_)egejP_(e ejP_)ee e gejQ_(e ejQ_)ee e gejR_(e ejR_)egejS_(e ejS_)egejT_(e ejT_)WneUk rdedYnXe:ede%e:ede!d S))unicode_literalsdivisionabsolute_importprint_function)CDLL CFUNCTYPEPOINTERc_void_pc_char_pc_intc_size_tc_long)_backend_config)FFIEngineError get_library)LibraryNotFoundError)libcrypto_version_infolibssl libssl_pathNsslZ44z%The library libssl could not be foundT) use_errno)rrverify_callbackzError initializing ctypes_STACKX509)V __future__rrrrctypesrrrr r r r r rZ_ffirrerrorsrZ _libcryptor__all__getrrZ P_SSL_METHODZ P_SSL_CTXZ P_SSL_SESSIONZP_SSLZ P_BIO_METHODZP_BIOrZP_X509Z P_X509_STOREZP_X509_STORE_CTXrZP_STACKZsk_numargtypesrestypeZsk_valueZSSL_library_initZ!OPENSSL_add_all_algorithms_noconfZ SSLv23_methodZOPENSSL_sk_numZOPENSSL_sk_valueZ TLS_methodZ BIO_s_memZBIO_newZBIO_freeZBIO_readZ BIO_writeZBIO_ctrl_pendingZ SSL_CTX_newZSSL_CTX_set_timeoutrsetattrZSSL_CTX_set_verifyZ SSL_CTX_set_default_verify_pathsZSSL_CTX_load_verify_locationsZSSL_get_verify_resultZSSL_CTX_get_cert_storeZX509_STORE_add_certZSSL_CTX_set_cipher_listZ SSL_CTX_ctrlZ arg_typesZ SSL_CTX_freeZSSL_newZSSL_freeZ SSL_set_bioZSSL_ctrlZSSL_get_peer_cert_chainZSSL_get1_sessionZSSL_set_sessionZSSL_SESSION_freeZSSL_set_connect_stateZSSL_do_handshakeZ SSL_get_errorZSSL_get_versionZSSL_readZ SSL_writeZ SSL_pendingZ SSL_shutdownAttributeErrorr&r&Q/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_openssl/_libssl_ctypes.pysX(                __pycache__/asymmetric.cpython-38.pyc000064400000120410147205320040013554 0ustar00U af;@s2ddlmZmZmZmZddlZddlmZm Z m Z m Z m Z m Z ddlmZmZmZmZmZmZmZmZmZddlmZddlmZmZmZmZmZm Z m!Z!m"Z"m#Z#dd l$m%Z%m&Z&m'Z'm(Z(dd l)m*Z*m+Z+m,Z,dd l-m.Z.m/Z/m0Z0m1Z1dd l2m3Z3d ddddddddddddddddddd d!gZ4Gd"ddeZ5Gd#ddeZ6Gd$d d eZdHd%dZ7d&d'Z8d(dZ9d)d*Z:dId+dZ;d,dZdKd0dZ?d1dZ@d2dZAd3dZBd4dZCd5d6ZDd7d8ZEd9d:ZFd;dZGddZJdLd@dAZKdBdZLdCd ZMdDdZNdEdZOdMdFdGZPdS)N)unicode_literalsdivisionabsolute_importprint_functionN) Certificate DHParametersECDomainParametersPrivateKeyInfoPublicKeyAlgorithm PublicKeyInfo) _CertificateBase _fingerprint _parse_pkcs12_PrivateKeyBase_PublicKeyBase_unwrap_private_key_infoparse_certificate parse_private parse_public)pretty_message) buffer_from_bytesbuffer_pointerbytes_from_bufferderefis_nullnewnullunwrapwrite_to_buffer) libcryptoLibcryptoConstlibcrypto_version_infohandle_openssl_error)AsymmetricKeyErrorIncompleteAsymmetricKeyErrorSignatureError) type_namestr_clsbyte_cls int_types)constant_comparerdsa_sign dsa_verify ecdsa_sign ecdsa_verify generate_pairload_certificate load_pkcs12load_private_keyload_public_key parse_pkcs12 PrivateKey PublicKeyrsa_oaep_decryptrsa_oaep_encryptrsa_pkcs1v15_decryptrsa_pkcs1v15_encryptrsa_pkcs1v15_signrsa_pkcs1v15_verify rsa_pss_signrsa_pss_verifyc@sDeZdZdZdZdZdZddZeddZ eddZ d d Z dS) r7zC Container for the OpenSSL representation of a private key NcCs||_||_t|_dS)z :param evp_pkey: An OpenSSL EVP_PKEY value from loading/importing the key :param asn1: An asn1crypto.keys.PrivateKeyInfo object Nevp_pkeyasn1r!_libselfrBrCrGM/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_openssl/asymmetric.py__init__Ps zPrivateKey.__init__c Cs|jdkrt|jt}t|}t|}t|j|}t|t||}t |}t dkr|j dkr| }d|dd<|}t||t|}ttt||} t| rtdt| ||_|jS)z\ :return: A PublicKey object corresponding to this private key. N rsassa_pssrsa algorithmr) _public_keyr!Z i2d_PUBKEYrBrrrr$rr loadr#rNcopydumprlen d2i_PUBKEYrr8) rF buffer_sizeZ pubkey_bufferZpubkey_pointerZ pubkey_lengthZ pubkey_datarCZ temp_asn1Z temp_dataZ pub_evp_pkeyrGrGrH public_key]s&      zPrivateKey.public_keycCs|jdkrt|jt|_|jS)aY Creates a fingerprint that can be compared with a public key to see if the two form a pair. This fingerprint is not compatible with fingerprints generated by any other software. :return: A byte string that is a sha256 hash of selected components (based on the key type) N)rrCr4rFrGrGrH fingerprints zPrivateKey.fingerprintcCs$|jr |j|jd|_d|_dSNrBrDZ EVP_PKEY_freerWrGrGrH__del__szPrivateKey.__del__) __name__ __module__ __qualname____doc__rBrOrDrIpropertyrVrXr[rGrGrGrHr7Ds  ! c@s(eZdZdZdZdZddZddZdS)r8zB Container for the OpenSSL representation of a public key NcCs||_||_t|_dS)z :param evp_pkey: An OpenSSL EVP_PKEY value from loading/importing the key :param asn1: An asn1crypto.keys.PublicKeyInfo object NrArErGrGrHrIs zPublicKey.__init__cCs$|jr |j|jd|_d|_dSrYrZrWrGrGrHr[szPublicKey.__del__)r\r]r^r_rBrDrIr[rGrGrGrHr8s  c@sTeZdZdZdZdZdZdZddZe ddZ e ddZ e d d Z d d Z dS) rzC Container for the OpenSSL representation of a certificate NcCs||_||_t|_dS)z :param x509: An OpenSSL X509 value from loading/importing the certificate :param asn1: An asn1crypto.x509.Certificate object N)x509rCr!rD)rFrarCrGrGrHrIs zCertificate.__init__cCs|jjS)z_ :return: The EVP_PKEY of the public key this certificate contains )rVrBrWrGrGrHrBszCertificate.evp_pkeycCsT|jsN|jrNtdkr2|jjjdkr2t|jj|_nt|j}t ||jj|_|jS)zh :return: The PublicKey object for the public key this certificate contains rJrL) rOrar#rCrVrNr5r!ZX509_get_pubkeyr8)rFrBrGrGrHrVs   zCertificate.public_keycCs|jdkrd|_|jjtddgkr|jdj}|jdj}|dkrJt}n8|dkrXt}n*|dkrft}n|d krtt }nt t d |z,||j |jd j |jd |d |_Wntk rYnX|jS)zT :return: A boolean - if the certificate is self-signed NFyesmaybeZsignature_algorithmZrsassa_pkcs1v15rLdsaZecdsaz Unable to verify the signature of the certificate since it uses the unsupported algorithm %s Zsignature_valueZtbs_certificateT) _self_signedrC self_signedsetsignature_algo hash_algor>r@r.r0OSErrorrrVZnativerRr')rFrhriZ verify_funcrGrGrHrfs8      zCertificate.self_signedcCs:|jr|jd|_|jr6|j|jd|_d|_dSrY)rOr[rarDZ X509_freerWrGrGrHr[s zCertificate.__del__)r\r]r^r_rarOrerDrIr`rBrVrfr[rGrGrGrHrs    +c Cs|tdddgkr$ttdt||dkrT|tddddgkrttd t|n~|dkrtd kr|dkrttd t|q|tdddgkrttd t|n,|dkr|td ddgkrttdt||dkrd}d}zt}t |rt dt td}t |d}t |t |}t|||t}t |t|t}|dkrbt |t|}t|t|}|dkrt |t||} t|t}|dkrt |t|}t|t|}|dkrt |t||} W5|rt||rt|Xnn|dkr8d} zt} t | r>t dt| |tdttt}t |t| }t |t| t}|dkrt |t|}t| t|}|dkrt |t||} t| t}|dkrt |t|}t| t|}|dkrt |t||} W5| r2t| XnJ|dkrd} z&tjtjtjd|} t | } t | r|t dt!| }t |t"| tj#t$| t}|dkrt |t|}t$| t|}|dkrt |t||}t%t&dt'd|dd|d}|(} t)| t}|dkr8t |t|}t)| t|}|dkrbt |t||} W5| rt| Xt*| t+| fS)aP Generates a public/private key pair :param algorithm: The key algorithm - "rsa", "dsa" or "ec" :param bit_size: An integer - used for "rsa" and "dsa". For "rsa" the value maye be 1024, 2048, 3072 or 4096. For "dsa" the value may be 1024, plus 2048 or 3072 if OpenSSL 1.0.0 or newer is available. :param curve: A unicode string - used for "ec" keys. Valid values include "secp256r1", "secp384r1" and "secp521r1". :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A 2-element tuple of (PublicKey, PrivateKey). The contents of each key may be saved by calling .asn1.dump(). rMrdeczM algorithm must be one of "rsa", "dsa", "ec", not %s iii zX bit_size must be one of 1024, 2048, 3072, 4096, not %s r zG bit_size must be 1024, not %s zZ bit_size must be one of 1024, 2048, 3072, not %s secp256r1 secp384r1 secp521r1zt curve must be one of "secp256r1", "secp384r1", "secp521r1", not %s Nrz BIGNUM **s65537)rnrorpnamed)namevalue)rN parameters)rNrV),rg ValueErrorrreprr#r!RSA_freeZBN_freeZRSA_newrr$rZ BN_dec2bnrZRSA_generate_key_exrZi2d_RSAPublicKeyrrrZi2d_RSAPrivateKeyDSA_freeZDSA_newZDSA_generate_parameters_exZDSA_generate_keyZi2d_DSA_PUBKEYZi2d_DSAPrivateKey EC_KEY_freer"ZNID_X9_62_prime256v1Z NID_secp384r1Z NID_secp521r1ZEC_KEY_new_by_curve_nameZEC_KEY_generate_keyZEC_KEY_set_asn1_flagZOPENSSL_EC_NAMED_CURVEZi2o_ECPublicKeyr r r rRZi2d_ECPrivateKeyr5r4)rNbit_sizeZcurverMexponentZexponent_pointerresult buffer_lengthbufferZpublic_key_bytesZprivate_key_bytesrdec_keyZcurve_idZpublic_key_point_bytesrVrGrGrHr1#s                             c Cst|tsttdt||dkr,td|dkr           cCsrtdkr,|jdkr,|jdkr,ttd|jt|}t|}t t t |t |}t|rhtdt||S)z Loads a private key into a PrivateKey object :param private_object: An asn1crypto.keys.PrivateKeyInfo object :return: A PrivateKey object rmrdrz OpenSSL 0.9.8 only supports DSA keys based on SHA1 (2048 bits or less) - this key is based on SHA2 and is %s bits r)r#rNrir%rrzrrRrr!Zd2i_AutoPrivateKeyrrrSrr$r7)rrr~rBrGrGrHrs  rcCs t||tS)a Parses a PKCS#12 ANS.1 DER-encoded structure and extracts certs and keys :param data: A byte string of a DER-encoded PKCS#12 file :param password: A byte string of the password to any encrypted data :raises: ValueError - when any of the parameters are of the wrong type or value OSError - when an error is returned by one of the OS decryption functions :return: A three-element tuple of: 1. An asn1crypto.keys.PrivateKeyInfo object 2. An asn1crypto.x509.Certificate object 3. A list of zero or more asn1crypto.x509.Certificate objects that are "extra" certificates, possibly intermediates from the cert chain )rr4)rrrGrGrHr6 sc Cs|dk r8t|tr|d}t|ts8ttdt|t|trbt|d}|}W5QRXnt|ts~ttdt|t ||\}}}d}d}|rt |}|rt |}dd|D}|||fS)a Loads a .p12 or .pfx file into a PrivateKey object and one or more Certificates objects :param source: A byte string of file contents or a unicode string filename :param password: A byte or unicode string to decrypt the PKCS12 file. Unicode strings will be encoded using UTF-8. :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type oscrypto.errors.AsymmetricKeyError - when a contained key is incompatible with the OS crypto library OSError - when an error is returned by the OS crypto library :return: A three-element tuple containing (PrivateKey, Certificate, [Certificate, ...]) NrzH password must be a byte string, not %s rzR source must be a byte string or a unicode string, not %s cSsg|] }t|qSrG)r).0inforGrGrH [szload_pkcs12..) rr)rr*rrr(rrr6rr) rrrZkey_infoZ cert_infoZextra_certs_infokeycertZ extra_certsrGrGrHr3#s2      cCst||tjS)aF Encrypts a byte string using an RSA public key or certificate. Uses PKCS#1 v1.5 padding. :param certificate_or_public_key: A PublicKey or Certificate object :param data: A byte string, with a maximum length 11 bytes less than the key length (in bytes) :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the encrypted data )_encryptr"RSA_PKCS1_PADDINGcertificate_or_public_keyrrGrGrHr<`scCst||tjS)a Decrypts a byte string using an RSA private key. Uses PKCS#1 v1.5 padding. :param private_key: A PrivateKey object :param ciphertext: A byte string of the encrypted data :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the original plaintext )_decryptr"r private_key ciphertextrGrGrHr;xscCst||tjS)aZ Encrypts a byte string using an RSA public key or certificate. Uses PKCS#1 OAEP padding with SHA1. :param certificate_or_public_key: A PublicKey or Certificate object :param data: A byte string, with a maximum length 41 bytes (or more) less than the key length (in bytes) :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the encrypted data )rr"RSA_PKCS1_OAEP_PADDINGrrGrGrHr:scCst||tjS)a Decrypts a byte string using an RSA private key. Uses PKCS#1 OAEP padding with SHA1. :param private_key: A PrivateKey object :param ciphertext: A byte string of the encrypted data :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the original plaintext )rr"rrrGrGrHr9scCstdkrt|St|S)z Handles the function name change from OpenSSL 1.1 -> 3.0 :param evp_pkey: The EVP_PKEY of the Certificte or PublicKey to get the size of :return: An int of the number of bytes necessary for the key rJ)r#r!Z EVP_PKEY_sizeZEVP_PKEY_get_size)rBrGrGrH_evp_pkey_get_sizes  rc Cst|ttfs ttdt|t|ts<s  cCs<|j}|dkr*|dkr*ttd|jt||||ddS)a Verifies an RSASSA-PSS signature. For the PSS padding the mask gen algorithm will be mgf1 using the same hash algorithm as the signature. The salt length with be the length of the hash algorithm, and the trailer field with be the standard 0xBC byte. :param certificate_or_public_key: A Certificate or PublicKey instance to verify the signature with :param signature: A byte string of the signature to verify :param data: A byte string of the data the signature is for :param hash_algorithm: A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512" :raises: oscrypto.errors.SignatureError - when the signature is determined to be invalid ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library rMrLrTrsa_pss_paddingr)rrrrcp_algrGrGrHr@dscCs,|jdkrttd|jt||||S)a Verifies a DSA signature :param certificate_or_public_key: A Certificate or PublicKey instance to verify the signature with :param signature: A byte string of the signature to verify :param data: A byte string of the data the signature is for :param hash_algorithm: A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512" :raises: oscrypto.errors.SignatureError - when the signature is determined to be invalid ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library rdzK The key specified is not a DSA public key, but %s rrrGrGrHr.s  cCs,|jdkrttd|jt||||S)a Verifies an ECDSA signature :param certificate_or_public_key: A Certificate or PublicKey instance to verify the signature with :param signature: A byte string of the signature to verify :param data: A byte string of the data the signature is for :param hash_algorithm: A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512" :raises: oscrypto.errors.SignatureError - when the signature is determined to be invalid ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library rkzK The key specified is not an EC public key, but %s rrrGrGrHr0s  Fc CsHt|ttfs ttdt|t|ts|}|rt?|tj@dtjAtjBt2}t|tdkrt?|tj@tjCtjDBtjEdt2}t|t3||t |}t|tF||t |}|dkrtdt|W5|rtdkrt|n t|| rt| |rt||r"t ||r2t!||rBt"|XdS)aI Verifies an RSA, DSA or ECDSA signature :param certificate_or_public_key: A Certificate or PublicKey instance to verify the signature with :param signature: A byte string of the signature to verify :param data: A byte string of the data the signature is for :param hash_algorithm: A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512" :param rsa_pss_padding: If the certificate_or_public_key is an RSA key, this enables PSS padding :raises: oscrypto.errors.SignatureError - when the signature is determined to be invalid ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library rzA signature must be a byte string, not %s rrMrLmd5sha1sha224sha256sha384sha512raw5"md5", "sha1", "sha224", "sha256", "sha384", "sha512", "raw"B hash_algorithm must be one of %s, not %s o PSS padding can only be used with RSA keys - the key provided is a %s key data must be 11 bytes shorter than the key size when hash_algorithm is "raw" - key size is %s bytes, but data is %s bytes long NrzSignature is invalidr r rrrrrrrmrdrkEVP_PKEY_CTX **rKrr )Grrr8rrr(r*rNrgrurvrrS byte_sizer!rwrrBrr$rrZRSA_public_decryptr"rrr,r'r#EVP_MD_CTX_destroyEVP_MD_CTX_freerx DSA_SIG_freeryECDSA_SIG_freeEVP_MD_CTX_createEVP_MD_CTX_newEVP_md5EVP_sha1 EVP_sha224 EVP_sha256 EVP_sha384 EVP_sha512getattrhashlibdigestRSA_NO_PADDINGZRSA_verify_PKCS1_PSSEVP_MD_CTX_FLAG_PSS_MDLENEVP_DigestInit_exrEVP_DigestUpdateZEVP_VerifyFinalrZ d2i_DSA_SIGEVP_PKEY_get1_DSAZ DSA_do_verifyZ d2i_ECDSA_SIGEVP_PKEY_get1_EC_KEYZECDSA_do_verifyrZEVP_DigestVerifyInitrEVP_PKEY_CTX_ctrl EVP_PKEY_RSAEVP_PKEY_CTRL_RSA_PADDINGRSA_PKCS1_PSS_PADDINGEVP_PKEY_OP_SIGNEVP_PKEY_OP_VERIFYEVP_PKEY_CTRL_RSA_PSS_SALTLENZEVP_DigestVerifyFinal)rrrrrrZ cp_is_rsavalid_hash_algorithmsvalid_hash_algorithms_errorrMrUZdecrypted_bufferZdecrypted_lengthZdecrypted_bytes evp_md_ctxrddsa_sigr ecdsa_sigevp_mdrZdecoded_bufferZdecoded_lengthrsignature_buffersignature_pointerevp_pkey_ctx_pointer_pointerevp_pkey_ctx_pointerrGrGrHrsv                                    rcCs*|jdkrttd|jt|||S)a^ Generates an RSASSA-PKCS-v1.5 signature. When the hash_algorithm is "raw", the operation is identical to RSA private key encryption. That is: the data is not hashed and no ASN.1 structure with an algorithm identifier of the hash algorithm is placed in the encrypted byte string. :param private_key: The PrivateKey to generate the signature with :param data: A byte string of the data the signature is for :param hash_algorithm: A unicode string of "md5", "sha1", "sha224", "sha256", "sha384", "sha512" or "raw" :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the signature rMM The key specified is not an RSA private key, but %s rNrurr_signrrrrGrGrHr=s  cCs8|j}|dkr(|dkr(ttd|t|||ddS)a. Generates an RSASSA-PSS signature. For the PSS padding the mask gen algorithm will be mgf1 using the same hash algorithm as the signature. The salt length with be the length of the hash algorithm, and the trailer field with be the standard 0xBC byte. :param private_key: The PrivateKey to generate the signature with :param data: A byte string of the data the signature is for :param hash_algorithm: A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512" :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the signature rMrLrTrr)rrrpkey_algrGrGrHr? scCs*|jdkrttd|jt|||S)aA Generates a DSA signature :param private_key: The PrivateKey to generate the signature with :param data: A byte string of the data the signature is for :param hash_algorithm: A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512" :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the signature rdzL The key specified is not a DSA private key, but %s rrrGrGrHr-/s  cCs*|jdkrttd|jt|||S)aD Generates an ECDSA signature :param private_key: The PrivateKey to generate the signature with :param data: A byte string of the data the signature is for :param hash_algorithm: A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512" :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the signature rkzL The key specified is not an EC private key, but %s rrrGrGrHr/Ps  c Csxt|tsttdt|t|ts8ttdt||j}|dkpL|dk}tddddd d g}|dkr||s||td gO}||krd }|r|s|d 7}ttd|t ||s|rttd| |rt|d krtt ||j dkrttd|j t |d}z^t |j}t|r"tdt|j} t| } t t ||| |tj} t| t| | WS|rrt |Xd} d}d} d}d}d}zltdkrt } nt !} t j"t j#t j$t j%t j&t j'd|}tdkr |rl|rlt(t)||*}t |j}t|rtdt|j} t| }t +||||tj,}t|t| } t | || |tj-} t| q|rt|j} t| } t.t d} t /| |t0}t|t 1| |t |}t|t 2| | | |j}t|t3| } q|dkrxt(t)||*}t 4|j} t| r tdt 5|t || }t|rDtdt 6|t0} t| } t7| }t 6||} t| n|dkrt(t)||*}t 8|j}t|rtdt 9|t ||}t|rtdt :|t0} t| } t7| }t :||} t| nt|j} t| } t.t d| } t.t d}t ;| ||t0|j}t|t<|}|rt =|tj>dtj?tj@t0}t|tdkrt =|tj>tjAtjBBtjCdt0}t|t 1| |t |}t|t D| | | }t|t3| } t| | WS| r"tdkrt | n t | |r2t || rBt | |rRt ||rbt ||rrt |XdS)a Generates an RSA, DSA or ECDSA signature :param private_key: The PrivateKey to generate the signature with :param data: A byte string of the data the signature is for :param hash_algorithm: A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512" :param rsa_pss_padding: If the private_key is an RSA key, this enables PSS padding :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library :return: A byte string of the signature zO private_key must be an instance of PrivateKey, not %s rrMrLrrrrrrrrrrrrrNrrrrmzunsigned int *rdrkzsize_t *rrr)Err7rrr(r*rNrgrurvrrSrr!rwrrBrr$rrZRSA_private_encryptr"rrr#rrrxrryrrrrrrrrrrrrZRSA_padding_add_PKCS1_PSSrrrrrrZ EVP_SignFinalrrZ DSA_do_signZ i2d_DSA_SIGrrZ ECDSA_do_signZ i2d_ECDSA_SIGZEVP_DigestSignInitrrrrrrrrZEVP_DigestSignFinal)rrrrrZ pkey_is_rsarrrMrUrZsignature_lengthrrdrrrrrZ em_bufferrrrrrGrGrHrqs                                           r)NN)N)N)N)F)F)Q __future__rrrrrZ_asn1rrrr r r r Z _asymmetricr rrrrrrrr_errorsrZ_ffirrrrrrrrrZ _libcryptor!r"r#r$errorsr%r&r'_typesr(r)r*r+utilr,__all__r7r8r1rr2rr4r5rr6r3r<r;r:r9rrrr>r@r.r0rr=r?r-r/rrGrGrGrHs~ , ,  Tl OC' 8F  =87('"" '&!!__pycache__/symmetric.cpython-38.pyc000064400000042612147205320040013422 0ustar00U af[ @s ddlmZmZmZmZddlZddlmZddlm Z m Z m Z m Z m Z mZddlmZmZmZmZddlmZdd lmZmZd d d d ddddddddg Zdd Zdd Zdd Zdd ZddZddZddZ ddZ!ddZ"d dZ#d!dZ$d"dZ%d#dZ&d$d%Z'd&d'Z(d(d)Z)dS)*)unicode_literalsdivisionabsolute_importprint_functionN)pretty_message)newnullis_nullbuffer_from_bytesbytes_from_bufferderef) libcryptolibcrypto_legacy_supportLibcryptoConsthandle_openssl_error) rand_bytes) type_namebyte_clsaes_cbc_no_padding_decryptaes_cbc_no_padding_encryptaes_cbc_pkcs7_decryptaes_cbc_pkcs7_encryptdes_cbc_pkcs5_decryptdes_cbc_pkcs5_encryptrc2_cbc_pkcs5_decryptrc2_cbc_pkcs5_encrypt rc4_decrypt rc4_encrypttripledes_cbc_pkcs5_decrypttripledes_cbc_pkcs5_encryptcCsjt|}|std}nt|dkr4ttdt|t|ddkrVttdt||t||||dfS)a Encrypts plaintext using AES in CBC mode with a 128, 192 or 256 bit key and no padding. This means the ciphertext must be an exact multiple of 16 bytes long. :param key: The encryption key - a byte string either 16, 24 or 32 bytes long :param data: The plaintext - a byte string :param iv: The initialization vector - either a byte string 16-bytes long or None to generate an IV :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A tuple of two byte strings (iv, ciphertext) : iv must be 16 bytes long - is %s rzJ data must be a multiple of 16 bytes long - is %s F_calculate_aes_cipherrlen ValueErrorr_encryptkeydataivcipherr.L/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_openssl/symmetric.pyrs  cCs6t|}t|dkr&ttdt|t||||dS)aM Decrypts AES ciphertext in CBC mode using a 128, 192 or 256 bit key and no padding. :param key: The encryption key - a byte string either 16, 24 or 32 bytes long :param data: The ciphertext - a byte string :param iv: The initialization vector - a byte string 16-bytes long :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A byte string of the plaintext r"r#Fr%r&r'r_decryptr)r.r.r/rMs cCsHt|}|std}nt|dkr4ttdt||t||||dfS)a Encrypts plaintext using AES in CBC mode with a 128, 192 or 256 bit key and PKCS#7 padding. :param key: The encryption key - a byte string either 16, 24 or 32 bytes long :param data: The plaintext - a byte string :param iv: The initialization vector - either a byte string 16-bytes long or None to generate an IV :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A tuple of two byte strings (iv, ciphertext) r"r#Tr$r)r.r.r/rqs  cCs6t|}t|dkr&ttdt|t||||dS)a9 Decrypts AES ciphertext in CBC mode using a 128, 192 or 256 bit key :param key: The encryption key - a byte string either 16, 24 or 32 bytes long :param data: The ciphertext - a byte string :param iv: The initialization vector - a byte string 16-bytes long :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A byte string of the plaintext r"r#Tr0r)r.r.r/rs cCsVt|dkrttdt|t|dkr0d}n"t|dkrBd}nt|dkrRd}|S) a Determines if the key is a valid AES 128, 192 or 256 key :param key: A byte string of the key to use :raises: ValueError - when an invalid key is provided :return: A unicode string of the AES variation - "aes128", "aes192" or "aes256" )r" zo key must be either 16, 24 or 32 bytes (128, 192 or 256 bits) long - is %s r"aes128r2aes192r3aes256)r&r'r)r*r-r.r.r/r%s    r%cCsFts tdt|dks$t|dkr6ttdt|td||ddS)a Encrypts plaintext using RC4 with a 40-128 bit key :param key: The encryption key - a byte string 5-16 bytes long :param data: The plaintext - a byte string :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A byte string of the ciphertext -OpenSSL has been compiled without RC4 supportr"Q key must be 5 to 16 bytes (40 to 128 bits) long - is %s rc4N)rEnvironmentErrorr&r'rr(r*r+r.r.r/rscCsFts tdt|dks$t|dkr6ttdt|td||ddS)a Decrypts RC4 ciphertext using a 40-128 bit key :param key: The encryption key - a byte string 5-16 bytes long :param data: The ciphertext - a byte string :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A byte string of the plaintext r7r8r"r9r:Nrr;r&r'rr1r<r.r.r/rscCsvts tdt|dks$t|dkr6ttdt||sDtd}nt|dkrbttdt||td|||dfS) ah Encrypts plaintext using RC2 in CBC mode with a 40-128 bit key and PKCS#5 padding. :param key: The encryption key - a byte string 8 bytes long :param data: The plaintext - a byte string :param iv: The initialization vector - a byte string 8-bytes long or None to generate an IV :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A tuple of two byte strings (iv, ciphertext) -OpenSSL has been compiled without RC2 supportr8r"r99 iv must be 8 bytes long - is %s rc2Trr;r&r'rrr(r*r+r,r.r.r/rs  cCsdts tdt|dks$t|dkr6ttdt|t|dkrTttdt|td|||dS) a5 Decrypts RC2 ciphertext ib CBC mode using a 40-128 bit key and PKCS#5 padding. :param key: The encryption key - a byte string 8 bytes long :param data: The ciphertext - a byte string :param iv: The initialization vector - a byte string 8 bytes long :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A byte string of the plaintext r>r8r"r9r?r@rATr=rCr.r.r/rNs cCst|dkr*t|dkr*ttdt||s8td}nt|dkrVttdt|d}t|dkrz||dd}d}|t||||d fS) a Encrypts plaintext using 3DES in CBC mode using either the 2 or 3 key variant (16 or 24 byte long key) and PKCS#5 padding. :param key: The encryption key - a byte string 16 or 24 bytes long (2 or 3 key mode) :param data: The plaintext - a byte string :param iv: The initialization vector - a byte string 8-bytes long or None to generate an IV :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A tuple of two byte strings (iv, ciphertext) r"r2zT key must be 16 bytes (2 key) or 24 bytes (3 key) long - %s r?z6 iv must be 8 bytes long - %s tripledes_3keyrtripledes_2keyT)r&r'rrr(r)r.r.r/r!{s"   cCs|t|dkr*t|dkr*ttdt|t|dkrHttdt|d}t|dkrl||dd}d}t||||d S) au Decrypts 3DES ciphertext in CBC mode using either the 2 or 3 key variant (16 or 24 byte long key) and PKCS#5 padding. :param key: The encryption key - a byte string 16 or 24 bytes long (2 or 3 key mode) :param data: The ciphertext - a byte string :param iv: The initialization vector - a byte string 8-bytes long :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A byte string of the plaintext r"r2zW key must be 16 bytes (2 key) or 24 bytes (3 key) long - is %s r?r@rDrrET)r&r'rr1r)r.r.r/r s  cCsjts tdt|dkr*ttdt||s8td}nt|dkrVttdt||td|||dfS)a Encrypts plaintext using DES in CBC mode with a 56 bit key and PKCS#5 padding. :param key: The encryption key - a byte string 8 bytes long (includes error correction bits) :param data: The plaintext - a byte string :param iv: The initialization vector - a byte string 8-bytes long or None to generate an IV :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A tuple of two byte strings (iv, ciphertext) -OpenSSL has been compiled without DES supportr?T key must be 8 bytes (56 bits + 8 parity bits) long - is %s r@desTrBrCr.r.r/rs   cCsXts tdt|dkr*ttdt|t|dkrHttdt|td|||dS)aN Decrypts DES ciphertext in CBC mode using a 56 bit key and PKCS#5 padding. :param key: The encryption key - a byte string 8 bytes long (includes error correction bits) :param data: The ciphertext - a byte string :param iv: The initialization vector - a byte string 8-bytes long :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A byte string of the plaintext rFr?rGr@rHTr=rCr.r.r/rs  c Cst|tsttdt|t|ts8ttdt||dkr\t|ts\ttdt||dkr|s|tdddgk}|r|rt|dd krtd d }z^t }t |rt d t ||\}}|d krt}|td dgkrTt||ttt} t | t|t|} t | |d krNt|tjt|d t} t | t}t||t||} t | |d k rt|t|} t | t|} ttd} t|| | |t|} t | t| t| } t|| | } t | | t| t| 7} | WS|rt |Xd S)a Encrypts plaintext :param cipher: A unicode string of "aes128", "aes192", "aes256", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: The encryption key - a byte string 5-32 bytes long :param data: The plaintext - a byte string :param iv: The initialization vector - a byte string - unused for RC4 :param padding: Boolean, if padding should be used - unused for RC4 :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A byte string of the ciphertext ; key must be a byte string, not %s < data must be a byte string, not %s r:: iv must be a byte string, not %s r4r5r6r"rpadding must be specifiedNrAr?int *) isinstancer TypeErrorrrsetr&r'rEVP_CIPHER_CTX_freeEVP_CIPHER_CTX_newr r_setup_evp_encrypt_decryptr ZEVP_EncryptInit_exEVP_CIPHER_CTX_set_key_lengthEVP_CIPHER_CTX_ctrlrEVP_CTRL_SET_RC2_KEY_BITSEVP_CIPHER_CTX_set_paddingintr rZEVP_EncryptUpdater r ZEVP_EncryptFinal_ex) r-r*r+r,paddingZis_aesevp_cipher_ctx evp_cipher buffer_sizeresbuffer output_lengthoutputr.r.r/r(:sr       r(c Cst|tsttdt|t|ts8ttdt||dkr\t|ts\ttdt||tddddgkr||s|tdd }z^t }t |rt d t ||\}}|d krt }|td dgkr6t||t t t }t |t|t|}t ||d kr0t|tjt|d t }t |t }t||t ||}t ||d k rtt|t|}t |t|} ttd } t|| | |t|}t |t| t| } t|| | }t || t| t| 7} | WS|rt|Xd S)a Decrypts AES/RC4/RC2/3DES/DES ciphertext :param cipher: A unicode string of "aes128", "aes192", "aes256", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: The encryption key - a byte string 5-32 bytes long :param data: The ciphertext - a byte string :param iv: The initialization vector - a byte string - unused for RC4 :param padding: Boolean, if padding should be used - unused for RC4 :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by OpenSSL :return: A byte string of the plaintext rIrJr:rKr4r5r6rLNrrAr?rM)rNrrOrrrPr'rrQrRr rrSr ZEVP_DecryptInit_exrTr&rUrrVrWrXr rZEVP_DecryptUpdater r ZEVP_DecryptFinal_ex) r-r*r+r,rYrZr[r\r]r^r_r`r.r.r/r1sn      r1c Csxtjtjtjtjtjtjtjtjd|}|dkr>t |}n2dddddddd|}|t t t ||}||fS)a Creates an EVP_CIPHER pointer object and determines the buffer size necessary for the parameter specified. :param evp_cipher_ctx: An EVP_CIPHER_CTX pointer :param cipher: A unicode string of "aes128", "aes192", "aes256", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: The key byte string :param data: The plaintext or ciphertext as a byte string :param padding: If padding is to be used :return: A 2-element tuple with the first element being an EVP_CIPHER pointer and the second being an integer that is the required buffer size )r4r5r6rAr:rHrErDr:r"r?)r4r5r6rArHrErD) rZEVP_aes_128_cbcZEVP_aes_192_cbcZEVP_aes_256_cbcZ EVP_rc2_cbcZEVP_rc4Z EVP_des_cbcZEVP_des_ede_cbcZEVP_des_ede3_cbcr&rXmathceil)r-r+r[r\ block_sizer.r.r/rSs2    rS)* __future__rrrrra_errorsrZ_ffirr r r r r Z _libcryptorrrrutilr_typesrr__all__rrrrr%rrrrr!r rrr(r1rSr.r.r.r/sF   0$'#!!!0-300,rn__pycache__/tls.cpython-38.pyc000064400000064774147205320040012225 0ustar00U af@sddlmZmZmZmZddlZddlZddlZddl Z ddl Z ddl m Z m Z ddlmZmZmZmZddlmZddlmZdd lmZdd lmZmZmZmZmZdd l m!Z!m"Z"m#Z#m$Z$dd l%m&Z&m'Z'm(Z(dd l)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;ddlm?Z?ddl@mAZAejBdkr\eCZDejBdkrpejEZFnejFZFddgZGeHdZIeJdZKe jLe jMe jNe jOe jPdZQddZRGdddeSZTGdddeSZUdS))unicode_literalsdivisionabsolute_importprint_functionN)libssl LibsslConst) libcryptolibcrypto_version_infohandle_openssl_errorpeek_openssl_error)_backend_config) Certificate)pretty_message)nullbytes_from_bufferbuffer_from_bytesis_nullbuffer_pointer) type_namestr_clsbyte_cls int_types)TLSErrorTLSDisconnectErrorTLSGracefulDisconnectError)detect_client_auth_request extract_chainget_dh_params_lengthparse_session_inforaise_client_authraise_dh_paramsraise_disconnectionraise_expired_not_yet_validraise_handshakeraise_hostnameraise_no_issuerraise_protocol_errorraise_protocol_versionraise_self_signedraise_verificationraise_weak_signatureparse_tls_recordsparse_handshake_messages)load_certificater)parse_certificate)get_path)r3 TLSSession TLSSockettrust_list_paths( | | ))SSLv2SSLv3TLSv1TLSv1.1TLSv1.2cCstdkr |S|dd|dfS)a^ Takes a 3-element tuple from peek_openssl_error() and modifies it to handle the changes in OpenSSL 3.0. That release removed the concept of an error function, meaning the second item in the tuple will always be 0. :param error_tuple: A 3-element tuple of integers :return: A 3-element tuple of integers r2rr )r )Z error_tupler=F/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_openssl/tls.py_homogenize_openssl3_errorDsr?c@s:eZdZdZdZdZdZdZdZdZ dddZ ddZ dS) r5zj A TLS session object that multiple TLSSocket objects can share for the sake of session reuse NFc Cst|tsttdt|||_|dkr8tdddg}t|trNt|g}nt|tsjttdt|tddddg}||}|rttdt |||_ g|_ |r4|D]}t|t r|j }nbt|trt|}nNt|trt|d }t|}W5QRXnt|ts&ttd t||j |qd}z|td krPt} nt} t| }t|rttd ||_t|d t|tjtj t!t"j#tddgkrt$} | dkrt%} t"j#dkrd} nd} t&|| '| t!} n t(|} t| |rtj)ntj*} t+|| t!t,|d} t| tdg}|||j O}|D]}t|tj-t.|t!qV|j rt/|}|j D]$}t0|}t1||j2} t| qWn.t3k r|rt4|d|_YnXdS)a] :param protocol: A unicode string or set of unicode strings representing allowable protocols to negotiate with the server: - "TLSv1.2" - "TLSv1.1" - "TLSv1" - "SSLv3" Default is: {"TLSv1", "TLSv1.1", "TLSv1.2"} :param manual_validation: If certificate and certificate path validation should be skipped and left to the developer to implement :param extra_trust_roots: A list containing one or more certificates to be treated as trust roots, in one of the following formats: - A byte string of the DER encoded certificate - A unicode string of the certificate filename - An asn1crypto.x509.Certificate object - An oscrypto.asymmetric.Certificate object :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library zM manual_validation must be a boolean, not %s Nr:r;r<zu protocol must be a unicode string or set of unicode strings, not %s r9z protocol must contain only the unicode strings "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2", not %s rbz extra_trust_roots must be a list of byte strings, unicode strings, asn1crypto.x509.Certificate objects or oscrypto.asymmetric.Certificate objects, not %s rrriXwin32darwinmbcsutf-8sECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHAr8)5 isinstancebool TypeErrorrr_manual_validationsetr ValueErrorrepr _protocols_extra_trust_rootsrasn1rr0openreadAsn1Certificateappendr rZ SSLv23_methodZ TLS_methodZ SSL_CTX_newrr _ssl_ctxZSSL_CTX_set_timeoutZ SSL_CTX_ctrlrZSSL_CTRL_SET_SESS_CACHE_MODEZSSL_SESS_CACHE_CLIENTrsysplatform_trust_list_pathr1ZSSL_CTX_load_verify_locationsencodeZ SSL_CTX_set_default_verify_pathsZSSL_VERIFY_NONEZSSL_VERIFY_PEERZSSL_CTX_set_verifyZSSL_CTX_set_cipher_listZSSL_CTRL_OPTIONS _PROTOCOL_MAPZSSL_CTX_get_cert_storer/ZX509_STORE_add_certx509 Exception SSL_CTX_free)selfprotocolZmanual_validationZextra_trust_rootsZvalid_protocolsZunsupported_protocolsZextra_trust_rootfZssl_ctxmethodr7Z path_encodingresult verify_modeZdisabled_protocolsZdisabled_protocolZ x509_storecert oscrypto_certr=r=r>__init__ds                      zTLSSession.__init__cCs4|jrt|jd|_|jr0t|jd|_dSN)rTrr\ _ssl_sessionSSL_SESSION_freer]r=r=r>__del__s   zTLSSession.__del__)NFN) __name__ __module__ __qualname____doc__rMZ_ciphersrIrNrTrgrerjr=r=r=r>r5Ws 3c@seZdZdZdZdZdZdZdZdZ dZ dZ dZ dZ dZdZdZdZdZdZdZdZdZdZed@ddZdAdd Zd d Zd d ZddZddZdBddZddZ ddZ!ddZ"ddZ#dCddZ$ddZ%d d!Z&d"d#Z'd$d%Z(d&d'Z)e*d(d)Z+e*d*d+Z,e*d,d-Z-e*d.d/Z.e*d0d1Z/e*d2d3Z0e*d4d5Z1e*d6d7Z2e*d8d9Z3e*d:d;Z4e*dd?Z6dS)Dr6z8 A wrapper around a socket.socket that adds TLS N FcCst|tjsttdt|t|ts:ttdt||dk r^t|ts^ttdt||dd|d}||_||_ | |S)az Takes an existing socket and adds TLS :param socket: A socket.socket object to wrap with TLS :param hostname: A unicode string of the hostname or IP the socket is connected to :param session: An existing TLSSession object to allow for session reuse, specific protocol or manual certificate validation :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library zU socket must be an instance of socket.socket, not %s zK hostname must be a unicode string, not %s N` session must be an instance of oscrypto.tls.TLSSession, not %s )session) rFsocket_socketrHrrrr5_socket _hostname _handshake)clsrshostnamerqZ new_socketr=r=r>wrapSs(  zTLSSocket.wrap cCsd|_d|_|dkr$|dkr$d|_n|t|ts@ttdt|t|ts\ttdt||dk rt|t j sttdt|t ||f||_|j ||dkrt}nt|tsttdt|||_|jr||_|dS)a :param address: A unicode string of the domain name or IP address to connect to :param port: An integer of the port number to connect to :param timeout: An integer timeout to use for the socket :param session: An oscrypto.tls.TLSSession object to allow for session reuse and controlling the protocols and validation performed NzR address must be a unicode string, not %s zI port must be an integer, not %s zJ timeout must be a number, not %s rp) _raw_bytes_decrypted_bytesrtrFrrHrrrnumbersNumberrrcreate_connection settimeoutr5_sessionrurv)r]addressporttimeoutrqr=r=r>res@    zTLSSocket.__init__c# CsNd|_d|_d|_zt|jj|_t|jr>d|_tdt }t ||_t|jrdtdt ||_t|jrtdt |j|j|j|j d}t|jtjtj|t|j|jjrt|j|jjt|j|_t|j|_d}d}t|j}||7}|dkr$qt|j|}|tjkr|}|dkrx|dkr`tt|rpt t!|||7}q|tj"kr||7}q|tj#krd|_$|%d|&qt'}tj(tj)tj*f} t+| } tj(tj,tj*f} t+| } tj(tj-tj.f} t+| } || ks.|| ks.|| kr4t/t0dkrPtj(tj1tj2f} ntj(tj3tj4f} t+| } || krzt!|tj(tj1tj5f} t+| } || krt6tj(tj1tj7f}t0d kr||krt8tj(tj9tj7f}t+|}||krPd}t:|D]B\}}}|d krqt;|D]\}}|d krd}qqq|rJt t8t0dkrltj(tjtj=f}t+|}tj?tj@tjAf}t+|}||krtB|}|r|d}tC|}|jDjEtFd d gkrtG|||krtH|j}tB|}d}d}d}d}d}|rl|d}tC|}|jI}tFtjJtjKtjLg}||krT| }tFtjMtjNg} || k}|rztO||rtP||rtQ||r|jDjEtFd d gkrtG|tR|tdtSqtT||}!|!d|_U|!d|_V|!d|_W|!d|_X|!d|_Y|jVZddkrrvs                                             zTLSSocket._handshakecCs\|j}z||jd7}Wntjk r0YnX|}t|j|t|}||d|_|S)aD Reads data from the socket and writes it to the memory bio used by libssl to decrypt the data. Returns the unencrypted data for the purpose of debugging handshakes. :return: A byte string of ciphertext from the socket. Used for debugging the handshake only. roN) r|rtrecvrrrrZ BIO_writerlen)r]dataoutputZwrittenr=r=r>rs zTLSSocket._raw_readc Cst|j}|dkrdSt|j|}t|j|j|}t|j|}|}t|rd}z|j |}WnZt j k r}z:|j dks|j dkrd}ntjdkr|j dkrd}nW5d }~XYnX|rt||d }t|rF|qF|S) z Takes ciphertext from the memory bio and writes it to the socket. :return: A byte string of ciphertext going to the socket. Used for debugging the handshake only. rr{Fh TrC)N)rZBIO_ctrl_pendingrminrZBIO_readrrrrtsendrrrerrnorUrVr# select_write) r]Zdata_availableto_readrQZto_writerZraise_disconnectsenter=r=r>rs.     zTLSSocket._raw_writecCst|tsttdt|t|j}||krP|jd|}|j|d|_|S|jdkrb||dkr| ds|j}d|_|St |j ||}|j}d}|rXd}t |j|j|}||dkrFt |j|}|tjkr|dkrd}qtnH|tjkr|d}qn,|tjkrrQsX          zTLSSocket.readcCs8t|jdkrdSt|jggg|\}}}t|dkS)aZ Blocks until the socket is ready to be read from, or the timeout is hit :param timeout: A float - the period of time to wait for data to be read. None for no time limit. :return: A boolean - if data is ready to be read. Will only be False if timeout is not None. rT)rr}selectrt)r]rZ read_readyrr=r=r>rvszTLSSocket.select_readc Cst|ts&t|ts&ttdt|d}t|t}t|jdkrP|j}d|_n,|jdkrb| t |jppd}| |}t|}||7}|r| |}|dk r|}qq4td|t|d} ||| }|dkr4|t|}qq4||d|j|_|d|S)a Reads data from the socket until a marker is found. Data read includes the marker. :param marker: A byte string or regex object from re.compile(). Used to determine when to stop reading. Regex objects are more inefficient since they must scan the entire byte string of read data each time data is read off the socket. :return: A byte string of the data read, including the marker z_ marker must be a byte string or compiled regex object, not %s r{rNrorr)rFrPatternrHrrrr}rrrZ SSL_pendingrQsearchendmaxr) r]markerris_regexrroffsetmatchrstartr=r=r> read_untils8      zTLSSocket.read_untilcCs |tS)z Reads a line from the socket, including the line ending of "\r\n", "\r", or "\n" :return: A byte string of the next line from the socket )r _line_regexrir=r=r> read_lines zTLSSocket.read_linecCs0d}|}|dkr,|||7}|t|}q|S)z Reads exactly the specified number of bytes from the socket :param num_bytes: An integer - the exact number of bytes to read :return: A byte string of the data that was read r{r)rQr)r] num_bytesr remainingr=r=r> read_exactlys zTLSSocket.read_exactlycCst|}|r|jdkr|t|j||}||dkrt|j|}|tjkrl| dkrdqt nD|tj kr|qn.|tj krd|_ |d|n tdt||d}t|}qdS)a Writes data to the TLS-wrapped socket :param data: A byte string to write to the socket :raises: socket.socket - when a non-TLS socket error occurs oscrypto.errors.TLSError - when a TLS-related error occurs ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type OSError - when an error is returned by the OS crypto library Nrr{TF)rrrrZ SSL_writerrrrrr#rrrrr r)r]rdata_lenrarr=r=r>writes,         zTLSSocket.writecCs&tg|jgg|\}}}t|dkS)aw Blocks until the socket is ready to be written to, or the timeout is hit :param timeout: A float - the period of time to wait for the socket to be ready to written to. None for no time limit. :return: A boolean - if the socket is ready for writing. Will only be False if timeout is not None. r)rrtr)r]rrZ write_readyr=r=r>rs zTLSSocket.select_writecCs|jdkrdSt|j}z |Wntk r:YnX|dkrFq|dkrt|j|}|tjkrz|dkrqqqq|tj kr|qqt dt q|rd|_ t |jd|_d|_d|_z|jtjWntjk rYnXdS)z Shuts down the TLS session and then shuts down the underlying socket :param manual: A boolean if the connection was manually shutdown Nrr{T)rrZ SSL_shutdownrrrrrrrr r _local_closedrrrrtshutdownrr SHUT_RDWRr)r]Zmanualrarr=r=r>rs:        zTLSSocket._shutdowncCs|ddS)zV Shuts down the TLS session and then shuts down the underlying socket TN)rrir=r=r>rQszTLSSocket.shutdowncCsFz |W5|jr@z|jWntjk r8YnXd|_XdS)zN Shuts down the TLS session and socket and forcibly closes it N)rtrrrrrrir=r=r>rXs zTLSSocket.closec Cst|j}t|rtdttdkr2t|}n t|}g|_ t d|D]}tdkrft ||}n t ||}t |t}t|}t|}t ||}t|t||} t| } |dkr| |_qL|j | qLdS)zh Reads end-entity and intermediate certificate information from the TLS session rrAN)rZSSL_get_peer_cert_chainrrr rr Zsk_numZOPENSSL_sk_num_intermediatesrangeZsk_valueZOPENSSL_sk_valuer Zi2d_X509rrrrrRload _certificaterS) r]Z stack_pointerZ number_certsindexZx509_ buffer_sizeZ cert_bufferZ cert_pointerZ cert_lengthZ cert_datarcr=r=r>_read_certificateshs*        zTLSSocket._read_certificatescCs,|jrtdn|jr tdntddS)zi Raises an exception describing if the local or remote end closed the connection z!The connection was already closedz$The remote end closed the connectionzThe connection was closedN)rrrrrir=r=r>rs   zTLSSocket._raise_closedcCs*|jdkr||jdkr$||jS)zu An asn1crypto.x509.Certificate object of the end-entity certificate presented by the server N)rrrrrir=r=r>rs   zTLSSocket.certificatecCs*|jdkr||jdkr$||jS)zz A list of asn1crypto.x509.Certificate objects that were presented as intermediates by the server N)rrrrrrir=r=r> intermediatess   zTLSSocket.intermediatescCs|jS)zg A unicode string of the IANA cipher suite name of the negotiated cipher suite )rrir=r=r>rszTLSSocket.cipher_suitecCs|jS)zM A unicode string of: "TLSv1.2", "TLSv1.1", "TLSv1", "SSLv3" )rrir=r=r>r^szTLSSocket.protocolcCs|jS)z5 A boolean if compression is enabled )rrir=r=r>rszTLSSocket.compressioncCs|jSzM A unicode string of "new" or "reused" or None for no ticket )rrir=r=r>rszTLSSocket.session_idcCs|jSr)rrir=r=r>rszTLSSocket.session_ticketcCs|jS)zM The oscrypto.tls.TLSSession object used for this connection )rrir=r=r>rqszTLSSocket.sessioncCs|jS)zN A unicode string of the TLS server domain name or IP address )rurir=r=r>rxszTLSSocket.hostnamecCs|jdS)zJ An integer of the port number the socket is connected to r)rs getpeernamerir=r=r>rszTLSSocket.portcCs|jdkr||jS)z9 The underlying socket.socket connection N)rrrtrir=r=r>rss zTLSSocket.socketcCs |dSrf)rrir=r=r>rjszTLSSocket.__del__)N)rzN)N)N)7rkrlrmrnrtrrrrrrrr|r}rurrrrrrrrr classmethodryrervrrrQrrrrrrrrrrrpropertyrrrr^rrrrqrxrrsrjr=r=r=r>r6 s 3 C'W : , 3$            )V __future__rrrrrUrersrrrr~Z_libsslrrZ _libcryptor r r r rZ_asn1rrR_errorsrZ_ffirrrrr_typesrrrrerrorsrrr_tlsrrrr r!r"r#r$r%r&r'r(r)r*r+r,r-r.Z asymmetricr/keysr0Z trust_listr1 version_infoxrangerZ _pattern_typer__all__getrWcompilerZSSL_OP_NO_SSLv2ZSSL_OP_NO_SSLv3ZSSL_OP_NO_TLSv1ZSSL_OP_NO_TLSv1_1ZSSL_OP_NO_TLSv1_2rYr?objectr5r6r=r=r=r>sJ   P       J__pycache__/util.cpython-38.pyc000064400000011712147205320040012360 0ustar00U af@sddlmZmZmZmZddlmZddlmZm Z ddl m Z m Z m Z ddlmZddlmZmZmZd d d gZe d krdd lmZndd Zde_dd ZdS))unicode_literalsdivisionabsolute_importprint_function)pretty_message)buffer_from_bytesbytes_from_buffer) libcryptolibcrypto_version_infohandle_openssl_error) rand_bytes) type_namebyte_cls int_typespbkdf2 pkcs12_kdfr)r )rc Cst|tsttdt|t|ts8ttdt|t|tsTttdt||dkrdtdt|tsttdt||dkrtd|tdd d d d gkrttd t|t j t j t j t j t jd|}t|}t |t||t|||||}t|t|S)a PBKDF2 from PKCS#5 :param hash_algorithm: The string name of the hash algorithm to use: "sha1", "sha224", "sha256", "sha384", "sha512" :param password: A byte string of the password to use an input to the KDF :param salt: A cryptographic random byte string :param iterations: The numbers of iterations to use when deriving the key :param key_length: The length of the desired key in bytes :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type :return: The derived key as a byte string zH password must be a byte string, not %s zD salt must be a byte string, not %s zG iterations must be an integer, not %s r z!iterations must be greater than 0zG key_length must be an integer, not %s z!key_length must be greater than 0sha1sha224sha256sha384sha512z hash_algorithm must be one of "sha1", "sha224", "sha256", "sha384", "sha512", not %s )rrrrr) isinstancer TypeErrorrrr ValueErrorsetreprr EVP_sha1 EVP_sha224 EVP_sha256 EVP_sha384 EVP_sha512rZPKCS5_PBKDF2_HMAClenr r )hash_algorithmpasswordsalt iterations key_lengthZevp_md output_bufferresultr+G/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_openssl/util.pyrsd      Fc Csdt|tsttdt|t|ts8ttdt|t|tsTttdt||dkrnttdt|t|tsttdt||dkrttdt||tdd d d d d gkrttdt||tdddgkrttdt|| d dd}t j t j t jt jt jt jd|}t|}t |t||t|||||| } t| t|S)a0 KDF from RFC7292 appendix B.2 - https://tools.ietf.org/html/rfc7292#page-19 :param hash_algorithm: The string name of the hash algorithm to use: "md5", "sha1", "sha224", "sha256", "sha384", "sha512" :param password: A byte string of the password to use an input to the KDF :param salt: A cryptographic random byte string :param iterations: The numbers of iterations to use when deriving the key :param key_length: The length of the desired key in bytes :param id_: The ID of the usage - 1 for key, 2 for iv, 3 for mac :raises: ValueError - when any of the parameters contain an invalid value TypeError - when any of the parameters are of the wrong type :return: The derived key as a byte string z@ password must be a byte string, not %s z< salt must be a byte string, not %s z? iterations must be an integer, not %s r zC iterations must be greater than 0 - is %s z? key_length must be an integer, not %s zC key_length must be greater than 0 - is %s md5rrrrrz hash_algorithm must be one of "md5", "sha1", "sha224", "sha256", "sha384", "sha512", not %s rz< id_ must be one of 1, 2, 3, not %s zutf-8zutf-16bes)r-rrrrr)rrrrrrrrrdecodeencoder ZEVP_md5rrr r!r"rZPKCS12_key_gen_unir#r r ) r$r%r&r'r(Zid_Zutf16_passwordZ digest_typer)r*r+r+r,r{s      N) __future__rrrr_errorsrZ_ffirr Z _libcryptor r r Z_randr_typesrrr__all__Z_pkcs5rZ pure_pythonrr+r+r+r,s  a