__init__.py000064400000023032147205106110006652 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import os import platform import sys import threading from ._types import str_cls, type_name from .errors import LibraryNotFoundError from .version import __version__, __version_info__ __all__ = [ '__version__', '__version_info__', 'backend', 'ffi', 'load_order', 'use_ctypes', 'use_openssl', 'use_winlegacy', ] _backend_lock = threading.Lock() _module_values = { 'backend': None, 'backend_config': None, 'ffi': None } def backend(): """ :return: A unicode string of the backend being used: "openssl", "mac", "win", "winlegacy" """ if _module_values['backend'] is not None: return _module_values['backend'] with _backend_lock: if _module_values['backend'] is not None: return _module_values['backend'] if sys.platform == 'win32': # Windows XP was major version 5, Vista was 6 if sys.getwindowsversion()[0] < 6: _module_values['backend'] = 'winlegacy' else: _module_values['backend'] = 'win' elif sys.platform == 'darwin': _module_values['backend'] = 'mac' else: _module_values['backend'] = 'openssl' return _module_values['backend'] def _backend_config(): """ :return: A dict of config info for the backend. Only currently used by "openssl", it may contains zero or more of the following keys: - "libcrypto_path" - "libssl_path" """ if backend() != 'openssl': return {} if _module_values['backend_config'] is not None: return _module_values['backend_config'] with _backend_lock: if _module_values['backend_config'] is not None: return _module_values['backend_config'] _module_values['backend_config'] = {} return _module_values['backend_config'] def use_openssl(libcrypto_path, libssl_path, trust_list_path=None): """ Forces using OpenSSL dynamic libraries on OS X (.dylib) or Windows (.dll), or using a specific dynamic library on Linux/BSD (.so). This can also be used to configure oscrypto to use LibreSSL dynamic libraries. This method must be called before any oscrypto submodules are imported. :param libcrypto_path: A unicode string of the file path to the OpenSSL/LibreSSL libcrypto dynamic library. :param libssl_path: A unicode string of the file path to the OpenSSL/LibreSSL libssl dynamic library. :param trust_list_path: An optional unicode string of the path to a file containing OpenSSL-compatible CA certificates in PEM format. If this is not provided and the platform is OS X or Windows, the system trust roots will be exported from the OS and used for all TLS connections. :raises: ValueError - when one of the paths is not a unicode string OSError - when the trust_list_path does not exist on the filesystem oscrypto.errors.LibraryNotFoundError - when one of the path does not exist on the filesystem RuntimeError - when this function is called after another part of oscrypto has been imported """ if not isinstance(libcrypto_path, str_cls): raise ValueError('libcrypto_path must be a unicode string, not %s' % type_name(libcrypto_path)) if not isinstance(libssl_path, str_cls): raise ValueError('libssl_path must be a unicode string, not %s' % type_name(libssl_path)) if not os.path.exists(libcrypto_path): raise LibraryNotFoundError('libcrypto does not exist at %s' % libcrypto_path) if not os.path.exists(libssl_path): raise LibraryNotFoundError('libssl does not exist at %s' % libssl_path) if trust_list_path is not None: if not isinstance(trust_list_path, str_cls): raise ValueError('trust_list_path must be a unicode string, not %s' % type_name(trust_list_path)) if not os.path.exists(trust_list_path): raise OSError('trust_list_path does not exist at %s' % trust_list_path) with _backend_lock: new_config = { 'libcrypto_path': libcrypto_path, 'libssl_path': libssl_path, 'trust_list_path': trust_list_path, } if _module_values['backend'] == 'openssl' and _module_values['backend_config'] == new_config: return if _module_values['backend'] is not None: raise RuntimeError('Another part of oscrypto has already been imported, unable to force use of OpenSSL') _module_values['backend'] = 'openssl' _module_values['backend_config'] = new_config def use_winlegacy(): """ Forces use of the legacy Windows CryptoAPI. This should only be used on Windows XP or for testing. It is less full-featured than the Cryptography Next Generation (CNG) API, and as a result the elliptic curve and PSS padding features are implemented in pure Python. This isn't ideal, but it a shim for end-user client code. No one is going to run a server on Windows XP anyway, right?! :raises: EnvironmentError - when this function is called on an operating system other than Windows RuntimeError - when this function is called after another part of oscrypto has been imported """ if sys.platform != 'win32': plat = platform.system() or sys.platform if plat == 'Darwin': plat = 'OS X' raise EnvironmentError('The winlegacy backend can only be used on Windows, not %s' % plat) with _backend_lock: if _module_values['backend'] == 'winlegacy': return if _module_values['backend'] is not None: raise RuntimeError( 'Another part of oscrypto has already been imported, unable to force use of Windows legacy CryptoAPI' ) _module_values['backend'] = 'winlegacy' def use_ctypes(): """ Forces use of ctypes instead of cffi for the FFI layer :raises: RuntimeError - when this function is called after another part of oscrypto has been imported """ with _backend_lock: if _module_values['ffi'] == 'ctypes': return if _module_values['backend'] is not None: raise RuntimeError( 'Another part of oscrypto has already been imported, unable to force use of ctypes' ) _module_values['ffi'] = 'ctypes' def ffi(): """ Returns the FFI module being used :return: A unicode string of "cffi" or "ctypes" """ if _module_values['ffi'] is not None: return _module_values['ffi'] with _backend_lock: try: import cffi # noqa: F401 _module_values['ffi'] = 'cffi' except (ImportError): _module_values['ffi'] = 'ctypes' return _module_values['ffi'] def load_order(): """ Returns a list of the module and sub-module names for oscrypto in dependency load order, for the sake of live reloading code :return: A list of unicode strings of module names, as they would appear in sys.modules, ordered by which module should be reloaded first """ return [ 'oscrypto._asn1', 'oscrypto._cipher_suites', 'oscrypto._errors', 'oscrypto._int', 'oscrypto._types', 'oscrypto.errors', 'oscrypto.version', 'oscrypto', 'oscrypto._ffi', 'oscrypto._pkcs12', 'oscrypto._pkcs5', 'oscrypto._rand', 'oscrypto._tls', 'oscrypto._linux_bsd.trust_list', 'oscrypto._mac._common_crypto_cffi', 'oscrypto._mac._common_crypto_ctypes', 'oscrypto._mac._common_crypto', 'oscrypto._mac._core_foundation_cffi', 'oscrypto._mac._core_foundation_ctypes', 'oscrypto._mac._core_foundation', 'oscrypto._mac._security_cffi', 'oscrypto._mac._security_ctypes', 'oscrypto._mac._security', 'oscrypto._mac.trust_list', 'oscrypto._mac.util', 'oscrypto._openssl._libcrypto_cffi', 'oscrypto._openssl._libcrypto_ctypes', 'oscrypto._openssl._libcrypto', 'oscrypto._openssl._libssl_cffi', 'oscrypto._openssl._libssl_ctypes', 'oscrypto._openssl._libssl', 'oscrypto._openssl.util', 'oscrypto._win._cng_cffi', 'oscrypto._win._cng_ctypes', 'oscrypto._win._cng', 'oscrypto._win._decode', 'oscrypto._win._advapi32_cffi', 'oscrypto._win._advapi32_ctypes', 'oscrypto._win._advapi32', 'oscrypto._win._kernel32_cffi', 'oscrypto._win._kernel32_ctypes', 'oscrypto._win._kernel32', 'oscrypto._win._secur32_cffi', 'oscrypto._win._secur32_ctypes', 'oscrypto._win._secur32', 'oscrypto._win._crypt32_cffi', 'oscrypto._win._crypt32_ctypes', 'oscrypto._win._crypt32', 'oscrypto._win.trust_list', 'oscrypto._win.util', 'oscrypto.trust_list', 'oscrypto.util', 'oscrypto.kdf', 'oscrypto._mac.symmetric', 'oscrypto._openssl.symmetric', 'oscrypto._win.symmetric', 'oscrypto.symmetric', 'oscrypto._asymmetric', 'oscrypto._ecdsa', 'oscrypto._pkcs1', 'oscrypto._mac.asymmetric', 'oscrypto._openssl.asymmetric', 'oscrypto._win.asymmetric', 'oscrypto.asymmetric', 'oscrypto.keys', 'oscrypto._mac.tls', 'oscrypto._openssl.tls', 'oscrypto._win.tls', 'oscrypto.tls', ] _asn1.py000064400000003647147205106110006126 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function # This file exists strictly to make it easier to vendor a combination of # oscrypto and asn1crypto from asn1crypto import algos, cms, core, keys, pem, pkcs12, util, x509 DHParameters = algos.DHParameters DSASignature = algos.DSASignature KeyExchangeAlgorithm = algos.KeyExchangeAlgorithm Pbkdf2Salt = algos.Pbkdf2Salt EncryptedData = cms.EncryptedData Integer = core.Integer Null = core.Null OctetString = core.OctetString DSAParams = keys.DSAParams DSAPrivateKey = keys.DSAPrivateKey ECDomainParameters = keys.ECDomainParameters ECPointBitString = keys.ECPointBitString ECPrivateKey = keys.ECPrivateKey EncryptedPrivateKeyInfo = keys.EncryptedPrivateKeyInfo PrivateKeyAlgorithm = keys.PrivateKeyAlgorithm PrivateKeyInfo = keys.PrivateKeyInfo PublicKeyAlgorithm = keys.PublicKeyAlgorithm PublicKeyInfo = keys.PublicKeyInfo RSAPrivateKey = keys.RSAPrivateKey RSAPublicKey = keys.RSAPublicKey int_from_bytes = util.int_from_bytes int_to_bytes = util.int_to_bytes OrderedDict = util.OrderedDict timezone = util.timezone armor = pem.armor unarmor = pem.unarmor CertBag = pkcs12.CertBag Pfx = pkcs12.Pfx SafeContents = pkcs12.SafeContents Certificate = x509.Certificate TrustedCertificate = x509.TrustedCertificate __all__ = [ 'armor', 'CertBag', 'Certificate', 'DHParameters', 'DSAParams', 'DSAPrivateKey', 'DSASignature', 'ECDomainParameters', 'ECPointBitString', 'ECPrivateKey', 'EncryptedData', 'EncryptedPrivateKeyInfo', 'int_from_bytes', 'int_to_bytes', 'Integer', 'KeyExchangeAlgorithm', 'Null', 'OctetString', 'OrderedDict', 'Pbkdf2Salt', 'Pfx', 'PrivateKeyAlgorithm', 'PrivateKeyInfo', 'PublicKeyAlgorithm', 'PublicKeyInfo', 'RSAPrivateKey', 'RSAPublicKey', 'SafeContents', 'timezone', 'TrustedCertificate', 'unarmor', ] _asymmetric.py000064400000074300147205106110007433 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import hashlib import hmac import re import binascii from ._asn1 import ( CertBag, Certificate, DSAPrivateKey, ECPrivateKey, EncryptedData, EncryptedPrivateKeyInfo, Integer, OctetString, Pfx, PrivateKeyInfo, PublicKeyInfo, RSAPrivateKey, RSAPublicKey, SafeContents, unarmor, ) from .kdf import pbkdf1, pbkdf2, pkcs12_kdf from .symmetric import ( aes_cbc_pkcs7_decrypt, des_cbc_pkcs5_decrypt, rc2_cbc_pkcs5_decrypt, rc4_decrypt, tripledes_cbc_pkcs5_decrypt, ) from .util import constant_compare from ._errors import pretty_message from ._types import byte_cls, str_cls, type_name class _PrivateKeyBase(): asn1 = None _fingerprint = None def unwrap(self): """ Unwraps the private key into an asn1crypto.keys.RSAPrivateKey, asn1crypto.keys.DSAPrivateKey or asn1crypto.keys.ECPrivateKey object :return: An asn1crypto.keys.RSAPrivateKey, asn1crypto.keys.DSAPrivateKey or asn1crypto.keys.ECPrivateKey object """ if self.algorithm == 'rsa': return self.asn1['private_key'].parsed if self.algorithm == 'dsa': params = self.asn1['private_key_algorithm']['parameters'] return DSAPrivateKey({ 'version': 0, 'p': params['p'], 'q': params['q'], 'g': params['g'], 'public_key': self.public_key.unwrap(), 'private_key': self.asn1['private_key'].parsed, }) if self.algorithm == 'ec': output = self.asn1['private_key'].parsed output['parameters'] = self.asn1['private_key_algorithm']['parameters'] output['public_key'] = self.public_key.unwrap() return output @property def algorithm(self): """ :return: A unicode string of "rsa", "dsa" or "ec" """ return self.asn1.algorithm @property def curve(self): """ :return: A unicode string of EC curve name """ return self.asn1.curve[1] @property def bit_size(self): """ :return: The number of bits in the key, as an integer """ return self.asn1.bit_size @property def byte_size(self): """ :return: The number of bytes in the key, as an integer """ return self.asn1.byte_size class _PublicKeyBase(): asn1 = None _fingerprint = None def unwrap(self): """ Unwraps a public key into an asn1crypto.keys.RSAPublicKey, asn1crypto.core.Integer (for DSA) or asn1crypto.keys.ECPointBitString object :return: An asn1crypto.keys.RSAPublicKey, asn1crypto.core.Integer or asn1crypto.keys.ECPointBitString object """ if self.algorithm == 'ec': return self.asn1['public_key'] return self.asn1['public_key'].parsed @property def fingerprint(self): """ Creates a fingerprint that can be compared with a private 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, None) return self._fingerprint @property def algorithm(self): """ :return: A unicode string of "rsa", "dsa" or "ec" """ return self.asn1.algorithm @property def curve(self): """ :return: A unicode string of EC curve name """ return self.asn1.curve[1] @property def bit_size(self): """ :return: The number of bits in the key, as an integer """ return self.asn1.bit_size @property def byte_size(self): """ :return: The number of bytes in the key, as an integer """ return self.asn1.byte_size class _CertificateBase(): asn1 = None @property def algorithm(self): """ :return: A unicode string of "rsa", "dsa" or "ec" """ return self.public_key.algorithm @property def curve(self): """ :return: A unicode string of EC curve name """ return self.public_key.curve @property def bit_size(self): """ :return: The number of bits in the public key, as an integer """ return self.public_key.bit_size @property def byte_size(self): """ :return: The number of bytes in the public key, as an integer """ return self.public_key.byte_size def _unwrap_private_key_info(key_info): """ Unwraps an asn1crypto.keys.PrivateKeyInfo object into an asn1crypto.keys.RSAPrivateKey, asn1crypto.keys.DSAPrivateKey or asn1crypto.keys.ECPrivateKey. :param key_info: An asn1crypto.keys.PrivateKeyInfo object :return: One of: - asn1crypto.keys.RSAPrivateKey - asn1crypto.keys.DSAPrivateKey - asn1crypto.keys.ECPrivateKey """ key_alg = key_info.algorithm if key_alg == 'rsa' or key_alg == 'rsassa_pss': return key_info['private_key'].parsed if key_alg == 'dsa': params = key_info['private_key_algorithm']['parameters'] parsed = key_info['private_key'].parsed return DSAPrivateKey({ 'version': 0, 'p': params['p'], 'q': params['q'], 'g': params['g'], 'public_key': Integer(pow( params['g'].native, parsed.native, params['p'].native )), 'private_key': parsed, }) if key_alg == 'ec': parsed = key_info['private_key'].parsed parsed['parameters'] = key_info['private_key_algorithm']['parameters'] return parsed raise ValueError('Unsupported key_info.algorithm "%s"' % key_info.algorithm) def _fingerprint(key_object, load_private_key): """ Returns a fingerprint used for correlating public keys and private keys :param key_object: An asn1crypto.keys.PrivateKeyInfo or asn1crypto.keys.PublicKeyInfo :raises: ValueError - when the key_object is not of the proper type ;return: A byte string fingerprint """ if isinstance(key_object, PrivateKeyInfo): key = key_object['private_key'].parsed if key_object.algorithm == 'rsa': to_hash = '%d:%d' % ( key['modulus'].native, key['public_exponent'].native, ) elif key_object.algorithm == 'dsa': params = key_object['private_key_algorithm']['parameters'] public_key = Integer(pow( params['g'].native, key_object['private_key'].parsed.native, params['p'].native )) to_hash = '%d:%d:%d:%d' % ( params['p'].native, params['q'].native, params['g'].native, public_key.native, ) elif key_object.algorithm == 'ec': public_key = key['public_key'].native if public_key is None: # This is gross, but since the EC public key is optional, # and we need to load the private key and use the crypto lib # to get the public key, we have to import the platform-specific # asymmetric implementation. This is the reason a bunch of the # imports are module imports, so we don't get an import cycle. public_key_object = load_private_key(key_object).public_key public_key = public_key_object.asn1['public_key'].parsed.native to_hash = '%s:' % key_object.curve[1] to_hash = to_hash.encode('utf-8') to_hash += public_key if isinstance(to_hash, str_cls): to_hash = to_hash.encode('utf-8') return hashlib.sha256(to_hash).digest() if isinstance(key_object, PublicKeyInfo): if key_object.algorithm == 'rsa': key = key_object['public_key'].parsed to_hash = '%d:%d' % ( key['modulus'].native, key['public_exponent'].native, ) elif key_object.algorithm == 'dsa': key = key_object['public_key'].parsed params = key_object['algorithm']['parameters'] to_hash = '%d:%d:%d:%d' % ( params['p'].native, params['q'].native, params['g'].native, key.native, ) elif key_object.algorithm == 'ec': public_key = key_object['public_key'].native to_hash = '%s:' % key_object.curve[1] to_hash = to_hash.encode('utf-8') to_hash += public_key if isinstance(to_hash, str_cls): to_hash = to_hash.encode('utf-8') return hashlib.sha256(to_hash).digest() raise ValueError(pretty_message( ''' key_object must be an instance of the asn1crypto.keys.PrivateKeyInfo or asn1crypto.keys.PublicKeyInfo classes, not %s ''', type_name(key_object) )) crypto_funcs = { 'rc2': rc2_cbc_pkcs5_decrypt, 'rc4': rc4_decrypt, 'des': des_cbc_pkcs5_decrypt, 'tripledes': tripledes_cbc_pkcs5_decrypt, 'aes': aes_cbc_pkcs7_decrypt, } def parse_public(data): """ Loads a public key from a DER or PEM-formatted file. Supports RSA, DSA and EC public keys. For RSA keys, both the old RSAPublicKey and SubjectPublicKeyInfo structures are supported. Also allows extracting a public key from an X.509 certificate. :param data: A byte string to load the public key from :raises: ValueError - when the data does not appear to contain a public key :return: An asn1crypto.keys.PublicKeyInfo object """ if not isinstance(data, byte_cls): raise TypeError(pretty_message( ''' data must be a byte string, not %s ''', type_name(data) )) key_type = None # Appears to be PEM formatted if re.match(b'\\s*-----', data) is not None: key_type, algo, data = _unarmor_pem(data) if key_type == 'private key': raise ValueError(pretty_message( ''' The data specified does not appear to be a public key or certificate, but rather a private key ''' )) # When a public key returning from _unarmor_pem has a known algorithm # of RSA, that means the DER structure is of the type RSAPublicKey, so # we need to wrap it in the PublicKeyInfo structure. if algo == 'rsa': return PublicKeyInfo.wrap(data, 'rsa') if key_type is None or key_type == 'public key': try: pki = PublicKeyInfo.load(data) # Call .native to fully parse since asn1crypto is lazy pki.native return pki except (ValueError): pass # Data was not PublicKeyInfo try: rpk = RSAPublicKey.load(data) # Call .native to fully parse since asn1crypto is lazy rpk.native return PublicKeyInfo.wrap(rpk, 'rsa') except (ValueError): pass # Data was not an RSAPublicKey if key_type is None or key_type == 'certificate': try: parsed_cert = Certificate.load(data) key_info = parsed_cert['tbs_certificate']['subject_public_key_info'] return key_info except (ValueError): pass # Data was not a cert raise ValueError('The data specified does not appear to be a known public key or certificate format') def parse_certificate(data): """ Loads a certificate from a DER or PEM-formatted file. Supports X.509 certificates only. :param data: A byte string to load the certificate from :raises: ValueError - when the data does not appear to contain a certificate :return: An asn1crypto.x509.Certificate object """ if not isinstance(data, byte_cls): raise TypeError(pretty_message( ''' data must be a byte string, not %s ''', type_name(data) )) key_type = None # Appears to be PEM formatted if re.match(b'\\s*-----', data) is not None: key_type, _, data = _unarmor_pem(data) if key_type == 'private key': raise ValueError(pretty_message( ''' The data specified does not appear to be a certificate, but rather a private key ''' )) if key_type == 'public key': raise ValueError(pretty_message( ''' The data specified does not appear to be a certificate, but rather a public key ''' )) if key_type is None or key_type == 'certificate': try: return Certificate.load(data) except (ValueError): pass # Data was not a Certificate raise ValueError(pretty_message( ''' The data specified does not appear to be a known certificate format ''' )) def parse_private(data, password=None): """ Loads a private key from a DER or PEM-formatted file. Supports RSA, DSA and EC private keys. Works with the follow formats: - RSAPrivateKey (PKCS#1) - ECPrivateKey (SECG SEC1 V2) - DSAPrivateKey (OpenSSL) - PrivateKeyInfo (RSA/DSA/EC - PKCS#8) - EncryptedPrivateKeyInfo (RSA/DSA/EC - PKCS#8) - Encrypted RSAPrivateKey (PEM only, OpenSSL) - Encrypted DSAPrivateKey (PEM only, OpenSSL) - Encrypted ECPrivateKey (PEM only, OpenSSL) :param data: A byte string to load the private key from :param password: The password to unencrypt the private key :raises: ValueError - when the data does not appear to contain a private key, or the password is invalid :return: An asn1crypto.keys.PrivateKeyInfo object """ if not isinstance(data, byte_cls): raise TypeError(pretty_message( ''' data must be a byte string, not %s ''', type_name(data) )) if password is not None: if not isinstance(password, byte_cls): raise TypeError(pretty_message( ''' password must be a byte string, not %s ''', type_name(password) )) else: password = b'' # Appears to be PEM formatted if re.match(b'\\s*-----', data) is not None: key_type, _, data = _unarmor_pem(data, password) if key_type == 'public key': raise ValueError(pretty_message( ''' The data specified does not appear to be a private key, but rather a public key ''' )) if key_type == 'certificate': raise ValueError(pretty_message( ''' The data specified does not appear to be a private key, but rather a certificate ''' )) try: pki = PrivateKeyInfo.load(data) # Call .native to fully parse since asn1crypto is lazy pki.native return pki except (ValueError): pass # Data was not PrivateKeyInfo try: parsed_wrapper = EncryptedPrivateKeyInfo.load(data) encryption_algorithm_info = parsed_wrapper['encryption_algorithm'] encrypted_data = parsed_wrapper['encrypted_data'].native decrypted_data = _decrypt_encrypted_data(encryption_algorithm_info, encrypted_data, password) pki = PrivateKeyInfo.load(decrypted_data) # Call .native to fully parse since asn1crypto is lazy pki.native return pki except (ValueError): pass # Data was not EncryptedPrivateKeyInfo try: parsed = RSAPrivateKey.load(data) # Call .native to fully parse since asn1crypto is lazy parsed.native return PrivateKeyInfo.wrap(parsed, 'rsa') except (ValueError): pass # Data was not an RSAPrivateKey try: parsed = DSAPrivateKey.load(data) # Call .native to fully parse since asn1crypto is lazy parsed.native return PrivateKeyInfo.wrap(parsed, 'dsa') except (ValueError): pass # Data was not a DSAPrivateKey try: parsed = ECPrivateKey.load(data) # Call .native to fully parse since asn1crypto is lazy parsed.native return PrivateKeyInfo.wrap(parsed, 'ec') except (ValueError): pass # Data was not an ECPrivateKey raise ValueError(pretty_message( ''' The data specified does not appear to be a known private key format ''' )) def _unarmor_pem(data, password=None): """ Removes PEM-encoding from a public key, private key or certificate. If the private key is encrypted, the password will be used to decrypt it. :param data: A byte string of the PEM-encoded data :param password: A byte string of the encryption password, or None :return: A 3-element tuple in the format: (key_type, algorithm, der_bytes). The key_type will be a unicode string of "public key", "private key" or "certificate". The algorithm will be a unicode string of "rsa", "dsa" or "ec". """ object_type, headers, der_bytes = unarmor(data) type_regex = '^((DSA|EC|RSA) PRIVATE KEY|ENCRYPTED PRIVATE KEY|PRIVATE KEY|PUBLIC KEY|RSA PUBLIC KEY|CERTIFICATE)' armor_type = re.match(type_regex, object_type) if not armor_type: raise ValueError(pretty_message( ''' data does not seem to contain a PEM-encoded certificate, private key or public key ''' )) pem_header = armor_type.group(1) data = data.strip() # RSA private keys are encrypted after being DER-encoded, but before base64 # encoding, so they need to be handled specially if pem_header in set(['RSA PRIVATE KEY', 'DSA PRIVATE KEY', 'EC PRIVATE KEY']): algo = armor_type.group(2).lower() return ('private key', algo, _unarmor_pem_openssl_private(headers, der_bytes, password)) key_type = pem_header.lower() algo = None if key_type == 'encrypted private key': key_type = 'private key' elif key_type == 'rsa public key': key_type = 'public key' algo = 'rsa' return (key_type, algo, der_bytes) def _unarmor_pem_openssl_private(headers, data, password): """ Parses a PKCS#1 private key, or encrypted private key :param headers: A dict of "Name: Value" lines from right after the PEM header :param data: A byte string of the DER-encoded PKCS#1 private key :param password: A byte string of the password to use if the private key is encrypted :return: A byte string of the DER-encoded private key """ enc_algo = None enc_iv_hex = None enc_iv = None if 'DEK-Info' in headers: params = headers['DEK-Info'] if params.find(',') != -1: enc_algo, enc_iv_hex = params.strip().split(',') else: enc_algo = 'RC4' if not enc_algo: return data if enc_iv_hex: enc_iv = binascii.unhexlify(enc_iv_hex.encode('ascii')) enc_algo = enc_algo.lower() enc_key_length = { 'aes-128-cbc': 16, 'aes-128': 16, 'aes-192-cbc': 24, 'aes-192': 24, 'aes-256-cbc': 32, 'aes-256': 32, 'rc4': 16, 'rc4-64': 8, 'rc4-40': 5, 'rc2-64-cbc': 8, 'rc2-40-cbc': 5, 'rc2-cbc': 16, 'rc2': 16, 'des-ede3-cbc': 24, 'des-ede3': 24, 'des3': 24, 'des-ede-cbc': 16, 'des-cbc': 8, 'des': 8, }[enc_algo] enc_key = hashlib.md5(password + enc_iv[0:8]).digest() while enc_key_length > len(enc_key): enc_key += hashlib.md5(enc_key + password + enc_iv[0:8]).digest() enc_key = enc_key[0:enc_key_length] enc_algo_name = { 'aes-128-cbc': 'aes', 'aes-128': 'aes', 'aes-192-cbc': 'aes', 'aes-192': 'aes', 'aes-256-cbc': 'aes', 'aes-256': 'aes', 'rc4': 'rc4', 'rc4-64': 'rc4', 'rc4-40': 'rc4', 'rc2-64-cbc': 'rc2', 'rc2-40-cbc': 'rc2', 'rc2-cbc': 'rc2', 'rc2': 'rc2', 'des-ede3-cbc': 'tripledes', 'des-ede3': 'tripledes', 'des3': 'tripledes', 'des-ede-cbc': 'tripledes', 'des-cbc': 'des', 'des': 'des', }[enc_algo] decrypt_func = crypto_funcs[enc_algo_name] if enc_algo_name == 'rc4': return decrypt_func(enc_key, data) return decrypt_func(enc_key, data, enc_iv) def _parse_pkcs12(data, password, load_private_key): """ 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 :param load_private_key: A callable that will accept a byte string and return an oscrypto.asymmetric.PrivateKey object :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 """ if not isinstance(data, byte_cls): raise TypeError(pretty_message( ''' data must be a byte string, not %s ''', type_name(data) )) if password is not None: if not isinstance(password, byte_cls): raise TypeError(pretty_message( ''' password must be a byte string, not %s ''', type_name(password) )) else: password = b'' certs = {} private_keys = {} pfx = Pfx.load(data) auth_safe = pfx['auth_safe'] if auth_safe['content_type'].native != 'data': raise ValueError(pretty_message( ''' Only password-protected PKCS12 files are currently supported ''' )) authenticated_safe = pfx.authenticated_safe mac_data = pfx['mac_data'] if mac_data: mac_algo = mac_data['mac']['digest_algorithm']['algorithm'].native key_length = { 'sha1': 20, 'sha224': 28, 'sha256': 32, 'sha384': 48, 'sha512': 64, 'sha512_224': 28, 'sha512_256': 32, }[mac_algo] mac_key = pkcs12_kdf( mac_algo, password, mac_data['mac_salt'].native, mac_data['iterations'].native, key_length, 3 # ID 3 is for generating an HMAC key ) hash_mod = getattr(hashlib, mac_algo) computed_hmac = hmac.new(mac_key, auth_safe['content'].contents, hash_mod).digest() stored_hmac = mac_data['mac']['digest'].native if not constant_compare(computed_hmac, stored_hmac): raise ValueError('Password provided is invalid') for content_info in authenticated_safe: content = content_info['content'] if isinstance(content, OctetString): _parse_safe_contents(content.native, certs, private_keys, password, load_private_key) elif isinstance(content, EncryptedData): encrypted_content_info = content['encrypted_content_info'] encryption_algorithm_info = encrypted_content_info['content_encryption_algorithm'] encrypted_content = encrypted_content_info['encrypted_content'].native decrypted_content = _decrypt_encrypted_data(encryption_algorithm_info, encrypted_content, password) _parse_safe_contents(decrypted_content, certs, private_keys, password, load_private_key) else: raise ValueError(pretty_message( ''' Public-key-based PKCS12 files are not currently supported ''' )) key_fingerprints = set(private_keys.keys()) cert_fingerprints = set(certs.keys()) common_fingerprints = sorted(list(key_fingerprints & cert_fingerprints)) key = None cert = None other_certs = [] if len(common_fingerprints) >= 1: fingerprint = common_fingerprints[0] key = private_keys[fingerprint] cert = certs[fingerprint] other_certs = [certs[f] for f in certs if f != fingerprint] return (key, cert, other_certs) if len(private_keys) > 0: first_key = sorted(list(private_keys.keys()))[0] key = private_keys[first_key] if len(certs) > 0: first_key = sorted(list(certs.keys()))[0] cert = certs[first_key] del certs[first_key] if len(certs) > 0: other_certs = sorted(list(certs.values()), key=lambda c: c.subject.human_friendly) return (key, cert, other_certs) def _parse_safe_contents(safe_contents, certs, private_keys, password, load_private_key): """ Parses a SafeContents PKCS#12 ANS.1 structure and extracts certs and keys :param safe_contents: A byte string of ber-encoded SafeContents, or a asn1crypto.pkcs12.SafeContents parsed object :param certs: A dict to store certificates in :param keys: A dict to store keys in :param password: A byte string of the password to any encrypted data :param load_private_key: A callable that will accept a byte string and return an oscrypto.asymmetric.PrivateKey object """ if isinstance(safe_contents, byte_cls): safe_contents = SafeContents.load(safe_contents) for safe_bag in safe_contents: bag_value = safe_bag['bag_value'] if isinstance(bag_value, CertBag): if bag_value['cert_id'].native == 'x509': cert = bag_value['cert_value'].parsed public_key_info = cert['tbs_certificate']['subject_public_key_info'] certs[_fingerprint(public_key_info, None)] = bag_value['cert_value'].parsed elif isinstance(bag_value, PrivateKeyInfo): private_keys[_fingerprint(bag_value, load_private_key)] = bag_value elif isinstance(bag_value, EncryptedPrivateKeyInfo): encryption_algorithm_info = bag_value['encryption_algorithm'] encrypted_key_bytes = bag_value['encrypted_data'].native decrypted_key_bytes = _decrypt_encrypted_data(encryption_algorithm_info, encrypted_key_bytes, password) private_key = PrivateKeyInfo.load(decrypted_key_bytes) private_keys[_fingerprint(private_key, load_private_key)] = private_key elif isinstance(bag_value, SafeContents): _parse_safe_contents(bag_value, certs, private_keys, password, load_private_key) else: # We don't care about CRL bags or secret bags pass def _decrypt_encrypted_data(encryption_algorithm_info, encrypted_content, password): """ Decrypts encrypted ASN.1 data :param encryption_algorithm_info: An instance of asn1crypto.pkcs5.Pkcs5EncryptionAlgorithm :param encrypted_content: A byte string of the encrypted content :param password: A byte string of the encrypted content's password :return: A byte string of the decrypted plaintext """ decrypt_func = crypto_funcs[encryption_algorithm_info.encryption_cipher] # Modern, PKCS#5 PBES2-based encryption if encryption_algorithm_info.kdf == 'pbkdf2': if encryption_algorithm_info.encryption_cipher == 'rc5': raise ValueError(pretty_message( ''' PBES2 encryption scheme utilizing RC5 encryption is not supported ''' )) enc_key = pbkdf2( encryption_algorithm_info.kdf_hmac, password, encryption_algorithm_info.kdf_salt, encryption_algorithm_info.kdf_iterations, encryption_algorithm_info.key_length ) enc_iv = encryption_algorithm_info.encryption_iv plaintext = decrypt_func(enc_key, encrypted_content, enc_iv) elif encryption_algorithm_info.kdf == 'pbkdf1': derived_output = pbkdf1( encryption_algorithm_info.kdf_hmac, password, encryption_algorithm_info.kdf_salt, encryption_algorithm_info.kdf_iterations, encryption_algorithm_info.key_length + 8 ) enc_key = derived_output[0:8] enc_iv = derived_output[8:16] plaintext = decrypt_func(enc_key, encrypted_content, enc_iv) elif encryption_algorithm_info.kdf == 'pkcs12_kdf': enc_key = pkcs12_kdf( encryption_algorithm_info.kdf_hmac, password, encryption_algorithm_info.kdf_salt, encryption_algorithm_info.kdf_iterations, encryption_algorithm_info.key_length, 1 # ID 1 is for generating a key ) # Since RC4 is a stream cipher, we don't use an IV if encryption_algorithm_info.encryption_cipher == 'rc4': plaintext = decrypt_func(enc_key, encrypted_content) else: enc_iv = pkcs12_kdf( encryption_algorithm_info.kdf_hmac, password, encryption_algorithm_info.kdf_salt, encryption_algorithm_info.kdf_iterations, encryption_algorithm_info.encryption_block_size, 2 # ID 2 is for generating an IV ) plaintext = decrypt_func(enc_key, encrypted_content, enc_iv) return plaintext _cipher_suites.py000064400000043225147205106110010126 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function __all__ = [ 'CIPHER_SUITE_MAP', ] CIPHER_SUITE_MAP = { b'\x00\x00': 'TLS_NULL_WITH_NULL_NULL', b'\x00\x01': 'TLS_RSA_WITH_NULL_MD5', b'\x00\x02': 'TLS_RSA_WITH_NULL_SHA', b'\x00\x03': 'TLS_RSA_EXPORT_WITH_RC4_40_MD5', b'\x00\x04': 'TLS_RSA_WITH_RC4_128_MD5', b'\x00\x05': 'TLS_RSA_WITH_RC4_128_SHA', b'\x00\x06': 'TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5', b'\x00\x07': 'TLS_RSA_WITH_IDEA_CBC_SHA', b'\x00\x08': 'TLS_RSA_EXPORT_WITH_DES40_CBC_SHA', b'\x00\x09': 'TLS_RSA_WITH_DES_CBC_SHA', b'\x00\x0A': 'TLS_RSA_WITH_3DES_EDE_CBC_SHA', b'\x00\x0B': 'TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA', b'\x00\x0C': 'TLS_DH_DSS_WITH_DES_CBC_SHA', b'\x00\x0D': 'TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA', b'\x00\x0E': 'TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA', b'\x00\x0F': 'TLS_DH_RSA_WITH_DES_CBC_SHA', b'\x00\x10': 'TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA', b'\x00\x11': 'TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA', b'\x00\x12': 'TLS_DHE_DSS_WITH_DES_CBC_SHA', b'\x00\x13': 'TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA', b'\x00\x14': 'TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA', b'\x00\x15': 'TLS_DHE_RSA_WITH_DES_CBC_SHA', b'\x00\x16': 'TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA', b'\x00\x17': 'TLS_DH_anon_EXPORT_WITH_RC4_40_MD5', b'\x00\x18': 'TLS_DH_anon_WITH_RC4_128_MD5', b'\x00\x19': 'TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA', b'\x00\x1A': 'TLS_DH_anon_WITH_DES_CBC_SHA', b'\x00\x1B': 'TLS_DH_anon_WITH_3DES_EDE_CBC_SHA', b'\x00\x1E': 'TLS_KRB5_WITH_DES_CBC_SHA', b'\x00\x1F': 'TLS_KRB5_WITH_3DES_EDE_CBC_SHA', b'\x00\x20': 'TLS_KRB5_WITH_RC4_128_SHA', b'\x00\x21': 'TLS_KRB5_WITH_IDEA_CBC_SHA', b'\x00\x22': 'TLS_KRB5_WITH_DES_CBC_MD5', b'\x00\x23': 'TLS_KRB5_WITH_3DES_EDE_CBC_MD5', b'\x00\x24': 'TLS_KRB5_WITH_RC4_128_MD5', b'\x00\x25': 'TLS_KRB5_WITH_IDEA_CBC_MD5', b'\x00\x26': 'TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA', b'\x00\x27': 'TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA', b'\x00\x28': 'TLS_KRB5_EXPORT_WITH_RC4_40_SHA', b'\x00\x29': 'TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5', b'\x00\x2A': 'TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5', b'\x00\x2B': 'TLS_KRB5_EXPORT_WITH_RC4_40_MD5', b'\x00\x2C': 'TLS_PSK_WITH_NULL_SHA', b'\x00\x2D': 'TLS_DHE_PSK_WITH_NULL_SHA', b'\x00\x2E': 'TLS_RSA_PSK_WITH_NULL_SHA', b'\x00\x2F': 'TLS_RSA_WITH_AES_128_CBC_SHA', b'\x00\x30': 'TLS_DH_DSS_WITH_AES_128_CBC_SHA', b'\x00\x31': 'TLS_DH_RSA_WITH_AES_128_CBC_SHA', b'\x00\x32': 'TLS_DHE_DSS_WITH_AES_128_CBC_SHA', b'\x00\x33': 'TLS_DHE_RSA_WITH_AES_128_CBC_SHA', b'\x00\x34': 'TLS_DH_anon_WITH_AES_128_CBC_SHA', b'\x00\x35': 'TLS_RSA_WITH_AES_256_CBC_SHA', b'\x00\x36': 'TLS_DH_DSS_WITH_AES_256_CBC_SHA', b'\x00\x37': 'TLS_DH_RSA_WITH_AES_256_CBC_SHA', b'\x00\x38': 'TLS_DHE_DSS_WITH_AES_256_CBC_SHA', b'\x00\x39': 'TLS_DHE_RSA_WITH_AES_256_CBC_SHA', b'\x00\x3A': 'TLS_DH_anon_WITH_AES_256_CBC_SHA', b'\x00\x3B': 'TLS_RSA_WITH_NULL_SHA256', b'\x00\x3C': 'TLS_RSA_WITH_AES_128_CBC_SHA256', b'\x00\x3D': 'TLS_RSA_WITH_AES_256_CBC_SHA256', b'\x00\x3E': 'TLS_DH_DSS_WITH_AES_128_CBC_SHA256', b'\x00\x3F': 'TLS_DH_RSA_WITH_AES_128_CBC_SHA256', b'\x00\x40': 'TLS_DHE_DSS_WITH_AES_128_CBC_SHA256', b'\x00\x41': 'TLS_RSA_WITH_CAMELLIA_128_CBC_SHA', b'\x00\x42': 'TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA', b'\x00\x43': 'TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA', b'\x00\x44': 'TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA', b'\x00\x45': 'TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA', b'\x00\x46': 'TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA', b'\x00\x67': 'TLS_DHE_RSA_WITH_AES_128_CBC_SHA256', b'\x00\x68': 'TLS_DH_DSS_WITH_AES_256_CBC_SHA256', b'\x00\x69': 'TLS_DH_RSA_WITH_AES_256_CBC_SHA256', b'\x00\x6A': 'TLS_DHE_DSS_WITH_AES_256_CBC_SHA256', b'\x00\x6B': 'TLS_DHE_RSA_WITH_AES_256_CBC_SHA256', b'\x00\x6C': 'TLS_DH_anon_WITH_AES_128_CBC_SHA256', b'\x00\x6D': 'TLS_DH_anon_WITH_AES_256_CBC_SHA256', b'\x00\x84': 'TLS_RSA_WITH_CAMELLIA_256_CBC_SHA', b'\x00\x85': 'TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA', b'\x00\x86': 'TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA', b'\x00\x87': 'TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA', b'\x00\x88': 'TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA', b'\x00\x89': 'TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA', b'\x00\x8A': 'TLS_PSK_WITH_RC4_128_SHA', b'\x00\x8B': 'TLS_PSK_WITH_3DES_EDE_CBC_SHA', b'\x00\x8C': 'TLS_PSK_WITH_AES_128_CBC_SHA', b'\x00\x8D': 'TLS_PSK_WITH_AES_256_CBC_SHA', b'\x00\x8E': 'TLS_DHE_PSK_WITH_RC4_128_SHA', b'\x00\x8F': 'TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA', b'\x00\x90': 'TLS_DHE_PSK_WITH_AES_128_CBC_SHA', b'\x00\x91': 'TLS_DHE_PSK_WITH_AES_256_CBC_SHA', b'\x00\x92': 'TLS_RSA_PSK_WITH_RC4_128_SHA', b'\x00\x93': 'TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA', b'\x00\x94': 'TLS_RSA_PSK_WITH_AES_128_CBC_SHA', b'\x00\x95': 'TLS_RSA_PSK_WITH_AES_256_CBC_SHA', b'\x00\x96': 'TLS_RSA_WITH_SEED_CBC_SHA', b'\x00\x97': 'TLS_DH_DSS_WITH_SEED_CBC_SHA', b'\x00\x98': 'TLS_DH_RSA_WITH_SEED_CBC_SHA', b'\x00\x99': 'TLS_DHE_DSS_WITH_SEED_CBC_SHA', b'\x00\x9A': 'TLS_DHE_RSA_WITH_SEED_CBC_SHA', b'\x00\x9B': 'TLS_DH_anon_WITH_SEED_CBC_SHA', b'\x00\x9C': 'TLS_RSA_WITH_AES_128_GCM_SHA256', b'\x00\x9D': 'TLS_RSA_WITH_AES_256_GCM_SHA384', b'\x00\x9E': 'TLS_DHE_RSA_WITH_AES_128_GCM_SHA256', b'\x00\x9F': 'TLS_DHE_RSA_WITH_AES_256_GCM_SHA384', b'\x00\xA0': 'TLS_DH_RSA_WITH_AES_128_GCM_SHA256', b'\x00\xA1': 'TLS_DH_RSA_WITH_AES_256_GCM_SHA384', b'\x00\xA2': 'TLS_DHE_DSS_WITH_AES_128_GCM_SHA256', b'\x00\xA3': 'TLS_DHE_DSS_WITH_AES_256_GCM_SHA384', b'\x00\xA4': 'TLS_DH_DSS_WITH_AES_128_GCM_SHA256', b'\x00\xA5': 'TLS_DH_DSS_WITH_AES_256_GCM_SHA384', b'\x00\xA6': 'TLS_DH_anon_WITH_AES_128_GCM_SHA256', b'\x00\xA7': 'TLS_DH_anon_WITH_AES_256_GCM_SHA384', b'\x00\xA8': 'TLS_PSK_WITH_AES_128_GCM_SHA256', b'\x00\xA9': 'TLS_PSK_WITH_AES_256_GCM_SHA384', b'\x00\xAA': 'TLS_DHE_PSK_WITH_AES_128_GCM_SHA256', b'\x00\xAB': 'TLS_DHE_PSK_WITH_AES_256_GCM_SHA384', b'\x00\xAC': 'TLS_RSA_PSK_WITH_AES_128_GCM_SHA256', b'\x00\xAD': 'TLS_RSA_PSK_WITH_AES_256_GCM_SHA384', b'\x00\xAE': 'TLS_PSK_WITH_AES_128_CBC_SHA256', b'\x00\xAF': 'TLS_PSK_WITH_AES_256_CBC_SHA384', b'\x00\xB0': 'TLS_PSK_WITH_NULL_SHA256', b'\x00\xB1': 'TLS_PSK_WITH_NULL_SHA384', b'\x00\xB2': 'TLS_DHE_PSK_WITH_AES_128_CBC_SHA256', b'\x00\xB3': 'TLS_DHE_PSK_WITH_AES_256_CBC_SHA384', b'\x00\xB4': 'TLS_DHE_PSK_WITH_NULL_SHA256', b'\x00\xB5': 'TLS_DHE_PSK_WITH_NULL_SHA384', b'\x00\xB6': 'TLS_RSA_PSK_WITH_AES_128_CBC_SHA256', b'\x00\xB7': 'TLS_RSA_PSK_WITH_AES_256_CBC_SHA384', b'\x00\xB8': 'TLS_RSA_PSK_WITH_NULL_SHA256', b'\x00\xB9': 'TLS_RSA_PSK_WITH_NULL_SHA384', b'\x00\xBA': 'TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256', b'\x00\xBB': 'TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256', b'\x00\xBC': 'TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256', b'\x00\xBD': 'TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256', b'\x00\xBE': 'TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256', b'\x00\xBF': 'TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256', b'\x00\xC0': 'TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256', b'\x00\xC1': 'TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256', b'\x00\xC2': 'TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256', b'\x00\xC3': 'TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256', b'\x00\xC4': 'TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256', b'\x00\xC5': 'TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256', b'\x00\xFF': 'TLS_EMPTY_RENEGOTIATION_INFO_SCSV', b'\x13\x01': 'TLS_AES_128_GCM_SHA256', b'\x13\x02': 'TLS_AES_256_GCM_SHA384', b'\x13\x03': 'TLS_CHACHA20_POLY1305_SHA256', b'\x13\x04': 'TLS_AES_128_CCM_SHA256', b'\x13\x05': 'TLS_AES_128_CCM_8_SHA256', b'\xC0\x01': 'TLS_ECDH_ECDSA_WITH_NULL_SHA', b'\xC0\x02': 'TLS_ECDH_ECDSA_WITH_RC4_128_SHA', b'\xC0\x03': 'TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA', b'\xC0\x04': 'TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA', b'\xC0\x05': 'TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA', b'\xC0\x06': 'TLS_ECDHE_ECDSA_WITH_NULL_SHA', b'\xC0\x07': 'TLS_ECDHE_ECDSA_WITH_RC4_128_SHA', b'\xC0\x08': 'TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA', b'\xC0\x09': 'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA', b'\xC0\x0A': 'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA', b'\xC0\x0B': 'TLS_ECDH_RSA_WITH_NULL_SHA', b'\xC0\x0C': 'TLS_ECDH_RSA_WITH_RC4_128_SHA', b'\xC0\x0D': 'TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA', b'\xC0\x0E': 'TLS_ECDH_RSA_WITH_AES_128_CBC_SHA', b'\xC0\x0F': 'TLS_ECDH_RSA_WITH_AES_256_CBC_SHA', b'\xC0\x10': 'TLS_ECDHE_RSA_WITH_NULL_SHA', b'\xC0\x11': 'TLS_ECDHE_RSA_WITH_RC4_128_SHA', b'\xC0\x12': 'TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA', b'\xC0\x13': 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA', b'\xC0\x14': 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA', b'\xC0\x15': 'TLS_ECDH_anon_WITH_NULL_SHA', b'\xC0\x16': 'TLS_ECDH_anon_WITH_RC4_128_SHA', b'\xC0\x17': 'TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA', b'\xC0\x18': 'TLS_ECDH_anon_WITH_AES_128_CBC_SHA', b'\xC0\x19': 'TLS_ECDH_anon_WITH_AES_256_CBC_SHA', b'\xC0\x1A': 'TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA', b'\xC0\x1B': 'TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA', b'\xC0\x1C': 'TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA', b'\xC0\x1D': 'TLS_SRP_SHA_WITH_AES_128_CBC_SHA', b'\xC0\x1E': 'TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA', b'\xC0\x1F': 'TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA', b'\xC0\x20': 'TLS_SRP_SHA_WITH_AES_256_CBC_SHA', b'\xC0\x21': 'TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA', b'\xC0\x22': 'TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA', b'\xC0\x23': 'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256', b'\xC0\x24': 'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384', b'\xC0\x25': 'TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256', b'\xC0\x26': 'TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384', b'\xC0\x27': 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256', b'\xC0\x28': 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384', b'\xC0\x29': 'TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256', b'\xC0\x2A': 'TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384', b'\xC0\x2B': 'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256', b'\xC0\x2C': 'TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384', b'\xC0\x2D': 'TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256', b'\xC0\x2E': 'TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384', b'\xC0\x2F': 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256', b'\xC0\x30': 'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384', b'\xC0\x31': 'TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256', b'\xC0\x32': 'TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384', b'\xC0\x33': 'TLS_ECDHE_PSK_WITH_RC4_128_SHA', b'\xC0\x34': 'TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA', b'\xC0\x35': 'TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA', b'\xC0\x36': 'TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA', b'\xC0\x37': 'TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256', b'\xC0\x38': 'TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384', b'\xC0\x39': 'TLS_ECDHE_PSK_WITH_NULL_SHA', b'\xC0\x3A': 'TLS_ECDHE_PSK_WITH_NULL_SHA256', b'\xC0\x3B': 'TLS_ECDHE_PSK_WITH_NULL_SHA384', b'\xC0\x3C': 'TLS_RSA_WITH_ARIA_128_CBC_SHA256', b'\xC0\x3D': 'TLS_RSA_WITH_ARIA_256_CBC_SHA384', b'\xC0\x3E': 'TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256', b'\xC0\x3F': 'TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384', b'\xC0\x40': 'TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256', b'\xC0\x41': 'TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384', b'\xC0\x42': 'TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256', b'\xC0\x43': 'TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384', b'\xC0\x44': 'TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256', b'\xC0\x45': 'TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384', b'\xC0\x46': 'TLS_DH_anon_WITH_ARIA_128_CBC_SHA256', b'\xC0\x47': 'TLS_DH_anon_WITH_ARIA_256_CBC_SHA384', b'\xC0\x48': 'TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256', b'\xC0\x49': 'TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384', b'\xC0\x4A': 'TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256', b'\xC0\x4B': 'TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384', b'\xC0\x4C': 'TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256', b'\xC0\x4D': 'TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384', b'\xC0\x4E': 'TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256', b'\xC0\x4F': 'TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384', b'\xC0\x50': 'TLS_RSA_WITH_ARIA_128_GCM_SHA256', b'\xC0\x51': 'TLS_RSA_WITH_ARIA_256_GCM_SHA384', b'\xC0\x52': 'TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256', b'\xC0\x53': 'TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384', b'\xC0\x54': 'TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256', b'\xC0\x55': 'TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384', b'\xC0\x56': 'TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256', b'\xC0\x57': 'TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384', b'\xC0\x58': 'TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256', b'\xC0\x59': 'TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384', b'\xC0\x5A': 'TLS_DH_anon_WITH_ARIA_128_GCM_SHA256', b'\xC0\x5B': 'TLS_DH_anon_WITH_ARIA_256_GCM_SHA384', b'\xC0\x5C': 'TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256', b'\xC0\x5D': 'TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384', b'\xC0\x5E': 'TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256', b'\xC0\x5F': 'TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384', b'\xC0\x60': 'TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256', b'\xC0\x61': 'TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384', b'\xC0\x62': 'TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256', b'\xC0\x63': 'TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384', b'\xC0\x64': 'TLS_PSK_WITH_ARIA_128_CBC_SHA256', b'\xC0\x65': 'TLS_PSK_WITH_ARIA_256_CBC_SHA384', b'\xC0\x66': 'TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256', b'\xC0\x67': 'TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384', b'\xC0\x68': 'TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256', b'\xC0\x69': 'TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384', b'\xC0\x6A': 'TLS_PSK_WITH_ARIA_128_GCM_SHA256', b'\xC0\x6B': 'TLS_PSK_WITH_ARIA_256_GCM_SHA384', b'\xC0\x6C': 'TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256', b'\xC0\x6D': 'TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384', b'\xC0\x6E': 'TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256', b'\xC0\x6F': 'TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384', b'\xC0\x70': 'TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256', b'\xC0\x71': 'TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384', b'\xC0\x72': 'TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256', b'\xC0\x73': 'TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384', b'\xC0\x74': 'TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256', b'\xC0\x75': 'TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384', b'\xC0\x76': 'TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256', b'\xC0\x77': 'TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384', b'\xC0\x78': 'TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256', b'\xC0\x79': 'TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384', b'\xC0\x7A': 'TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256', b'\xC0\x7B': 'TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384', b'\xC0\x7C': 'TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256', b'\xC0\x7D': 'TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384', b'\xC0\x7E': 'TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256', b'\xC0\x7F': 'TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384', b'\xC0\x80': 'TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256', b'\xC0\x81': 'TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384', b'\xC0\x82': 'TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256', b'\xC0\x83': 'TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384', b'\xC0\x84': 'TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256', b'\xC0\x85': 'TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384', b'\xC0\x86': 'TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256', b'\xC0\x87': 'TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384', b'\xC0\x88': 'TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256', b'\xC0\x89': 'TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384', b'\xC0\x8A': 'TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256', b'\xC0\x8B': 'TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384', b'\xC0\x8C': 'TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256', b'\xC0\x8D': 'TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384', b'\xC0\x8E': 'TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256', b'\xC0\x8F': 'TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384', b'\xC0\x90': 'TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256', b'\xC0\x91': 'TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384', b'\xC0\x92': 'TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256', b'\xC0\x93': 'TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384', b'\xC0\x94': 'TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256', b'\xC0\x95': 'TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384', b'\xC0\x96': 'TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256', b'\xC0\x97': 'TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384', b'\xC0\x98': 'TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256', b'\xC0\x99': 'TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384', b'\xC0\x9A': 'TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256', b'\xC0\x9B': 'TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384', b'\xC0\x9C': 'TLS_RSA_WITH_AES_128_CCM', b'\xC0\x9D': 'TLS_RSA_WITH_AES_256_CCM', b'\xC0\x9E': 'TLS_DHE_RSA_WITH_AES_128_CCM', b'\xC0\x9F': 'TLS_DHE_RSA_WITH_AES_256_CCM', b'\xC0\xA0': 'TLS_RSA_WITH_AES_128_CCM_8', b'\xC0\xA1': 'TLS_RSA_WITH_AES_256_CCM_8', b'\xC0\xA2': 'TLS_DHE_RSA_WITH_AES_128_CCM_8', b'\xC0\xA3': 'TLS_DHE_RSA_WITH_AES_256_CCM_8', b'\xC0\xA4': 'TLS_PSK_WITH_AES_128_CCM', b'\xC0\xA5': 'TLS_PSK_WITH_AES_256_CCM', b'\xC0\xA6': 'TLS_DHE_PSK_WITH_AES_128_CCM', b'\xC0\xA7': 'TLS_DHE_PSK_WITH_AES_256_CCM', b'\xC0\xA8': 'TLS_PSK_WITH_AES_128_CCM_8', b'\xC0\xA9': 'TLS_PSK_WITH_AES_256_CCM_8', b'\xC0\xAA': 'TLS_PSK_DHE_WITH_AES_128_CCM_8', b'\xC0\xAB': 'TLS_PSK_DHE_WITH_AES_256_CCM_8', b'\xCC\xA8': 'TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256', b'\xCC\xA9': 'TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256', b'\xCC\xAA': 'TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256', b'\xCC\xAB': 'TLS_PSK_WITH_CHACHA20_POLY1305_SHA256', b'\xCC\xAC': 'TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256', b'\xCC\xAD': 'TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256', b'\xCC\xAE': 'TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256', } _ecdsa.py000064400000054442147205106110006342 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import hashlib import hmac import sys from . import backend from ._asn1 import ( Certificate, DSASignature, ECDomainParameters, ECPointBitString, ECPrivateKey, int_from_bytes, PrivateKeyAlgorithm, PrivateKeyInfo, PublicKeyAlgorithm, PublicKeyInfo, ) from ._errors import pretty_message from ._types import type_name, byte_cls from .util import rand_bytes from .errors import SignatureError if sys.version_info < (3,): chr_cls = chr range = xrange # noqa else: def chr_cls(num): return bytes([num]) _backend = backend() if _backend != 'winlegacy': # This pure-Python ECDSA code is only suitable for use on client machines, # and is only needed on Windows 5.x (XP/2003). For testing sake it is # possible to force use of it on newer versions of Windows. raise SystemError('Pure-python ECDSA code is only for Windows XP/2003') __all__ = [ 'ec_generate_pair', 'ec_compute_public_key_point', 'ec_public_key_info', 'ecdsa_sign', 'ecdsa_verify', ] CURVE_BYTES = { 'secp256r1': 32, 'secp384r1': 48, 'secp521r1': 66, } CURVE_EXTRA_BITS = { 'secp256r1': 0, 'secp384r1': 0, 'secp521r1': 7, } def ec_generate_pair(curve): """ Generates a EC public/private key pair :param curve: A unicode string. 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 :return: A 2-element tuple of (asn1crypto.keys.PublicKeyInfo, asn1crypto.keys.PrivateKeyInfo) """ if curve not in set(['secp256r1', 'secp384r1', 'secp521r1']): raise ValueError(pretty_message( ''' curve must be one of "secp256r1", "secp384r1", "secp521r1", not %s ''', repr(curve) )) curve_num_bytes = CURVE_BYTES[curve] curve_base_point = { 'secp256r1': SECP256R1_BASE_POINT, 'secp384r1': SECP384R1_BASE_POINT, 'secp521r1': SECP521R1_BASE_POINT, }[curve] while True: private_key_bytes = rand_bytes(curve_num_bytes) private_key_int = int_from_bytes(private_key_bytes, signed=False) if private_key_int > 0 and private_key_int < curve_base_point.order: break private_key_info = PrivateKeyInfo({ 'version': 0, 'private_key_algorithm': PrivateKeyAlgorithm({ 'algorithm': 'ec', 'parameters': ECDomainParameters( name='named', value=curve ) }), 'private_key': ECPrivateKey({ 'version': 'ecPrivkeyVer1', 'private_key': private_key_int }), }) ec_point = ec_compute_public_key_point(private_key_info) private_key_info['private_key'].parsed['public_key'] = ec_point.copy() return (ec_public_key_info(ec_point, curve), private_key_info) def ec_compute_public_key_point(private_key): """ Constructs the PublicKeyInfo for a PrivateKeyInfo :param private_key: An asn1crypto.keys.PrivateKeyInfo object :raises: ValueError - when any of the parameters contain an invalid value :return: An asn1crypto.keys.ECPointBitString object """ if not isinstance(private_key, PrivateKeyInfo): raise TypeError(pretty_message( ''' private_key must be an instance of the asn1crypto.keys.PrivateKeyInfo class, not %s ''', type_name(private_key) )) curve_type, details = private_key.curve if curve_type == 'implicit_ca': raise ValueError(pretty_message( ''' Unable to compute public key for EC key using Implicit CA parameters ''' )) if curve_type == 'specified': raise ValueError(pretty_message( ''' Unable to compute public key for EC key over a specified field ''' )) elif curve_type == 'named': if details not in set(['secp256r1', 'secp384r1', 'secp521r1']): raise ValueError(pretty_message( ''' Named curve must be one of "secp256r1", "secp384r1", "secp521r1", not %s ''', repr(details) )) base_point = { 'secp256r1': SECP256R1_BASE_POINT, 'secp384r1': SECP384R1_BASE_POINT, 'secp521r1': SECP521R1_BASE_POINT, }[details] public_point = base_point * private_key['private_key'].parsed['private_key'].native return ECPointBitString.from_coords(public_point.x, public_point.y) def ec_public_key_info(public_key_point, curve): """ Constructs the PublicKeyInfo for an ECPointBitString :param private_key: An asn1crypto.keys.ECPointBitString object :param curve: A unicode string of the curve name - one of secp256r1, secp384r1 or secp521r1 :raises: ValueError - when any of the parameters contain an invalid value :return: An asn1crypto.keys.PublicKeyInfo object """ if curve not in set(['secp256r1', 'secp384r1', 'secp521r1']): raise ValueError(pretty_message( ''' curve must be one of "secp256r1", "secp384r1", "secp521r1", not %s ''', repr(curve) )) return PublicKeyInfo({ 'algorithm': PublicKeyAlgorithm({ 'algorithm': 'ec', 'parameters': ECDomainParameters( name='named', value=curve ) }), 'public_key': public_key_point, }) def ecdsa_sign(private_key, data, hash_algorithm): """ Generates an ECDSA signature in pure Python (thus slow) :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 "sha1", "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 not hasattr(private_key, 'asn1') or not isinstance(private_key.asn1, PrivateKeyInfo): raise TypeError(pretty_message( ''' private_key must be an instance of the oscrypto.asymmetric.PrivateKey class, not %s ''', type_name(private_key) )) curve_name = private_key.curve if curve_name not in set(['secp256r1', 'secp384r1', 'secp521r1']): raise ValueError(pretty_message( ''' private_key does not use one of the named curves secp256r1, secp384r1 or secp521r1 ''' )) if not isinstance(data, byte_cls): raise TypeError(pretty_message( ''' data must be a byte string, not %s ''', type_name(data) )) 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) )) hash_func = getattr(hashlib, hash_algorithm) ec_private_key = private_key.asn1['private_key'].parsed private_key_bytes = ec_private_key['private_key'].contents private_key_int = ec_private_key['private_key'].native curve_num_bytes = CURVE_BYTES[curve_name] curve_base_point = { 'secp256r1': SECP256R1_BASE_POINT, 'secp384r1': SECP384R1_BASE_POINT, 'secp521r1': SECP521R1_BASE_POINT, }[curve_name] n = curve_base_point.order # RFC 6979 section 3.2 # a. digest = hash_func(data).digest() hash_length = len(digest) h = int_from_bytes(digest, signed=False) % n # b. V = b'\x01' * hash_length # c. K = b'\x00' * hash_length # d. K = hmac.new(K, V + b'\x00' + private_key_bytes + digest, hash_func).digest() # e. V = hmac.new(K, V, hash_func).digest() # f. K = hmac.new(K, V + b'\x01' + private_key_bytes + digest, hash_func).digest() # g. V = hmac.new(K, V, hash_func).digest() # h. r = 0 s = 0 while True: # h. 1 T = b'' # h. 2 while len(T) < curve_num_bytes: V = hmac.new(K, V, hash_func).digest() T += V # h. 3 k = int_from_bytes(T[0:curve_num_bytes], signed=False) if k == 0 or k >= n: continue # Calculate the signature in the loop in case we need a new k r = (curve_base_point * k).x % n if r == 0: continue s = (inverse_mod(k, n) * (h + (private_key_int * r) % n)) % n if s == 0: continue break return DSASignature({'r': r, 's': s}).dump() def ecdsa_verify(certificate_or_public_key, signature, data, hash_algorithm): """ Verifies an ECDSA signature in pure Python (thus slow) :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", "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 """ has_asn1 = hasattr(certificate_or_public_key, 'asn1') if not has_asn1 or not isinstance(certificate_or_public_key.asn1, (PublicKeyInfo, Certificate)): raise TypeError(pretty_message( ''' certificate_or_public_key must be an instance of the oscrypto.asymmetric.PublicKey or oscrypto.asymmetric.Certificate classes, not %s ''', type_name(certificate_or_public_key) )) curve_name = certificate_or_public_key.curve if curve_name not in set(['secp256r1', 'secp384r1', 'secp521r1']): raise ValueError(pretty_message( ''' certificate_or_public_key does not use one of the named curves secp256r1, secp384r1 or secp521r1 ''' )) 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) )) 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) )) asn1 = certificate_or_public_key.asn1 if isinstance(asn1, Certificate): asn1 = asn1.public_key curve_base_point = { 'secp256r1': SECP256R1_BASE_POINT, 'secp384r1': SECP384R1_BASE_POINT, 'secp521r1': SECP521R1_BASE_POINT, }[curve_name] x, y = asn1['public_key'].to_coords() n = curve_base_point.order # Validates that the point is valid public_key_point = PrimePoint(curve_base_point.curve, x, y, n) try: signature = DSASignature.load(signature) r = signature['r'].native s = signature['s'].native except (ValueError): raise SignatureError('Signature is invalid') invalid = 0 # Check r is valid invalid |= r < 1 invalid |= r >= n # Check s is valid invalid |= s < 1 invalid |= s >= n if invalid: raise SignatureError('Signature is invalid') hash_func = getattr(hashlib, hash_algorithm) digest = hash_func(data).digest() z = int_from_bytes(digest, signed=False) % n w = inverse_mod(s, n) u1 = (z * w) % n u2 = (r * w) % n hash_point = (curve_base_point * u1) + (public_key_point * u2) if r != (hash_point.x % n): raise SignatureError('Signature is invalid') """ Classes and objects to represent prime-field elliptic curves and points on them. Exports the following items: - PrimeCurve() - PrimePoint() - SECP192R1_CURVE - SECP192R1_BASE_POINT - SECP224R1_CURVE - SECP224R1_BASE_POINT - SECP256R1_CURVE - SECP256R1_BASE_POINT - SECP384R1_CURVE - SECP384R1_BASE_POINT - SECP521R1_CURVE - SECP521R1_BASE_POINT The curve constants are all PrimeCurve() objects and the base point constants are all PrimePoint() objects. Some of the following source code is derived from http://webpages.charter.net/curryfans/peter/downloads.html, but has been heavily modified to fit into this projects lint settings. The original project license is listed below: Copyright (c) 2014 Peter Pearson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ def inverse_mod(a, p): """ Compute the modular inverse of a (mod p) :param a: An integer :param p: An integer :return: An integer """ if a < 0 or p <= a: a = a % p # From Ferguson and Schneier, roughly: c, d = a, p uc, vc, ud, vd = 1, 0, 0, 1 while c != 0: q, c, d = divmod(d, c) + (c,) uc, vc, ud, vd = ud - q * uc, vd - q * vc, uc, vc # At this point, d is the GCD, and ud*a+vd*p = d. # If d == 1, this means that ud is a inverse. assert d == 1 if ud > 0: return ud else: return ud + p class PrimeCurve(): """ Elliptic curve over a prime field. Characteristic two field curves are not supported. """ def __init__(self, p, a, b): """ The curve of points satisfying y^2 = x^3 + a*x + b (mod p) :param p: The prime number as an integer :param a: The component a as an integer :param b: The component b as an integer """ self.p = p self.a = a self.b = b def contains(self, point): """ :param point: A Point object :return: Boolean if the point is on this curve """ y2 = point.y * point.y x3 = point.x * point.x * point.x return (y2 - (x3 + self.a * point.x + self.b)) % self.p == 0 class PrimePoint(): """ A point on a prime-field elliptic curve """ def __init__(self, curve, x, y, order=None): """ :param curve: A PrimeCurve object :param x: The x coordinate of the point as an integer :param y: The y coordinate of the point as an integer :param order: The order of the point, as an integer - optional """ self.curve = curve self.x = x self.y = y self.order = order # self.curve is allowed to be None only for INFINITY: if self.curve: if not self.curve.contains(self): raise ValueError('Invalid EC point') if self.order: if self * self.order != INFINITY: raise ValueError('Invalid EC point') def __cmp__(self, other): """ :param other: A PrimePoint object :return: 0 if identical, 1 otherwise """ if self.curve == other.curve and self.x == other.x and self.y == other.y: return 0 else: return 1 def __add__(self, other): """ :param other: A PrimePoint object :return: A PrimePoint object """ # X9.62 B.3: if other == INFINITY: return self if self == INFINITY: return other assert self.curve == other.curve if self.x == other.x: if (self.y + other.y) % self.curve.p == 0: return INFINITY else: return self.double() p = self.curve.p l_ = ((other.y - self.y) * inverse_mod(other.x - self.x, p)) % p x3 = (l_ * l_ - self.x - other.x) % p y3 = (l_ * (self.x - x3) - self.y) % p return PrimePoint(self.curve, x3, y3) def __mul__(self, other): """ :param other: An integer to multiple the Point by :return: A PrimePoint object """ def leftmost_bit(x): assert x > 0 result = 1 while result <= x: result = 2 * result return result // 2 e = other if self.order: e = e % self.order if e == 0: return INFINITY if self == INFINITY: return INFINITY assert e > 0 # From X9.62 D.3.2: e3 = 3 * e negative_self = PrimePoint(self.curve, self.x, -self.y, self.order) i = leftmost_bit(e3) // 2 result = self # print "Multiplying %s by %d (e3 = %d):" % ( self, other, e3 ) while i > 1: result = result.double() if (e3 & i) != 0 and (e & i) == 0: result = result + self if (e3 & i) == 0 and (e & i) != 0: result = result + negative_self # print ". . . i = %d, result = %s" % ( i, result ) i = i // 2 return result def __rmul__(self, other): """ :param other: An integer to multiple the Point by :return: A PrimePoint object """ return self * other def double(self): """ :return: A PrimePoint object that is twice this point """ # X9.62 B.3: p = self.curve.p a = self.curve.a l_ = ((3 * self.x * self.x + a) * inverse_mod(2 * self.y, p)) % p x3 = (l_ * l_ - 2 * self.x) % p y3 = (l_ * (self.x - x3) - self.y) % p return PrimePoint(self.curve, x3, y3) # This one point is the Point At Infinity for all purposes: INFINITY = PrimePoint(None, None, None) # NIST Curve P-192: SECP192R1_CURVE = PrimeCurve( 6277101735386680763835789423207666416083908700390324961279, -3, 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1 ) SECP192R1_BASE_POINT = PrimePoint( SECP192R1_CURVE, 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012, 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811, 6277101735386680763835789423176059013767194773182842284081 ) # NIST Curve P-224: SECP224R1_CURVE = PrimeCurve( 26959946667150639794667015087019630673557916260026308143510066298881, -3, 0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4 ) SECP224R1_BASE_POINT = PrimePoint( SECP224R1_CURVE, 0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21, 0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34, 26959946667150639794667015087019625940457807714424391721682722368061 ) # NIST Curve P-256: SECP256R1_CURVE = PrimeCurve( 115792089210356248762697446949407573530086143415290314195533631308867097853951, -3, 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b ) SECP256R1_BASE_POINT = PrimePoint( SECP256R1_CURVE, 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296, 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5, 115792089210356248762697446949407573529996955224135760342422259061068512044369 ) # NIST Curve P-384: SECP384R1_CURVE = PrimeCurve( 39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319, # noqa -3, 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef ) SECP384R1_BASE_POINT = PrimePoint( SECP384R1_CURVE, 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7, 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f, 39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643 ) # NIST Curve P-521: SECP521R1_CURVE = PrimeCurve( 6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151, # noqa -3, 0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00 # noqa ) SECP521R1_BASE_POINT = PrimePoint( SECP521R1_CURVE, 0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66, # noqa 0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650, # noqa 6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449 # noqa ) _errors.py000064400000001775147205106110006600 0ustar00# coding: utf-8 """ Helper for formatting exception messages. Exports the following items: - pretty_message() """ from __future__ import unicode_literals, division, absolute_import, print_function import re import textwrap __all__ = [ 'pretty_message', ] def pretty_message(string, *params): """ Takes a multi-line string and does the following: - dedents - converts newlines with text before and after into a single line - strips leading and trailing whitespace :param string: The string to format :param *params: Params to interpolate into the string :return: The formatted string """ output = textwrap.dedent(string) # Unwrap lines, taking into account bulleted lists, ordered lists and # underlines consisting of = signs if output.find('\n') != -1: output = re.sub('(?<=\\S)\n(?=[^ \n\t\\d\\*\\-=])', ' ', output) if params: output = output % params output = output.strip() return output _ffi.py000064400000027506147205106110006030 0ustar00# coding: utf-8 """ Exceptions and compatibility shims for consistently using ctypes and cffi """ from __future__ import unicode_literals, division, absolute_import, print_function import sys import platform from ctypes.util import find_library from . import ffi from ._types import str_cls, byte_cls, int_types, bytes_to_list __all__ = [ 'array_from_pointer', 'array_set', 'buffer_from_bytes', 'buffer_from_unicode', 'buffer_pointer', 'byte_array', 'byte_string_from_buffer', 'bytes_from_buffer', 'callback', 'cast', 'deref', 'errno', 'FFIEngineError', 'get_library', 'is_null', 'native', 'new', 'null', 'pointer_set', 'ref', 'register_ffi', 'sizeof', 'struct', 'struct_bytes', 'struct_from_buffer', 'unwrap', 'write_to_buffer', ] if ffi() == 'cffi': from cffi import FFI _ffi_registry = {} ffi = FFI() def register_ffi(library, ffi_obj): _ffi_registry[library] = ffi_obj def _get_ffi(library): if library in _ffi_registry: return _ffi_registry[library] return ffi def buffer_from_bytes(initializer): if sys.platform == 'win32': return ffi.new('unsigned char[]', initializer) return ffi.new('char[]', initializer) def buffer_from_unicode(initializer): return ffi.new('wchar_t []', initializer) def write_to_buffer(buffer, data, offset=0): buffer[offset:offset + len(data)] = data def buffer_pointer(buffer): return ffi.new('char *[]', [buffer]) def cast(library, type_, value): ffi_obj = _get_ffi(library) return ffi_obj.cast(type_, value) def sizeof(library, value): ffi_obj = _get_ffi(library) return ffi_obj.sizeof(value) def bytes_from_buffer(buffer, maxlen=None): if maxlen is not None: return ffi.buffer(buffer, maxlen)[:] return ffi.buffer(buffer)[:] def byte_string_from_buffer(buffer): return ffi.string(buffer) def byte_array(byte_string): return byte_string def pointer_set(pointer_, value): pointer_[0] = value def array_set(array, value): for index, val in enumerate(value): array[index] = val def null(): return ffi.NULL def is_null(point): if point is None: return True if point == ffi.NULL: return True if ffi.getctype(ffi.typeof(point)) == 'void *': return False if point[0] == ffi.NULL: return True return False def errno(): return ffi.errno def new(library, type_, value=None): ffi_obj = _get_ffi(library) params = [] if value is not None: params.append(value) if type_ in set(['BCRYPT_KEY_HANDLE', 'BCRYPT_ALG_HANDLE']): return ffi_obj.cast(type_, 0) return ffi_obj.new(type_, *params) def ref(value, offset=0): return value + offset def native(type_, value): if type_ == str_cls: return ffi.string(value) if type_ == byte_cls: return ffi.buffer(value)[:] return type_(value) def deref(point): return point[0] def unwrap(point): return point[0] def struct(library, name): ffi_obj = _get_ffi(library) return ffi_obj.new('%s *' % name) def struct_bytes(struct_): return ffi.buffer(struct_)[:] def struct_from_buffer(library, name, buffer): ffi_obj = _get_ffi(library) new_struct_pointer = ffi_obj.new('%s *' % name) new_struct = new_struct_pointer[0] struct_size = sizeof(library, new_struct) struct_buffer = ffi_obj.buffer(new_struct_pointer) struct_buffer[:] = ffi_obj.buffer(buffer, struct_size)[:] return new_struct_pointer def array_from_pointer(library, name, point, size): ffi_obj = _get_ffi(library) array = ffi_obj.cast('%s[%s]' % (name, size), point) total_bytes = ffi_obj.sizeof(array) if total_bytes == 0: return [] output = [] string_types = { 'LPSTR': True, 'LPCSTR': True, 'LPWSTR': True, 'LPCWSTR': True, 'char *': True, 'wchar_t *': True, } string_type = name in string_types for i in range(0, size): value = array[i] if string_type: value = ffi_obj.string(value) output.append(value) return output def callback(library, signature_name, func): ffi_obj = _get_ffi(library) return ffi_obj.callback(signature_name, func) engine = 'cffi' else: import ctypes from ctypes import pointer, c_int, c_char_p, c_uint, c_void_p, c_wchar_p _pointer_int_types = int_types + (c_char_p, ctypes.POINTER(ctypes.c_byte)) _pointer_types = { 'void *': True, 'wchar_t *': True, 'char *': True, 'char **': True, } _type_map = { 'void *': c_void_p, 'wchar_t *': c_wchar_p, 'char *': c_char_p, 'char **': ctypes.POINTER(c_char_p), 'int': c_int, 'unsigned int': c_uint, 'size_t': ctypes.c_size_t, 'uint32_t': ctypes.c_uint32, } if sys.platform == 'win32': from ctypes import wintypes _pointer_types.update({ 'LPSTR': True, 'LPWSTR': True, 'LPCSTR': True, 'LPCWSTR': True, }) _type_map.update({ 'BYTE': ctypes.c_byte, 'LPSTR': c_char_p, 'LPWSTR': c_wchar_p, 'LPCSTR': c_char_p, 'LPCWSTR': c_wchar_p, 'ULONG': wintypes.ULONG, 'DWORD': wintypes.DWORD, 'char *': ctypes.POINTER(ctypes.c_byte), 'char **': ctypes.POINTER(ctypes.POINTER(ctypes.c_byte)), }) def _type_info(library, type_): is_double_pointer = type_[-3:] == ' **' if is_double_pointer: type_ = type_[:-1] is_pointer = type_[-2:] == ' *' and type_ not in _pointer_types if is_pointer: type_ = type_[:-2] is_array = type_.find('[') != -1 if is_array: is_array = type_[type_.find('[') + 1:type_.find(']')] if is_array == '': is_array = True else: is_array = int(is_array) type_ = type_[0:type_.find('[')] if type_ in _type_map: type_ = _type_map[type_] else: type_ = getattr(library, type_) if is_double_pointer: type_ = ctypes.POINTER(type_) return (is_pointer, is_array, type_) def register_ffi(library, ffi_obj): pass def buffer_from_bytes(initializer): return ctypes.create_string_buffer(initializer) def buffer_from_unicode(initializer): return ctypes.create_unicode_buffer(initializer) def write_to_buffer(buffer, data, offset=0): if isinstance(buffer, ctypes.POINTER(ctypes.c_byte)): ctypes.memmove(buffer, data, len(data)) return if offset == 0: buffer.value = data else: buffer.value = buffer.raw[0:offset] + data def buffer_pointer(buffer): return pointer(ctypes.cast(buffer, c_char_p)) def cast(library, type_, value): is_pointer, is_array, type_ = _type_info(library, type_) if is_pointer: type_ = ctypes.POINTER(type_) elif is_array: type_ = type_ * is_array return ctypes.cast(value, type_) def sizeof(library, value): return ctypes.sizeof(value) def bytes_from_buffer(buffer, maxlen=None): if isinstance(buffer, _pointer_int_types): return ctypes.string_at(buffer, maxlen) if maxlen is not None: return buffer.raw[0:maxlen] return buffer.raw def byte_string_from_buffer(buffer): return buffer.value def byte_array(byte_string): return (ctypes.c_byte * len(byte_string))(*bytes_to_list(byte_string)) def pointer_set(pointer_, value): pointer_.contents.value = value def array_set(array, value): for index, val in enumerate(value): array[index] = val def null(): return None def is_null(point): return not bool(point) def errno(): return ctypes.get_errno() def new(library, type_, value=None): is_pointer, is_array, type_ = _type_info(library, type_) if is_array: if is_array is True: type_ = type_ * value value = None else: type_ = type_ * is_array params = [] if value is not None: params.append(value) output = type_(*params) if is_pointer: output = pointer(output) return output def ref(value, offset=0): if offset == 0: return ctypes.byref(value) return ctypes.cast(ctypes.addressof(value) + offset, ctypes.POINTER(ctypes.c_byte)) def native(type_, value): if isinstance(value, type_): return value if sys.version_info < (3,) and type_ == int and isinstance(value, int_types): return value if isinstance(value, ctypes.Array) and value._type_ == ctypes.c_byte: return ctypes.string_at(ctypes.addressof(value), value._length_) return type_(value.value) def deref(point): return point[0] def unwrap(point): return point.contents def struct(library, name): return pointer(getattr(library, name)()) def struct_bytes(struct_): return ctypes.string_at(struct_, ctypes.sizeof(struct_.contents)) def struct_from_buffer(library, type_, buffer): class_ = getattr(library, type_) value = class_() ctypes.memmove(ctypes.addressof(value), buffer, ctypes.sizeof(class_)) return ctypes.pointer(value) def array_from_pointer(library, type_, point, size): _, _, type_ = _type_info(library, type_) array = ctypes.cast(point, ctypes.POINTER(type_)) output = [] for i in range(0, size): output.append(array[i]) return output def callback(library, signature_type, func): return getattr(library, signature_type)(func) engine = 'ctypes' def get_library(name, dylib_name, version): """ Retrieve the C library path with special handling for Mac :param name: A unicode string of the library to search the system for :param dylib_name: Mac only - a unicode string of the unversioned dylib name :param version: Mac only - a unicode string of the dylib version to use. Used on macOS 10.15+ when the unversioned dylib is found, since unversioned OpenSSL/LibreSSL are just placeholders, and a versioned dylib must be imported. Used on macOS 10.16+ when find_library() doesn't return a result, due to system dylibs not being present on the filesystem any longer. :return: A unicode string of the path to the library """ library = find_library(name) if sys.platform == 'darwin': unversioned = '/usr/lib/%s' % dylib_name versioned = unversioned.replace('.dylib', '.%s.dylib' % version) mac_ver = tuple(map(int, platform.mac_ver()[0].split('.'))) if not library and mac_ver >= (10, 16): # On macOS 10.16+, find_library doesn't work, so we set a static path library = versioned elif mac_ver >= (10, 15) and library == unversioned: # On macOS 10.15+, we want to strongly version since unversioned libcrypto has a non-stable ABI library = versioned return library class FFIEngineError(Exception): """ An exception when trying to instantiate ctypes or cffi """ pass _int.py000064400000001232147205106110006042 0ustar00# coding: utf-8 """ Function to fill ensure integers converted to a byte string are a specific width. Exports the following items: - fill_width() """ from __future__ import unicode_literals, division, absolute_import, print_function __all__ = [ 'fill_width', ] def fill_width(bytes_, width): """ Ensure a byte string representing a positive integer is a specific width (in bytes) :param bytes_: The integer byte string :param width: The desired width as an integer :return: A byte string of the width specified """ while len(bytes_) < width: bytes_ = b'\x00' + bytes_ return bytes_ _pkcs1.py000064400000047535147205106110006311 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import sys import hashlib import math import platform import struct import os from . import backend from .util import constant_compare, rand_bytes from ._asn1 import ( Certificate, int_from_bytes, int_to_bytes, PrivateKeyInfo, PublicKeyInfo, ) from ._errors import pretty_message from ._int import fill_width from ._types import type_name, byte_cls, int_types if sys.version_info < (3,): chr_cls = chr range = xrange # noqa else: def chr_cls(num): return bytes([num]) _backend = backend() __all__ = [ 'add_pss_padding', 'add_pkcs1v15_signature_padding', 'raw_rsa_private_crypt', 'raw_rsa_public_crypt', 'remove_pkcs1v15_encryption_padding', 'remove_pkcs1v15_signature_padding', 'verify_pss_padding', ] def _is_osx_107(): """ :return: A bool if the current machine is running OS X 10.7 """ if sys.platform != 'darwin': return False version = platform.mac_ver()[0] return tuple(map(int, version.split('.')))[0:2] == (10, 7) def add_pss_padding(hash_algorithm, salt_length, key_length, message): """ Pads a byte string using the EMSA-PSS-Encode operation described in PKCS#1 v2.2. :param hash_algorithm: The string name of the hash algorithm to use: "sha1", "sha224", "sha256", "sha384", "sha512" :param salt_length: The length of the salt as an integer - typically the same as the length of the output from the hash_algorithm :param key_length: The length of the RSA key, in bits :param message: A byte string of the message to pad :return: The encoded (passed) message """ if _backend != 'winlegacy' and sys.platform != 'darwin': raise SystemError(pretty_message( ''' Pure-python RSA PSS signature padding addition code is only for Windows XP/2003 and OS X ''' )) if not isinstance(message, byte_cls): raise TypeError(pretty_message( ''' message must be a byte string, not %s ''', type_name(message) )) if not isinstance(salt_length, int_types): raise TypeError(pretty_message( ''' salt_length must be an integer, not %s ''', type_name(salt_length) )) if salt_length < 0: raise ValueError(pretty_message( ''' salt_length must be 0 or more - is %s ''', repr(salt_length) )) 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 < 512: raise ValueError(pretty_message( ''' key_length must be 512 or more - is %s ''', repr(key_length) )) 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) )) hash_func = getattr(hashlib, hash_algorithm) # The maximal bit size of a non-negative integer is one less than the bit # size of the key since the first bit is used to store sign em_bits = key_length - 1 em_len = int(math.ceil(em_bits / 8)) message_digest = hash_func(message).digest() hash_length = len(message_digest) if em_len < hash_length + salt_length + 2: raise ValueError(pretty_message( ''' Key is not long enough to use with specified hash_algorithm and salt_length ''' )) if salt_length > 0: salt = os.urandom(salt_length) else: salt = b'' m_prime = (b'\x00' * 8) + message_digest + salt m_prime_digest = hash_func(m_prime).digest() padding = b'\x00' * (em_len - salt_length - hash_length - 2) db = padding + b'\x01' + salt db_mask = _mgf1(hash_algorithm, m_prime_digest, em_len - hash_length - 1) masked_db = int_to_bytes(int_from_bytes(db) ^ int_from_bytes(db_mask)) masked_db = fill_width(masked_db, len(db_mask)) zero_bits = (8 * em_len) - em_bits left_bit_mask = ('0' * zero_bits) + ('1' * (8 - zero_bits)) left_int_mask = int(left_bit_mask, 2) if left_int_mask != 255: masked_db = chr_cls(left_int_mask & ord(masked_db[0:1])) + masked_db[1:] return masked_db + m_prime_digest + b'\xBC' def verify_pss_padding(hash_algorithm, salt_length, key_length, message, signature): """ Verifies the PSS padding on an encoded message :param hash_algorithm: The string name of the hash algorithm to use: "sha1", "sha224", "sha256", "sha384", "sha512" :param salt_length: The length of the salt as an integer - typically the same as the length of the output from the hash_algorithm :param key_length: The length of the RSA key, in bits :param message: A byte string of the message to pad :param signature: The signature to verify :return: A boolean indicating if the signature is invalid """ if _backend != 'winlegacy' and sys.platform != 'darwin': raise SystemError(pretty_message( ''' Pure-python RSA PSS signature padding verification code is only for Windows XP/2003 and OS X ''' )) if not isinstance(message, byte_cls): raise TypeError(pretty_message( ''' message must be a byte string, not %s ''', type_name(message) )) if not isinstance(signature, byte_cls): raise TypeError(pretty_message( ''' signature must be a byte string, not %s ''', type_name(signature) )) if not isinstance(salt_length, int_types): raise TypeError(pretty_message( ''' salt_length must be an integer, not %s ''', type_name(salt_length) )) if salt_length < 0: raise ValueError(pretty_message( ''' salt_length must be 0 or more - is %s ''', repr(salt_length) )) 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) )) hash_func = getattr(hashlib, hash_algorithm) em_bits = key_length - 1 em_len = int(math.ceil(em_bits / 8)) message_digest = hash_func(message).digest() hash_length = len(message_digest) if em_len < hash_length + salt_length + 2: return False if signature[-1:] != b'\xBC': return False zero_bits = (8 * em_len) - em_bits masked_db_length = em_len - hash_length - 1 masked_db = signature[0:masked_db_length] first_byte = ord(masked_db[0:1]) bits_that_should_be_zero = first_byte >> (8 - zero_bits) if bits_that_should_be_zero != 0: return False m_prime_digest = signature[masked_db_length:masked_db_length + hash_length] db_mask = _mgf1(hash_algorithm, m_prime_digest, em_len - hash_length - 1) left_bit_mask = ('0' * zero_bits) + ('1' * (8 - zero_bits)) left_int_mask = int(left_bit_mask, 2) if left_int_mask != 255: db_mask = chr_cls(left_int_mask & ord(db_mask[0:1])) + db_mask[1:] db = int_to_bytes(int_from_bytes(masked_db) ^ int_from_bytes(db_mask)) if len(db) < len(masked_db): db = (b'\x00' * (len(masked_db) - len(db))) + db zero_length = em_len - hash_length - salt_length - 2 zero_string = b'\x00' * zero_length if not constant_compare(db[0:zero_length], zero_string): return False if db[zero_length:zero_length + 1] != b'\x01': return False salt = db[0 - salt_length:] m_prime = (b'\x00' * 8) + message_digest + salt h_prime = hash_func(m_prime).digest() return constant_compare(m_prime_digest, h_prime) def _mgf1(hash_algorithm, seed, mask_length): """ The PKCS#1 MGF1 mask generation algorithm :param hash_algorithm: The string name of the hash algorithm to use: "sha1", "sha224", "sha256", "sha384", "sha512" :param seed: A byte string to use as the seed for the mask :param mask_length: The desired mask length, as an integer :return: A byte string of the mask """ if not isinstance(seed, byte_cls): raise TypeError(pretty_message( ''' seed must be a byte string, not %s ''', type_name(seed) )) if not isinstance(mask_length, int_types): raise TypeError(pretty_message( ''' mask_length must be an integer, not %s ''', type_name(mask_length) )) if mask_length < 1: raise ValueError(pretty_message( ''' mask_length must be greater than 0 - is %s ''', repr(mask_length) )) 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) )) output = b'' hash_length = { 'sha1': 20, 'sha224': 28, 'sha256': 32, 'sha384': 48, 'sha512': 64 }[hash_algorithm] iterations = int(math.ceil(mask_length / hash_length)) pack = struct.Struct(b'>I').pack hash_func = getattr(hashlib, hash_algorithm) for counter in range(0, iterations): b = pack(counter) output += hash_func(seed + b).digest() return output[0:mask_length] def add_pkcs1v15_signature_padding(key_length, data): """ Adds PKCS#1 v1.5 padding to a message to be signed :param key_length: An integer of the number of bytes in the key :param data: A byte string to pad :return: The padded data as a byte string """ if _backend != 'winlegacy': raise SystemError(pretty_message( ''' Pure-python RSA PKCSv1.5 signature padding addition code is only for Windows XP/2003 ''' )) return _add_pkcs1v15_padding(key_length, data, 'signing') def remove_pkcs1v15_signature_padding(key_length, data): """ Removes PKCS#1 v1.5 padding from a signed message using constant time operations :param key_length: An integer of the number of bytes in the key :param data: A byte string to unpad :return: The unpadded data as a byte string """ if _backend != 'winlegacy': raise SystemError(pretty_message( ''' Pure-python RSA PKCSv1.5 signature padding removal code is only for Windows XP/2003 ''' )) return _remove_pkcs1v15_padding(key_length, data, 'verifying') def remove_pkcs1v15_encryption_padding(key_length, data): """ Removes PKCS#1 v1.5 padding from a decrypted message using constant time operations :param key_length: An integer of the number of bytes in the key :param data: A byte string to unpad :return: The unpadded data as a byte string """ if not _is_osx_107(): raise SystemError(pretty_message( ''' Pure-python RSA PKCSv1.5 encryption padding removal code is only for OS X 10.7 ''' )) return _remove_pkcs1v15_padding(key_length, data, 'decrypting') def _add_pkcs1v15_padding(key_length, data, operation): """ Adds PKCS#1 v1.5 padding to a message :param key_length: An integer of the number of bytes in the key :param data: A byte string to unpad :param operation: A unicode string of "encrypting" or "signing" :return: The padded data as a byte string """ if operation == 'encrypting': second_byte = b'\x02' else: second_byte = b'\x01' if not isinstance(data, byte_cls): raise TypeError(pretty_message( ''' data must be a byte string, not %s ''', type_name(data) )) 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 < 64: raise ValueError(pretty_message( ''' key_length must be 64 or more - is %s ''', repr(key_length) )) if len(data) > key_length - 11: raise ValueError(pretty_message( ''' data must be between 1 and %s bytes long - is %s ''', key_length - 11, len(data) )) required_bytes = key_length - 3 - len(data) padding = b'' while required_bytes > 0: temp_padding = rand_bytes(required_bytes) # Remove null bytes since they are markers in PKCS#1 v1.5 temp_padding = b''.join(temp_padding.split(b'\x00')) padding += temp_padding required_bytes -= len(temp_padding) return b'\x00' + second_byte + padding + b'\x00' + data def _remove_pkcs1v15_padding(key_length, data, operation): """ Removes PKCS#1 v1.5 padding from a message using constant time operations :param key_length: An integer of the number of bytes in the key :param data: A byte string to unpad :param operation: A unicode string of "decrypting" or "verifying" :return: The unpadded data as a byte string """ if operation == 'decrypting': second_byte = 2 else: second_byte = 1 if not isinstance(data, byte_cls): raise TypeError(pretty_message( ''' data must be a byte string, not %s ''', type_name(data) )) 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 < 64: raise ValueError(pretty_message( ''' key_length must be 64 or more - is %s ''', repr(key_length) )) if len(data) != key_length: raise ValueError('Error %s' % operation) error = 0 trash = 0 padding_end = 0 # Uses bitwise operations on an error variable and another trash variable # to perform constant time error checking/token scanning on the data for i in range(0, len(data)): byte = data[i:i + 1] byte_num = ord(byte) # First byte should be \x00 if i == 0: error |= byte_num # Second byte should be \x02 for decryption, \x01 for verification elif i == 1: error |= int((byte_num | second_byte) != second_byte) # Bytes 3-10 should not be \x00 elif i < 10: error |= int((byte_num ^ 0) == 0) # Byte 11 or after that is zero is end of padding else: non_zero = byte_num | 0 if padding_end == 0: if non_zero: trash |= i else: padding_end |= i else: if non_zero: trash |= i else: trash |= i if error != 0: raise ValueError('Error %s' % operation) return data[padding_end + 1:] def raw_rsa_private_crypt(private_key, data): """ Performs a raw RSA algorithm in a byte string using a private key. This is a low-level primitive and is prone to disastrous results if used incorrectly. :param private_key: An oscrypto.asymmetric.PrivateKey object :param data: A byte string of the plaintext to be signed or ciphertext to be decrypted. Must be less than or equal to the length of the private key. In the case of signing, padding must already be applied. In the case of decryption, padding must be removed afterward. :return: A byte string of the transformed data """ if _backend != 'winlegacy': raise SystemError('Pure-python RSA crypt is only for Windows XP/2003') if not hasattr(private_key, 'asn1') or not isinstance(private_key.asn1, PrivateKeyInfo): raise TypeError(pretty_message( ''' private_key must be an instance of the oscrypto.asymmetric.PrivateKey class, not %s ''', type_name(private_key) )) algo = private_key.asn1['private_key_algorithm']['algorithm'].native if algo != 'rsa' and algo != 'rsassa_pss': raise ValueError(pretty_message( ''' private_key must be an RSA key, not %s ''', algo.upper() )) if not isinstance(data, byte_cls): raise TypeError(pretty_message( ''' data must be a byte string, not %s ''', type_name(data) )) rsa_private_key = private_key.asn1['private_key'].parsed transformed_int = pow( int_from_bytes(data), rsa_private_key['private_exponent'].native, rsa_private_key['modulus'].native ) return int_to_bytes(transformed_int, width=private_key.asn1.byte_size) def raw_rsa_public_crypt(certificate_or_public_key, data): """ Performs a raw RSA algorithm in a byte string using a certificate or public key. This is a low-level primitive and is prone to disastrous results if used incorrectly. :param certificate_or_public_key: An oscrypto.asymmetric.PublicKey or oscrypto.asymmetric.Certificate object :param data: A byte string of the signature when verifying, or padded plaintext when encrypting. Must be less than or equal to the length of the public key. When verifying, padding will need to be removed afterwards. When encrypting, padding must be applied before. :return: A byte string of the transformed data """ if _backend != 'winlegacy': raise SystemError('Pure-python RSA crypt is only for Windows XP/2003') has_asn1 = hasattr(certificate_or_public_key, 'asn1') valid_types = (PublicKeyInfo, Certificate) if not has_asn1 or not isinstance(certificate_or_public_key.asn1, valid_types): raise TypeError(pretty_message( ''' certificate_or_public_key must be an instance of the oscrypto.asymmetric.PublicKey or oscrypto.asymmetric.Certificate classes, not %s ''', type_name(certificate_or_public_key) )) algo = certificate_or_public_key.asn1['algorithm']['algorithm'].native if algo != 'rsa' and algo != 'rsassa_pss': raise ValueError(pretty_message( ''' certificate_or_public_key must be an RSA key, not %s ''', algo.upper() )) if not isinstance(data, byte_cls): raise TypeError(pretty_message( ''' data must be a byte string, not %s ''', type_name(data) )) rsa_public_key = certificate_or_public_key.asn1['public_key'].parsed transformed_int = pow( int_from_bytes(data), rsa_public_key['public_exponent'].native, rsa_public_key['modulus'].native ) return int_to_bytes( transformed_int, width=certificate_or_public_key.asn1.byte_size ) _pkcs12.py000064400000011414147205106110006356 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import sys import hashlib import math from ._asn1 import int_from_bytes, int_to_bytes from ._errors import pretty_message from ._types import type_name, byte_cls, int_types if sys.version_info < (3,): chr_cls = chr else: def chr_cls(num): return bytes([num]) __all__ = [ 'pkcs12_kdf', ] 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 :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' algo = getattr(hashlib, hash_algorithm) # u and v values are bytes (not bits as in the RFC) u = { 'md5': 16, 'sha1': 20, 'sha224': 28, 'sha256': 32, 'sha384': 48, 'sha512': 64 }[hash_algorithm] if hash_algorithm in ['sha384', 'sha512']: v = 128 else: v = 64 # Step 1 d = chr_cls(id_) * v # Step 2 s = b'' if salt != b'': s_len = v * int(math.ceil(float(len(salt)) / v)) while len(s) < s_len: s += salt s = s[0:s_len] # Step 3 p = b'' if utf16_password != b'': p_len = v * int(math.ceil(float(len(utf16_password)) / v)) while len(p) < p_len: p += utf16_password p = p[0:p_len] # Step 4 i = s + p # Step 5 c = int(math.ceil(float(key_length) / u)) a = b'\x00' * (c * u) for num in range(1, c + 1): # Step 6A a2 = algo(d + i).digest() for _ in range(2, iterations + 1): a2 = algo(a2).digest() if num < c: # Step 6B b = b'' while len(b) < v: b += a2 b = int_from_bytes(b[0:v]) + 1 # Step 6C for num2 in range(0, len(i) // v): start = num2 * v end = (num2 + 1) * v i_num2 = i[start:end] i_num2 = int_to_bytes(int_from_bytes(i_num2) + b) # Ensure the new slice is the right size i_num2_l = len(i_num2) if i_num2_l > v: i_num2 = i_num2[i_num2_l - v:] i = i[0:start] + i_num2 + i[end:] # Step 7 (one piece at a time) begin = (num - 1) * u to_copy = min(key_length, u) a = a[0:begin] + a2[0:to_copy] + a[begin + to_copy:] return a[0:key_length] _pkcs5.py000064400000006525147205106110006307 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import sys import hashlib import hmac import struct from ._asn1 import int_from_bytes, int_to_bytes from ._errors import pretty_message from ._types import type_name, byte_cls, int_types if sys.version_info < (3,): chr_cls = chr else: def chr_cls(num): return bytes([num]) __all__ = [ 'pbkdf2', ] def pbkdf2(hash_algorithm, password, salt, iterations, key_length): """ Implements PBKDF2 from PKCS#5 v2.2 in pure Python :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 :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) )) algo = getattr(hashlib, hash_algorithm) hash_length = { 'md5': 16, 'sha1': 20, 'sha224': 28, 'sha256': 32, 'sha384': 48, 'sha512': 64 }[hash_algorithm] original_hmac = hmac.new(password, None, algo) block = 1 output = b'' while len(output) < key_length: prf = original_hmac.copy() prf.update(salt + struct.pack(b'>I', block)) last = prf.digest() u = int_from_bytes(last) for _ in range(iterations-1): prf = original_hmac.copy() prf.update(last) last = prf.digest() u ^= int_from_bytes(last) output += int_to_bytes(u, width=hash_length) block += 1 return output[0:key_length] pbkdf2.pure_python = True _rand.py000064400000002020147205106110006170 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import os from ._errors import pretty_message from ._types import type_name, int_types __all__ = [ 'rand_bytes', ] def rand_bytes(length): """ Returns a number of random bytes suitable for cryptographic purposes :param length: The desired number of 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 OpenSSL :return: A byte string """ if not isinstance(length, int_types): raise TypeError(pretty_message( ''' length must be an integer, not %s ''', type_name(length) )) if length < 1: raise ValueError('length must be greater than 0') if length > 1024: raise ValueError('length must not be greater than 1024') return os.urandom(length) _tls.py000064400000042665147205106110006071 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import re from datetime import datetime from ._asn1 import Certificate, int_from_bytes, timezone from ._cipher_suites import CIPHER_SUITE_MAP from .errors import TLSVerificationError, TLSDisconnectError, TLSError __all__ = [ 'detect_client_auth_request', 'extract_chain', 'get_dh_params_length', 'parse_alert', 'parse_handshake_messages', 'parse_session_info', 'parse_tls_records', 'raise_client_auth', 'raise_dh_params', 'raise_disconnection', 'raise_expired_not_yet_valid', 'raise_handshake', 'raise_hostname', 'raise_no_issuer', 'raise_protocol_error', 'raise_revoked', 'raise_self_signed', 'raise_verification', 'raise_weak_signature', ] def extract_chain(server_handshake_bytes): """ Extracts the X.509 certificates from the server handshake bytes for use when debugging :param server_handshake_bytes: A byte string of the handshake data received from the server :return: A list of asn1crypto.x509.Certificate objects """ output = [] chain_bytes = None for record_type, _, record_data in parse_tls_records(server_handshake_bytes): if record_type != b'\x16': continue for message_type, message_data in parse_handshake_messages(record_data): if message_type == b'\x0b': chain_bytes = message_data break if chain_bytes: break if chain_bytes: # The first 3 bytes are the cert chain length pointer = 3 while pointer < len(chain_bytes): cert_length = int_from_bytes(chain_bytes[pointer:pointer + 3]) cert_start = pointer + 3 cert_end = cert_start + cert_length pointer = cert_end cert_bytes = chain_bytes[cert_start:cert_end] output.append(Certificate.load(cert_bytes)) return output def detect_client_auth_request(server_handshake_bytes): """ Determines if a CertificateRequest message is sent from the server asking the client for a certificate :param server_handshake_bytes: A byte string of the handshake data received from the server :return: A boolean - if a client certificate request was found """ for record_type, _, record_data in parse_tls_records(server_handshake_bytes): if record_type != b'\x16': continue for message_type, message_data in parse_handshake_messages(record_data): if message_type == b'\x0d': return True return False def get_dh_params_length(server_handshake_bytes): """ Determines the length of the DH params from the ServerKeyExchange :param server_handshake_bytes: A byte string of the handshake data received from the server :return: None or an integer of the bit size of the DH parameters """ output = None dh_params_bytes = None for record_type, _, record_data in parse_tls_records(server_handshake_bytes): if record_type != b'\x16': continue for message_type, message_data in parse_handshake_messages(record_data): if message_type == b'\x0c': dh_params_bytes = message_data break if dh_params_bytes: break if dh_params_bytes: output = int_from_bytes(dh_params_bytes[0:2]) * 8 return output def parse_alert(server_handshake_bytes): """ Parses the handshake for protocol alerts :param server_handshake_bytes: A byte string of the handshake data received from the server :return: None or an 2-element tuple of integers: 0: 1 (warning) or 2 (fatal) 1: The alert description (see https://tools.ietf.org/html/rfc5246#section-7.2) """ for record_type, _, record_data in parse_tls_records(server_handshake_bytes): if record_type != b'\x15': continue if len(record_data) != 2: return None return (int_from_bytes(record_data[0:1]), int_from_bytes(record_data[1:2])) return None def parse_session_info(server_handshake_bytes, client_handshake_bytes): """ Parse the TLS handshake from the client to the server to extract information including the cipher suite selected, if compression is enabled, the session id and if a new or reused session ticket exists. :param server_handshake_bytes: A byte string of the handshake data received from the server :param client_handshake_bytes: A byte string of the handshake data sent to the server :return: A dict with the following keys: - "protocol": unicode string - "cipher_suite": unicode string - "compression": boolean - "session_id": "new", "reused" or None - "session_ticket: "new", "reused" or None """ protocol = None cipher_suite = None compression = False session_id = None session_ticket = None server_session_id = None client_session_id = None for record_type, _, record_data in parse_tls_records(server_handshake_bytes): if record_type != b'\x16': continue for message_type, message_data in parse_handshake_messages(record_data): # Ensure we are working with a ServerHello message if message_type != b'\x02': continue protocol = { b'\x03\x00': "SSLv3", b'\x03\x01': "TLSv1", b'\x03\x02': "TLSv1.1", b'\x03\x03': "TLSv1.2", b'\x03\x04': "TLSv1.3", }[message_data[0:2]] session_id_length = int_from_bytes(message_data[34:35]) if session_id_length > 0: server_session_id = message_data[35:35 + session_id_length] cipher_suite_start = 35 + session_id_length cipher_suite_bytes = message_data[cipher_suite_start:cipher_suite_start + 2] cipher_suite = CIPHER_SUITE_MAP[cipher_suite_bytes] compression_start = cipher_suite_start + 2 compression = message_data[compression_start:compression_start + 1] != b'\x00' extensions_length_start = compression_start + 1 extensions_data = message_data[extensions_length_start:] for extension_type, extension_data in _parse_hello_extensions(extensions_data): if extension_type == 35: session_ticket = "new" break break for record_type, _, record_data in parse_tls_records(client_handshake_bytes): if record_type != b'\x16': continue for message_type, message_data in parse_handshake_messages(record_data): # Ensure we are working with a ClientHello message if message_type != b'\x01': continue session_id_length = int_from_bytes(message_data[34:35]) if session_id_length > 0: client_session_id = message_data[35:35 + session_id_length] cipher_suite_start = 35 + session_id_length cipher_suite_length = int_from_bytes(message_data[cipher_suite_start:cipher_suite_start + 2]) compression_start = cipher_suite_start + 2 + cipher_suite_length compression_length = int_from_bytes(message_data[compression_start:compression_start + 1]) # On subsequent requests, the session ticket will only be seen # in the ClientHello message if server_session_id is None and session_ticket is None: extensions_length_start = compression_start + 1 + compression_length extensions_data = message_data[extensions_length_start:] for extension_type, extension_data in _parse_hello_extensions(extensions_data): if extension_type == 35: session_ticket = "reused" break break if server_session_id is not None: if client_session_id is None: session_id = "new" else: if client_session_id != server_session_id: session_id = "new" else: session_id = "reused" return { "protocol": protocol, "cipher_suite": cipher_suite, "compression": compression, "session_id": session_id, "session_ticket": session_ticket, } def parse_tls_records(data): """ Creates a generator returning tuples of information about each record in a byte string of data from a TLS client or server. Stops as soon as it find a ChangeCipherSpec message since all data from then on is encrypted. :param data: A byte string of TLS records :return: A generator that yields 3-element tuples: [0] Byte string of record type [1] Byte string of protocol version [2] Byte string of record data """ pointer = 0 data_len = len(data) while pointer < data_len: # Don't try to parse any more once the ChangeCipherSpec is found if data[pointer:pointer + 1] == b'\x14': break length = int_from_bytes(data[pointer + 3:pointer + 5]) yield ( data[pointer:pointer + 1], data[pointer + 1:pointer + 3], data[pointer + 5:pointer + 5 + length] ) pointer += 5 + length def parse_handshake_messages(data): """ Creates a generator returning tuples of information about each message in a byte string of data from a TLS handshake record :param data: A byte string of a TLS handshake record data :return: A generator that yields 2-element tuples: [0] Byte string of message type [1] Byte string of message data """ pointer = 0 data_len = len(data) while pointer < data_len: length = int_from_bytes(data[pointer + 1:pointer + 4]) yield ( data[pointer:pointer + 1], data[pointer + 4:pointer + 4 + length] ) pointer += 4 + length def _parse_hello_extensions(data): """ Creates a generator returning tuples of information about each extension from a byte string of extension data contained in a ServerHello ores ClientHello message :param data: A byte string of a extension data from a TLS ServerHello or ClientHello message :return: A generator that yields 2-element tuples: [0] Byte string of extension type [1] Byte string of extension data """ if data == b'': return extentions_length = int_from_bytes(data[0:2]) extensions_start = 2 extensions_end = 2 + extentions_length pointer = extensions_start while pointer < extensions_end: extension_type = int_from_bytes(data[pointer:pointer + 2]) extension_length = int_from_bytes(data[pointer + 2:pointer + 4]) yield ( extension_type, data[pointer + 4:pointer + 4 + extension_length] ) pointer += 4 + extension_length def raise_hostname(certificate, hostname): """ Raises a TLSVerificationError due to a hostname mismatch :param certificate: An asn1crypto.x509.Certificate object :raises: TLSVerificationError """ is_ip = re.match('^\\d+\\.\\d+\\.\\d+\\.\\d+$', hostname) or hostname.find(':') != -1 if is_ip: hostname_type = 'IP address %s' % hostname else: hostname_type = 'domain name %s' % hostname message = 'Server certificate verification failed - %s does not match' % hostname_type valid_ips = ', '.join(certificate.valid_ips) valid_domains = ', '.join(certificate.valid_domains) if valid_domains: message += ' valid domains: %s' % valid_domains if valid_domains and valid_ips: message += ' or' if valid_ips: message += ' valid IP addresses: %s' % valid_ips raise TLSVerificationError(message, certificate) def raise_verification(certificate): """ Raises a generic TLSVerificationError :param certificate: An asn1crypto.x509.Certificate object :raises: TLSVerificationError """ message = 'Server certificate verification failed' raise TLSVerificationError(message, certificate) def raise_weak_signature(certificate): """ Raises a TLSVerificationError when a certificate uses a weak signature algorithm :param certificate: An asn1crypto.x509.Certificate object :raises: TLSVerificationError """ message = 'Server certificate verification failed - weak certificate signature algorithm' raise TLSVerificationError(message, certificate) def raise_client_auth(): """ Raises a TLSError indicating client authentication is required :raises: TLSError """ message = 'TLS handshake failed - client authentication required' raise TLSError(message) def raise_revoked(certificate): """ Raises a TLSVerificationError due to the certificate being revoked :param certificate: An asn1crypto.x509.Certificate object :raises: TLSVerificationError """ message = 'Server certificate verification failed - certificate has been revoked' raise TLSVerificationError(message, certificate) def raise_no_issuer(certificate): """ Raises a TLSVerificationError due to no issuer certificate found in trust roots :param certificate: An asn1crypto.x509.Certificate object :raises: TLSVerificationError """ message = 'Server certificate verification failed - certificate issuer not found in trusted root certificate store' raise TLSVerificationError(message, certificate) def raise_self_signed(certificate): """ Raises a TLSVerificationError due to a self-signed certificate roots :param certificate: An asn1crypto.x509.Certificate object :raises: TLSVerificationError """ message = 'Server certificate verification failed - certificate is self-signed' raise TLSVerificationError(message, certificate) def raise_lifetime_too_long(certificate): """ Raises a TLSVerificationError due to a certificate lifetime exceeding the CAB forum certificate lifetime limit :param certificate: An asn1crypto.x509.Certificate object :raises: TLSVerificationError """ message = 'Server certificate verification failed - certificate lifetime is too long' raise TLSVerificationError(message, certificate) def raise_expired_not_yet_valid(certificate): """ Raises a TLSVerificationError due to certificate being expired, or not yet being valid :param certificate: An asn1crypto.x509.Certificate object :raises: TLSVerificationError """ validity = certificate['tbs_certificate']['validity'] not_after = validity['not_after'].native not_before = validity['not_before'].native now = datetime.now(timezone.utc) if not_before > now: formatted_before = not_before.strftime('%Y-%m-%d %H:%M:%SZ') message = 'Server certificate verification failed - certificate not valid until %s' % formatted_before elif not_after < now: formatted_after = not_after.strftime('%Y-%m-%d %H:%M:%SZ') message = 'Server certificate verification failed - certificate expired %s' % formatted_after raise TLSVerificationError(message, certificate) def raise_disconnection(): """ Raises a TLSDisconnectError due to a disconnection :raises: TLSDisconnectError """ raise TLSDisconnectError('The remote end closed the connection') def raise_protocol_error(server_handshake_bytes): """ Raises a TLSError due to a protocol error :param server_handshake_bytes: A byte string of the handshake data received from the server :raises: TLSError """ other_protocol = detect_other_protocol(server_handshake_bytes) if other_protocol: raise TLSError('TLS protocol error - server responded using %s' % other_protocol) raise TLSError('TLS protocol error - server responded using a different protocol') def raise_handshake(): """ Raises a TLSError due to a handshake error :raises: TLSError """ raise TLSError('TLS handshake failed') def raise_protocol_version(): """ Raises a TLSError due to a TLS version incompatibility :raises: TLSError """ raise TLSError('TLS handshake failed - protocol version error') def raise_dh_params(): """ Raises a TLSError due to weak DH params :raises: TLSError """ raise TLSError('TLS handshake failed - weak DH parameters') def detect_other_protocol(server_handshake_bytes): """ Looks at the server handshake bytes to try and detect a different protocol :param server_handshake_bytes: A byte string of the handshake data received from the server :return: None, or a unicode string of "ftp", "http", "imap", "pop3", "smtp" """ if server_handshake_bytes[0:5] == b'HTTP/': return 'HTTP' if server_handshake_bytes[0:4] == b'220 ': if re.match(b'^[^\r\n]*ftp', server_handshake_bytes, re.I): return 'FTP' else: return 'SMTP' if server_handshake_bytes[0:4] == b'220-': return 'FTP' if server_handshake_bytes[0:4] == b'+OK ': return 'POP3' if server_handshake_bytes[0:4] == b'* OK' or server_handshake_bytes[0:9] == b'* PREAUTH': return 'IMAP' return None _types.py000064400000001550147205106110006417 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import sys import inspect if sys.version_info < (3,): str_cls = unicode # noqa byte_cls = str int_types = (int, long) # noqa def bytes_to_list(byte_string): return [ord(b) for b in byte_string] else: str_cls = str byte_cls = bytes int_types = (int,) bytes_to_list = list def type_name(value): """ Returns a user-readable name for the type of an object :param value: A value to get the type name of :return: A unicode string of the object's type name """ if inspect.isclass(value): cls = value else: cls = value.__class__ if cls.__module__ in set(['builtins', '__builtin__']): return cls.__name__ return '%s.%s' % (cls.__module__, cls.__name__) asymmetric.py000064400000031526147205106110007277 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import hashlib import binascii from . import backend from ._asn1 import ( armor, Certificate as Asn1Certificate, DHParameters, EncryptedPrivateKeyInfo, Null, OrderedDict, Pbkdf2Salt, PrivateKeyInfo, PublicKeyInfo, ) from ._asymmetric import _unwrap_private_key_info from ._errors import pretty_message from ._types import type_name, str_cls from .kdf import pbkdf2, pbkdf2_iteration_calculator from .symmetric import aes_cbc_pkcs7_encrypt from .util import rand_bytes _backend = backend() if _backend == 'mac': from ._mac.asymmetric import ( Certificate, dsa_sign, dsa_verify, ecdsa_sign, ecdsa_verify, generate_pair, generate_dh_parameters, load_certificate, load_pkcs12, load_private_key, load_public_key, PrivateKey, PublicKey, rsa_pkcs1v15_sign, rsa_pkcs1v15_verify, rsa_pss_sign, rsa_pss_verify, rsa_pkcs1v15_encrypt, rsa_pkcs1v15_decrypt, rsa_oaep_encrypt, rsa_oaep_decrypt, ) elif _backend == 'win' or _backend == 'winlegacy': from ._win.asymmetric import ( Certificate, dsa_sign, dsa_verify, ecdsa_sign, ecdsa_verify, generate_pair, generate_dh_parameters, load_certificate, load_pkcs12, load_private_key, load_public_key, PrivateKey, PublicKey, rsa_pkcs1v15_sign, rsa_pkcs1v15_verify, rsa_pss_sign, rsa_pss_verify, rsa_pkcs1v15_encrypt, rsa_pkcs1v15_decrypt, rsa_oaep_encrypt, rsa_oaep_decrypt, ) else: from ._openssl.asymmetric import ( Certificate, dsa_sign, dsa_verify, ecdsa_sign, ecdsa_verify, generate_pair, generate_dh_parameters, load_certificate, load_pkcs12, load_private_key, load_public_key, PrivateKey, PublicKey, rsa_pkcs1v15_sign, rsa_pkcs1v15_verify, rsa_pss_sign, rsa_pss_verify, rsa_pkcs1v15_encrypt, rsa_pkcs1v15_decrypt, rsa_oaep_encrypt, rsa_oaep_decrypt, ) __all__ = [ 'Certificate', 'dsa_sign', 'dsa_verify', 'dump_certificate', 'dump_dh_parameters', 'dump_openssl_private_key', 'dump_private_key', 'dump_public_key', 'ecdsa_sign', 'ecdsa_verify', 'generate_pair', 'generate_dh_parameters', 'load_certificate', 'load_pkcs12', 'load_private_key', 'load_public_key', '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', ] def dump_dh_parameters(dh_parameters, encoding='pem'): """ Serializes an asn1crypto.algos.DHParameters object into a byte string :param dh_parameters: An asn1crypto.algos.DHParameters object :param encoding: A unicode string of "pem" or "der" :return: A byte string of the encoded DH parameters """ if encoding not in set(['pem', 'der']): raise ValueError(pretty_message( ''' encoding must be one of "pem", "der", not %s ''', repr(encoding) )) if not isinstance(dh_parameters, DHParameters): raise TypeError(pretty_message( ''' dh_parameters must be an instance of asn1crypto.algos.DHParameters, not %s ''', type_name(dh_parameters) )) output = dh_parameters.dump() if encoding == 'pem': output = armor('DH PARAMETERS', output) return output def dump_public_key(public_key, encoding='pem'): """ Serializes a public key object into a byte string :param public_key: An oscrypto.asymmetric.PublicKey or asn1crypto.keys.PublicKeyInfo object :param encoding: A unicode string of "pem" or "der" :return: A byte string of the encoded public key """ if encoding not in set(['pem', 'der']): raise ValueError(pretty_message( ''' encoding must be one of "pem", "der", not %s ''', repr(encoding) )) is_oscrypto = isinstance(public_key, PublicKey) if not isinstance(public_key, PublicKeyInfo) and not is_oscrypto: raise TypeError(pretty_message( ''' public_key must be an instance of oscrypto.asymmetric.PublicKey or asn1crypto.keys.PublicKeyInfo, not %s ''', type_name(public_key) )) if is_oscrypto: public_key = public_key.asn1 output = public_key.dump() if encoding == 'pem': output = armor('PUBLIC KEY', output) return output def dump_certificate(certificate, encoding='pem'): """ Serializes a certificate object into a byte string :param certificate: An oscrypto.asymmetric.Certificate or asn1crypto.x509.Certificate object :param encoding: A unicode string of "pem" or "der" :return: A byte string of the encoded certificate """ if encoding not in set(['pem', 'der']): raise ValueError(pretty_message( ''' encoding must be one of "pem", "der", not %s ''', repr(encoding) )) is_oscrypto = isinstance(certificate, Certificate) if not isinstance(certificate, Asn1Certificate) and not is_oscrypto: raise TypeError(pretty_message( ''' certificate must be an instance of oscrypto.asymmetric.Certificate or asn1crypto.x509.Certificate, not %s ''', type_name(certificate) )) if is_oscrypto: certificate = certificate.asn1 output = certificate.dump() if encoding == 'pem': output = armor('CERTIFICATE', output) return output def dump_private_key(private_key, passphrase, encoding='pem', target_ms=200): """ Serializes a private key object into a byte string of the PKCS#8 format :param private_key: An oscrypto.asymmetric.PrivateKey or asn1crypto.keys.PrivateKeyInfo object :param passphrase: A unicode string of the passphrase to encrypt the private key with. A passphrase of None will result in no encryption. A blank string will result in a ValueError to help ensure that the lack of passphrase is intentional. :param encoding: A unicode string of "pem" or "der" :param target_ms: Use PBKDF2 with the number of iterations that takes about this many milliseconds on the current machine. :raises: ValueError - when a blank string is provided for the passphrase :return: A byte string of the encoded and encrypted public key """ if encoding not in set(['pem', 'der']): raise ValueError(pretty_message( ''' encoding must be one of "pem", "der", not %s ''', repr(encoding) )) if passphrase is not None: if not isinstance(passphrase, str_cls): raise TypeError(pretty_message( ''' passphrase must be a unicode string, not %s ''', type_name(passphrase) )) if passphrase == '': raise ValueError(pretty_message( ''' passphrase may not be a blank string - pass None to disable encryption ''' )) is_oscrypto = isinstance(private_key, PrivateKey) if not isinstance(private_key, PrivateKeyInfo) and not is_oscrypto: raise TypeError(pretty_message( ''' private_key must be an instance of oscrypto.asymmetric.PrivateKey or asn1crypto.keys.PrivateKeyInfo, not %s ''', type_name(private_key) )) if is_oscrypto: private_key = private_key.asn1 output = private_key.dump() if passphrase is not None: cipher = 'aes256_cbc' key_length = 32 kdf_hmac = 'sha256' kdf_salt = rand_bytes(key_length) iterations = pbkdf2_iteration_calculator(kdf_hmac, key_length, target_ms=target_ms, quiet=True) # Need a bare minimum of 10,000 iterations for PBKDF2 as of 2015 if iterations < 10000: iterations = 10000 passphrase_bytes = passphrase.encode('utf-8') key = pbkdf2(kdf_hmac, passphrase_bytes, kdf_salt, iterations, key_length) iv, ciphertext = aes_cbc_pkcs7_encrypt(key, output, None) output = EncryptedPrivateKeyInfo({ 'encryption_algorithm': { 'algorithm': 'pbes2', 'parameters': { 'key_derivation_func': { 'algorithm': 'pbkdf2', 'parameters': { 'salt': Pbkdf2Salt( name='specified', value=kdf_salt ), 'iteration_count': iterations, 'prf': { 'algorithm': kdf_hmac, 'parameters': Null() } } }, 'encryption_scheme': { 'algorithm': cipher, 'parameters': iv } } }, 'encrypted_data': ciphertext }).dump() if encoding == 'pem': if passphrase is None: object_type = 'PRIVATE KEY' else: object_type = 'ENCRYPTED PRIVATE KEY' output = armor(object_type, output) return output def dump_openssl_private_key(private_key, passphrase): """ Serializes a private key object into a byte string of the PEM formats used by OpenSSL. The format chosen will depend on the type of private key - RSA, DSA or EC. Do not use this method unless you really must interact with a system that does not support PKCS#8 private keys. The encryption provided by PKCS#8 is far superior to the OpenSSL formats. This is due to the fact that the OpenSSL formats don't stretch the passphrase, making it very easy to brute-force. :param private_key: An oscrypto.asymmetric.PrivateKey or asn1crypto.keys.PrivateKeyInfo object :param passphrase: A unicode string of the passphrase to encrypt the private key with. A passphrase of None will result in no encryption. A blank string will result in a ValueError to help ensure that the lack of passphrase is intentional. :raises: ValueError - when a blank string is provided for the passphrase :return: A byte string of the encoded and encrypted public key """ if passphrase is not None: if not isinstance(passphrase, str_cls): raise TypeError(pretty_message( ''' passphrase must be a unicode string, not %s ''', type_name(passphrase) )) if passphrase == '': raise ValueError(pretty_message( ''' passphrase may not be a blank string - pass None to disable encryption ''' )) is_oscrypto = isinstance(private_key, PrivateKey) if not isinstance(private_key, PrivateKeyInfo) and not is_oscrypto: raise TypeError(pretty_message( ''' private_key must be an instance of oscrypto.asymmetric.PrivateKey or asn1crypto.keys.PrivateKeyInfo, not %s ''', type_name(private_key) )) if is_oscrypto: private_key = private_key.asn1 output = _unwrap_private_key_info(private_key).dump() headers = None if passphrase is not None: iv = rand_bytes(16) headers = OrderedDict() headers['Proc-Type'] = '4,ENCRYPTED' headers['DEK-Info'] = 'AES-128-CBC,%s' % binascii.hexlify(iv).decode('ascii') key_length = 16 passphrase_bytes = passphrase.encode('utf-8') key = hashlib.md5(passphrase_bytes + iv[0:8]).digest() while key_length > len(key): key += hashlib.md5(key + passphrase_bytes + iv[0:8]).digest() key = key[0:key_length] iv, output = aes_cbc_pkcs7_encrypt(key, output, iv) if private_key.algorithm == 'ec': object_type = 'EC PRIVATE KEY' elif private_key.algorithm == 'rsa': object_type = 'RSA PRIVATE KEY' elif private_key.algorithm == 'dsa': object_type = 'DSA PRIVATE KEY' return armor(object_type, output, headers=headers) errors.py000064400000003570147205106110006434 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import sys import socket __all__ = [ 'AsymmetricKeyError', 'CACertsError', 'LibraryNotFoundError', 'SignatureError', 'TLSError', 'TLSConnectionError', 'TLSDisconnectError', 'TLSGracefulDisconnectError', 'TLSVerificationError', ] class LibraryNotFoundError(Exception): """ An exception when trying to find a shared library """ pass class SignatureError(Exception): """ An exception when validating a signature """ pass class AsymmetricKeyError(Exception): """ An exception when a key is invalid or unsupported """ pass class IncompleteAsymmetricKeyError(AsymmetricKeyError): """ An exception when a key is missing necessary information """ pass class CACertsError(Exception): """ An exception when exporting CA certs from the OS trust store """ pass class TLSError(socket.error): """ An exception related to TLS functionality """ message = None def __init__(self, message): self.args = (message,) self.message = message def __str__(self): output = self.__unicode__() if sys.version_info < (3,): output = output.encode('utf-8') return output def __unicode__(self): return self.message class TLSConnectionError(TLSError): pass class TLSDisconnectError(TLSConnectionError): pass class TLSGracefulDisconnectError(TLSDisconnectError): pass class TLSVerificationError(TLSError): """ A server certificate verification error happened during a TLS handshake """ certificate = None def __init__(self, message, certificate): TLSError.__init__(self, message) self.certificate = certificate self.args = (message, certificate) kdf.py000064400000016262147205106110005666 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import sys import hashlib from datetime import datetime from . import backend from .util import rand_bytes from ._types import type_name, byte_cls, int_types from ._errors import pretty_message from ._ffi import new, deref _backend = backend() if _backend == 'mac': from ._mac.util import pbkdf2, pkcs12_kdf elif _backend == 'win' or _backend == 'winlegacy': from ._win.util import pbkdf2, pkcs12_kdf from ._win._kernel32 import kernel32, handle_error else: from ._openssl.util import pbkdf2, pkcs12_kdf __all__ = [ 'pbkdf1', 'pbkdf2', 'pbkdf2_iteration_calculator', 'pkcs12_kdf', ] if sys.platform == 'win32': def _get_start(): number = new(kernel32, 'LARGE_INTEGER *') res = kernel32.QueryPerformanceCounter(number) handle_error(res) return deref(number) def _get_elapsed(start): length = _get_start() - start return int(length / 1000.0) else: def _get_start(): return datetime.now() def _get_elapsed(start): length = datetime.now() - start seconds = length.seconds + (length.days * 24 * 3600) milliseconds = (length.microseconds / 10 ** 3) return int(milliseconds + (seconds * 10 ** 3)) def pbkdf2_iteration_calculator(hash_algorithm, key_length, target_ms=100, quiet=False): """ Runs pbkdf2() twice to determine the approximate number of iterations to use to hit a desired time per run. Use this on a production machine to dynamically adjust the number of iterations as high as you can. :param hash_algorithm: The string name of the hash algorithm to use: "md5", "sha1", "sha224", "sha256", "sha384", "sha512" :param key_length: The length of the desired key in bytes :param target_ms: The number of milliseconds the derivation should take :param quiet: If no output should be printed as attempts are made :return: An integer number of iterations of PBKDF2 using the specified hash that will take at least target_ms """ 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) )) 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 not isinstance(target_ms, int_types): raise TypeError(pretty_message( ''' target_ms must be an integer, not %s ''', type_name(target_ms) )) if target_ms < 1: raise ValueError(pretty_message( ''' target_ms must be greater than 0 - is %s ''', repr(target_ms) )) if pbkdf2.pure_python: raise OSError(pretty_message( ''' Only a very slow, pure-python version of PBKDF2 is available, making this function useless ''' )) iterations = 10000 password = 'this is a test'.encode('utf-8') salt = rand_bytes(key_length) def _measure(): start = _get_start() pbkdf2(hash_algorithm, password, salt, iterations, key_length) observed_ms = _get_elapsed(start) if not quiet: print('%s iterations in %sms' % (iterations, observed_ms)) return 1.0 / target_ms * observed_ms # Measure the initial guess, then estimate how many iterations it would # take to reach 1/2 of the target ms and try it to get a good final number fraction = _measure() iterations = int(iterations / fraction / 2.0) fraction = _measure() iterations = iterations / fraction # < 20,000 round to 1000 # 20,000-100,000 round to 5,000 # > 100,000 round to 10,000 round_factor = -3 if iterations < 100000 else -4 result = int(round(iterations, round_factor)) if result > 20000: result = (result // 5000) * 5000 return result def pbkdf1(hash_algorithm, password, salt, iterations, key_length): """ An implementation of PBKDF1 - should only be used for interop with legacy systems, not new architectures :param hash_algorithm: The string name of the hash algorithm to use: "md2", "md5", "sha1" :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 :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(['md2', 'md5', 'sha1']): raise ValueError(pretty_message( ''' hash_algorithm must be one of "md2", "md5", "sha1", not %s ''', repr(hash_algorithm) )) if key_length > 16 and hash_algorithm in set(['md2', 'md5']): raise ValueError(pretty_message( ''' key_length can not be longer than 16 for %s - is %s ''', (hash_algorithm, repr(key_length)) )) if key_length > 20 and hash_algorithm == 'sha1': raise ValueError(pretty_message( ''' key_length can not be longer than 20 for sha1 - is %s ''', repr(key_length) )) algo = getattr(hashlib, hash_algorithm) output = algo(password + salt).digest() for _ in range(2, iterations + 1): output = algo(output).digest() return output[:key_length] keys.py000064400000001036147205106110006066 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from . import backend from ._asymmetric import parse_certificate, parse_private, parse_public _backend = backend() if _backend == 'mac': from ._mac.asymmetric import parse_pkcs12 elif _backend == 'win' or _backend == 'winlegacy': from ._win.asymmetric import parse_pkcs12 else: from ._openssl.asymmetric import parse_pkcs12 __all__ = [ 'parse_certificate', 'parse_pkcs12', 'parse_private', 'parse_public', ] symmetric.py000064400000003460147205106110007132 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from . import backend _backend = backend() if _backend == 'mac': from ._mac.symmetric import ( 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, ) elif _backend == 'win' or _backend == 'winlegacy': from ._win.symmetric import ( 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, ) else: from ._openssl.symmetric import ( 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, ) __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', ] tls.py000064400000000766147205106110005726 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from . import backend _backend = backend() if _backend == 'mac': from ._mac.tls import ( TLSSession, TLSSocket, ) elif _backend == 'win' or _backend == 'winlegacy': from ._win.tls import ( TLSSession, TLSSocket, ) else: from ._openssl.tls import ( TLSSession, TLSSocket, ) __all__ = [ 'TLSSession', 'TLSSocket', ] trust_list.py000064400000032001147205106110007323 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import os import time import sys import tempfile import threading from ._asn1 import armor, Certificate from ._errors import pretty_message from .errors import CACertsError if sys.platform == 'win32': from ._win.trust_list import extract_from_system, system_path elif sys.platform == 'darwin': from ._mac.trust_list import extract_from_system, system_path else: from ._linux_bsd.trust_list import extract_from_system, system_path __all__ = [ 'clear_cache', 'get_list', 'get_path', ] path_lock = threading.Lock() memory_lock = threading.Lock() _module_values = { 'last_update': None, 'certs': None } _oid_map = { # apple_smime -> email_protection '1.2.840.113635.100.1.8': set(['1.3.6.1.5.5.7.3.4']), # apple_code_signing -> code_signing '1.2.840.113635.100.1.16': set(['1.3.6.1.5.5.7.3.3']), # apple_time_stamping -> time_stamping '1.2.840.113635.100.1.20': set(['1.3.6.1.5.5.7.3.8']), # microsoft_time_stamp_signing -> time_stamping '1.3.6.1.4.1.311.10.3.2': set(['1.3.6.1.5.5.7.3.8']), # apple_ssl -> (server_auth, client_auth) '1.2.840.113635.100.1.3': set([ '1.3.6.1.5.5.7.3.1', '1.3.6.1.5.5.7.3.2', ]), # apple_eap -> (eap_over_ppp, eap_over_lan) '1.2.840.113635.100.1.9': set([ '1.3.6.1.5.5.7.3.13', '1.3.6.1.5.5.7.3.14', ]), # apple_ipsec -> (ipsec_end_system, ipsec_tunnel, ipsec_user, ipsec_ike) '1.2.840.113635.100.1.11': set([ '1.3.6.1.5.5.7.3.5', '1.3.6.1.5.5.7.3.6', '1.3.6.1.5.5.7.3.7', '1.3.6.1.5.5.7.3.17', ]) } def get_path(temp_dir=None, cache_length=24, cert_callback=None): """ Get the filesystem path to a file that contains OpenSSL-compatible CA certs. On OS X and Windows, there are extracted from the system certificate store and cached in a file on the filesystem. This path should not be writable by other users, otherwise they could inject CA certs into the trust list. :param temp_dir: The temporary directory to cache the CA certs in on OS X and Windows. Needs to have secure permissions so other users can not modify the contents. :param cache_length: The number of hours to cache the CA certs on OS X and Windows :param cert_callback: A callback that is called once for each certificate in the trust store. It should accept two parameters: an asn1crypto.x509.Certificate object, and a reason. The reason will be None if the certificate is being exported, otherwise it will be a unicode string of the reason it won't. This is only called on Windows and OS X when passed to this function. :raises: oscrypto.errors.CACertsError - when an error occurs exporting/locating certs :return: The full filesystem path to a CA certs file """ ca_path, temp = _ca_path(temp_dir) # Windows and OS X if temp and _cached_path_needs_update(ca_path, cache_length): empty_set = set() any_purpose = '2.5.29.37.0' apple_ssl = '1.2.840.113635.100.1.3' win_server_auth = '1.3.6.1.5.5.7.3.1' with path_lock: if _cached_path_needs_update(ca_path, cache_length): with open(ca_path, 'wb') as f: for cert, trust_oids, reject_oids in extract_from_system(cert_callback, True): if sys.platform == 'darwin': if trust_oids != empty_set and any_purpose not in trust_oids \ and apple_ssl not in trust_oids: if cert_callback: cert_callback(Certificate.load(cert), 'implicitly distrusted for TLS') continue if reject_oids != empty_set and (apple_ssl in reject_oids or any_purpose in reject_oids): if cert_callback: cert_callback(Certificate.load(cert), 'explicitly distrusted for TLS') continue elif sys.platform == 'win32': if trust_oids != empty_set and any_purpose not in trust_oids \ and win_server_auth not in trust_oids: if cert_callback: cert_callback(Certificate.load(cert), 'implicitly distrusted for TLS') continue if reject_oids != empty_set and (win_server_auth in reject_oids or any_purpose in reject_oids): if cert_callback: cert_callback(Certificate.load(cert), 'explicitly distrusted for TLS') continue if cert_callback: cert_callback(Certificate.load(cert), None) f.write(armor('CERTIFICATE', cert)) if not ca_path: raise CACertsError('No CA certs found') return ca_path def get_list(cache_length=24, map_vendor_oids=True, cert_callback=None): """ Retrieves (and caches in memory) the list of CA certs from the OS. Includes trust information from the OS - purposes the certificate should be trusted or rejected for. Trust information is encoded via object identifiers (OIDs) that are sourced from various RFCs and vendors (Apple and Microsoft). This trust information augments what is in the certificate itself. Any OID that is in the set of trusted purposes indicates the certificate has been explicitly trusted for a purpose beyond the extended key purpose extension. Any OID in the reject set is a purpose that the certificate should not be trusted for, even if present in the extended key purpose extension. *A list of common trust OIDs can be found as part of the `KeyPurposeId()` class in the `asn1crypto.x509` module of the `asn1crypto` package.* :param cache_length: The number of hours to cache the CA certs in memory before they are refreshed :param map_vendor_oids: A bool indicating if the following mapping of OIDs should happen for trust information from the OS trust list: - 1.2.840.113635.100.1.3 (apple_ssl) -> 1.3.6.1.5.5.7.3.1 (server_auth) - 1.2.840.113635.100.1.3 (apple_ssl) -> 1.3.6.1.5.5.7.3.2 (client_auth) - 1.2.840.113635.100.1.8 (apple_smime) -> 1.3.6.1.5.5.7.3.4 (email_protection) - 1.2.840.113635.100.1.9 (apple_eap) -> 1.3.6.1.5.5.7.3.13 (eap_over_ppp) - 1.2.840.113635.100.1.9 (apple_eap) -> 1.3.6.1.5.5.7.3.14 (eap_over_lan) - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.5 (ipsec_end_system) - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.6 (ipsec_tunnel) - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.7 (ipsec_user) - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.17 (ipsec_ike) - 1.2.840.113635.100.1.16 (apple_code_signing) -> 1.3.6.1.5.5.7.3.3 (code_signing) - 1.2.840.113635.100.1.20 (apple_time_stamping) -> 1.3.6.1.5.5.7.3.8 (time_stamping) - 1.3.6.1.4.1.311.10.3.2 (microsoft_time_stamp_signing) -> 1.3.6.1.5.5.7.3.8 (time_stamping) :param cert_callback: A callback that is called once for each certificate in the trust store. It should accept two parameters: an asn1crypto.x509.Certificate object, and a reason. The reason will be None if the certificate is being exported, otherwise it will be a unicode string of the reason it won't. :raises: oscrypto.errors.CACertsError - when an error occurs exporting/locating certs :return: A (copied) list of 3-element tuples containing CA certs from the OS trust ilst: - 0: an asn1crypto.x509.Certificate object - 1: a set of unicode strings of OIDs of trusted purposes - 2: a set of unicode strings of OIDs of rejected purposes """ if not _in_memory_up_to_date(cache_length): with memory_lock: if not _in_memory_up_to_date(cache_length): certs = [] for cert_bytes, trust_oids, reject_oids in extract_from_system(cert_callback): if map_vendor_oids: trust_oids = _map_oids(trust_oids) reject_oids = _map_oids(reject_oids) certs.append((Certificate.load(cert_bytes), trust_oids, reject_oids)) _module_values['certs'] = certs _module_values['last_update'] = time.time() return list(_module_values['certs']) def clear_cache(temp_dir=None): """ Clears any cached info that was exported from the OS trust store. This will ensure the latest changes are returned from calls to get_list() and get_path(), but at the expense of re-exporting and parsing all certificates. :param temp_dir: The temporary directory to cache the CA certs in on OS X and Windows. Needs to have secure permissions so other users can not modify the contents. Must be the same value passed to get_path(). """ with memory_lock: _module_values['last_update'] = None _module_values['certs'] = None ca_path, temp = _ca_path(temp_dir) if temp: with path_lock: if os.path.exists(ca_path): os.remove(ca_path) def _ca_path(temp_dir=None): """ Returns the file path to the CA certs file :param temp_dir: The temporary directory to cache the CA certs in on OS X and Windows. Needs to have secure permissions so other users can not modify the contents. :return: A 2-element tuple: - 0: A unicode string of the file path - 1: A bool if the file is a temporary file """ ca_path = system_path() # Windows and OS X if ca_path is None: if temp_dir is None: temp_dir = tempfile.gettempdir() if not os.path.isdir(temp_dir): raise CACertsError(pretty_message( ''' The temp dir specified, "%s", is not a directory ''', temp_dir )) ca_path = os.path.join(temp_dir, 'oscrypto-ca-bundle.crt') return (ca_path, True) return (ca_path, False) def _map_oids(oids): """ Takes a set of unicode string OIDs and converts vendor-specific OIDs into generics OIDs from RFCs. - 1.2.840.113635.100.1.3 (apple_ssl) -> 1.3.6.1.5.5.7.3.1 (server_auth) - 1.2.840.113635.100.1.3 (apple_ssl) -> 1.3.6.1.5.5.7.3.2 (client_auth) - 1.2.840.113635.100.1.8 (apple_smime) -> 1.3.6.1.5.5.7.3.4 (email_protection) - 1.2.840.113635.100.1.9 (apple_eap) -> 1.3.6.1.5.5.7.3.13 (eap_over_ppp) - 1.2.840.113635.100.1.9 (apple_eap) -> 1.3.6.1.5.5.7.3.14 (eap_over_lan) - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.5 (ipsec_end_system) - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.6 (ipsec_tunnel) - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.7 (ipsec_user) - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.17 (ipsec_ike) - 1.2.840.113635.100.1.16 (apple_code_signing) -> 1.3.6.1.5.5.7.3.3 (code_signing) - 1.2.840.113635.100.1.20 (apple_time_stamping) -> 1.3.6.1.5.5.7.3.8 (time_stamping) - 1.3.6.1.4.1.311.10.3.2 (microsoft_time_stamp_signing) -> 1.3.6.1.5.5.7.3.8 (time_stamping) :param oids: A set of unicode strings :return: The original set of OIDs with any mapped OIDs added """ new_oids = set() for oid in oids: if oid in _oid_map: new_oids |= _oid_map[oid] return oids | new_oids def _cached_path_needs_update(ca_path, cache_length): """ Checks to see if a cache file needs to be refreshed :param ca_path: A unicode string of the path to the cache file :param cache_length: An integer representing the number of hours the cache is valid for :return: A boolean - True if the cache needs to be updated, False if the file is up-to-date """ exists = os.path.exists(ca_path) if not exists: return True stats = os.stat(ca_path) if stats.st_mtime < time.time() - cache_length * 60 * 60: return True if stats.st_size == 0: return True return False def _in_memory_up_to_date(cache_length): """ Checks to see if the in-memory cache of certificates is fresh :param cache_length: An integer representing the number of hours the cache is valid for :return: A boolean - True if the cache is up-to-date, False if it needs to be refreshed """ return ( _module_values['certs'] and _module_values['last_update'] and _module_values['last_update'] > time.time() - (cache_length * 60 * 60) ) util.py000064400000002463147205106110006075 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import sys from ._errors import pretty_message from ._types import type_name, byte_cls if sys.platform == 'darwin': from ._mac.util import rand_bytes elif sys.platform == 'win32': from ._win.util import rand_bytes else: from ._openssl.util import rand_bytes __all__ = [ 'constant_compare', 'rand_bytes', ] def constant_compare(a, b): """ Compares two byte strings in constant time to see if they are equal :param a: The first byte string :param b: The second byte string :return: A boolean if the two byte strings are equal """ if not isinstance(a, byte_cls): raise TypeError(pretty_message( ''' a must be a byte string, not %s ''', type_name(a) )) if not isinstance(b, byte_cls): raise TypeError(pretty_message( ''' b must be a byte string, not %s ''', type_name(b) )) if len(a) != len(b): return False if sys.version_info < (3,): a = [ord(char) for char in a] b = [ord(char) for char in b] result = 0 for x, y in zip(a, b): result |= x ^ y return result == 0 version.py000064400000000230147205106110006573 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function __version__ = '1.3.0' __version_info__ = (1, 3, 0) _linux_bsd/__init__.py000064400000000000147205106110010766 0ustar00_linux_bsd/trust_list.py000064400000007671147205106110011470 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import os from .._asn1 import Certificate, TrustedCertificate, unarmor from .._errors import pretty_message __all__ = [ 'extract_from_system', 'system_path', ] def system_path(): """ Tries to find a CA certs bundle in common locations :raises: OSError - when no valid CA certs bundle was found on the filesystem :return: The full filesystem path to a CA certs bundle file """ ca_path = None # Common CA cert paths paths = [ '/usr/lib/ssl/certs/ca-certificates.crt', '/etc/ssl/certs/ca-certificates.crt', '/etc/ssl/certs/ca-bundle.crt', '/etc/pki/tls/certs/ca-bundle.crt', '/etc/ssl/ca-bundle.pem', '/usr/local/share/certs/ca-root-nss.crt', '/etc/ssl/cert.pem' ] # First try SSL_CERT_FILE if 'SSL_CERT_FILE' in os.environ: paths.insert(0, os.environ['SSL_CERT_FILE']) for path in paths: if os.path.exists(path) and os.path.getsize(path) > 0: ca_path = path break if not ca_path: raise OSError(pretty_message( ''' Unable to find a CA certs bundle in common locations - try setting the SSL_CERT_FILE environmental variable ''' )) return ca_path def extract_from_system(cert_callback=None, callback_only_on_failure=False): """ Extracts trusted CA certs from the system CA cert bundle :param cert_callback: A callback that is called once for each certificate in the trust store. It should accept two parameters: an asn1crypto.x509.Certificate object, and a reason. The reason will be None if the certificate is being exported, otherwise it will be a unicode string of the reason it won't. :param callback_only_on_failure: A boolean - if the callback should only be called when a certificate is not exported. :return: A list of 3-element tuples: - 0: a byte string of a DER-encoded certificate - 1: a set of unicode strings that are OIDs of purposes to trust the certificate for - 2: a set of unicode strings that are OIDs of purposes to reject the certificate for """ all_purposes = '2.5.29.37.0' ca_path = system_path() output = [] with open(ca_path, 'rb') as f: for armor_type, _, cert_bytes in unarmor(f.read(), multiple=True): # Without more info, a certificate is trusted for all purposes if armor_type == 'CERTIFICATE': if cert_callback: cert_callback(Certificate.load(cert_bytes), None) output.append((cert_bytes, set(), set())) # The OpenSSL TRUSTED CERTIFICATE construct adds OIDs for trusted # and rejected purposes, so we extract that info. elif armor_type == 'TRUSTED CERTIFICATE': cert, aux = TrustedCertificate.load(cert_bytes) reject_all = False trust_oids = set() reject_oids = set() for purpose in aux['trust']: if purpose.dotted == all_purposes: trust_oids = set([purpose.dotted]) break trust_oids.add(purpose.dotted) for purpose in aux['reject']: if purpose.dotted == all_purposes: reject_all = True break reject_oids.add(purpose.dotted) if reject_all: if cert_callback: cert_callback(cert, 'explicitly distrusted') continue if cert_callback and not callback_only_on_failure: cert_callback(cert, None) output.append((cert.dump(), trust_oids, reject_oids)) return output _linux_bsd/__pycache__/__init__.cpython-38.pyc000064400000000250147205106110015263 0ustar00U af@sdS)NrrrM/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_linux_bsd/__init__.py_linux_bsd/__pycache__/trust_list.cpython-38.pyc000064400000006046147205106110015751 0ustar00U af@s^ddlmZmZmZmZddlZddlmZmZm Z ddl m Z ddgZ ddZ d d dZdS) )unicode_literalsdivisionabsolute_importprint_functionN) CertificateTrustedCertificateunarmor)pretty_messageextract_from_system system_pathcCstd}dddddddg}d tjkr2|d tjd |D](}tj|r6tj|d kr6|}q`q6|spttd |S) z Tries to find a CA certs bundle in common locations :raises: OSError - when no valid CA certs bundle was found on the filesystem :return: The full filesystem path to a CA certs bundle file Nz&/usr/lib/ssl/certs/ca-certificates.crtz"/etc/ssl/certs/ca-certificates.crtz/etc/ssl/certs/ca-bundle.crtz /etc/pki/tls/certs/ca-bundle.crtz/etc/ssl/ca-bundle.pemz&/usr/local/share/certs/ca-root-nss.crtz/etc/ssl/cert.pemZ SSL_CERT_FILErz Unable to find a CA certs bundle in common locations - try setting the SSL_CERT_FILE environmental variable )osenvironinsertpathexistsgetsizeOSErrorr )ca_pathpathsrrO/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_linux_bsd/trust_list.pyr s(  Fc Cs@d}t}g}t|d}t|ddD]\}}}|dkrj|rT|t|d||ttfq,|dkr,t|\} } d} t} t} | d D]*}|j |krt|j g} q| |j q| d D]"}|j |krd} q| |j q| r|r,|| d q,|r|s|| d|| | | fq,W5QRX|S) ag Extracts trusted CA certs from the system CA cert bundle :param cert_callback: A callback that is called once for each certificate in the trust store. It should accept two parameters: an asn1crypto.x509.Certificate object, and a reason. The reason will be None if the certificate is being exported, otherwise it will be a unicode string of the reason it won't. :param callback_only_on_failure: A boolean - if the callback should only be called when a certificate is not exported. :return: A list of 3-element tuples: - 0: a byte string of a DER-encoded certificate - 1: a set of unicode strings that are OIDs of purposes to trust the certificate for - 2: a set of unicode strings that are OIDs of purposes to reject the certificate for z 2.5.29.37.0rbT)multiple CERTIFICATENzTRUSTED CERTIFICATEFtrustZrejectzexplicitly distrusted) r openr readrloadappendsetrZdottedadddump)Z cert_callbackZcallback_only_on_failureZ all_purposesroutputfZ armor_type_Z cert_bytescertZauxZ reject_allZ trust_oidsZ reject_oidspurposerrrr <s@         )NF) __future__rrrrr Z_asn1rrr _errorsr __all__r r rrrrs ,_mac/__init__.py000064400000000000147205106110007537 0ustar00_mac/_common_crypto.py000064400000000756147205106110011051 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from .. import ffi if ffi() == 'cffi': from ._common_crypto_cffi import CommonCrypto else: from ._common_crypto_ctypes import CommonCrypto __all__ = [ 'CommonCrypto', 'CommonCryptoConst', ] class CommonCryptoConst(): kCCPBKDF2 = 2 kCCPRFHmacAlgSHA1 = 1 kCCPRFHmacAlgSHA224 = 2 kCCPRFHmacAlgSHA256 = 3 kCCPRFHmacAlgSHA384 = 4 kCCPRFHmacAlgSHA512 = 5 _mac/_common_crypto_cffi.py000064400000001341147205106110012027 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from .._ffi import register_ffi from cffi import FFI __all__ = [ 'CommonCrypto', ] ffi = FFI() ffi.cdef(""" typedef uint32_t CCPBKDFAlgorithm; typedef uint32_t CCPseudoRandomAlgorithm; typedef unsigned int uint; int CCKeyDerivationPBKDF(CCPBKDFAlgorithm algorithm, const char *password, size_t passwordLen, const char *salt, size_t saltLen, CCPseudoRandomAlgorithm prf, uint rounds, char *derivedKey, size_t derivedKeyLen); """) common_crypto_path = '/usr/lib/system/libcommonCrypto.dylib' CommonCrypto = ffi.dlopen(common_crypto_path) register_ffi(CommonCrypto, ffi) _mac/_common_crypto_ctypes.py000064400000001313147205106110012426 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from ctypes import CDLL, c_uint32, c_char_p, c_size_t, c_int, c_uint from .._ffi import FFIEngineError __all__ = [ 'CommonCrypto', ] common_crypto_path = '/usr/lib/system/libcommonCrypto.dylib' CommonCrypto = CDLL(common_crypto_path, use_errno=True) try: CommonCrypto.CCKeyDerivationPBKDF.argtypes = [ c_uint32, c_char_p, c_size_t, c_char_p, c_size_t, c_uint32, c_uint, c_char_p, c_size_t ] CommonCrypto.CCKeyDerivationPBKDF.restype = c_int except (AttributeError): raise FFIEngineError('Error initializing ctypes') _mac/_core_foundation.py000064400000023715147205106110011337 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from .. import ffi from .._ffi import is_null, unwrap if ffi() == 'cffi': from ._core_foundation_cffi import CoreFoundation, CFHelpers else: from ._core_foundation_ctypes import CoreFoundation, CFHelpers _all__ = [ 'CFHelpers', 'CoreFoundation', 'handle_cf_error', ] def handle_cf_error(error_pointer): """ Checks a CFErrorRef and throws an exception if there is an error to report :param error_pointer: A CFErrorRef :raises: OSError - when the CFErrorRef contains an error """ if is_null(error_pointer): return error = unwrap(error_pointer) if is_null(error): return cf_string_domain = CoreFoundation.CFErrorGetDomain(error) domain = CFHelpers.cf_string_to_unicode(cf_string_domain) CoreFoundation.CFRelease(cf_string_domain) num = CoreFoundation.CFErrorGetCode(error) cf_string_ref = CoreFoundation.CFErrorCopyDescription(error) output = CFHelpers.cf_string_to_unicode(cf_string_ref) CoreFoundation.CFRelease(cf_string_ref) if output is None: if domain == 'NSOSStatusErrorDomain': code_map = { -2147416010: 'ACL add failed', -2147416025: 'ACL base certs not supported', -2147416019: 'ACL challenge callback failed', -2147416015: 'ACL change failed', -2147416012: 'ACL delete failed', -2147416017: 'ACL entry tag not found', -2147416011: 'ACL replace failed', -2147416021: 'ACL subject type not supported', -2147415789: 'Algid mismatch', -2147415726: 'Already logged in', -2147415040: 'Apple add application ACL subject', -2147415036: 'Apple invalid key end date', -2147415037: 'Apple invalid key start date', -2147415039: 'Apple public key incomplete', -2147415038: 'Apple signature mismatch', -2147415034: 'Apple SSLv2 rollback', -2147415802: 'Attach handle busy', -2147415731: 'Block size mismatch', -2147415722: 'Crypto data callback failed', -2147415804: 'Device error', -2147415835: 'Device failed', -2147415803: 'Device memory error', -2147415836: 'Device reset', -2147415728: 'Device verify failed', -2147416054: 'Function failed', -2147416057: 'Function not implemented', -2147415807: 'Input length error', -2147415837: 'Insufficient client identification', -2147416063: 'Internal error', -2147416027: 'Invalid access credentials', -2147416026: 'Invalid ACL base certs', -2147416020: 'Invalid ACL challenge callback', -2147416016: 'Invalid ACL edit mode', -2147416018: 'Invalid ACL entry tag', -2147416022: 'Invalid ACL subject value', -2147415759: 'Invalid algorithm', -2147415678: 'Invalid attr access credentials', -2147415704: 'Invalid attr alg params', -2147415686: 'Invalid attr base', -2147415738: 'Invalid attr block size', -2147415680: 'Invalid attr dl db handle', -2147415696: 'Invalid attr effective bits', -2147415692: 'Invalid attr end date', -2147415752: 'Invalid attr init vector', -2147415682: 'Invalid attr iteration count', -2147415754: 'Invalid attr key', -2147415740: 'Invalid attr key length', -2147415700: 'Invalid attr key type', -2147415702: 'Invalid attr label', -2147415698: 'Invalid attr mode', -2147415708: 'Invalid attr output size', -2147415748: 'Invalid attr padding', -2147415742: 'Invalid attr passphrase', -2147415688: 'Invalid attr prime', -2147415674: 'Invalid attr private key format', -2147415676: 'Invalid attr public key format', -2147415746: 'Invalid attr random', -2147415706: 'Invalid attr rounds', -2147415750: 'Invalid attr salt', -2147415744: 'Invalid attr seed', -2147415694: 'Invalid attr start date', -2147415684: 'Invalid attr subprime', -2147415672: 'Invalid attr symmetric key format', -2147415690: 'Invalid attr version', -2147415670: 'Invalid attr wrapped key format', -2147415760: 'Invalid context', -2147416000: 'Invalid context handle', -2147415976: 'Invalid crypto data', -2147415994: 'Invalid data', -2147415768: 'Invalid data count', -2147415723: 'Invalid digest algorithm', -2147416059: 'Invalid input pointer', -2147415766: 'Invalid input vector', -2147415792: 'Invalid key', -2147415780: 'Invalid keyattr mask', -2147415782: 'Invalid keyusage mask', -2147415790: 'Invalid key class', -2147415776: 'Invalid key format', -2147415778: 'Invalid key label', -2147415783: 'Invalid key pointer', -2147415791: 'Invalid key reference', -2147415727: 'Invalid login name', -2147416014: 'Invalid new ACL entry', -2147416013: 'Invalid new ACL owner', -2147416058: 'Invalid output pointer', -2147415765: 'Invalid output vector', -2147415978: 'Invalid passthrough id', -2147416060: 'Invalid pointer', -2147416024: 'Invalid sample value', -2147415733: 'Invalid signature', -2147415787: 'Key blob type incorrect', -2147415786: 'Key header inconsistent', -2147415724: 'Key label already exists', -2147415788: 'Key usage incorrect', -2147416061: 'Mds error', -2147416062: 'Memory error', -2147415677: 'Missing attr access credentials', -2147415703: 'Missing attr alg params', -2147415685: 'Missing attr base', -2147415737: 'Missing attr block size', -2147415679: 'Missing attr dl db handle', -2147415695: 'Missing attr effective bits', -2147415691: 'Missing attr end date', -2147415751: 'Missing attr init vector', -2147415681: 'Missing attr iteration count', -2147415753: 'Missing attr key', -2147415739: 'Missing attr key length', -2147415699: 'Missing attr key type', -2147415701: 'Missing attr label', -2147415697: 'Missing attr mode', -2147415707: 'Missing attr output size', -2147415747: 'Missing attr padding', -2147415741: 'Missing attr passphrase', -2147415687: 'Missing attr prime', -2147415673: 'Missing attr private key format', -2147415675: 'Missing attr public key format', -2147415745: 'Missing attr random', -2147415705: 'Missing attr rounds', -2147415749: 'Missing attr salt', -2147415743: 'Missing attr seed', -2147415693: 'Missing attr start date', -2147415683: 'Missing attr subprime', -2147415671: 'Missing attr symmetric key format', -2147415689: 'Missing attr version', -2147415669: 'Missing attr wrapped key format', -2147415801: 'Not logged in', -2147415840: 'No user interaction', -2147416029: 'Object ACL not supported', -2147416028: 'Object ACL required', -2147416030: 'Object manip auth denied', -2147416031: 'Object use auth denied', -2147416032: 'Operation auth denied', -2147416055: 'OS access denied', -2147415806: 'Output length error', -2147415725: 'Private key already exists', -2147415730: 'Private key not found', -2147415989: 'Privilege not granted', -2147415805: 'Privilege not supported', -2147415729: 'Public key inconsistent', -2147415732: 'Query size unknown', -2147416023: 'Sample value not supported', -2147416056: 'Self check failed', -2147415838: 'Service not available', -2147415736: 'Staged operation in progress', -2147415735: 'Staged operation not started', -2147415779: 'Unsupported keyattr mask', -2147415781: 'Unsupported keyusage mask', -2147415785: 'Unsupported key format', -2147415777: 'Unsupported key label', -2147415784: 'Unsupported key size', -2147415839: 'User canceled', -2147415767: 'Vector of bufs unsupported', -2147415734: 'Verify failed', } if num in code_map: output = code_map[num] if not output: output = '%s %s' % (domain, num) raise OSError(output) CFHelpers.register_native_mapping( CoreFoundation.CFStringGetTypeID(), CFHelpers.cf_string_to_unicode ) CFHelpers.register_native_mapping( CoreFoundation.CFNumberGetTypeID(), CFHelpers.cf_number_to_number ) CFHelpers.register_native_mapping( CoreFoundation.CFDataGetTypeID(), CFHelpers.cf_data_to_bytes ) CFHelpers.register_native_mapping( CoreFoundation.CFDictionaryGetTypeID(), CFHelpers.cf_dictionary_to_dict ) _mac/_core_foundation_cffi.py000064400000025255147205106110012327 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from .._ffi import ( buffer_from_bytes, byte_string_from_buffer, deref, is_null, new, register_ffi, ) from cffi import FFI __all__ = [ 'CFHelpers', 'CoreFoundation', ] ffi = FFI() ffi.cdef(""" typedef bool Boolean; typedef long CFIndex; typedef unsigned long CFStringEncoding; typedef unsigned long CFNumberType; typedef unsigned long CFTypeID; typedef void *CFTypeRef; typedef CFTypeRef CFArrayRef; typedef CFTypeRef CFDataRef; typedef CFTypeRef CFStringRef; typedef CFTypeRef CFNumberRef; typedef CFTypeRef CFBooleanRef; typedef CFTypeRef CFDictionaryRef; typedef CFTypeRef CFErrorRef; typedef CFTypeRef CFAllocatorRef; typedef struct { CFIndex version; void *retain; void *release; void *copyDescription; void *equal; void *hash; } CFDictionaryKeyCallBacks; typedef struct { CFIndex version; void *retain; void *release; void *copyDescription; void *equal; } CFDictionaryValueCallBacks; typedef struct { CFIndex version; void *retain; void *release; void *copyDescription; void *equal; } CFArrayCallBacks; CFIndex CFDataGetLength(CFDataRef theData); const char *CFDataGetBytePtr(CFDataRef theData); CFDataRef CFDataCreate(CFAllocatorRef allocator, const char *bytes, CFIndex length); CFDictionaryRef CFDictionaryCreate(CFAllocatorRef allocator, const void **keys, const void **values, CFIndex numValues, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks); CFIndex CFDictionaryGetCount(CFDictionaryRef theDict); const char *CFStringGetCStringPtr(CFStringRef theString, CFStringEncoding encoding); Boolean CFStringGetCString(CFStringRef theString, char *buffer, CFIndex bufferSize, CFStringEncoding encoding); CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding); CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr); CFStringRef CFCopyTypeIDDescription(CFTypeID type_id); void CFRelease(CFTypeRef cf); void CFRetain(CFTypeRef cf); CFStringRef CFErrorCopyDescription(CFErrorRef err); CFStringRef CFErrorGetDomain(CFErrorRef err); CFIndex CFErrorGetCode(CFErrorRef err); Boolean CFBooleanGetValue(CFBooleanRef boolean); CFTypeID CFDictionaryGetTypeID(void); CFTypeID CFNumberGetTypeID(void); CFTypeID CFStringGetTypeID(void); CFTypeID CFDataGetTypeID(void); CFArrayRef CFArrayCreate(CFAllocatorRef allocator, const void **values, CFIndex numValues, const CFArrayCallBacks *callBacks); CFIndex CFArrayGetCount(CFArrayRef theArray); CFTypeRef CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx); CFNumberType CFNumberGetType(CFNumberRef number); Boolean CFNumberGetValue(CFNumberRef number, CFNumberType theType, void *valuePtr); CFIndex CFDictionaryGetKeysAndValues(CFDictionaryRef theDict, const void **keys, const void **values); CFTypeID CFGetTypeID(CFTypeRef cf); extern CFAllocatorRef kCFAllocatorDefault; extern CFArrayCallBacks kCFTypeArrayCallBacks; extern CFBooleanRef kCFBooleanTrue; extern CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks; extern CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks; """) core_foundation_path = '/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation' CoreFoundation = ffi.dlopen(core_foundation_path) register_ffi(CoreFoundation, ffi) kCFNumberCFIndexType = 14 kCFStringEncodingUTF8 = 0x08000100 class CFHelpers(): """ Namespace for core foundation helpers """ _native_map = {} @classmethod def register_native_mapping(cls, type_id, callback): """ Register a function to convert a core foundation data type into its equivalent in python :param type_id: The CFTypeId for the type :param callback: A callback to pass the CFType object to """ cls._native_map[int(type_id)] = callback @staticmethod def cf_number_to_number(value): """ Converts a CFNumber object to a python float or integer :param value: The CFNumber object :return: A python number (float or integer) """ type_ = CoreFoundation.CFNumberGetType(value) type_name_ = { 1: 'int8_t', # kCFNumberSInt8Type 2: 'in16_t', # kCFNumberSInt16Type 3: 'int32_t', # kCFNumberSInt32Type 4: 'int64_t', # kCFNumberSInt64Type 5: 'float', # kCFNumberFloat32Type 6: 'double', # kCFNumberFloat64Type 7: 'char', # kCFNumberCharType 8: 'short', # kCFNumberShortType 9: 'int', # kCFNumberIntType 10: 'long', # kCFNumberLongType 11: 'long long', # kCFNumberLongLongType 12: 'float', # kCFNumberFloatType 13: 'double', # kCFNumberDoubleType 14: 'long', # kCFNumberCFIndexType 15: 'int', # kCFNumberNSIntegerType 16: 'double', # kCFNumberCGFloatType }[type_] output = new(CoreFoundation, type_name_ + ' *') CoreFoundation.CFNumberGetValue(value, type_, output) return deref(output) @staticmethod def cf_dictionary_to_dict(dictionary): """ Converts a CFDictionary object into a python dictionary :param dictionary: The CFDictionary to convert :return: A python dict """ dict_length = CoreFoundation.CFDictionaryGetCount(dictionary) keys = new(CoreFoundation, 'CFTypeRef[%s]' % dict_length) values = new(CoreFoundation, 'CFTypeRef[%s]' % dict_length) CoreFoundation.CFDictionaryGetKeysAndValues( dictionary, keys, values ) output = {} for index in range(0, dict_length): output[CFHelpers.native(keys[index])] = CFHelpers.native(values[index]) return output @classmethod def native(cls, value): """ Converts a CF* object into its python equivalent :param value: The CF* object to convert :return: The native python object """ type_id = CoreFoundation.CFGetTypeID(value) if type_id in cls._native_map: return cls._native_map[type_id](value) else: return value @staticmethod def cf_string_to_unicode(value): """ Creates a python unicode string from a CFString object :param value: The CFString to convert :return: A python unicode string """ string_ptr = CoreFoundation.CFStringGetCStringPtr( value, kCFStringEncodingUTF8 ) string = None if is_null(string_ptr) else ffi.string(string_ptr) if string is None: buffer = buffer_from_bytes(1024) result = CoreFoundation.CFStringGetCString( value, buffer, 1024, kCFStringEncodingUTF8 ) if not result: raise OSError('Error copying C string from CFStringRef') string = byte_string_from_buffer(buffer) if string is not None: string = string.decode('utf-8') return string @staticmethod def cf_string_from_unicode(string): """ Creates a CFStringRef object from a unicode string :param string: The unicode string to create the CFString object from :return: A CFStringRef """ return CoreFoundation.CFStringCreateWithCString( CoreFoundation.kCFAllocatorDefault, string.encode('utf-8'), kCFStringEncodingUTF8 ) @staticmethod def cf_data_to_bytes(value): """ Extracts a bytestring from a CFData object :param value: A CFData object :return: A byte string """ start = CoreFoundation.CFDataGetBytePtr(value) num_bytes = CoreFoundation.CFDataGetLength(value) return ffi.buffer(start, num_bytes)[:] @staticmethod def cf_data_from_bytes(bytes_): """ Creates a CFDataRef object from a byte string :param bytes_: The data to create the CFData object from :return: A CFDataRef """ return CoreFoundation.CFDataCreate( CoreFoundation.kCFAllocatorDefault, bytes_, len(bytes_) ) @staticmethod def cf_dictionary_from_pairs(pairs): """ Creates a CFDictionaryRef object from a list of 2-element tuples representing the key and value. Each key should be a CFStringRef and each value some sort of CF* type. :param pairs: A list of 2-element tuples :return: A CFDictionaryRef """ length = len(pairs) keys = [] values = [] for pair in pairs: key, value = pair keys.append(key) values.append(value) return CoreFoundation.CFDictionaryCreate( CoreFoundation.kCFAllocatorDefault, keys, values, length, ffi.addressof(CoreFoundation.kCFTypeDictionaryKeyCallBacks), ffi.addressof(CoreFoundation.kCFTypeDictionaryValueCallBacks) ) @staticmethod def cf_array_from_list(values): """ Creates a CFArrayRef object from a list of CF* type objects. :param values: A list of CF* type object :return: A CFArrayRef """ length = len(values) return CoreFoundation.CFArrayCreate( CoreFoundation.kCFAllocatorDefault, values, length, ffi.addressof(CoreFoundation.kCFTypeArrayCallBacks) ) @staticmethod def cf_number_from_integer(integer): """ Creates a CFNumber object from an integer :param integer: The integer to create the CFNumber for :return: A CFNumber """ integer_as_long = ffi.new('long *', integer) return CoreFoundation.CFNumberCreate( CoreFoundation.kCFAllocatorDefault, kCFNumberCFIndexType, integer_as_long ) _mac/_core_foundation_ctypes.py000064400000032247147205106110012726 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from ctypes import c_void_p, c_long, c_uint32, c_char_p, c_byte, c_ulong, c_bool from ctypes import CDLL, string_at, cast, POINTER, byref import ctypes from .._ffi import FFIEngineError, buffer_from_bytes, byte_string_from_buffer __all__ = [ 'CFHelpers', 'CoreFoundation', ] core_foundation_path = '/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation' CoreFoundation = CDLL(core_foundation_path, use_errno=True) CFIndex = c_long CFStringEncoding = c_uint32 CFArray = c_void_p CFData = c_void_p CFString = c_void_p CFNumber = c_void_p CFDictionary = c_void_p CFError = c_void_p CFType = c_void_p CFTypeID = c_ulong CFBoolean = c_void_p CFNumberType = c_uint32 CFTypeRef = POINTER(CFType) CFArrayRef = POINTER(CFArray) CFDataRef = POINTER(CFData) CFStringRef = POINTER(CFString) CFNumberRef = POINTER(CFNumber) CFBooleanRef = POINTER(CFBoolean) CFDictionaryRef = POINTER(CFDictionary) CFErrorRef = POINTER(CFError) CFAllocatorRef = c_void_p CFDictionaryKeyCallBacks = c_void_p CFDictionaryValueCallBacks = c_void_p CFArrayCallBacks = c_void_p pointer_p = POINTER(c_void_p) try: CoreFoundation.CFDataGetLength.argtypes = [ CFDataRef ] CoreFoundation.CFDataGetLength.restype = CFIndex CoreFoundation.CFDataGetBytePtr.argtypes = [ CFDataRef ] CoreFoundation.CFDataGetBytePtr.restype = c_void_p CoreFoundation.CFDataCreate.argtypes = [ CFAllocatorRef, c_char_p, CFIndex ] CoreFoundation.CFDataCreate.restype = CFDataRef CoreFoundation.CFDictionaryCreate.argtypes = [ CFAllocatorRef, CFStringRef, CFTypeRef, CFIndex, CFDictionaryKeyCallBacks, CFDictionaryValueCallBacks ] CoreFoundation.CFDictionaryCreate.restype = CFDictionaryRef CoreFoundation.CFDictionaryGetCount.argtypes = [ CFDictionaryRef ] CoreFoundation.CFDictionaryGetCount.restype = CFIndex CoreFoundation.CFStringGetCStringPtr.argtypes = [ CFStringRef, CFStringEncoding ] CoreFoundation.CFStringGetCStringPtr.restype = c_char_p CoreFoundation.CFStringGetCString.argtypes = [ CFStringRef, c_char_p, CFIndex, CFStringEncoding ] CoreFoundation.CFStringGetCString.restype = c_bool CoreFoundation.CFStringCreateWithCString.argtypes = [ CFAllocatorRef, c_char_p, CFStringEncoding ] CoreFoundation.CFStringCreateWithCString.restype = CFStringRef CoreFoundation.CFNumberCreate.argtypes = [ CFAllocatorRef, CFNumberType, c_void_p ] CoreFoundation.CFNumberCreate.restype = CFNumberRef CoreFoundation.CFCopyTypeIDDescription.argtypes = [ CFTypeID ] CoreFoundation.CFCopyTypeIDDescription.restype = CFStringRef CoreFoundation.CFRelease.argtypes = [ CFTypeRef ] CoreFoundation.CFRelease.restype = None CoreFoundation.CFRetain.argtypes = [ CFTypeRef ] CoreFoundation.CFRetain.restype = None CoreFoundation.CFErrorCopyDescription.argtypes = [ CFErrorRef ] CoreFoundation.CFErrorCopyDescription.restype = CFStringRef CoreFoundation.CFErrorGetDomain.argtypes = [ CFErrorRef ] CoreFoundation.CFErrorGetDomain.restype = CFStringRef CoreFoundation.CFErrorGetCode.argtypes = [ CFErrorRef ] CoreFoundation.CFErrorGetCode.restype = CFIndex CoreFoundation.CFBooleanGetValue.argtypes = [ CFBooleanRef ] CoreFoundation.CFBooleanGetValue.restype = c_byte CoreFoundation.CFDictionaryGetTypeID.argtypes = [] CoreFoundation.CFDictionaryGetTypeID.restype = CFTypeID CoreFoundation.CFNumberGetTypeID.argtypes = [] CoreFoundation.CFNumberGetTypeID.restype = CFTypeID CoreFoundation.CFStringGetTypeID.argtypes = [] CoreFoundation.CFStringGetTypeID.restype = CFTypeID CoreFoundation.CFDataGetTypeID.argtypes = [] CoreFoundation.CFDataGetTypeID.restype = CFTypeID CoreFoundation.CFArrayCreate.argtypes = [ CFAllocatorRef, POINTER(c_void_p), CFIndex, CFArrayCallBacks ] CoreFoundation.CFArrayCreate.restype = CFArrayRef CoreFoundation.CFArrayGetCount.argtypes = [ CFArrayRef ] CoreFoundation.CFArrayGetCount.restype = CFIndex CoreFoundation.CFArrayGetValueAtIndex.argtypes = [ CFArrayRef, CFIndex ] CoreFoundation.CFArrayGetValueAtIndex.restype = CFTypeRef CoreFoundation.CFNumberGetType.argtypes = [ CFNumberRef ] CoreFoundation.CFNumberGetType.restype = CFNumberType CoreFoundation.CFNumberGetValue.argtypes = [ CFNumberRef, CFNumberType, c_void_p ] CoreFoundation.CFNumberGetValue.restype = c_bool CoreFoundation.CFDictionaryGetKeysAndValues.argtypes = [ CFDictionaryRef, pointer_p, pointer_p ] CoreFoundation.CFDictionaryGetKeysAndValues.restype = CFIndex CoreFoundation.CFGetTypeID.argtypes = [ CFTypeRef ] CoreFoundation.CFGetTypeID.restype = CFTypeID setattr(CoreFoundation, 'kCFAllocatorDefault', CFAllocatorRef.in_dll(CoreFoundation, 'kCFAllocatorDefault')) setattr(CoreFoundation, 'kCFBooleanTrue', CFTypeRef.in_dll(CoreFoundation, 'kCFBooleanTrue')) kCFTypeDictionaryKeyCallBacks = c_void_p.in_dll(CoreFoundation, 'kCFTypeDictionaryKeyCallBacks') kCFTypeDictionaryValueCallBacks = c_void_p.in_dll(CoreFoundation, 'kCFTypeDictionaryValueCallBacks') kCFTypeArrayCallBacks = c_void_p.in_dll(CoreFoundation, 'kCFTypeArrayCallBacks') except (AttributeError): raise FFIEngineError('Error initializing ctypes') setattr(CoreFoundation, 'CFDataRef', CFDataRef) setattr(CoreFoundation, 'CFErrorRef', CFErrorRef) setattr(CoreFoundation, 'CFArrayRef', CFArrayRef) kCFNumberCFIndexType = CFNumberType(14) kCFStringEncodingUTF8 = CFStringEncoding(0x08000100) def _cast_pointer_p(value): """ Casts a value to a pointer of a pointer :param value: A ctypes object :return: A POINTER(c_void_p) object """ return cast(value, pointer_p) class CFHelpers(): """ Namespace for core foundation helpers """ _native_map = {} @classmethod def register_native_mapping(cls, type_id, callback): """ Register a function to convert a core foundation data type into its equivalent in python :param type_id: The CFTypeId for the type :param callback: A callback to pass the CFType object to """ cls._native_map[int(type_id)] = callback @staticmethod def cf_number_to_number(value): """ Converts a CFNumber object to a python float or integer :param value: The CFNumber object :return: A python number (float or integer) """ type_ = CoreFoundation.CFNumberGetType(_cast_pointer_p(value)) c_type = { 1: c_byte, # kCFNumberSInt8Type 2: ctypes.c_short, # kCFNumberSInt16Type 3: ctypes.c_int32, # kCFNumberSInt32Type 4: ctypes.c_int64, # kCFNumberSInt64Type 5: ctypes.c_float, # kCFNumberFloat32Type 6: ctypes.c_double, # kCFNumberFloat64Type 7: c_byte, # kCFNumberCharType 8: ctypes.c_short, # kCFNumberShortType 9: ctypes.c_int, # kCFNumberIntType 10: c_long, # kCFNumberLongType 11: ctypes.c_longlong, # kCFNumberLongLongType 12: ctypes.c_float, # kCFNumberFloatType 13: ctypes.c_double, # kCFNumberDoubleType 14: c_long, # kCFNumberCFIndexType 15: ctypes.c_int, # kCFNumberNSIntegerType 16: ctypes.c_double, # kCFNumberCGFloatType }[type_] output = c_type(0) CoreFoundation.CFNumberGetValue(_cast_pointer_p(value), type_, byref(output)) return output.value @staticmethod def cf_dictionary_to_dict(dictionary): """ Converts a CFDictionary object into a python dictionary :param dictionary: The CFDictionary to convert :return: A python dict """ dict_length = CoreFoundation.CFDictionaryGetCount(dictionary) keys = (CFTypeRef * dict_length)() values = (CFTypeRef * dict_length)() CoreFoundation.CFDictionaryGetKeysAndValues( dictionary, _cast_pointer_p(keys), _cast_pointer_p(values) ) output = {} for index in range(0, dict_length): output[CFHelpers.native(keys[index])] = CFHelpers.native(values[index]) return output @classmethod def native(cls, value): """ Converts a CF* object into its python equivalent :param value: The CF* object to convert :return: The native python object """ type_id = CoreFoundation.CFGetTypeID(value) if type_id in cls._native_map: return cls._native_map[type_id](value) else: return value @staticmethod def cf_string_to_unicode(value): """ Creates a python unicode string from a CFString object :param value: The CFString to convert :return: A python unicode string """ string = CoreFoundation.CFStringGetCStringPtr( _cast_pointer_p(value), kCFStringEncodingUTF8 ) if string is None: buffer = buffer_from_bytes(1024) result = CoreFoundation.CFStringGetCString( _cast_pointer_p(value), buffer, 1024, kCFStringEncodingUTF8 ) if not result: raise OSError('Error copying C string from CFStringRef') string = byte_string_from_buffer(buffer) if string is not None: string = string.decode('utf-8') return string @staticmethod def cf_string_from_unicode(string): """ Creates a CFStringRef object from a unicode string :param string: The unicode string to create the CFString object from :return: A CFStringRef """ return CoreFoundation.CFStringCreateWithCString( CoreFoundation.kCFAllocatorDefault, string.encode('utf-8'), kCFStringEncodingUTF8 ) @staticmethod def cf_data_to_bytes(value): """ Extracts a bytestring from a CFData object :param value: A CFData object :return: A byte string """ start = CoreFoundation.CFDataGetBytePtr(value) num_bytes = CoreFoundation.CFDataGetLength(value) return string_at(start, num_bytes) @staticmethod def cf_data_from_bytes(bytes_): """ Creates a CFDataRef object from a byte string :param bytes_: The data to create the CFData object from :return: A CFDataRef """ return CoreFoundation.CFDataCreate( CoreFoundation.kCFAllocatorDefault, bytes_, len(bytes_) ) @staticmethod def cf_dictionary_from_pairs(pairs): """ Creates a CFDictionaryRef object from a list of 2-element tuples representing the key and value. Each key should be a CFStringRef and each value some sort of CF* type. :param pairs: A list of 2-element tuples :return: A CFDictionaryRef """ length = len(pairs) keys = [] values = [] for pair in pairs: key, value = pair keys.append(key) values.append(value) keys = (CFStringRef * length)(*keys) values = (CFTypeRef * length)(*values) return CoreFoundation.CFDictionaryCreate( CoreFoundation.kCFAllocatorDefault, _cast_pointer_p(byref(keys)), _cast_pointer_p(byref(values)), length, kCFTypeDictionaryKeyCallBacks, kCFTypeDictionaryValueCallBacks ) @staticmethod def cf_array_from_list(values): """ Creates a CFArrayRef object from a list of CF* type objects. :param values: A list of CF* type object :return: A CFArrayRef """ length = len(values) values = (CFTypeRef * length)(*values) return CoreFoundation.CFArrayCreate( CoreFoundation.kCFAllocatorDefault, _cast_pointer_p(byref(values)), length, kCFTypeArrayCallBacks ) @staticmethod def cf_number_from_integer(integer): """ Creates a CFNumber object from an integer :param integer: The integer to create the CFNumber for :return: A CFNumber """ integer_as_long = c_long(integer) return CoreFoundation.CFNumberCreate( CoreFoundation.kCFAllocatorDefault, kCFNumberCFIndexType, byref(integer_as_long) ) _mac/_security.py000064400000010132147205106110010015 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from .. import ffi from .._ffi import null from ..errors import TLSDisconnectError, TLSGracefulDisconnectError if ffi() == 'cffi': from ._security_cffi import Security, version_info as osx_version_info from ._core_foundation_cffi import CoreFoundation, CFHelpers else: from ._security_ctypes import Security, version_info as osx_version_info from ._core_foundation_ctypes import CoreFoundation, CFHelpers __all__ = [ 'handle_sec_error', 'osx_version_info', 'Security', 'SecurityConst', ] def handle_sec_error(error, exception_class=None): """ Checks a Security OSStatus error code and throws an exception if there is an error to report :param error: An OSStatus :param exception_class: The exception class to use for the exception if an error occurred :raises: OSError - when the OSStatus contains an error """ if error == 0: return if error in set([SecurityConst.errSSLClosedNoNotify, SecurityConst.errSSLClosedAbort]): raise TLSDisconnectError('The remote end closed the connection') if error == SecurityConst.errSSLClosedGraceful: raise TLSGracefulDisconnectError('The remote end closed the connection') cf_error_string = Security.SecCopyErrorMessageString(error, null()) output = CFHelpers.cf_string_to_unicode(cf_error_string) CoreFoundation.CFRelease(cf_error_string) if output is None or output == '': output = 'OSStatus %s' % error if exception_class is None: exception_class = OSError raise exception_class(output) def _extract_policy_properties(value): properties_dict = Security.SecPolicyCopyProperties(value) return CFHelpers.cf_dictionary_to_dict(properties_dict) CFHelpers.register_native_mapping( Security.SecPolicyGetTypeID(), _extract_policy_properties ) class SecurityConst(): kSecTrustSettingsDomainUser = 0 kSecTrustSettingsDomainAdmin = 1 kSecTrustSettingsDomainSystem = 2 kSecTrustResultProceed = 1 kSecTrustResultUnspecified = 4 kSecTrustOptionImplicitAnchors = 0x00000040 kSecFormatOpenSSL = 1 kSecItemTypePrivateKey = 1 kSecItemTypePublicKey = 2 kSSLSessionOptionBreakOnServerAuth = 0 kSSLProtocol2 = 1 kSSLProtocol3 = 2 kTLSProtocol1 = 4 kTLSProtocol11 = 7 kTLSProtocol12 = 8 kSSLClientSide = 1 kSSLStreamType = 0 errSSLProtocol = -9800 errSSLWouldBlock = -9803 errSSLClosedGraceful = -9805 errSSLClosedNoNotify = -9816 errSSLClosedAbort = -9806 errSSLXCertChainInvalid = -9807 errSSLCrypto = -9809 errSSLInternal = -9810 errSSLCertExpired = -9814 errSSLCertNotYetValid = -9815 errSSLUnknownRootCert = -9812 errSSLNoRootCert = -9813 errSSLHostNameMismatch = -9843 errSSLPeerHandshakeFail = -9824 errSSLPeerProtocolVersion = -9836 errSSLPeerUserCancelled = -9839 errSSLWeakPeerEphemeralDHKey = -9850 errSSLServerAuthCompleted = -9841 errSSLRecordOverflow = -9847 CSSMERR_APPLETP_HOSTNAME_MISMATCH = -2147408896 CSSMERR_TP_CERT_EXPIRED = -2147409654 CSSMERR_TP_CERT_NOT_VALID_YET = -2147409653 CSSMERR_TP_CERT_REVOKED = -2147409652 CSSMERR_TP_NOT_TRUSTED = -2147409622 CSSMERR_TP_CERT_SUSPENDED = -2147409651 CSSM_CERT_X_509v3 = 0x00000004 APPLE_TP_REVOCATION_CRL = b'*\x86H\x86\xf7cd\x01\x06' APPLE_TP_REVOCATION_OCSP = b'*\x86H\x86\xf7cd\x01\x07' CSSM_APPLE_TP_OCSP_OPTS_VERSION = 0 CSSM_TP_ACTION_OCSP_DISABLE_NET = 0x00000004 CSSM_TP_ACTION_OCSP_CACHE_READ_DISABLE = 0x00000008 CSSM_APPLE_TP_CRL_OPTS_VERSION = 0 errSecVerifyFailed = -67808 errSecNoTrustSettings = -25263 errSecItemNotFound = -25300 errSecInvalidTrustSettings = -25262 kSecPaddingNone = 0 kSecPaddingPKCS1 = 1 CSSM_KEYUSE_SIGN = 0x00000004 CSSM_KEYUSE_VERIFY = 0x00000008 CSSM_ALGID_DH = 2 CSSM_ALGID_RSA = 42 CSSM_ALGID_DSA = 43 CSSM_ALGID_ECDSA = 73 CSSM_KEYATTR_PERMANENT = 0x00000001 CSSM_KEYATTR_EXTRACTABLE = 0x00000020 _mac/_security_cffi.py000064400000025272147205106110011017 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import platform from .._ffi import register_ffi from cffi import FFI __all__ = [ 'Security', 'version', 'version_info', ] version = platform.mac_ver()[0] version_info = tuple(map(int, version.split('.'))) if version_info < (10, 7): raise OSError('Only OS X 10.7 and newer are supported, not %s.%s' % (version_info[0], version_info[1])) ffi = FFI() ffi.cdef(""" typedef bool Boolean; typedef long CFIndex; typedef int32_t OSStatus; typedef unsigned long CFTypeID; typedef uint32_t SecTrustSettingsDomain; typedef uint32_t SecPadding; typedef uint32_t SecItemImportExportFlags; typedef uint32_t SecKeyImportExportFlags; typedef uint32_t SecExternalFormat; typedef uint32_t SecExternalItemType; typedef uint32_t CSSM_ALGORITHMS; typedef uint64_t CSSM_CC_HANDLE; typedef uint32_t CSSM_KEYUSE; typedef uint32_t CSSM_CERT_TYPE; typedef uint32_t SSLProtocol; typedef uint32_t SSLCipherSuite; typedef uint32_t SecTrustResultType; typedef void *CFTypeRef; typedef CFTypeRef CFArrayRef; typedef CFTypeRef CFDataRef; typedef CFTypeRef CFStringRef; typedef CFTypeRef CFDictionaryRef; typedef CFTypeRef CFErrorRef; typedef CFTypeRef CFAllocatorRef; typedef ... *SecKeyRef; typedef ... *SecCertificateRef; typedef ... *SecTransformRef; typedef ... *SecRandomRef; typedef ... *SecPolicyRef; typedef ... *SecPolicySearchRef; typedef ... *SecAccessRef; typedef struct { uint32_t version; SecKeyImportExportFlags flags; CFTypeRef passphrase; CFStringRef alertTitle; CFStringRef alertPrompt; SecAccessRef accessRef; CFArrayRef keyUsage; CFArrayRef keyAttributes; } SecItemImportExportKeyParameters; typedef ... *SecKeychainRef; typedef ... *SSLContextRef; typedef ... *SecTrustRef; typedef uint32_t SSLConnectionRef; typedef struct { uint32_t Length; char *Data; } CSSM_DATA, CSSM_OID; typedef struct { uint32_t Version; uint32_t Flags; CSSM_DATA *LocalResponder; CSSM_DATA *LocalResponderCert; } CSSM_APPLE_TP_OCSP_OPTIONS; typedef struct { uint32_t Version; uint32_t CrlFlags; void *crlStore; } CSSM_APPLE_TP_CRL_OPTIONS; OSStatus SecKeychainCreate(char *path, uint32_t pass_len, void *pass, Boolean prompt, SecAccessRef initialAccess, SecKeychainRef *keychain); OSStatus SecKeychainDelete(SecKeychainRef keychain); int SecRandomCopyBytes(SecRandomRef rnd, size_t count, char *bytes); SecKeyRef SecKeyCreateFromData(CFDictionaryRef parameters, CFDataRef keyData, CFErrorRef *error); SecTransformRef SecEncryptTransformCreate(SecKeyRef keyRef, CFErrorRef *error); SecTransformRef SecDecryptTransformCreate(SecKeyRef keyRef, CFErrorRef *error); Boolean SecTransformSetAttribute(SecTransformRef transformRef, CFStringRef key, CFTypeRef value, CFErrorRef *error); CFTypeRef SecTransformExecute(SecTransformRef transformRef, CFErrorRef *errorRef); SecTransformRef SecVerifyTransformCreate(SecKeyRef key, CFDataRef signature, CFErrorRef *error); SecTransformRef SecSignTransformCreate(SecKeyRef key, CFErrorRef *error); SecCertificateRef SecCertificateCreateWithData(CFAllocatorRef allocator, CFDataRef data); OSStatus SecCertificateCopyPublicKey(SecCertificateRef certificate, SecKeyRef *key); CFStringRef SecCopyErrorMessageString(OSStatus status, void *reserved); OSStatus SecTrustCopyAnchorCertificates(CFArrayRef *anchors); CFDataRef SecCertificateCopyData(SecCertificateRef certificate); OSStatus SecTrustSettingsCopyCertificates(SecTrustSettingsDomain domain, CFArrayRef *certArray); OSStatus SecTrustSettingsCopyTrustSettings(SecCertificateRef certRef, SecTrustSettingsDomain domain, CFArrayRef *trustSettings); CFDictionaryRef SecPolicyCopyProperties(SecPolicyRef policyRef); CFTypeID SecPolicyGetTypeID(void); OSStatus SecKeyEncrypt(SecKeyRef key, SecPadding padding, const char *plainText, size_t plainTextLen, char *cipherText, size_t *cipherTextLen); OSStatus SecKeyDecrypt(SecKeyRef key, SecPadding padding, const char *cipherText, size_t cipherTextLen, char *plainText, size_t *plainTextLen); OSStatus SecKeyRawSign(SecKeyRef key, SecPadding padding, const char *dataToSign, size_t dataToSignLen, char *sig, size_t * sigLen); OSStatus SecKeyRawVerify(SecKeyRef key, SecPadding padding, const char *signedData, size_t signedDataLen, const char *sig, size_t sigLen); OSStatus SecItemImport(CFDataRef importedData, CFStringRef fileNameOrExtension, SecExternalFormat *inputFormat, SecExternalItemType *itemType, SecItemImportExportFlags flags, const SecItemImportExportKeyParameters *keyParams, SecKeychainRef importKeychain, CFArrayRef *outItems); OSStatus SecItemExport(CFTypeRef secItemOrArray, SecExternalFormat outputFormat, SecItemImportExportFlags flags, const SecItemImportExportKeyParameters *keyParams, CFDataRef *exportedData); OSStatus SecAccessCreate(CFStringRef descriptor, CFArrayRef trustedlist, SecAccessRef *accessRef); OSStatus SecKeyCreatePair(SecKeychainRef keychainRef, CSSM_ALGORITHMS algorithm, uint32_t keySizeInBits, CSSM_CC_HANDLE contextHandle, CSSM_KEYUSE publicKeyUsage, uint32_t publicKeyAttr, CSSM_KEYUSE privateKeyUsage, uint32_t privateKeyAttr, SecAccessRef initialAccess, SecKeyRef* publicKeyRef, SecKeyRef* privateKeyRef); OSStatus SecKeychainItemDelete(SecKeyRef itemRef); typedef OSStatus (*SSLReadFunc)(SSLConnectionRef connection, char *data, size_t *dataLength); typedef OSStatus (*SSLWriteFunc)(SSLConnectionRef connection, const char *data, size_t *dataLength); OSStatus SSLSetIOFuncs(SSLContextRef context, SSLReadFunc readFunc, SSLWriteFunc writeFunc); OSStatus SSLSetPeerID(SSLContextRef context, const char *peerID, size_t peerIDLen); OSStatus SSLSetConnection(SSLContextRef context, SSLConnectionRef connection); OSStatus SSLSetPeerDomainName(SSLContextRef context, const char *peerName, size_t peerNameLen); OSStatus SSLHandshake(SSLContextRef context); OSStatus SSLGetBufferedReadSize(SSLContextRef context, size_t *bufSize); OSStatus SSLRead(SSLContextRef context, char *data, size_t dataLength, size_t *processed); OSStatus SSLWrite(SSLContextRef context, const char *data, size_t dataLength, size_t *processed); OSStatus SSLClose(SSLContextRef context); OSStatus SSLGetNumberSupportedCiphers(SSLContextRef context, size_t *numCiphers); OSStatus SSLGetSupportedCiphers(SSLContextRef context, SSLCipherSuite *ciphers, size_t *numCiphers); OSStatus SSLSetEnabledCiphers(SSLContextRef context, const SSLCipherSuite *ciphers, size_t numCiphers); OSStatus SSLGetNumberEnabledCiphers(SSLContextRef context, size_t *numCiphers); OSStatus SSLGetEnabledCiphers(SSLContextRef context, SSLCipherSuite *ciphers, size_t *numCiphers); OSStatus SSLGetNegotiatedCipher(SSLContextRef context, SSLCipherSuite *cipherSuite); OSStatus SSLGetNegotiatedProtocolVersion(SSLContextRef context, SSLProtocol *protocol); OSStatus SSLCopyPeerTrust(SSLContextRef context, SecTrustRef *trust); OSStatus SecTrustGetCssmResultCode(SecTrustRef trust, OSStatus *resultCode); CFIndex SecTrustGetCertificateCount(SecTrustRef trust); SecCertificateRef SecTrustGetCertificateAtIndex(SecTrustRef trust, CFIndex ix); OSStatus SecTrustSetAnchorCertificates(SecTrustRef trust, CFArrayRef anchorCertificates); OSStatus SecTrustSetAnchorCertificatesOnly(SecTrustRef trust, Boolean anchorCertificatesOnly); OSStatus SecTrustSetPolicies(SecTrustRef trust, CFArrayRef policies); SecPolicyRef SecPolicyCreateSSL(Boolean server, CFStringRef hostname); OSStatus SecPolicySearchCreate(CSSM_CERT_TYPE certType, const CSSM_OID *policyOID, const CSSM_DATA *value, SecPolicySearchRef *searchRef); OSStatus SecPolicySearchCopyNext(SecPolicySearchRef searchRef, SecPolicyRef *policyRef); OSStatus SecPolicySetValue(SecPolicyRef policyRef, const CSSM_DATA *value); OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType *result); extern SecRandomRef kSecRandomDefault; extern CFStringRef kSecPaddingKey; extern CFStringRef kSecPaddingPKCS7Key; extern CFStringRef kSecPaddingPKCS5Key; extern CFStringRef kSecPaddingPKCS1Key; extern CFStringRef kSecPaddingOAEPKey; extern CFStringRef kSecPaddingNoneKey; extern CFStringRef kSecModeCBCKey; extern CFStringRef kSecTransformInputAttributeName; extern CFStringRef kSecDigestTypeAttribute; extern CFStringRef kSecDigestLengthAttribute; extern CFStringRef kSecIVKey; extern CFStringRef kSecAttrIsExtractable; extern CFStringRef kSecDigestSHA1; extern CFStringRef kSecDigestSHA2; extern CFStringRef kSecDigestMD5; extern CFStringRef kSecAttrKeyType; extern CFTypeRef kSecAttrKeyTypeRSA; extern CFTypeRef kSecAttrKeyTypeDSA; extern CFTypeRef kSecAttrKeyTypeECDSA; extern CFStringRef kSecAttrKeySizeInBits; extern CFStringRef kSecAttrLabel; extern CFTypeRef kSecAttrCanSign; extern CFTypeRef kSecAttrCanVerify; extern CFTypeRef kSecAttrKeyTypeAES; extern CFTypeRef kSecAttrKeyTypeRC4; extern CFTypeRef kSecAttrKeyTypeRC2; extern CFTypeRef kSecAttrKeyType3DES; extern CFTypeRef kSecAttrKeyTypeDES; """) if version_info < (10, 8): ffi.cdef(""" OSStatus SSLNewContext(Boolean isServer, SSLContextRef *contextPtr); OSStatus SSLDisposeContext(SSLContextRef context); OSStatus SSLSetEnableCertVerify(SSLContextRef context, Boolean enableVerify); OSStatus SSLSetProtocolVersionEnabled(SSLContextRef context, SSLProtocol protocol, Boolean enable); """) else: ffi.cdef(""" typedef uint32_t SSLProtocolSide; typedef uint32_t SSLConnectionType; typedef uint32_t SSLSessionOption; SSLContextRef SSLCreateContext(CFAllocatorRef alloc, SSLProtocolSide protocolSide, SSLConnectionType connectionType); OSStatus SSLSetSessionOption(SSLContextRef context, SSLSessionOption option, Boolean value); OSStatus SSLSetProtocolVersionMin(SSLContextRef context, SSLProtocol minVersion); OSStatus SSLSetProtocolVersionMax(SSLContextRef context, SSLProtocol maxVersion); """) security_path = '/System/Library/Frameworks/Security.framework/Security' Security = ffi.dlopen(security_path) register_ffi(Security, ffi) _mac/_security_ctypes.py000064400000044060147205106110011413 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import platform from ctypes import c_void_p, c_int32, c_char_p, c_size_t, c_byte, c_int, c_uint32, c_uint64, c_ulong, c_long, c_bool from ctypes import CDLL, POINTER, CFUNCTYPE, Structure from .._ffi import FFIEngineError __all__ = [ 'Security', 'version', 'version_info', ] version = platform.mac_ver()[0] version_info = tuple(map(int, platform.mac_ver()[0].split('.'))) if version_info < (10, 7): raise OSError('Only OS X 10.7 and newer are supported, not %s.%s' % (version_info[0], version_info[1])) security_path = '/System/Library/Frameworks/Security.framework/Security' Security = CDLL(security_path, use_errno=True) Boolean = c_bool CFIndex = c_long CFData = c_void_p CFString = c_void_p CFArray = c_void_p CFDictionary = c_void_p CFError = c_void_p CFType = c_void_p CFTypeID = c_ulong CFTypeRef = POINTER(CFType) CFAllocatorRef = c_void_p OSStatus = c_int32 CFDataRef = POINTER(CFData) CFStringRef = POINTER(CFString) CFArrayRef = POINTER(CFArray) CFDictionaryRef = POINTER(CFDictionary) CFErrorRef = POINTER(CFError) SecKeyRef = POINTER(c_void_p) SecCertificateRef = POINTER(c_void_p) SecTransformRef = POINTER(c_void_p) SecRandomRef = c_void_p SecTrustSettingsDomain = c_uint32 SecItemImportExportFlags = c_uint32 SecKeyImportExportFlags = c_uint32 SecExternalFormat = c_uint32 SecExternalItemType = c_uint32 SecPadding = c_uint32 SSLProtocol = c_uint32 SSLCipherSuite = c_uint32 SecPolicyRef = POINTER(c_void_p) CSSM_CC_HANDLE = c_uint64 CSSM_ALGORITHMS = c_uint32 CSSM_KEYUSE = c_uint32 SecAccessRef = POINTER(c_void_p) SecKeychainRef = POINTER(c_void_p) SSLContextRef = POINTER(c_void_p) SecTrustRef = POINTER(c_void_p) SSLConnectionRef = c_uint32 SecTrustResultType = c_uint32 SecTrustOptionFlags = c_uint32 SecPolicySearchRef = c_void_p CSSM_CERT_TYPE = c_uint32 class CSSM_DATA(Structure): # noqa _fields_ = [ ('Length', c_uint32), ('Data', c_char_p) ] CSSM_OID = CSSM_DATA class CSSM_APPLE_TP_OCSP_OPTIONS(Structure): # noqa _fields_ = [ ('Version', c_uint32), ('Flags', c_uint32), ('LocalResponder', POINTER(CSSM_DATA)), ('LocalResponderCert', POINTER(CSSM_DATA)), ] class CSSM_APPLE_TP_CRL_OPTIONS(Structure): # noqa _fields_ = [ ('Version', c_uint32), ('CrlFlags', c_uint32), ('crlStore', c_void_p), ] class SecItemImportExportKeyParameters(Structure): _fields_ = [ ('version', c_uint32), ('flags', SecKeyImportExportFlags), ('passphrase', CFTypeRef), ('alertTitle', CFStringRef), ('alertPrompt', CFStringRef), ('accessRef', SecAccessRef), ('keyUsage', CFArrayRef), ('keyAttributes', CFArrayRef), ] try: Security.SecKeychainCreate.argtypes = [ c_char_p, c_uint32, c_void_p, Boolean, SecAccessRef, POINTER(SecKeychainRef) ] Security.SecKeychainCreate.restype = OSStatus Security.SecKeychainDelete.argtypes = [SecKeychainRef] Security.SecKeychainDelete.restype = OSStatus Security.SecRandomCopyBytes.argtypes = [ SecRandomRef, c_size_t, c_char_p ] Security.SecRandomCopyBytes.restype = c_int Security.SecKeyCreateFromData.argtypes = [ CFDictionaryRef, CFDataRef, POINTER(CFErrorRef) ] Security.SecKeyCreateFromData.restype = SecKeyRef Security.SecEncryptTransformCreate.argtypes = [ SecKeyRef, POINTER(CFErrorRef) ] Security.SecEncryptTransformCreate.restype = SecTransformRef Security.SecDecryptTransformCreate.argtypes = [ SecKeyRef, POINTER(CFErrorRef) ] Security.SecDecryptTransformCreate.restype = SecTransformRef Security.SecTransformSetAttribute.argtypes = [ SecTransformRef, CFStringRef, CFTypeRef, POINTER(CFErrorRef) ] Security.SecTransformSetAttribute.restype = Boolean Security.SecTransformExecute.argtypes = [ SecTransformRef, POINTER(CFErrorRef) ] Security.SecTransformExecute.restype = CFTypeRef Security.SecVerifyTransformCreate.argtypes = [ SecKeyRef, CFDataRef, POINTER(CFErrorRef) ] Security.SecVerifyTransformCreate.restype = SecTransformRef Security.SecSignTransformCreate.argtypes = [ SecKeyRef, POINTER(CFErrorRef) ] Security.SecSignTransformCreate.restype = SecTransformRef Security.SecCertificateCreateWithData.argtypes = [ CFAllocatorRef, CFDataRef ] Security.SecCertificateCreateWithData.restype = SecCertificateRef Security.SecCertificateCopyPublicKey.argtypes = [ SecCertificateRef, POINTER(SecKeyRef) ] Security.SecCertificateCopyPublicKey.restype = OSStatus Security.SecCopyErrorMessageString.argtypes = [ OSStatus, c_void_p ] Security.SecCopyErrorMessageString.restype = CFStringRef Security.SecTrustCopyAnchorCertificates.argtypes = [ POINTER(CFArrayRef) ] Security.SecTrustCopyAnchorCertificates.restype = OSStatus Security.SecCertificateCopyData.argtypes = [ SecCertificateRef ] Security.SecCertificateCopyData.restype = CFDataRef Security.SecTrustSettingsCopyCertificates.argtypes = [ SecTrustSettingsDomain, POINTER(CFArrayRef) ] Security.SecTrustSettingsCopyCertificates.restype = OSStatus Security.SecTrustSettingsCopyTrustSettings.argtypes = [ SecCertificateRef, SecTrustSettingsDomain, POINTER(CFArrayRef) ] Security.SecTrustSettingsCopyTrustSettings.restype = OSStatus Security.SecPolicyCopyProperties.argtypes = [ SecPolicyRef ] Security.SecPolicyCopyProperties.restype = CFDictionaryRef Security.SecPolicyGetTypeID.argtypes = [] Security.SecPolicyGetTypeID.restype = CFTypeID Security.SecKeyEncrypt.argtypes = [ SecKeyRef, SecPadding, c_char_p, c_size_t, c_char_p, POINTER(c_size_t) ] Security.SecKeyEncrypt.restype = OSStatus Security.SecKeyDecrypt.argtypes = [ SecKeyRef, SecPadding, c_char_p, c_size_t, c_char_p, POINTER(c_size_t) ] Security.SecKeyDecrypt.restype = OSStatus Security.SecKeyRawSign.argtypes = [ SecKeyRef, SecPadding, c_char_p, c_size_t, c_char_p, POINTER(c_size_t) ] Security.SecKeyRawSign.restype = OSStatus Security.SecKeyRawVerify.argtypes = [ SecKeyRef, SecPadding, c_char_p, c_size_t, c_char_p, c_size_t ] Security.SecKeyRawVerify.restype = OSStatus Security.SecAccessCreate.argtypes = [ CFStringRef, CFArrayRef, POINTER(SecAccessRef) ] Security.SecAccessCreate.restype = OSStatus Security.SecKeyCreatePair.argtypes = [ SecKeychainRef, CSSM_ALGORITHMS, c_uint32, CSSM_CC_HANDLE, CSSM_KEYUSE, c_uint32, CSSM_KEYUSE, c_uint32, SecAccessRef, POINTER(SecKeyRef), POINTER(SecKeyRef) ] Security.SecKeyCreatePair.restype = OSStatus Security.SecItemImport.argtypes = [ CFDataRef, CFStringRef, POINTER(SecExternalFormat), POINTER(SecExternalItemType), SecItemImportExportFlags, POINTER(SecItemImportExportKeyParameters), SecKeychainRef, POINTER(CFArrayRef) ] Security.SecItemImport.restype = OSStatus Security.SecItemExport.argtypes = [ CFTypeRef, SecExternalFormat, SecItemImportExportFlags, POINTER(SecItemImportExportKeyParameters), POINTER(CFDataRef) ] Security.SecItemExport.restype = OSStatus Security.SecKeychainItemDelete.argtypes = [ SecKeyRef ] Security.SecKeychainItemDelete.restype = OSStatus SSLReadFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, POINTER(c_byte), POINTER(c_size_t)) SSLWriteFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, POINTER(c_byte), POINTER(c_size_t)) Security.SSLSetIOFuncs.argtypes = [ SSLContextRef, SSLReadFunc, SSLWriteFunc ] Security.SSLSetIOFuncs.restype = OSStatus Security.SSLSetPeerID.argtypes = [ SSLContextRef, c_char_p, c_size_t ] Security.SSLSetPeerID.restype = OSStatus Security.SSLSetCertificateAuthorities.argtypes = [ SSLContextRef, CFTypeRef, Boolean ] Security.SSLSetCertificateAuthorities.restype = OSStatus Security.SecTrustSetPolicies.argtypes = [ SecTrustRef, CFArrayRef ] Security.SecTrustSetPolicies.restype = OSStatus Security.SecPolicyCreateSSL.argtypes = [ Boolean, CFStringRef ] Security.SecPolicyCreateSSL.restype = SecPolicyRef Security.SecPolicySearchCreate.argtypes = [ CSSM_CERT_TYPE, POINTER(CSSM_OID), POINTER(CSSM_DATA), POINTER(SecPolicySearchRef) ] Security.SecPolicySearchCreate.restype = OSStatus Security.SecPolicySearchCopyNext.argtypes = [ SecPolicySearchRef, POINTER(SecPolicyRef) ] Security.SecPolicySearchCopyNext.restype = OSStatus Security.SecPolicySetValue.argtypes = [ SecPolicyRef, POINTER(CSSM_DATA) ] Security.SecPolicySetValue.restype = OSStatus Security.SSLSetConnection.argtypes = [ SSLContextRef, SSLConnectionRef ] Security.SSLSetConnection.restype = OSStatus Security.SSLSetPeerDomainName.argtypes = [ SSLContextRef, c_char_p, c_size_t ] Security.SSLSetPeerDomainName.restype = OSStatus Security.SSLHandshake.argtypes = [ SSLContextRef ] Security.SSLHandshake.restype = OSStatus Security.SSLGetBufferedReadSize.argtypes = [ SSLContextRef, POINTER(c_size_t) ] Security.SSLGetBufferedReadSize.restype = OSStatus Security.SSLRead.argtypes = [ SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t) ] Security.SSLRead.restype = OSStatus Security.SSLWrite.argtypes = [ SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t) ] Security.SSLWrite.restype = OSStatus Security.SSLClose.argtypes = [ SSLContextRef ] Security.SSLClose.restype = OSStatus Security.SSLGetNumberSupportedCiphers.argtypes = [ SSLContextRef, POINTER(c_size_t) ] Security.SSLGetNumberSupportedCiphers.restype = OSStatus Security.SSLGetSupportedCiphers.argtypes = [ SSLContextRef, POINTER(SSLCipherSuite), POINTER(c_size_t) ] Security.SSLGetSupportedCiphers.restype = OSStatus Security.SSLSetEnabledCiphers.argtypes = [ SSLContextRef, POINTER(SSLCipherSuite), c_size_t ] Security.SSLSetEnabledCiphers.restype = OSStatus Security.SSLGetNumberEnabledCiphers.argtype = [ SSLContextRef, POINTER(c_size_t) ] Security.SSLGetNumberEnabledCiphers.restype = OSStatus Security.SSLGetEnabledCiphers.argtypes = [ SSLContextRef, POINTER(SSLCipherSuite), POINTER(c_size_t) ] Security.SSLGetEnabledCiphers.restype = OSStatus Security.SSLGetNegotiatedCipher.argtypes = [ SSLContextRef, POINTER(SSLCipherSuite) ] Security.SSLGetNegotiatedCipher.restype = OSStatus Security.SSLGetNegotiatedProtocolVersion.argtypes = [ SSLContextRef, POINTER(SSLProtocol) ] Security.SSLGetNegotiatedProtocolVersion.restype = OSStatus Security.SSLCopyPeerTrust.argtypes = [ SSLContextRef, POINTER(SecTrustRef) ] Security.SSLCopyPeerTrust.restype = OSStatus Security.SecTrustGetCssmResultCode.argtypes = [ SecTrustRef, POINTER(OSStatus) ] Security.SecTrustGetCssmResultCode.restype = OSStatus Security.SecTrustGetCertificateCount.argtypes = [ SecTrustRef ] Security.SecTrustGetCertificateCount.restype = CFIndex Security.SecTrustGetCertificateAtIndex.argtypes = [ SecTrustRef, CFIndex ] Security.SecTrustGetCertificateAtIndex.restype = SecCertificateRef Security.SecTrustSetAnchorCertificates.argtypes = [ SecTrustRef, CFArrayRef ] Security.SecTrustSetAnchorCertificates.restype = OSStatus Security.SecTrustSetAnchorCertificatesOnly.argstypes = [ SecTrustRef, Boolean ] Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus Security.SecTrustEvaluate.argtypes = [ SecTrustRef, POINTER(SecTrustResultType) ] Security.SecTrustEvaluate.restype = OSStatus if version_info < (10, 8): Security.SSLNewContext.argtypes = [ Boolean, POINTER(SSLContextRef) ] Security.SSLNewContext.restype = OSStatus Security.SSLDisposeContext.argtypes = [ SSLContextRef ] Security.SSLDisposeContext.restype = OSStatus Security.SSLSetEnableCertVerify.argtypes = [ SSLContextRef, Boolean ] Security.SSLSetEnableCertVerify.restype = OSStatus Security.SSLSetProtocolVersionEnabled.argtypes = [ SSLContextRef, SSLProtocol, Boolean ] Security.SSLSetProtocolVersionEnabled.restype = OSStatus else: SSLProtocolSide = c_uint32 SSLConnectionType = c_uint32 SSLSessionOption = c_uint32 Security.SSLCreateContext.argtypes = [ CFAllocatorRef, SSLProtocolSide, SSLConnectionType ] Security.SSLCreateContext.restype = SSLContextRef Security.SSLSetSessionOption.argtypes = [ SSLContextRef, SSLSessionOption, Boolean ] Security.SSLSetSessionOption.restype = OSStatus Security.SSLSetProtocolVersionMin.argtypes = [ SSLContextRef, SSLProtocol ] Security.SSLSetProtocolVersionMin.restype = OSStatus Security.SSLSetProtocolVersionMax.argtypes = [ SSLContextRef, SSLProtocol ] Security.SSLSetProtocolVersionMax.restype = OSStatus setattr(Security, 'SSLReadFunc', SSLReadFunc) setattr(Security, 'SSLWriteFunc', SSLWriteFunc) setattr(Security, 'SSLContextRef', SSLContextRef) setattr(Security, 'SSLProtocol', SSLProtocol) setattr(Security, 'SSLCipherSuite', SSLCipherSuite) setattr(Security, 'SecTrustRef', SecTrustRef) setattr(Security, 'SecTrustResultType', SecTrustResultType) setattr(Security, 'OSStatus', OSStatus) setattr(Security, 'SecAccessRef', SecAccessRef) setattr(Security, 'SecKeychainRef', SecKeychainRef) setattr(Security, 'SecKeyRef', SecKeyRef) setattr(Security, 'SecPolicySearchRef', SecPolicySearchRef) setattr(Security, 'SecPolicyRef', SecPolicyRef) setattr(Security, 'CSSM_DATA', CSSM_DATA) setattr(Security, 'CSSM_OID', CSSM_OID) setattr(Security, 'CSSM_APPLE_TP_OCSP_OPTIONS', CSSM_APPLE_TP_OCSP_OPTIONS) setattr(Security, 'CSSM_APPLE_TP_CRL_OPTIONS', CSSM_APPLE_TP_CRL_OPTIONS) setattr(Security, 'SecItemImportExportKeyParameters', SecItemImportExportKeyParameters) setattr(Security, 'kSecRandomDefault', SecRandomRef.in_dll(Security, 'kSecRandomDefault')) setattr(Security, 'kSecPaddingKey', CFStringRef.in_dll(Security, 'kSecPaddingKey')) setattr(Security, 'kSecPaddingPKCS7Key', CFStringRef.in_dll(Security, 'kSecPaddingPKCS7Key')) setattr(Security, 'kSecPaddingPKCS5Key', CFStringRef.in_dll(Security, 'kSecPaddingPKCS5Key')) setattr(Security, 'kSecPaddingPKCS1Key', CFStringRef.in_dll(Security, 'kSecPaddingPKCS1Key')) setattr(Security, 'kSecPaddingOAEPKey', CFStringRef.in_dll(Security, 'kSecPaddingOAEPKey')) setattr(Security, 'kSecPaddingNoneKey', CFStringRef.in_dll(Security, 'kSecPaddingNoneKey')) setattr(Security, 'kSecModeCBCKey', CFStringRef.in_dll(Security, 'kSecModeCBCKey')) setattr( Security, 'kSecTransformInputAttributeName', CFStringRef.in_dll(Security, 'kSecTransformInputAttributeName') ) setattr(Security, 'kSecDigestTypeAttribute', CFStringRef.in_dll(Security, 'kSecDigestTypeAttribute')) setattr(Security, 'kSecDigestLengthAttribute', CFStringRef.in_dll(Security, 'kSecDigestLengthAttribute')) setattr(Security, 'kSecIVKey', CFStringRef.in_dll(Security, 'kSecIVKey')) setattr(Security, 'kSecAttrIsExtractable', CFStringRef.in_dll(Security, 'kSecAttrIsExtractable')) setattr(Security, 'kSecDigestSHA1', CFStringRef.in_dll(Security, 'kSecDigestSHA1')) setattr(Security, 'kSecDigestSHA2', CFStringRef.in_dll(Security, 'kSecDigestSHA2')) setattr(Security, 'kSecDigestMD5', CFStringRef.in_dll(Security, 'kSecDigestMD5')) setattr(Security, 'kSecAttrKeyType', CFStringRef.in_dll(Security, 'kSecAttrKeyType')) setattr(Security, 'kSecAttrKeyTypeRSA', CFTypeRef.in_dll(Security, 'kSecAttrKeyTypeRSA')) setattr(Security, 'kSecAttrKeyTypeDSA', CFTypeRef.in_dll(Security, 'kSecAttrKeyTypeDSA')) setattr(Security, 'kSecAttrKeyTypeECDSA', CFTypeRef.in_dll(Security, 'kSecAttrKeyTypeECDSA')) setattr(Security, 'kSecAttrKeySizeInBits', CFStringRef.in_dll(Security, 'kSecAttrKeySizeInBits')) setattr(Security, 'kSecAttrLabel', CFStringRef.in_dll(Security, 'kSecAttrLabel')) setattr(Security, 'kSecAttrCanSign', CFTypeRef.in_dll(Security, 'kSecAttrCanSign')) setattr(Security, 'kSecAttrCanVerify', CFTypeRef.in_dll(Security, 'kSecAttrCanVerify')) setattr(Security, 'kSecAttrKeyTypeAES', CFTypeRef.in_dll(Security, 'kSecAttrKeyTypeAES')) setattr(Security, 'kSecAttrKeyTypeRC4', CFTypeRef.in_dll(Security, 'kSecAttrKeyTypeRC4')) setattr(Security, 'kSecAttrKeyTypeRC2', CFTypeRef.in_dll(Security, 'kSecAttrKeyTypeRC2')) setattr(Security, 'kSecAttrKeyType3DES', CFTypeRef.in_dll(Security, 'kSecAttrKeyType3DES')) setattr(Security, 'kSecAttrKeyTypeDES', CFTypeRef.in_dll(Security, 'kSecAttrKeyTypeDES')) except (AttributeError): raise FFIEngineError('Error initializing ctypes') _mac/asymmetric.py000064400000175734147205106110010210 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from base64 import b32encode import os import shutil import tempfile from .._asn1 import ( Certificate as Asn1Certificate, ECDomainParameters, Integer, KeyExchangeAlgorithm, Null, PrivateKeyInfo, PublicKeyAlgorithm, PublicKeyInfo, RSAPublicKey, ) 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 new, unwrap, bytes_from_buffer, buffer_from_bytes, deref, null, is_null, pointer_set from ._security import Security, SecurityConst, handle_sec_error, osx_version_info from ._core_foundation import CoreFoundation, CFHelpers, handle_cf_error from .util import rand_bytes from ..errors import AsymmetricKeyError, IncompleteAsymmetricKeyError, SignatureError from .._pkcs1 import add_pss_padding, verify_pss_padding, remove_pkcs1v15_encryption_padding from .._types import type_name, str_cls, byte_cls, int_types __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 OS crypto library representation of a private key """ sec_key_ref = 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, sec_key_ref, asn1): """ :param sec_key_ref: A Security framework SecKeyRef value from loading/importing the key :param asn1: An asn1crypto.keys.PrivateKeyInfo object """ self.sec_key_ref = sec_key_ref self.asn1 = asn1 self._lib = CoreFoundation @property def public_key(self): """ :return: A PublicKey object corresponding to this private key. """ if self._public_key is None: cf_data_private = None try: # We export here so that Security.framework will fill in the EC # public key for us, instead of us having to compute it cf_data_private_pointer = new(CoreFoundation, 'CFDataRef *') result = Security.SecItemExport(self.sec_key_ref, 0, 0, null(), cf_data_private_pointer) handle_sec_error(result) cf_data_private = unwrap(cf_data_private_pointer) private_key_bytes = CFHelpers.cf_data_to_bytes(cf_data_private) key = parse_private(private_key_bytes) if key.algorithm == 'rsa': public_asn1 = PublicKeyInfo({ 'algorithm': PublicKeyAlgorithm({ 'algorithm': 'rsa', 'parameters': Null() }), 'public_key': RSAPublicKey({ 'modulus': key['private_key'].parsed['modulus'], 'public_exponent': key['private_key'].parsed['public_exponent'], }) }) elif key.algorithm == 'dsa': params = key['private_key_algorithm']['parameters'] public_asn1 = PublicKeyInfo({ 'algorithm': PublicKeyAlgorithm({ 'algorithm': 'dsa', 'parameters': params.copy() }), 'public_key': Integer(pow( params['g'].native, key['private_key'].parsed.native, params['p'].native )) }) elif key.algorithm == 'ec': public_asn1 = PublicKeyInfo({ 'algorithm': PublicKeyAlgorithm({ 'algorithm': 'ec', 'parameters': ECDomainParameters( name='named', value=self.curve ) }), 'public_key': key['private_key'].parsed['public_key'], }) finally: if cf_data_private: CoreFoundation.CFRelease(cf_data_private) self._public_key = _load_key(public_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.sec_key_ref: self._lib.CFRelease(self.sec_key_ref) self._lib = None self.sec_key_ref = None class PublicKey(_PublicKeyBase): """ Container for the OS crypto library representation of a public key """ sec_key_ref = 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, sec_key_ref, asn1): """ :param sec_key_ref: A Security framework SecKeyRef value from loading/importing the key :param asn1: An asn1crypto.keys.PublicKeyInfo object """ self.sec_key_ref = sec_key_ref self.asn1 = asn1 self._lib = CoreFoundation def __del__(self): if self.sec_key_ref: self._lib.CFRelease(self.sec_key_ref) self._lib = None self.sec_key_ref = None class Certificate(_CertificateBase): """ Container for the OS crypto library representation of a certificate """ sec_certificate_ref = None _public_key = None _self_signed = None def __init__(self, sec_certificate_ref, asn1): """ :param sec_certificate_ref: A Security framework SecCertificateRef value from loading/importing the certificate :param asn1: An asn1crypto.x509.Certificate object """ self.sec_certificate_ref = sec_certificate_ref self.asn1 = asn1 @property def sec_key_ref(self): """ :return: The SecKeyRef of the public key """ return self.public_key.sec_key_ref @property def public_key(self): """ :return: The PublicKey object for the public key this certificate contains """ if not self._public_key and self.sec_certificate_ref: if self.asn1.signature_algo == "rsassa_pss": # macOS doesn't like importing RSA PSS certs, so we treat it like a # traditional RSA cert asn1 = self.asn1.copy() asn1['tbs_certificate']['subject_public_key_info']['algorithm']['algorithm'] = 'rsa' temp_cert = _load_x509(asn1) sec_cert_ref = temp_cert.sec_certificate_ref else: sec_cert_ref = self.sec_certificate_ref sec_public_key_ref_pointer = new(Security, 'SecKeyRef *') res = Security.SecCertificateCopyPublicKey(sec_cert_ref, sec_public_key_ref_pointer) handle_sec_error(res) sec_public_key_ref = unwrap(sec_public_key_ref_pointer) self._public_key = PublicKey(sec_public_key_ref, self.asn1['tbs_certificate']['subject_public_key_info']) 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.sec_certificate_ref: CoreFoundation.CFRelease(self.sec_certificate_ref) self.sec_certificate_ref = 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. :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 bit_size not in set([1024]): raise ValueError(pretty_message( ''' bit_size must be 1024, 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) )) cf_dict = None public_key_ref = None private_key_ref = None cf_data_public = None cf_data_private = None cf_string = None sec_access_ref = None sec_keychain_ref = None temp_dir = None try: alg_id = { 'dsa': SecurityConst.CSSM_ALGID_DSA, 'ec': SecurityConst.CSSM_ALGID_ECDSA, 'rsa': SecurityConst.CSSM_ALGID_RSA, }[algorithm] if algorithm == 'ec': key_size = { 'secp256r1': 256, 'secp384r1': 384, 'secp521r1': 521, }[curve] else: key_size = bit_size private_key_pointer = new(Security, 'SecKeyRef *') public_key_pointer = new(Security, 'SecKeyRef *') cf_string = CFHelpers.cf_string_from_unicode("Temporary oscrypto key") # We used to use SecKeyGeneratePair() for everything but DSA keys, but due to changes # in macOS security, we can't reliably access the default keychain, and instead # get an "OSError: User interaction is not allowed." result. Because of this we now # use SecKeyCreatePair() for everything, but we even use a throw-away keychain. passphrase_len = 16 rand_data = rand_bytes(10 + passphrase_len) passphrase = rand_data[10:] temp_filename = b32encode(rand_data[:10]).decode('utf-8') temp_dir = tempfile.mkdtemp() temp_path = os.path.join(temp_dir, temp_filename).encode('utf-8') sec_keychain_ref_pointer = new(Security, 'SecKeychainRef *') result = Security.SecKeychainCreate( temp_path, passphrase_len, passphrase, False, null(), sec_keychain_ref_pointer ) handle_sec_error(result) sec_keychain_ref = unwrap(sec_keychain_ref_pointer) sec_access_ref_pointer = new(Security, 'SecAccessRef *') result = Security.SecAccessCreate(cf_string, null(), sec_access_ref_pointer) handle_sec_error(result) sec_access_ref = unwrap(sec_access_ref_pointer) result = Security.SecKeyCreatePair( sec_keychain_ref, alg_id, key_size, 0, SecurityConst.CSSM_KEYUSE_VERIFY, SecurityConst.CSSM_KEYATTR_EXTRACTABLE | SecurityConst.CSSM_KEYATTR_PERMANENT, SecurityConst.CSSM_KEYUSE_SIGN, SecurityConst.CSSM_KEYATTR_EXTRACTABLE | SecurityConst.CSSM_KEYATTR_PERMANENT, sec_access_ref, public_key_pointer, private_key_pointer ) handle_sec_error(result) public_key_ref = unwrap(public_key_pointer) private_key_ref = unwrap(private_key_pointer) cf_data_public_pointer = new(CoreFoundation, 'CFDataRef *') result = Security.SecItemExport(public_key_ref, 0, 0, null(), cf_data_public_pointer) handle_sec_error(result) cf_data_public = unwrap(cf_data_public_pointer) public_key_bytes = CFHelpers.cf_data_to_bytes(cf_data_public) cf_data_private_pointer = new(CoreFoundation, 'CFDataRef *') result = Security.SecItemExport(private_key_ref, 0, 0, null(), cf_data_private_pointer) handle_sec_error(result) cf_data_private = unwrap(cf_data_private_pointer) private_key_bytes = CFHelpers.cf_data_to_bytes(cf_data_private) # Clean the new keys out of the keychain result = Security.SecKeychainItemDelete(public_key_ref) handle_sec_error(result) result = Security.SecKeychainItemDelete(private_key_ref) handle_sec_error(result) finally: if cf_dict: CoreFoundation.CFRelease(cf_dict) if public_key_ref: CoreFoundation.CFRelease(public_key_ref) if private_key_ref: CoreFoundation.CFRelease(private_key_ref) if cf_data_public: CoreFoundation.CFRelease(cf_data_public) if cf_data_private: CoreFoundation.CFRelease(cf_data_private) if cf_string: CoreFoundation.CFRelease(cf_string) if sec_keychain_ref: Security.SecKeychainDelete(sec_keychain_ref) CoreFoundation.CFRelease(sec_keychain_ref) if temp_dir: shutil.rmtree(temp_dir) if sec_access_ref: CoreFoundation.CFRelease(sec_access_ref) 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') public_key_ref = None private_key_ref = None cf_data_public = None cf_data_private = None cf_string = None sec_keychain_ref = None sec_access_ref = None temp_dir = None try: public_key_pointer = new(Security, 'SecKeyRef *') private_key_pointer = new(Security, 'SecKeyRef *') cf_string = CFHelpers.cf_string_from_unicode("Temporary oscrypto key") passphrase_len = 16 rand_data = rand_bytes(10 + passphrase_len) passphrase = rand_data[10:] temp_filename = b32encode(rand_data[:10]).decode('utf-8') temp_dir = tempfile.mkdtemp() temp_path = os.path.join(temp_dir, temp_filename).encode('utf-8') sec_keychain_ref_pointer = new(Security, 'SecKeychainRef *') result = Security.SecKeychainCreate( temp_path, passphrase_len, passphrase, False, null(), sec_keychain_ref_pointer ) handle_sec_error(result) sec_keychain_ref = unwrap(sec_keychain_ref_pointer) sec_access_ref_pointer = new(Security, 'SecAccessRef *') result = Security.SecAccessCreate(cf_string, null(), sec_access_ref_pointer) handle_sec_error(result) sec_access_ref = unwrap(sec_access_ref_pointer) result = Security.SecKeyCreatePair( sec_keychain_ref, SecurityConst.CSSM_ALGID_DH, bit_size, 0, 0, SecurityConst.CSSM_KEYATTR_EXTRACTABLE | SecurityConst.CSSM_KEYATTR_PERMANENT, 0, SecurityConst.CSSM_KEYATTR_EXTRACTABLE | SecurityConst.CSSM_KEYATTR_PERMANENT, sec_access_ref, public_key_pointer, private_key_pointer ) handle_sec_error(result) public_key_ref = unwrap(public_key_pointer) private_key_ref = unwrap(private_key_pointer) cf_data_private_pointer = new(CoreFoundation, 'CFDataRef *') result = Security.SecItemExport(private_key_ref, 0, 0, null(), cf_data_private_pointer) handle_sec_error(result) cf_data_private = unwrap(cf_data_private_pointer) private_key_bytes = CFHelpers.cf_data_to_bytes(cf_data_private) # Clean the new keys out of the keychain result = Security.SecKeychainItemDelete(public_key_ref) handle_sec_error(result) result = Security.SecKeychainItemDelete(private_key_ref) handle_sec_error(result) return KeyExchangeAlgorithm.load(private_key_bytes)['parameters'] finally: if public_key_ref: CoreFoundation.CFRelease(public_key_ref) if private_key_ref: CoreFoundation.CFRelease(private_key_ref) if cf_data_public: CoreFoundation.CFRelease(cf_data_public) if cf_data_private: CoreFoundation.CFRelease(cf_data_private) if cf_string: CoreFoundation.CFRelease(cf_string) if sec_keychain_ref: Security.SecKeychainDelete(sec_keychain_ref) CoreFoundation.CFRelease(sec_keychain_ref) if temp_dir: shutil.rmtree(temp_dir) if sec_access_ref: CoreFoundation.CFRelease(sec_access_ref) 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() cf_source = None try: cf_source = CFHelpers.cf_data_from_bytes(source) sec_key_ref = Security.SecCertificateCreateWithData(CoreFoundation.kCFAllocatorDefault, cf_source) return Certificate(sec_key_ref, certificate) finally: if cf_source: CoreFoundation.CFRelease(cf_source) 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) )) return _load_key(public_key) def _load_key(key_object): """ Common code to load public and private keys into PublicKey and PrivateKey objects :param key_object: An asn1crypto.keys.PublicKeyInfo or asn1crypto.keys.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 key is incompatible with the OS crypto library OSError - when an error is returned by the OS crypto library :return: A PublicKey or PrivateKey object """ if key_object.algorithm == 'ec': curve_type, details = key_object.curve if curve_type != 'named': raise AsymmetricKeyError('OS X only supports EC keys using named curves') if details not in set(['secp256r1', 'secp384r1', 'secp521r1']): raise AsymmetricKeyError(pretty_message( ''' OS X only supports EC keys using the named curves secp256r1, secp384r1 and secp521r1 ''' )) elif key_object.algorithm == 'dsa' and key_object.hash_algo == 'sha2': raise AsymmetricKeyError(pretty_message( ''' OS X only supports DSA keys based on SHA1 (2048 bits or less) - this key is based on SHA2 and is %s bits ''', key_object.bit_size )) elif key_object.algorithm == 'dsa' and key_object.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 ''' )) if isinstance(key_object, PublicKeyInfo): if key_object.algorithm == 'rsassa_pss': # We have to masquerade an RSA PSS key as plain RSA or it won't # import properly temp_key_object = key_object.copy() temp_key_object['algorithm']['algorithm'] = 'rsa' source = temp_key_object.dump() else: source = key_object.dump() item_type = SecurityConst.kSecItemTypePublicKey else: source = _unwrap_private_key_info(key_object).dump() item_type = SecurityConst.kSecItemTypePrivateKey cf_source = None keys_array = None attr_array = None try: cf_source = CFHelpers.cf_data_from_bytes(source) format_pointer = new(Security, 'uint32_t *') pointer_set(format_pointer, SecurityConst.kSecFormatOpenSSL) type_pointer = new(Security, 'uint32_t *') pointer_set(type_pointer, item_type) keys_pointer = new(CoreFoundation, 'CFArrayRef *') attr_array = CFHelpers.cf_array_from_list([ Security.kSecAttrIsExtractable ]) import_export_params_pointer = new(Security, 'SecItemImportExportKeyParameters *') import_export_params = unwrap(import_export_params_pointer) import_export_params.version = 0 import_export_params.flags = 0 import_export_params.passphrase = null() import_export_params.alertTitle = null() import_export_params.alertPrompt = null() import_export_params.accessRef = null() import_export_params.keyUsage = null() import_export_params.keyAttributes = attr_array res = Security.SecItemImport( cf_source, null(), format_pointer, type_pointer, 0, import_export_params_pointer, null(), keys_pointer ) handle_sec_error(res) keys_array = unwrap(keys_pointer) length = CoreFoundation.CFArrayGetCount(keys_array) if length > 0: sec_key_ref = CoreFoundation.CFArrayGetValueAtIndex(keys_array, 0) CoreFoundation.CFRetain(sec_key_ref) if item_type == SecurityConst.kSecItemTypePublicKey: return PublicKey(sec_key_ref, key_object) if item_type == SecurityConst.kSecItemTypePrivateKey: return PrivateKey(sec_key_ref, key_object) finally: if attr_array: CoreFoundation.CFRelease(attr_array) if keys_array: CoreFoundation.CFRelease(keys_array) if cf_source: CoreFoundation.CFRelease(cf_source) 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 """ 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) )) key_length = certificate_or_public_key.byte_size buffer = buffer_from_bytes(key_length) output_length = new(Security, 'size_t *', key_length) result = Security.SecKeyEncrypt( certificate_or_public_key.sec_key_ref, SecurityConst.kSecPaddingPKCS1, data, len(data), buffer, output_length ) handle_sec_error(result) return bytes_from_buffer(buffer, deref(output_length)) 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 """ if not isinstance(private_key, PrivateKey): raise TypeError(pretty_message( ''' private_key must an instance of the PrivateKey class, not %s ''', type_name(private_key) )) if not isinstance(ciphertext, byte_cls): raise TypeError(pretty_message( ''' data must be a byte string, not %s ''', type_name(ciphertext) )) key_length = private_key.byte_size buffer = buffer_from_bytes(key_length) output_length = new(Security, 'size_t *', key_length) if osx_version_info < (10, 8): padding = SecurityConst.kSecPaddingNone else: padding = SecurityConst.kSecPaddingPKCS1 result = Security.SecKeyDecrypt( private_key.sec_key_ref, padding, ciphertext, len(ciphertext), buffer, output_length ) handle_sec_error(result) output = bytes_from_buffer(buffer, deref(output_length)) if osx_version_info < (10, 8): output = remove_pkcs1v15_encryption_padding(key_length, output) return output 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, Security.kSecPaddingOAEPKey) 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, Security.kSecPaddingOAEPKey) def _encrypt(certificate_or_public_key, data, padding): """ Encrypts plaintext using an RSA public key or certificate :param certificate_or_public_key: A Certificate or PublicKey object :param data: The plaintext - a byte string :param padding: The padding mode to use, specified as a kSecPadding*Key value :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 ciphertext """ 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) )) if not padding: raise ValueError('padding must be specified') cf_data = None sec_transform = None try: cf_data = CFHelpers.cf_data_from_bytes(data) error_pointer = new(CoreFoundation, 'CFErrorRef *') sec_transform = Security.SecEncryptTransformCreate( certificate_or_public_key.sec_key_ref, error_pointer ) handle_cf_error(error_pointer) if padding: Security.SecTransformSetAttribute( sec_transform, Security.kSecPaddingKey, padding, error_pointer ) handle_cf_error(error_pointer) Security.SecTransformSetAttribute( sec_transform, Security.kSecTransformInputAttributeName, cf_data, error_pointer ) handle_cf_error(error_pointer) ciphertext = Security.SecTransformExecute(sec_transform, error_pointer) handle_cf_error(error_pointer) return CFHelpers.cf_data_to_bytes(ciphertext) finally: if cf_data: CoreFoundation.CFRelease(cf_data) if sec_transform: CoreFoundation.CFRelease(sec_transform) 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, specified as a kSecPadding*Key value :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) )) if not padding: raise ValueError('padding must be specified') cf_data = None sec_transform = None try: cf_data = CFHelpers.cf_data_from_bytes(ciphertext) error_pointer = new(CoreFoundation, 'CFErrorRef *') sec_transform = Security.SecDecryptTransformCreate( private_key.sec_key_ref, error_pointer ) handle_cf_error(error_pointer) Security.SecTransformSetAttribute( sec_transform, Security.kSecPaddingKey, padding, error_pointer ) handle_cf_error(error_pointer) Security.SecTransformSetAttribute( sec_transform, Security.kSecTransformInputAttributeName, cf_data, error_pointer ) handle_cf_error(error_pointer) plaintext = Security.SecTransformExecute(sec_transform, error_pointer) handle_cf_error(error_pointer) return CFHelpers.cf_data_to_bytes(plaintext) finally: if cf_data: CoreFoundation.CFRelease(cf_data) if sec_transform: CoreFoundation.CFRelease(sec_transform) 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('The key specified is not an RSA public key') 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 """ 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) )) cp_algo = certificate_or_public_key.algorithm if cp_algo != 'rsa' and cp_algo != 'rsassa_pss': raise ValueError('The key specified is not an RSA public key') hash_length = { 'sha1': 20, 'sha224': 28, 'sha256': 32, 'sha384': 48, 'sha512': 64 }.get(hash_algorithm, 0) key_length = certificate_or_public_key.byte_size buffer = buffer_from_bytes(key_length) output_length = new(Security, 'size_t *', key_length) result = Security.SecKeyEncrypt( certificate_or_public_key.sec_key_ref, SecurityConst.kSecPaddingNone, signature, len(signature), buffer, output_length ) handle_sec_error(result) plaintext = bytes_from_buffer(buffer, deref(output_length)) if not verify_pss_padding(hash_algorithm, hash_length, certificate_or_public_key.bit_size, data, plaintext): raise SignatureError('Signature is invalid') 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('The key specified is not a DSA public key') 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('The key specified is not an EC public key') return _verify(certificate_or_public_key, signature, data, hash_algorithm) def _verify(certificate_or_public_key, signature, data, hash_algorithm): """ 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" :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) )) valid_hash_algorithms = set(['md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512']) if certificate_or_public_key.algorithm == 'rsa': valid_hash_algorithms |= set(['raw']) if hash_algorithm not in valid_hash_algorithms: valid_hash_algorithms_error = '"md5", "sha1", "sha224", "sha256", "sha384", "sha512"' if certificate_or_public_key.algorithm == 'rsa': 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 certificate_or_public_key.algorithm == '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) )) result = Security.SecKeyRawVerify( certificate_or_public_key.sec_key_ref, SecurityConst.kSecPaddingPKCS1, data, len(data), signature, len(signature) ) # errSSLCrypto is returned in some situations on macOS 10.12 if result == SecurityConst.errSecVerifyFailed or result == SecurityConst.errSSLCrypto: raise SignatureError('Signature is invalid') handle_sec_error(result) return cf_signature = None cf_data = None cf_hash_length = None sec_transform = None try: error_pointer = new(CoreFoundation, 'CFErrorRef *') cf_signature = CFHelpers.cf_data_from_bytes(signature) sec_transform = Security.SecVerifyTransformCreate( certificate_or_public_key.sec_key_ref, cf_signature, error_pointer ) handle_cf_error(error_pointer) hash_constant = { 'md5': Security.kSecDigestMD5, 'sha1': Security.kSecDigestSHA1, 'sha224': Security.kSecDigestSHA2, 'sha256': Security.kSecDigestSHA2, 'sha384': Security.kSecDigestSHA2, 'sha512': Security.kSecDigestSHA2 }[hash_algorithm] Security.SecTransformSetAttribute( sec_transform, Security.kSecDigestTypeAttribute, hash_constant, error_pointer ) handle_cf_error(error_pointer) if hash_algorithm in set(['sha224', 'sha256', 'sha384', 'sha512']): hash_length = { 'sha224': 224, 'sha256': 256, 'sha384': 384, 'sha512': 512 }[hash_algorithm] cf_hash_length = CFHelpers.cf_number_from_integer(hash_length) Security.SecTransformSetAttribute( sec_transform, Security.kSecDigestLengthAttribute, cf_hash_length, error_pointer ) handle_cf_error(error_pointer) if certificate_or_public_key.algorithm == 'rsa': Security.SecTransformSetAttribute( sec_transform, Security.kSecPaddingKey, Security.kSecPaddingPKCS1Key, error_pointer ) handle_cf_error(error_pointer) cf_data = CFHelpers.cf_data_from_bytes(data) Security.SecTransformSetAttribute( sec_transform, Security.kSecTransformInputAttributeName, cf_data, error_pointer ) handle_cf_error(error_pointer) res = Security.SecTransformExecute(sec_transform, error_pointer) if not is_null(error_pointer): error = unwrap(error_pointer) if not is_null(error): raise SignatureError('Signature is invalid') res = bool(CoreFoundation.CFBooleanGetValue(res)) if not res: raise SignatureError('Signature is invalid') finally: if sec_transform: CoreFoundation.CFRelease(sec_transform) if cf_signature: CoreFoundation.CFRelease(cf_signature) if cf_data: CoreFoundation.CFRelease(cf_data) if cf_hash_length: CoreFoundation.CFRelease(cf_hash_length) 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('The key specified is not an RSA private key') 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 """ 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(data, byte_cls): raise TypeError(pretty_message( ''' data must be a byte string, not %s ''', type_name(data) )) pk_algo = private_key.algorithm if pk_algo != 'rsa' and pk_algo != 'rsassa_pss': raise ValueError('The key specified is not an RSA private key') hash_length = { 'sha1': 20, 'sha224': 28, 'sha256': 32, 'sha384': 48, 'sha512': 64 }.get(hash_algorithm, 0) encoded_data = add_pss_padding(hash_algorithm, hash_length, private_key.bit_size, data) key_length = private_key.byte_size buffer = buffer_from_bytes(key_length) output_length = new(Security, 'size_t *', key_length) result = Security.SecKeyDecrypt( private_key.sec_key_ref, SecurityConst.kSecPaddingNone, encoded_data, len(encoded_data), buffer, output_length ) handle_sec_error(result) return bytes_from_buffer(buffer, deref(output_length)) 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('The key specified is not a DSA private key') 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('The key specified is not an EC private key') return _sign(private_key, data, hash_algorithm) def _sign(private_key, data, hash_algorithm): """ 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" :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) )) valid_hash_algorithms = set(['md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512']) if private_key.algorithm == 'rsa': valid_hash_algorithms |= set(['raw']) if hash_algorithm not in valid_hash_algorithms: valid_hash_algorithms_error = '"md5", "sha1", "sha224", "sha256", "sha384", "sha512"' if private_key.algorithm == 'rsa': 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 private_key.algorithm == '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) )) key_length = private_key.byte_size buffer = buffer_from_bytes(key_length) output_length = new(Security, 'size_t *', key_length) result = Security.SecKeyRawSign( private_key.sec_key_ref, SecurityConst.kSecPaddingPKCS1, data, len(data), buffer, output_length ) handle_sec_error(result) return bytes_from_buffer(buffer, deref(output_length)) cf_signature = None cf_data = None cf_hash_length = None sec_transform = None try: error_pointer = new(CoreFoundation, 'CFErrorRef *') sec_transform = Security.SecSignTransformCreate(private_key.sec_key_ref, error_pointer) handle_cf_error(error_pointer) hash_constant = { 'md5': Security.kSecDigestMD5, 'sha1': Security.kSecDigestSHA1, 'sha224': Security.kSecDigestSHA2, 'sha256': Security.kSecDigestSHA2, 'sha384': Security.kSecDigestSHA2, 'sha512': Security.kSecDigestSHA2 }[hash_algorithm] Security.SecTransformSetAttribute( sec_transform, Security.kSecDigestTypeAttribute, hash_constant, error_pointer ) handle_cf_error(error_pointer) if hash_algorithm in set(['sha224', 'sha256', 'sha384', 'sha512']): hash_length = { 'sha224': 224, 'sha256': 256, 'sha384': 384, 'sha512': 512 }[hash_algorithm] cf_hash_length = CFHelpers.cf_number_from_integer(hash_length) Security.SecTransformSetAttribute( sec_transform, Security.kSecDigestLengthAttribute, cf_hash_length, error_pointer ) handle_cf_error(error_pointer) if private_key.algorithm == 'rsa': Security.SecTransformSetAttribute( sec_transform, Security.kSecPaddingKey, Security.kSecPaddingPKCS1Key, error_pointer ) handle_cf_error(error_pointer) cf_data = CFHelpers.cf_data_from_bytes(data) Security.SecTransformSetAttribute( sec_transform, Security.kSecTransformInputAttributeName, cf_data, error_pointer ) handle_cf_error(error_pointer) cf_signature = Security.SecTransformExecute(sec_transform, error_pointer) handle_cf_error(error_pointer) return CFHelpers.cf_data_to_bytes(cf_signature) finally: if sec_transform: CoreFoundation.CFRelease(sec_transform) if cf_signature: CoreFoundation.CFRelease(cf_signature) if cf_data: CoreFoundation.CFRelease(cf_data) if cf_hash_length: CoreFoundation.CFRelease(cf_hash_length) _mac/symmetric.py000064400000052235147205106110010035 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from .._errors import pretty_message from .._ffi import new, null from ._core_foundation import CoreFoundation, CFHelpers, handle_cf_error from ._security import Security 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 the OS crypto library :return: A tuple of two byte strings (iv, ciphertext) """ 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 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(Security.kSecAttrKeyTypeAES, key, data, iv, Security.kSecPaddingNoneKey)) 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 the OS crypto library :return: A byte string of the plaintext """ 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(iv) != 16: raise ValueError(pretty_message( ''' iv must be 16 bytes long - is %s ''', len(iv) )) return _decrypt(Security.kSecAttrKeyTypeAES, key, data, iv, Security.kSecPaddingNoneKey) 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 the OS crypto library :return: A tuple of two byte strings (iv, ciphertext) """ 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 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(Security.kSecAttrKeyTypeAES, key, data, iv, Security.kSecPaddingPKCS7Key)) 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 the OS crypto library :return: A byte string of the plaintext """ 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(iv) != 16: raise ValueError(pretty_message( ''' iv must be 16 bytes long - is %s ''', len(iv) )) return _decrypt(Security.kSecAttrKeyTypeAES, key, data, iv, Security.kSecPaddingPKCS7Key) 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 the OS crypto library :return: A byte string of the ciphertext """ 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(Security.kSecAttrKeyTypeRC4, 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 the OS crypto library :return: A byte string of the plaintext """ 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(Security.kSecAttrKeyTypeRC4, key, data, None, None) def rc2_cbc_pkcs5_encrypt(key, data, iv): """ Encrypts plaintext using RC2 with a 64 bit key :param key: The encryption key - a byte string 8 bytes long :param data: The plaintext - a byte string :param iv: The 8-byte initialization vector to use - a byte string - set as None to generate an appropriate one :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 tuple of two byte strings (iv, ciphertext) """ 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(Security.kSecAttrKeyTypeRC2, key, data, iv, Security.kSecPaddingPKCS5Key)) def rc2_cbc_pkcs5_decrypt(key, data, iv): """ Decrypts RC2 ciphertext using a 64 bit key :param key: The encryption key - a byte string 8 bytes long :param data: The ciphertext - a byte string :param iv: The initialization vector used for encryption - 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 the OS crypto library :return: A byte string of the plaintext """ 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(Security.kSecAttrKeyTypeRC2, key, data, iv, Security.kSecPaddingPKCS5Key) def tripledes_cbc_pkcs5_encrypt(key, data, iv): """ Encrypts plaintext using 3DES in either 2 or 3 key mode :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 8-byte initialization vector to use - a byte string - set as None to generate an appropriate one :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 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) )) # Expand 2-key to actual 24 byte byte string used by cipher if len(key) == 16: key = key + key[0:8] return (iv, _encrypt(Security.kSecAttrKeyType3DES, key, data, iv, Security.kSecPaddingPKCS5Key)) def tripledes_cbc_pkcs5_decrypt(key, data, iv): """ Decrypts 3DES ciphertext in either 2 or 3 key mode :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 used for encryption - 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 the OS crypto library :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) )) # Expand 2-key to actual 24 byte byte string used by cipher if len(key) == 16: key = key + key[0:8] return _decrypt(Security.kSecAttrKeyType3DES, key, data, iv, Security.kSecPaddingPKCS5Key) def des_cbc_pkcs5_encrypt(key, data, iv): """ Encrypts plaintext using DES with a 56 bit key :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 8-byte initialization vector to use - a byte string - set as None to generate an appropriate one :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 tuple of two byte strings (iv, ciphertext) """ 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(Security.kSecAttrKeyTypeDES, key, data, iv, Security.kSecPaddingPKCS5Key)) def des_cbc_pkcs5_decrypt(key, data, iv): """ Decrypts DES ciphertext using a 56 bit key :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 used for encryption - 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 the OS crypto library :return: A byte string of the plaintext """ 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(Security.kSecAttrKeyTypeDES, key, data, iv, Security.kSecPaddingPKCS5Key) def _encrypt(cipher, key, data, iv, padding): """ Encrypts plaintext :param cipher: A kSecAttrKeyType* value that specifies the cipher to use :param key: The encryption key - a byte string 5-16 bytes long :param data: The plaintext - a byte string :param iv: The initialization vector - a byte string - unused for RC4 :param padding: The padding mode to use, specified as a kSecPadding*Key value - 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 the OS crypto library :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 != Security.kSecAttrKeyTypeRC4 and not isinstance(iv, byte_cls): raise TypeError(pretty_message( ''' iv must be a byte string, not %s ''', type_name(iv) )) if cipher != Security.kSecAttrKeyTypeRC4 and not padding: raise ValueError('padding must be specified') cf_dict = None cf_key = None cf_data = None cf_iv = None sec_key = None sec_transform = None try: cf_dict = CFHelpers.cf_dictionary_from_pairs([(Security.kSecAttrKeyType, cipher)]) cf_key = CFHelpers.cf_data_from_bytes(key) cf_data = CFHelpers.cf_data_from_bytes(data) error_pointer = new(CoreFoundation, 'CFErrorRef *') sec_key = Security.SecKeyCreateFromData(cf_dict, cf_key, error_pointer) handle_cf_error(error_pointer) sec_transform = Security.SecEncryptTransformCreate(sec_key, error_pointer) handle_cf_error(error_pointer) if cipher != Security.kSecAttrKeyTypeRC4: Security.SecTransformSetAttribute(sec_transform, Security.kSecModeCBCKey, null(), error_pointer) handle_cf_error(error_pointer) Security.SecTransformSetAttribute(sec_transform, Security.kSecPaddingKey, padding, error_pointer) handle_cf_error(error_pointer) cf_iv = CFHelpers.cf_data_from_bytes(iv) Security.SecTransformSetAttribute(sec_transform, Security.kSecIVKey, cf_iv, error_pointer) handle_cf_error(error_pointer) Security.SecTransformSetAttribute( sec_transform, Security.kSecTransformInputAttributeName, cf_data, error_pointer ) handle_cf_error(error_pointer) ciphertext = Security.SecTransformExecute(sec_transform, error_pointer) handle_cf_error(error_pointer) return CFHelpers.cf_data_to_bytes(ciphertext) finally: if cf_dict: CoreFoundation.CFRelease(cf_dict) if cf_key: CoreFoundation.CFRelease(cf_key) if cf_data: CoreFoundation.CFRelease(cf_data) if cf_iv: CoreFoundation.CFRelease(cf_iv) if sec_key: CoreFoundation.CFRelease(sec_key) if sec_transform: CoreFoundation.CFRelease(sec_transform) def _decrypt(cipher, key, data, iv, padding): """ Decrypts AES/RC4/RC2/3DES/DES ciphertext :param cipher: A kSecAttrKeyType* value that specifies the cipher to use :param key: The encryption key - a byte string 5-16 bytes long :param data: The ciphertext - a byte string :param iv: The initialization vector - a byte string - unused for RC4 :param padding: The padding mode to use, specified as a kSecPadding*Key value - 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 the OS crypto library :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 != Security.kSecAttrKeyTypeRC4 and not isinstance(iv, byte_cls): raise TypeError(pretty_message( ''' iv must be a byte string, not %s ''', type_name(iv) )) if cipher != Security.kSecAttrKeyTypeRC4 and not padding: raise ValueError('padding must be specified') cf_dict = None cf_key = None cf_data = None cf_iv = None sec_key = None sec_transform = None try: cf_dict = CFHelpers.cf_dictionary_from_pairs([(Security.kSecAttrKeyType, cipher)]) cf_key = CFHelpers.cf_data_from_bytes(key) cf_data = CFHelpers.cf_data_from_bytes(data) error_pointer = new(CoreFoundation, 'CFErrorRef *') sec_key = Security.SecKeyCreateFromData(cf_dict, cf_key, error_pointer) handle_cf_error(error_pointer) sec_transform = Security.SecDecryptTransformCreate(sec_key, error_pointer) handle_cf_error(error_pointer) if cipher != Security.kSecAttrKeyTypeRC4: Security.SecTransformSetAttribute(sec_transform, Security.kSecModeCBCKey, null(), error_pointer) handle_cf_error(error_pointer) Security.SecTransformSetAttribute(sec_transform, Security.kSecPaddingKey, padding, error_pointer) handle_cf_error(error_pointer) cf_iv = CFHelpers.cf_data_from_bytes(iv) Security.SecTransformSetAttribute(sec_transform, Security.kSecIVKey, cf_iv, error_pointer) handle_cf_error(error_pointer) Security.SecTransformSetAttribute( sec_transform, Security.kSecTransformInputAttributeName, cf_data, error_pointer ) handle_cf_error(error_pointer) plaintext = Security.SecTransformExecute(sec_transform, error_pointer) handle_cf_error(error_pointer) return CFHelpers.cf_data_to_bytes(plaintext) finally: if cf_dict: CoreFoundation.CFRelease(cf_dict) if cf_key: CoreFoundation.CFRelease(cf_key) if cf_data: CoreFoundation.CFRelease(cf_data) if cf_iv: CoreFoundation.CFRelease(cf_iv) if sec_key: CoreFoundation.CFRelease(sec_key) if sec_transform: CoreFoundation.CFRelease(sec_transform) _mac/tls.py000064400000147625147205106110006633 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import datetime import sys import re import socket as socket_ import select import numbers import errno import weakref from ._security import Security, osx_version_info, handle_sec_error, SecurityConst from ._core_foundation import CoreFoundation, handle_cf_error, CFHelpers from .._asn1 import ( Certificate as Asn1Certificate, int_to_bytes, timezone, ) from .._errors import pretty_message from .._ffi import ( array_from_pointer, array_set, buffer_from_bytes, bytes_from_buffer, callback, cast, deref, new, null, pointer_set, struct, struct_bytes, unwrap, write_to_buffer, ) from .._types import type_name, str_cls, byte_cls, int_types from .._cipher_suites import CIPHER_SUITE_MAP from .util import rand_bytes from ..errors import TLSError, TLSDisconnectError, TLSGracefulDisconnectError from .._tls import ( detect_client_auth_request, detect_other_protocol, 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_lifetime_too_long, raise_no_issuer, raise_protocol_error, raise_protocol_version, raise_revoked, raise_self_signed, raise_verification, raise_weak_signature, ) from .asymmetric import load_certificate, Certificate from ..keys import parse_certificate 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', ] _PROTOCOL_STRING_CONST_MAP = { 'SSLv2': SecurityConst.kSSLProtocol2, 'SSLv3': SecurityConst.kSSLProtocol3, 'TLSv1': SecurityConst.kTLSProtocol1, 'TLSv1.1': SecurityConst.kTLSProtocol11, 'TLSv1.2': SecurityConst.kTLSProtocol12, } _PROTOCOL_CONST_STRING_MAP = { SecurityConst.kSSLProtocol2: 'SSLv2', SecurityConst.kSSLProtocol3: 'SSLv3', SecurityConst.kTLSProtocol1: 'TLSv1', SecurityConst.kTLSProtocol11: 'TLSv1.1', SecurityConst.kTLSProtocol12: 'TLSv1.2', } _line_regex = re.compile(b'(\r\n|\r|\n)') _cipher_blacklist_regex = re.compile('anon|PSK|SEED|RC4|MD5|NULL|CAMELLIA|ARIA|SRP|KRB5|EXPORT|(? 0.0: read_ready, _, _ = select.select([socket], [], [], timeout) if len(read_ready) == 0: raise socket_.error(errno.EAGAIN, 'timed out') chunk = socket.recv(bytes_requested - len(data)) data += chunk if chunk == b'': if len(data) == 0: if timeout is None: return SecurityConst.errSSLClosedNoNotify return SecurityConst.errSSLClosedAbort break except (socket_.error) as e: error = e.errno if error is not None and error != errno.EAGAIN: if error == errno.ECONNRESET or error == errno.EPIPE: return SecurityConst.errSSLClosedNoNotify return SecurityConst.errSSLClosedAbort if self and not self._done_handshake: # SecureTransport doesn't bother to check if the TLS record header # is valid before asking to read more data, which can result in # connection hangs. Here we do basic checks to get around the issue. if len(data) >= 3 and len(self._server_hello) == 0: # Check to ensure it is an alert or handshake first valid_record_type = data[0:1] in set([b'\x15', b'\x16']) # Check if the protocol version is SSL 3.0 or TLS 1.0-1.3 valid_protocol_version = data[1:3] in set([ b'\x03\x00', b'\x03\x01', b'\x03\x02', b'\x03\x03', b'\x03\x04' ]) if not valid_record_type or not valid_protocol_version: self._server_hello += data + _read_remaining(socket) return SecurityConst.errSSLProtocol self._server_hello += data write_to_buffer(data_buffer, data) pointer_set(data_length_pointer, len(data)) if len(data) != bytes_requested: return SecurityConst.errSSLWouldBlock return 0 except (KeyboardInterrupt) as e: if self: self._exception = e return SecurityConst.errSSLClosedAbort def _read_remaining(socket): """ Reads everything available from the socket - used for debugging when there is a protocol error :param socket: The socket to read from :return: A byte string of the remaining data """ output = b'' old_timeout = socket.gettimeout() try: socket.settimeout(0.0) output += socket.recv(8192) except (socket_.error): pass finally: socket.settimeout(old_timeout) return output def _write_callback(connection_id, data_buffer, data_length_pointer): """ Callback called by Secure Transport to actually write to the socket :param connection_id: An integer identifying the connection :param data_buffer: A char pointer FFI type containing the data to write :param data_length_pointer: A size_t pointer FFI type of the amount of data to write. Will be overwritten with the amount of data actually written on return. :return: An integer status code of the result - 0 for success """ try: self = _connection_refs.get(connection_id) if not self: socket = _socket_refs.get(connection_id) else: socket = self._socket if not self and not socket: return 0 data_length = deref(data_length_pointer) data = bytes_from_buffer(data_buffer, data_length) if self and not self._done_handshake: self._client_hello += data error = None try: sent = socket.send(data) except (socket_.error) as e: error = e.errno if error is not None and error != errno.EAGAIN: if error == errno.ECONNRESET or error == errno.EPIPE: return SecurityConst.errSSLClosedNoNotify return SecurityConst.errSSLClosedAbort if sent != data_length: pointer_set(data_length_pointer, sent) return SecurityConst.errSSLWouldBlock return 0 except (KeyboardInterrupt) as e: self._exception = e return SecurityConst.errSSLPeerUserCancelled _read_callback_pointer = callback(Security, 'SSLReadFunc', _read_callback) _write_callback_pointer = callback(Security, 'SSLWriteFunc', _write_callback) 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 _peer_id = 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) )) unsupported_protocols = protocol - set(['SSLv3', 'TLSv1', 'TLSv1.1', 'TLSv1.2']) 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) self._peer_id = rand_bytes(8) class TLSSocket(object): """ A wrapper around a socket.socket that adds TLS """ _socket = None _session = None _exception = None _session_context = None _decrypted_bytes = None _hostname = None _certificate = None _intermediates = None _protocol = None _cipher_suite = None _compression = None _session_id = None _session_ticket = None _done_handshake = None _server_hello = None _client_hello = None _local_closed = False _gracefully_closed = False _connection_id = None @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._done_handshake = False self._server_hello = b'' self._client_hello = 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 """ session_context = None ssl_policy_ref = None crl_search_ref = None crl_policy_ref = None ocsp_search_ref = None ocsp_policy_ref = None policy_array_ref = None trust_ref = None try: if osx_version_info < (10, 8): session_context_pointer = new(Security, 'SSLContextRef *') result = Security.SSLNewContext(False, session_context_pointer) handle_sec_error(result) session_context = unwrap(session_context_pointer) else: session_context = Security.SSLCreateContext( null(), SecurityConst.kSSLClientSide, SecurityConst.kSSLStreamType ) result = Security.SSLSetIOFuncs( session_context, _read_callback_pointer, _write_callback_pointer ) handle_sec_error(result) self._connection_id = id(self) % 2147483647 _connection_refs[self._connection_id] = self _socket_refs[self._connection_id] = self._socket result = Security.SSLSetConnection(session_context, self._connection_id) handle_sec_error(result) utf8_domain = self._hostname.encode('utf-8') result = Security.SSLSetPeerDomainName( session_context, utf8_domain, len(utf8_domain) ) handle_sec_error(result) if osx_version_info >= (10, 10): disable_auto_validation = self._session._manual_validation or self._session._extra_trust_roots explicit_validation = (not self._session._manual_validation) and self._session._extra_trust_roots else: disable_auto_validation = True explicit_validation = not self._session._manual_validation # Ensure requested protocol support is set for the session if osx_version_info < (10, 8): for protocol in ['SSLv2', 'SSLv3', 'TLSv1']: protocol_const = _PROTOCOL_STRING_CONST_MAP[protocol] enabled = protocol in self._session._protocols result = Security.SSLSetProtocolVersionEnabled( session_context, protocol_const, enabled ) handle_sec_error(result) if disable_auto_validation: result = Security.SSLSetEnableCertVerify(session_context, False) handle_sec_error(result) else: protocol_consts = [_PROTOCOL_STRING_CONST_MAP[protocol] for protocol in self._session._protocols] min_protocol = min(protocol_consts) max_protocol = max(protocol_consts) result = Security.SSLSetProtocolVersionMin( session_context, min_protocol ) handle_sec_error(result) result = Security.SSLSetProtocolVersionMax( session_context, max_protocol ) handle_sec_error(result) if disable_auto_validation: result = Security.SSLSetSessionOption( session_context, SecurityConst.kSSLSessionOptionBreakOnServerAuth, True ) handle_sec_error(result) # Disable all sorts of bad cipher suites supported_ciphers_pointer = new(Security, 'size_t *') result = Security.SSLGetNumberSupportedCiphers(session_context, supported_ciphers_pointer) handle_sec_error(result) supported_ciphers = deref(supported_ciphers_pointer) cipher_buffer = buffer_from_bytes(supported_ciphers * 4) supported_cipher_suites_pointer = cast(Security, 'uint32_t *', cipher_buffer) result = Security.SSLGetSupportedCiphers( session_context, supported_cipher_suites_pointer, supported_ciphers_pointer ) handle_sec_error(result) supported_ciphers = deref(supported_ciphers_pointer) supported_cipher_suites = array_from_pointer( Security, 'uint32_t', supported_cipher_suites_pointer, supported_ciphers ) good_ciphers = [] for supported_cipher_suite in supported_cipher_suites: cipher_suite = int_to_bytes(supported_cipher_suite, width=2) cipher_suite_name = CIPHER_SUITE_MAP.get(cipher_suite, cipher_suite) good_cipher = _cipher_blacklist_regex.search(cipher_suite_name) is None if good_cipher: good_ciphers.append(supported_cipher_suite) num_good_ciphers = len(good_ciphers) good_ciphers_array = new(Security, 'uint32_t[]', num_good_ciphers) array_set(good_ciphers_array, good_ciphers) good_ciphers_pointer = cast(Security, 'uint32_t *', good_ciphers_array) result = Security.SSLSetEnabledCiphers( session_context, good_ciphers_pointer, num_good_ciphers ) handle_sec_error(result) # Set a peer id from the session to allow for session reuse, the hostname # is appended to prevent a bug on OS X 10.7 where it tries to reuse a # connection even if the hostnames are different. peer_id = self._session._peer_id + self._hostname.encode('utf-8') result = Security.SSLSetPeerID(session_context, peer_id, len(peer_id)) handle_sec_error(result) handshake_result = Security.SSLHandshake(session_context) if self._exception is not None: exception = self._exception self._exception = None raise exception while handshake_result == SecurityConst.errSSLWouldBlock: handshake_result = Security.SSLHandshake(session_context) if self._exception is not None: exception = self._exception self._exception = None raise exception if osx_version_info < (10, 8) and osx_version_info >= (10, 7): do_validation = explicit_validation and handshake_result == 0 else: do_validation = explicit_validation and handshake_result == SecurityConst.errSSLServerAuthCompleted if do_validation: trust_ref_pointer = new(Security, 'SecTrustRef *') result = Security.SSLCopyPeerTrust( session_context, trust_ref_pointer ) handle_sec_error(result) trust_ref = unwrap(trust_ref_pointer) cf_string_hostname = CFHelpers.cf_string_from_unicode(self._hostname) ssl_policy_ref = Security.SecPolicyCreateSSL(True, cf_string_hostname) result = CoreFoundation.CFRelease(cf_string_hostname) handle_cf_error(result) # Create a new policy for OCSP checking to disable it ocsp_oid_pointer = struct(Security, 'CSSM_OID') ocsp_oid = unwrap(ocsp_oid_pointer) ocsp_oid.Length = len(SecurityConst.APPLE_TP_REVOCATION_OCSP) ocsp_oid_buffer = buffer_from_bytes(SecurityConst.APPLE_TP_REVOCATION_OCSP) ocsp_oid.Data = cast(Security, 'char *', ocsp_oid_buffer) ocsp_search_ref_pointer = new(Security, 'SecPolicySearchRef *') result = Security.SecPolicySearchCreate( SecurityConst.CSSM_CERT_X_509v3, ocsp_oid_pointer, null(), ocsp_search_ref_pointer ) handle_sec_error(result) ocsp_search_ref = unwrap(ocsp_search_ref_pointer) ocsp_policy_ref_pointer = new(Security, 'SecPolicyRef *') result = Security.SecPolicySearchCopyNext(ocsp_search_ref, ocsp_policy_ref_pointer) handle_sec_error(result) ocsp_policy_ref = unwrap(ocsp_policy_ref_pointer) ocsp_struct_pointer = struct(Security, 'CSSM_APPLE_TP_OCSP_OPTIONS') ocsp_struct = unwrap(ocsp_struct_pointer) ocsp_struct.Version = SecurityConst.CSSM_APPLE_TP_OCSP_OPTS_VERSION ocsp_struct.Flags = ( SecurityConst.CSSM_TP_ACTION_OCSP_DISABLE_NET | SecurityConst.CSSM_TP_ACTION_OCSP_CACHE_READ_DISABLE ) ocsp_struct_bytes = struct_bytes(ocsp_struct_pointer) cssm_data_pointer = struct(Security, 'CSSM_DATA') cssm_data = unwrap(cssm_data_pointer) cssm_data.Length = len(ocsp_struct_bytes) ocsp_struct_buffer = buffer_from_bytes(ocsp_struct_bytes) cssm_data.Data = cast(Security, 'char *', ocsp_struct_buffer) result = Security.SecPolicySetValue(ocsp_policy_ref, cssm_data_pointer) handle_sec_error(result) # Create a new policy for CRL checking to disable it crl_oid_pointer = struct(Security, 'CSSM_OID') crl_oid = unwrap(crl_oid_pointer) crl_oid.Length = len(SecurityConst.APPLE_TP_REVOCATION_CRL) crl_oid_buffer = buffer_from_bytes(SecurityConst.APPLE_TP_REVOCATION_CRL) crl_oid.Data = cast(Security, 'char *', crl_oid_buffer) crl_search_ref_pointer = new(Security, 'SecPolicySearchRef *') result = Security.SecPolicySearchCreate( SecurityConst.CSSM_CERT_X_509v3, crl_oid_pointer, null(), crl_search_ref_pointer ) handle_sec_error(result) crl_search_ref = unwrap(crl_search_ref_pointer) crl_policy_ref_pointer = new(Security, 'SecPolicyRef *') result = Security.SecPolicySearchCopyNext(crl_search_ref, crl_policy_ref_pointer) handle_sec_error(result) crl_policy_ref = unwrap(crl_policy_ref_pointer) crl_struct_pointer = struct(Security, 'CSSM_APPLE_TP_CRL_OPTIONS') crl_struct = unwrap(crl_struct_pointer) crl_struct.Version = SecurityConst.CSSM_APPLE_TP_CRL_OPTS_VERSION crl_struct.CrlFlags = 0 crl_struct_bytes = struct_bytes(crl_struct_pointer) cssm_data_pointer = struct(Security, 'CSSM_DATA') cssm_data = unwrap(cssm_data_pointer) cssm_data.Length = len(crl_struct_bytes) crl_struct_buffer = buffer_from_bytes(crl_struct_bytes) cssm_data.Data = cast(Security, 'char *', crl_struct_buffer) result = Security.SecPolicySetValue(crl_policy_ref, cssm_data_pointer) handle_sec_error(result) policy_array_ref = CFHelpers.cf_array_from_list([ ssl_policy_ref, crl_policy_ref, ocsp_policy_ref ]) result = Security.SecTrustSetPolicies(trust_ref, policy_array_ref) handle_sec_error(result) if self._session._extra_trust_roots: ca_cert_refs = [] ca_certs = [] for cert in self._session._extra_trust_roots: ca_cert = load_certificate(cert) ca_certs.append(ca_cert) ca_cert_refs.append(ca_cert.sec_certificate_ref) result = Security.SecTrustSetAnchorCertificatesOnly(trust_ref, False) handle_sec_error(result) array_ref = CFHelpers.cf_array_from_list(ca_cert_refs) result = Security.SecTrustSetAnchorCertificates(trust_ref, array_ref) handle_sec_error(result) result_pointer = new(Security, 'SecTrustResultType *') result = Security.SecTrustEvaluate(trust_ref, result_pointer) handle_sec_error(result) trust_result_code = deref(result_pointer) invalid_chain_error_codes = set([ SecurityConst.kSecTrustResultProceed, SecurityConst.kSecTrustResultUnspecified ]) if trust_result_code not in invalid_chain_error_codes: handshake_result = SecurityConst.errSSLXCertChainInvalid else: handshake_result = Security.SSLHandshake(session_context) while handshake_result == SecurityConst.errSSLWouldBlock: handshake_result = Security.SSLHandshake(session_context) self._done_handshake = True handshake_error_codes = set([ SecurityConst.errSSLXCertChainInvalid, SecurityConst.errSSLCertExpired, SecurityConst.errSSLCertNotYetValid, SecurityConst.errSSLUnknownRootCert, SecurityConst.errSSLNoRootCert, SecurityConst.errSSLHostNameMismatch, SecurityConst.errSSLInternal, ]) # In testing, only errSSLXCertChainInvalid was ever returned for # all of these different situations, however we include the others # for completeness. To get the real reason we have to use the # certificate from the handshake and use the deprecated function # SecTrustGetCssmResultCode(). if handshake_result in handshake_error_codes: if trust_ref: CoreFoundation.CFRelease(trust_ref) trust_ref = None trust_ref_pointer = new(Security, 'SecTrustRef *') result = Security.SSLCopyPeerTrust( session_context, trust_ref_pointer ) handle_sec_error(result) trust_ref = unwrap(trust_ref_pointer) result_code_pointer = new(Security, 'OSStatus *') result = Security.SecTrustGetCssmResultCode(trust_ref, result_code_pointer) result_code = deref(result_code_pointer) chain = extract_chain(self._server_hello) self_signed = False revoked = False expired = False not_yet_valid = False no_issuer = False cert = None bad_hostname = False if chain: cert = chain[0] oscrypto_cert = load_certificate(cert) self_signed = oscrypto_cert.self_signed revoked = result_code == SecurityConst.CSSMERR_TP_CERT_REVOKED no_issuer = not self_signed and result_code == SecurityConst.CSSMERR_TP_NOT_TRUSTED expired = result_code == SecurityConst.CSSMERR_TP_CERT_EXPIRED not_yet_valid = result_code == SecurityConst.CSSMERR_TP_CERT_NOT_VALID_YET bad_hostname = result_code == SecurityConst.CSSMERR_APPLETP_HOSTNAME_MISMATCH validity_too_long = result_code == SecurityConst.CSSMERR_TP_CERT_SUSPENDED # On macOS 10.12, some expired certificates return errSSLInternal if osx_version_info >= (10, 12): validity = cert['tbs_certificate']['validity'] not_before = validity['not_before'].chosen.native not_after = validity['not_after'].chosen.native utcnow = datetime.datetime.now(timezone.utc) expired = not_after < utcnow not_yet_valid = not_before > utcnow if chain and chain[0].hash_algo in set(['md5', 'md2']): raise_weak_signature(chain[0]) if revoked: raise_revoked(cert) if bad_hostname: raise_hostname(cert, self._hostname) elif expired or not_yet_valid: raise_expired_not_yet_valid(cert) elif no_issuer: raise_no_issuer(cert) elif self_signed: raise_self_signed(cert) elif validity_too_long: raise_lifetime_too_long(cert) if detect_client_auth_request(self._server_hello): raise_client_auth() raise_verification(cert) if handshake_result == SecurityConst.errSSLPeerHandshakeFail: if detect_client_auth_request(self._server_hello): raise_client_auth() raise_handshake() if handshake_result == SecurityConst.errSSLWeakPeerEphemeralDHKey: raise_dh_params() if handshake_result == SecurityConst.errSSLPeerProtocolVersion: raise_protocol_version() if handshake_result in set([SecurityConst.errSSLRecordOverflow, SecurityConst.errSSLProtocol]): self._server_hello += _read_remaining(self._socket) raise_protocol_error(self._server_hello) if handshake_result in set([SecurityConst.errSSLClosedNoNotify, SecurityConst.errSSLClosedAbort]): if not self._done_handshake: self._server_hello += _read_remaining(self._socket) if detect_other_protocol(self._server_hello): raise_protocol_error(self._server_hello) raise_disconnection() if osx_version_info < (10, 10): dh_params_length = get_dh_params_length(self._server_hello) if dh_params_length is not None and dh_params_length < 1024: raise_dh_params() would_block = handshake_result == SecurityConst.errSSLWouldBlock server_auth_complete = handshake_result == SecurityConst.errSSLServerAuthCompleted manual_validation = self._session._manual_validation and server_auth_complete if not would_block and not manual_validation: handle_sec_error(handshake_result, TLSError) self._session_context = session_context protocol_const_pointer = new(Security, 'SSLProtocol *') result = Security.SSLGetNegotiatedProtocolVersion( session_context, protocol_const_pointer ) handle_sec_error(result) protocol_const = deref(protocol_const_pointer) self._protocol = _PROTOCOL_CONST_STRING_MAP[protocol_const] cipher_int_pointer = new(Security, 'SSLCipherSuite *') result = Security.SSLGetNegotiatedCipher( session_context, cipher_int_pointer ) handle_sec_error(result) cipher_int = deref(cipher_int_pointer) cipher_bytes = int_to_bytes(cipher_int, width=2) self._cipher_suite = CIPHER_SUITE_MAP.get(cipher_bytes, cipher_bytes) session_info = parse_session_info( self._server_hello, self._client_hello ) self._compression = session_info['compression'] self._session_id = session_info['session_id'] self._session_ticket = session_info['session_ticket'] except (OSError, socket_.error): if session_context: if osx_version_info < (10, 8): result = Security.SSLDisposeContext(session_context) handle_sec_error(result) else: result = CoreFoundation.CFRelease(session_context) handle_cf_error(result) self._session_context = None self.close() raise finally: # Trying to release crl_search_ref or ocsp_search_ref results in # a segmentation fault, so we do not do that if ssl_policy_ref: result = CoreFoundation.CFRelease(ssl_policy_ref) handle_cf_error(result) ssl_policy_ref = None if crl_policy_ref: result = CoreFoundation.CFRelease(crl_policy_ref) handle_cf_error(result) crl_policy_ref = None if ocsp_policy_ref: result = CoreFoundation.CFRelease(ocsp_policy_ref) handle_cf_error(result) ocsp_policy_ref = None if policy_array_ref: result = CoreFoundation.CFRelease(policy_array_ref) handle_cf_error(result) policy_array_ref = None if trust_ref: CoreFoundation.CFRelease(trust_ref) trust_ref = None 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 oscrypto.errors.TLSDisconnectError - when the connection disconnects oscrypto.errors.TLSGracefulDisconnectError - when the remote end gracefully closed the connection 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) )) if self._session_context is None: # Even if the session is closed, we can use # buffered data to respond to read requests if self._decrypted_bytes != b'': output = self._decrypted_bytes self._decrypted_bytes = b'' return output self._raise_closed() 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 # 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 = max_length - len(self._decrypted_bytes) read_buffer = buffer_from_bytes(to_read) processed_pointer = new(Security, 'size_t *') result = Security.SSLRead( self._session_context, read_buffer, to_read, processed_pointer ) if self._exception is not None: exception = self._exception self._exception = None raise exception if result and result not in set([SecurityConst.errSSLWouldBlock, SecurityConst.errSSLClosedGraceful]): handle_sec_error(result, TLSError) if result and result == SecurityConst.errSSLClosedGraceful: self._gracefully_closed = True self._shutdown(False) self._raise_closed() bytes_read = deref(processed_pointer) output = self._decrypted_bytes + bytes_from_buffer(read_buffer, bytes_read) 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: to_read = self._os_buffered_size() 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 _os_buffered_size(self): """ Returns the number of bytes of decrypted data stored in the Secure Transport read buffer. This amount of data can be read from SSLRead() without calling self._socket.recv(). :return: An integer - the number of available bytes """ num_bytes_pointer = new(Security, 'size_t *') result = Security.SSLGetBufferedReadSize( self._session_context, num_bytes_pointer ) handle_sec_error(result) return deref(num_bytes_pointer) 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 oscrypto.errors.TLSDisconnectError - when the connection disconnects oscrypto.errors.TLSGracefulDisconnectError - when the remote end gracefully closed the connection 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 self._session_context is None: self._raise_closed() processed_pointer = new(Security, 'size_t *') data_len = len(data) while data_len: write_buffer = buffer_from_bytes(data) result = Security.SSLWrite( self._session_context, write_buffer, data_len, processed_pointer ) if self._exception is not None: exception = self._exception self._exception = None raise exception handle_sec_error(result, TLSError) bytes_written = deref(processed_pointer) data = data[bytes_written:] data_len = len(data) if data_len > 0: self.select_write() 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._session_context is None: return # Ignore error during close in case other end closed already result = Security.SSLClose(self._session_context) if osx_version_info < (10, 8): result = Security.SSLDisposeContext(self._session_context) handle_sec_error(result) else: result = CoreFoundation.CFRelease(self._session_context) handle_cf_error(result) self._session_context = None if manual: self._local_closed = True 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 if self._connection_id in _socket_refs: del _socket_refs[self._connection_id] def _read_certificates(self): """ Reads end-entity and intermediate certificate information from the TLS session """ trust_ref = None cf_data_ref = None result = None try: trust_ref_pointer = new(Security, 'SecTrustRef *') result = Security.SSLCopyPeerTrust( self._session_context, trust_ref_pointer ) handle_sec_error(result) trust_ref = unwrap(trust_ref_pointer) number_certs = Security.SecTrustGetCertificateCount(trust_ref) self._intermediates = [] for index in range(0, number_certs): sec_certificate_ref = Security.SecTrustGetCertificateAtIndex( trust_ref, index ) cf_data_ref = Security.SecCertificateCopyData(sec_certificate_ref) cert_data = CFHelpers.cf_data_to_bytes(cf_data_ref) result = CoreFoundation.CFRelease(cf_data_ref) handle_cf_error(result) cf_data_ref = None cert = Asn1Certificate.load(cert_data) if index == 0: self._certificate = cert else: self._intermediates.append(cert) finally: if trust_ref: result = CoreFoundation.CFRelease(trust_ref) handle_cf_error(result) if cf_data_ref: result = CoreFoundation.CFRelease(cf_data_ref) handle_cf_error(result) 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._session_context 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._session_context 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._session_context is None: self._raise_closed() return self._socket def __del__(self): self.close() _mac/trust_list.py000064400000016542147205106110010236 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import hashlib import sys from .._asn1 import Certificate from .._ffi import new, unwrap from ._core_foundation import CoreFoundation, CFHelpers from ._security import Security, SecurityConst, handle_sec_error if sys.version_info < (3,): range = xrange # noqa __all__ = [ 'extract_from_system', 'system_path', ] def system_path(): return None def extract_from_system(cert_callback=None, callback_only_on_failure=False): """ Extracts trusted CA certificates from the OS X trusted root keychain. :param cert_callback: A callback that is called once for each certificate in the trust store. It should accept two parameters: an asn1crypto.x509.Certificate object, and a reason. The reason will be None if the certificate is being exported, otherwise it will be a unicode string of the reason it won't. :param callback_only_on_failure: A boolean - if the callback should only be called when a certificate is not exported. :raises: OSError - when an error is returned by the OS crypto library :return: A list of 3-element tuples: - 0: a byte string of a DER-encoded certificate - 1: a set of unicode strings that are OIDs of purposes to trust the certificate for - 2: a set of unicode strings that are OIDs of purposes to reject the certificate for """ certs_pointer_pointer = new(CoreFoundation, 'CFArrayRef *') res = Security.SecTrustCopyAnchorCertificates(certs_pointer_pointer) handle_sec_error(res) certs_pointer = unwrap(certs_pointer_pointer) certificates = {} trust_info = {} all_purposes = '2.5.29.37.0' default_trust = (set(), set()) length = CoreFoundation.CFArrayGetCount(certs_pointer) for index in range(0, length): cert_pointer = CoreFoundation.CFArrayGetValueAtIndex(certs_pointer, index) der_cert, cert_hash = _cert_details(cert_pointer) certificates[cert_hash] = der_cert CoreFoundation.CFRelease(certs_pointer) for domain in [SecurityConst.kSecTrustSettingsDomainUser, SecurityConst.kSecTrustSettingsDomainAdmin]: cert_trust_settings_pointer_pointer = new(CoreFoundation, 'CFArrayRef *') res = Security.SecTrustSettingsCopyCertificates(domain, cert_trust_settings_pointer_pointer) if res == SecurityConst.errSecNoTrustSettings: continue handle_sec_error(res) cert_trust_settings_pointer = unwrap(cert_trust_settings_pointer_pointer) length = CoreFoundation.CFArrayGetCount(cert_trust_settings_pointer) for index in range(0, length): cert_pointer = CoreFoundation.CFArrayGetValueAtIndex(cert_trust_settings_pointer, index) trust_settings_pointer_pointer = new(CoreFoundation, 'CFArrayRef *') res = Security.SecTrustSettingsCopyTrustSettings(cert_pointer, domain, trust_settings_pointer_pointer) # In OS X 10.11, this value started being seen. From the comments in # the Security Framework Reference, the lack of any settings should # indicate "always trust this certificate" if res == SecurityConst.errSecItemNotFound: continue # If the trust settings for a certificate are invalid, we need to # assume the certificate should not be trusted if res == SecurityConst.errSecInvalidTrustSettings: der_cert, cert_hash = _cert_details(cert_pointer) if cert_hash in certificates: _cert_callback( cert_callback, certificates[cert_hash], 'invalid trust settings' ) del certificates[cert_hash] continue handle_sec_error(res) trust_settings_pointer = unwrap(trust_settings_pointer_pointer) trust_oids = set() reject_oids = set() settings_length = CoreFoundation.CFArrayGetCount(trust_settings_pointer) for settings_index in range(0, settings_length): settings_dict_entry = CoreFoundation.CFArrayGetValueAtIndex(trust_settings_pointer, settings_index) settings_dict = CFHelpers.cf_dictionary_to_dict(settings_dict_entry) # No policy OID means the trust result is for all purposes policy_oid = settings_dict.get('kSecTrustSettingsPolicy', {}).get('SecPolicyOid', all_purposes) # 0 = kSecTrustSettingsResultInvalid # 1 = kSecTrustSettingsResultTrustRoot # 2 = kSecTrustSettingsResultTrustAsRoot # 3 = kSecTrustSettingsResultDeny # 4 = kSecTrustSettingsResultUnspecified trust_result = settings_dict.get('kSecTrustSettingsResult', 1) should_trust = trust_result != 0 and trust_result != 3 if should_trust: trust_oids.add(policy_oid) else: reject_oids.add(policy_oid) der_cert, cert_hash = _cert_details(cert_pointer) # If rejected for all purposes, we don't export the certificate if all_purposes in reject_oids: if cert_hash in certificates: _cert_callback( cert_callback, certificates[cert_hash], 'explicitly distrusted' ) del certificates[cert_hash] else: if all_purposes in trust_oids: trust_oids = set([all_purposes]) trust_info[cert_hash] = (trust_oids, reject_oids) CoreFoundation.CFRelease(trust_settings_pointer) CoreFoundation.CFRelease(cert_trust_settings_pointer) output = [] for cert_hash in certificates: if not callback_only_on_failure: _cert_callback(cert_callback, certificates[cert_hash], None) cert_trust_info = trust_info.get(cert_hash, default_trust) output.append((certificates[cert_hash], cert_trust_info[0], cert_trust_info[1])) return output def _cert_callback(callback, der_cert, reason): """ Constructs an asn1crypto.x509.Certificate object and calls the export callback :param callback: The callback to call :param der_cert: A byte string of the DER-encoded certificate :param reason: None if cert is being exported, or a unicode string of the reason it is not being exported """ if not callback: return callback(Certificate.load(der_cert), reason) def _cert_details(cert_pointer): """ Return the certificate and a hash of it :param cert_pointer: A SecCertificateRef :return: A 2-element tuple: - [0]: A byte string of the SHA1 hash of the cert - [1]: A byte string of the DER-encoded contents of the cert """ data_pointer = None try: data_pointer = Security.SecCertificateCopyData(cert_pointer) der_cert = CFHelpers.cf_data_to_bytes(data_pointer) cert_hash = hashlib.sha1(der_cert).digest() return (der_cert, cert_hash) finally: if data_pointer is not None: CoreFoundation.CFRelease(data_pointer) _mac/util.py000064400000023454147205106110006777 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import os from .._errors import pretty_message from .._ffi import buffer_from_bytes, bytes_from_buffer, errno, byte_string_from_buffer from .._types import type_name, str_cls, byte_cls, int_types from ..errors import LibraryNotFoundError from ._common_crypto import CommonCrypto, CommonCryptoConst from ._security import Security __all__ = [ 'pbkdf2', 'pkcs12_kdf', 'rand_bytes', ] _encoding = 'utf-8' _fallback_encodings = ['utf-8', 'cp1252'] 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 _extract_error(): """ Extracts the last OS error message into a python unicode string :return: A unicode string error message """ error_num = errno() try: error_string = os.strerror(error_num) except (ValueError): return str_cls(error_num) if isinstance(error_string, str_cls): return error_string return _try_decode(error_string) 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 OSError - when an error is returned by the OS crypto library :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) )) algo = { 'sha1': CommonCryptoConst.kCCPRFHmacAlgSHA1, 'sha224': CommonCryptoConst.kCCPRFHmacAlgSHA224, 'sha256': CommonCryptoConst.kCCPRFHmacAlgSHA256, 'sha384': CommonCryptoConst.kCCPRFHmacAlgSHA384, 'sha512': CommonCryptoConst.kCCPRFHmacAlgSHA512 }[hash_algorithm] output_buffer = buffer_from_bytes(key_length) result = CommonCrypto.CCKeyDerivationPBKDF( CommonCryptoConst.kCCPBKDF2, password, len(password), salt, len(salt), algo, iterations, output_buffer, key_length ) if result != 0: raise OSError(_extract_error()) return bytes_from_buffer(output_buffer) pbkdf2.pure_python = False def rand_bytes(length): """ Returns a number of random bytes suitable for cryptographic purposes :param length: The desired number of 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 """ if not isinstance(length, int_types): raise TypeError(pretty_message( ''' length must be an integer, not %s ''', type_name(length) )) if length < 1: raise ValueError('length must be greater than 0') if length > 1024: raise ValueError('length must not be greater than 1024') buffer = buffer_from_bytes(length) result = Security.SecRandomCopyBytes(Security.kSecRandomDefault, length, buffer) if result != 0: raise OSError(_extract_error()) return bytes_from_buffer(buffer) # If in a future version of OS X they remove OpenSSL, this try/except block # will fall back to the pure Python implementation, which is just slower try: from .._openssl._libcrypto import libcrypto def _extract_openssl_error(): """ Extracts the last OpenSSL error message into a python unicode string :return: A unicode string error message """ 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) return _try_decode(error_string) 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 OSError - when an error is returned by the OS crypto library :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 ) if result != 1: raise OSError(_extract_openssl_error()) return bytes_from_buffer(output_buffer) except (LibraryNotFoundError): from .._pkcs12 import pkcs12_kdf _mac/__pycache__/__init__.cpython-38.pyc000064400000000242147205106110014035 0ustar00U af@sdS)NrrrG/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_mac/__init__.py_mac/__pycache__/_common_crypto.cpython-38.pyc000064400000001445147205106110015333 0ustar00U af@sbddlmZmZmZmZddlmZedkrs   _mac/__pycache__/_common_crypto_cffi.cpython-38.pyc000064400000001626147205106110016323 0ustar00U af@sbddlmZmZmZmZddlmZddlmZdgZ eZ e ddZ e e Zeee dS) )unicode_literalsdivisionabsolute_importprint_function) register_ffi)FFI CommonCryptoaw typedef uint32_t CCPBKDFAlgorithm; typedef uint32_t CCPseudoRandomAlgorithm; typedef unsigned int uint; int CCKeyDerivationPBKDF(CCPBKDFAlgorithm algorithm, const char *password, size_t passwordLen, const char *salt, size_t saltLen, CCPseudoRandomAlgorithm prf, uint rounds, char *derivedKey, size_t derivedKeyLen); z%/usr/lib/system/libcommonCrypto.dylibN) __future__rrrrZ_ffirZcffir__all__ffiZcdefZcommon_crypto_pathdlopenr rrR/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_mac/_common_crypto_cffi.pys    _mac/__pycache__/_common_crypto_ctypes.cpython-38.pyc000064400000001414147205106110016716 0ustar00U af @sddlmZmZmZmZddlmZmZmZm Z m Z m Z ddl m Z dgZdZeeddZz&eee ee ee ee g ej_e ej_Wnek re d YnXd S) )unicode_literalsdivisionabsolute_importprint_function)CDLLc_uint32c_char_pc_size_tc_intc_uint)FFIEngineError CommonCryptoz%/usr/lib/system/libcommonCrypto.dylibT) use_errnozError initializing ctypesN) __future__rrrrctypesrrrr r r Z_ffir __all__Zcommon_crypto_pathrZCCKeyDerivationPBKDFargtypesrestypeAttributeErrorrrT/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_mac/_common_crypto_ctypes.pys(    _mac/__pycache__/_core_foundation.cpython-38.pyc000064400000014623147205106110015623 0ustar00U af'@sddlmZmZmZmZddlmZddlmZm Z edkrPddl m Z m Z nddl m Z m Z dd d gZd d Ze e e je e e je e e je e e jd S) )unicode_literalsdivisionabsolute_importprint_function)ffi)is_nullunwrapZcffi)CoreFoundation CFHelpersr r handle_cf_errorcCst|r dSt|}t|r dSt|}t|}t|t|}t|}t|}t||dkr|dkrddddddd d d d d ddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;dd?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dddddddddddddddddddddddddddddd}||kr||}|sd||f}t |dS)z Checks a CFErrorRef and throws an exception if there is an error to report :param error_pointer: A CFErrorRef :raises: OSError - when the CFErrorRef contains an error NZNSOSStatusErrorDomainzACL add failedzACL base certs not supportedzACL challenge callback failedzACL change failedzACL delete failedzACL entry tag not foundzACL replace failedzACL subject type not supportedzAlgid mismatchzAlready logged inz!Apple add application ACL subjectzApple invalid key end datezApple invalid key start datezApple public key incompletezApple signature mismatchzApple SSLv2 rollbackzAttach handle busyzBlock size mismatchzCrypto data callback failedz Device errorz Device failedzDevice memory errorz Device resetzDevice verify failedzFunction failedzFunction not implementedzInput length errorz"Insufficient client identificationzInternal errorzInvalid access credentialszInvalid ACL base certszInvalid ACL challenge callbackzInvalid ACL edit modezInvalid ACL entry tagzInvalid ACL subject valuezInvalid algorithmzInvalid attr access credentialszInvalid attr alg paramszInvalid attr basezInvalid attr block sizezInvalid attr dl db handlezInvalid attr effective bitszInvalid attr end datezInvalid attr init vectorzInvalid attr iteration countzInvalid attr keyzInvalid attr key lengthzInvalid attr key typezInvalid attr labelzInvalid attr modezInvalid attr output sizezInvalid attr paddingzInvalid attr passphrasezInvalid attr primezInvalid attr private key formatzInvalid attr public key formatzInvalid attr randomzInvalid attr roundszInvalid attr saltzInvalid attr seedzInvalid attr start datezInvalid attr subprimez!Invalid attr symmetric key formatzInvalid attr versionzInvalid attr wrapped key formatzInvalid contextzInvalid context handlezInvalid crypto dataz Invalid datazInvalid data countzInvalid digest algorithmzInvalid input pointerzInvalid input vectorz Invalid keyzInvalid keyattr maskzInvalid keyusage maskzInvalid key classzInvalid key formatzInvalid key labelzInvalid key pointerzInvalid key referencezInvalid login namezInvalid new ACL entryzInvalid new ACL ownerzInvalid output pointerzInvalid output vectorzInvalid passthrough idzInvalid pointerzInvalid sample valuezInvalid signaturezKey blob type incorrectzKey header inconsistentzKey label already existszKey usage incorrectz Mds errorz Memory errorzMissing attr access credentialszMissing attr alg paramszMissing attr basezMissing attr block sizezMissing attr dl db handlezMissing attr effective bitszMissing attr end datezMissing attr init vectorzMissing attr iteration countzMissing attr keyzMissing attr key lengthzMissing attr key typezMissing attr labelzMissing attr modezMissing attr output sizezMissing attr paddingzMissing attr passphrasezMissing attr primezMissing attr private key formatzMissing attr public key formatzMissing attr randomzMissing attr roundszMissing attr saltzMissing attr seedzMissing attr start datezMissing attr subprimez!Missing attr symmetric key formatzMissing attr versionzMissing attr wrapped key formatz Not logged inzNo user interactionzObject ACL not supportedzObject ACL requiredzObject manip auth deniedzObject use auth deniedzOperation auth deniedzOS access deniedzOutput length errorzPrivate key already existszPrivate key not foundzPrivilege not grantedzPrivilege not supportedzPublic key inconsistentzQuery size unknownzSample value not supportedzSelf check failedzService not availablezStaged operation in progresszStaged operation not startedzUnsupported keyattr maskzUnsupported keyusage maskzUnsupported key formatzUnsupported key labelzUnsupported key sizez User canceledzVector of bufs unsupportedz Verify failed)i6i'i-i1i4i/i5i+i iR i i i i i i i iM iV i ii iiP i ii iii%i&i,i0i.i*i1 i ih iz iF i ip it i8 i~ i6 iD il ij in id i< iB ix i i i> if i: i@ ir i| i iv i i0 i@iXiFi( iU ii* i i i i i i i i iQ i2i3ii+ iVii(iK i i iT i iii ii i{ iG i iq iu i9 i i7 iE im ik io ie i= iC iy i i i? ig i; iA is i} i iw i i ii#i$i"i!i i i iS iN iKi iO iL i)iiiH iI i i i i i ii) iJ z%s %s) rr r ZCFErrorGetDomainr cf_string_to_unicodeZ CFReleaseZCFErrorGetCodeZCFErrorCopyDescriptionOSError)Z error_pointererrorZcf_string_domaindomainnumZ cf_string_refoutputZcode_maprO/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_mac/_core_foundation.pyr s^            N) __future__rrrrrZ_ffirr Z_core_foundation_cffir r Z_core_foundation_ctypesZ_all__r Zregister_native_mappingZCFStringGetTypeIDrZCFNumberGetTypeIDZcf_number_to_numberZCFDataGetTypeIDZcf_data_to_bytesZCFDictionaryGetTypeIDZcf_dictionary_to_dictrrrrs6  B_mac/__pycache__/_core_foundation_cffi.cpython-38.pyc000064400000023364147205106110016614 0ustar00U af*@sddlmZmZmZmZddlmZmZmZm Z m Z m Z ddl m Z ddgZe ZeddZeeZe eed Zd ZGd ddZd S) )unicode_literalsdivisionabsolute_importprint_function)buffer_from_bytesbyte_string_from_bufferderefis_nullnew register_ffi)FFI CFHelpersCoreFoundationa typedef bool Boolean; typedef long CFIndex; typedef unsigned long CFStringEncoding; typedef unsigned long CFNumberType; typedef unsigned long CFTypeID; typedef void *CFTypeRef; typedef CFTypeRef CFArrayRef; typedef CFTypeRef CFDataRef; typedef CFTypeRef CFStringRef; typedef CFTypeRef CFNumberRef; typedef CFTypeRef CFBooleanRef; typedef CFTypeRef CFDictionaryRef; typedef CFTypeRef CFErrorRef; typedef CFTypeRef CFAllocatorRef; typedef struct { CFIndex version; void *retain; void *release; void *copyDescription; void *equal; void *hash; } CFDictionaryKeyCallBacks; typedef struct { CFIndex version; void *retain; void *release; void *copyDescription; void *equal; } CFDictionaryValueCallBacks; typedef struct { CFIndex version; void *retain; void *release; void *copyDescription; void *equal; } CFArrayCallBacks; CFIndex CFDataGetLength(CFDataRef theData); const char *CFDataGetBytePtr(CFDataRef theData); CFDataRef CFDataCreate(CFAllocatorRef allocator, const char *bytes, CFIndex length); CFDictionaryRef CFDictionaryCreate(CFAllocatorRef allocator, const void **keys, const void **values, CFIndex numValues, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks); CFIndex CFDictionaryGetCount(CFDictionaryRef theDict); const char *CFStringGetCStringPtr(CFStringRef theString, CFStringEncoding encoding); Boolean CFStringGetCString(CFStringRef theString, char *buffer, CFIndex bufferSize, CFStringEncoding encoding); CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding); CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr); CFStringRef CFCopyTypeIDDescription(CFTypeID type_id); void CFRelease(CFTypeRef cf); void CFRetain(CFTypeRef cf); CFStringRef CFErrorCopyDescription(CFErrorRef err); CFStringRef CFErrorGetDomain(CFErrorRef err); CFIndex CFErrorGetCode(CFErrorRef err); Boolean CFBooleanGetValue(CFBooleanRef boolean); CFTypeID CFDictionaryGetTypeID(void); CFTypeID CFNumberGetTypeID(void); CFTypeID CFStringGetTypeID(void); CFTypeID CFDataGetTypeID(void); CFArrayRef CFArrayCreate(CFAllocatorRef allocator, const void **values, CFIndex numValues, const CFArrayCallBacks *callBacks); CFIndex CFArrayGetCount(CFArrayRef theArray); CFTypeRef CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx); CFNumberType CFNumberGetType(CFNumberRef number); Boolean CFNumberGetValue(CFNumberRef number, CFNumberType theType, void *valuePtr); CFIndex CFDictionaryGetKeysAndValues(CFDictionaryRef theDict, const void **keys, const void **values); CFTypeID CFGetTypeID(CFTypeRef cf); extern CFAllocatorRef kCFAllocatorDefault; extern CFArrayCallBacks kCFTypeArrayCallBacks; extern CFBooleanRef kCFBooleanTrue; extern CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks; extern CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks; zB/System/Library/Frameworks/CoreFoundation.framework/CoreFoundationic@seZdZdZiZeddZeddZeddZ edd Z ed d Z ed d Z eddZ eddZeddZeddZeddZdS)rz/ Namespace for core foundation helpers cCs||jt|<dS)z Register a function to convert a core foundation data type into its equivalent in python :param type_id: The CFTypeId for the type :param callback: A callback to pass the CFType object to N) _native_mapint)clstype_idcallbackrT/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_mac/_core_foundation_cffi.pyregister_native_mappings z!CFHelpers.register_native_mappingcCsXt|}ddddddddd d d ddd d dd |}tt|d }t|||t|S)z Converts a CFNumber object to a python float or integer :param value: The CFNumber object :return: A python number (float or integer) Zint8_tZin16_tZint32_tZint64_tfloatdoublecharshortrlongz long long)r rz *)rZCFNumberGetTyper ZCFNumberGetValuer )valuetype_Z type_name_outputrrrcf_number_to_numbers. zCFHelpers.cf_number_to_numbercCsht|}ttd|}ttd|}t|||i}td|D] }t|||t||<qB|S)z Converts a CFDictionary object into a python dictionary :param dictionary: The CFDictionary to convert :return: A python dict z CFTypeRef[%s]r)rZCFDictionaryGetCountr ZCFDictionaryGetKeysAndValuesrangernative) dictionaryZ dict_lengthkeysvaluesr.indexrrrcf_dictionary_to_dicts zCFHelpers.cf_dictionary_to_dictcCs*t|}||jkr"|j||S|SdS)z Converts a CF* object into its python equivalent :param value: The CF* object to convert :return: The native python object N)rZ CFGetTypeIDr)rr,rrrrr1s  zCFHelpers.nativecCslt|t}t|rdnt|}|dkrVtd}t||dt}|sNtdt |}|dk rh| d}|S)z Creates a python unicode string from a CFString object :param value: The CFString to convert :return: A python unicode string Niz'Error copying C string from CFStringRefutf-8) rZCFStringGetCStringPtrkCFStringEncodingUTF8r ffistringrZCFStringGetCStringOSErrorrdecode)r,Z string_ptrr:bufferresultrrrcf_string_to_unicodes&  zCFHelpers.cf_string_to_unicodecCsttj|dtS)z Creates a CFStringRef object from a unicode string :param string: The unicode string to create the CFString object from :return: A CFStringRef r7)rZCFStringCreateWithCStringkCFAllocatorDefaultencoder8)r:rrrcf_string_from_unicodes z CFHelpers.cf_string_from_unicodecCs(t|}t|}t||ddS)z Extracts a bytestring from a CFData object :param value: A CFData object :return: A byte string N)rZCFDataGetBytePtrZCFDataGetLengthr9r=)r,start num_bytesrrrcf_data_to_bytess  zCFHelpers.cf_data_to_bytescCsttj|t|S)z Creates a CFDataRef object from a byte string :param bytes_: The data to create the CFData object from :return: A CFDataRef )rZ CFDataCreater@len)bytes_rrrcf_data_from_bytes"s zCFHelpers.cf_data_from_bytesc Cs\t|}g}g}|D] }|\}}||||qttj|||ttjttjS)a7 Creates a CFDictionaryRef object from a list of 2-element tuples representing the key and value. Each key should be a CFStringRef and each value some sort of CF* type. :param pairs: A list of 2-element tuples :return: A CFDictionaryRef ) rFappendrZCFDictionaryCreater@r9 addressofZkCFTypeDictionaryKeyCallBacksZkCFTypeDictionaryValueCallBacks)pairslengthr3r4pairkeyr,rrrcf_dictionary_from_pairs4s    z"CFHelpers.cf_dictionary_from_pairscCs"t|}ttj||ttjS)z Creates a CFArrayRef object from a list of CF* type objects. :param values: A list of CF* type object :return: A CFArrayRef )rFrZ CFArrayCreater@r9rJZkCFTypeArrayCallBacks)r4rLrrrcf_array_from_listRs  zCFHelpers.cf_array_from_listcCstd|}ttjt|S)z Creates a CFNumber object from an integer :param integer: The integer to create the CFNumber for :return: A CFNumber zlong *)r9r rZCFNumberCreater@kCFNumberCFIndexType)integerZinteger_as_longrrrcf_number_from_integerfs z CFHelpers.cf_number_from_integerN)__name__ __module__ __qualname____doc__r classmethodr staticmethodr/r6r1r?rBrErHrOrPrSrrrrrys0  "        N) __future__rrrrZ_ffirrr r r r Zcffir __all__r9ZcdefZcore_foundation_pathdlopenrrQr8rrrrrs  Y  _mac/__pycache__/_core_foundation_ctypes.cpython-38.pyc000064400000021417147205106110017211 0ustar00U af4@sddlmZmZmZmZddlmZmZmZm Z m Z m Z m Z ddlm Z mZmZmZmZddlZddlmZmZmZddgZd Ze ed d ZeZeZeZeZeZeZeZeZ eZ!e Z"eZ#eZ$ee!Z%eeZ&eeZ'eeZ(eeZ)ee#Z*eeZ+ee Z,eZ-eZ.eZ/eZ0eeZ1z`e'gej2_3eej2_4e'gej5_3eej5_4e-e egej6_3e'ej6_4e-e(e%ee.e/gej7_3e+ej7_4e+gej8_3eej8_4e(egej9_3e ej9_4e(e eegej:_3e ej:_4e-e egej;_3e(ej;_4e-e$egej<_3e)ej<_4e"gej=_3e(ej=_4e%gej>_3dej>_4e%gej?_3dej?_4e,gej@_3e(ej@_4e,gejA_3e(ejA_4e,gejB_3eejB_4e*gejC_3e ejC_4gejD_3e"ejD_4gejE_3e"ejE_4gejF_3e"ejF_4gejG_3e"ejG_4e-eeee0gejH_3e&ejH_4e&gejI_3eejI_4e&egejJ_3e%ejJ_4e)gejK_3e$ejK_4e)e$egejL_3e ejL_4e+e1e1gejM_3eejM_4e%gejN_3e"ejN_4eOed e-Ped eOed e%Ped ePedZQePedZRePedZSWneTk redYnXeOede'eOede,eOede&e$dZUedZVddZWGdddZXdS))unicode_literalsdivisionabsolute_importprint_function)c_void_pc_longc_uint32c_char_pc_bytec_ulongc_bool)CDLL string_atcastPOINTERbyrefN)FFIEngineErrorbuffer_from_bytesbyte_string_from_buffer CFHelpersCoreFoundationzB/System/Library/Frameworks/CoreFoundation.framework/CoreFoundationT) use_errnokCFAllocatorDefaultZkCFBooleanTruekCFTypeDictionaryKeyCallBackskCFTypeDictionaryValueCallBackskCFTypeArrayCallBackszError initializing ctypes CFDataRef CFErrorRef CFArrayReficCs t|tS)z Casts a value to a pointer of a pointer :param value: A ctypes object :return: A POINTER(c_void_p) object )r pointer_p)valuer#V/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_mac/_core_foundation_ctypes.py_cast_pointer_ps r%c@seZdZdZiZeddZeddZeddZ edd Z ed d Z ed d Z eddZ eddZeddZeddZeddZdS)rz/ Namespace for core foundation helpers cCs||jt|<dS)z Register a function to convert a core foundation data type into its equivalent in python :param type_id: The CFTypeId for the type :param callback: A callback to pass the CFType object to N) _native_mapint)clstype_idcallbackr#r#r$register_native_mappings z!CFHelpers.register_native_mappingcCsttt|}ttjtjtjtjtj ttjtj t tj tjtj t tj tj d|}|d}t t||t||jS)z Converts a CFNumber object to a python float or integer :param value: The CFNumber object :return: A python number (float or integer) )r r r)rCFNumberGetTyper%r ctypesc_shortc_int32c_int64c_floatc_doublec_intr c_longlongCFNumberGetValuerr")r"type_Zc_typeoutputr#r#r$cf_number_to_numbers. zCFHelpers.cf_number_to_numbercCsht|}t|}t|}t|t|t|i}td|D] }t|||t||<qB|S)z Converts a CFDictionary object into a python dictionary :param dictionary: The CFDictionary to convert :return: A python dict r)rCFDictionaryGetCount CFTypeRefCFDictionaryGetKeysAndValuesr%rangernative) dictionaryZ dict_lengthkeysvaluesrEindexr#r#r$cf_dictionary_to_dict s   zCFHelpers.cf_dictionary_to_dictcCs*t|}||jkr"|j||S|SdS)z Converts a CF* object into its python equivalent :param value: The CF* object to convert :return: The native python object N)r CFGetTypeIDr&)r(r"r)r#r#r$rK<s  zCFHelpers.nativecCs^tt|t}|dkrHtd}tt||dt}|s@tdt|}|dk rZ|d}|S)z Creates a python unicode string from a CFString object :param value: The CFString to convert :return: A python unicode string Niz'Error copying C string from CFStringRefutf-8) rCFStringGetCStringPtrr%kCFStringEncodingUTF8rCFStringGetCStringOSErrorrdecode)r"stringbufferresultr#r#r$cf_string_to_unicodeNs$  zCFHelpers.cf_string_to_unicodecCsttj|dtS)z Creates a CFStringRef object from a unicode string :param string: The unicode string to create the CFString object from :return: A CFStringRef rR)rCFStringCreateWithCStringrencoderT)rXr#r#r$cf_string_from_unicodems z CFHelpers.cf_string_from_unicodecCst|}t|}t||S)z Extracts a bytestring from a CFData object :param value: A CFData object :return: A byte string )rCFDataGetBytePtrCFDataGetLengthr)r"start num_bytesr#r#r$cf_data_to_bytess  zCFHelpers.cf_data_to_bytescCsttj|t|S)z Creates a CFDataRef object from a byte string :param bytes_: The data to create the CFData object from :return: A CFDataRef )r CFDataCreaterlen)bytes_r#r#r$cf_data_from_bytess zCFHelpers.cf_data_from_bytescCstt|}g}g}|D] }|\}}||||qt||}t||}ttjtt|tt||t t S)a7 Creates a CFDictionaryRef object from a list of 2-element tuples representing the key and value. Each key should be a CFStringRef and each value some sort of CF* type. :param pairs: A list of 2-element tuples :return: A CFDictionaryRef ) reappend CFStringRefrHrCFDictionaryCreaterr%rrr)pairslengthrMrNpairkeyr"r#r#r$cf_dictionary_from_pairss"      z"CFHelpers.cf_dictionary_from_pairscCs.t|}t||}ttjtt||tS)z Creates a CFArrayRef object from a list of CF* type objects. :param values: A list of CF* type object :return: A CFArrayRef )rerHr CFArrayCreaterr%rr)rNrlr#r#r$cf_array_from_lists   zCFHelpers.cf_array_from_listcCst|}ttjtt|S)z Creates a CFNumber object from an integer :param integer: The integer to create the CFNumber for :return: A CFNumber )rrCFNumberCreaterkCFNumberCFIndexTyper)integerZinteger_as_longr#r#r$cf_number_from_integers z CFHelpers.cf_number_from_integerN)__name__ __module__ __qualname____doc__r& classmethodr+ staticmethodrFrPrKr[r^rcrgrorqrur#r#r#r$rs0  "        )Y __future__rrrrr;rrrr r r r r rrrrZ_ffirrr__all__Zcore_foundation_pathrZCFIndexZCFStringEncodingZCFArrayZCFDataZCFStringZCFNumberZ CFDictionaryZCFErrorZCFTypeZCFTypeIDZ CFBooleanZ CFNumberTyperHrrriZ CFNumberRefZ CFBooleanRefZCFDictionaryRefrZCFAllocatorRefZCFDictionaryKeyCallBacksZCFDictionaryValueCallBacksZCFArrayCallBacksr!r`argtypesrestyper_rdrjrGrSrUr\rrZCFCopyTypeIDDescriptionZ CFReleaseZCFRetainZCFErrorCopyDescriptionZCFErrorGetDomainZCFErrorGetCodeZCFBooleanGetValueZCFDictionaryGetTypeIDZCFNumberGetTypeIDZCFStringGetTypeIDZCFDataGetTypeIDrpZCFArrayGetCountZCFArrayGetValueAtIndexr:rCrIrQsetattrin_dllrrrAttributeErrorrsrTr%rr#r#r#r$s*$      _mac/__pycache__/_security.cpython-38.pyc000064400000007756147205106110014325 0ustar00U afZ@sddlmZmZmZmZddlmZddlmZddl m Z m Z edkrlddl m Z mZdd lmZmZn ddlm Z mZdd lmZmZd d d d gZddd ZddZee eGdd d ZdS))unicode_literalsdivisionabsolute_importprint_function)ffi)null)TLSDisconnectErrorTLSGracefulDisconnectErrorZcffi)Security version_info)CoreFoundation CFHelpershandle_sec_errorosx_version_infor SecurityConstNcCs|dkr dS|ttjtjgkr(td|tjkr:tdt|t }t |}t ||dksl|dkrtd|}|dkrt}||dS)a< Checks a Security OSStatus error code and throws an exception if there is an error to report :param error: An OSStatus :param exception_class: The exception class to use for the exception if an error occurred :raises: OSError - when the OSStatus contains an error rNz$The remote end closed the connectionz OSStatus %s)setrerrSSLClosedNoNotifyerrSSLClosedAbortr errSSLClosedGracefulr r ZSecCopyErrorMessageStringrrZcf_string_to_unicoderZ CFReleaseOSError)errorZexception_classZcf_error_stringoutputrH/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_mac/_security.pyrs   cCst|}t|S)N)r ZSecPolicyCopyPropertiesrZcf_dictionary_to_dict)valueZproperties_dictrrr_extract_policy_properties<s rc@seZdZdZdZdZdZdZdZdZ dZ dZ dZ dZ dZdZdZdZdZdZdZd Zd Zd Zd Zd ZdZdZdZdZdZdZdZ dZ!dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ*dZ+d Z,dZ-d!Z.d"Z/dZ0dZ1dZ2dZ3d#Z4d$Z5d%Z6d&Z7dZ8dZ9dZ:dZ;dZd)Z?dZ@d*ZAd+S),rrr r@iiiiiiiiiiiiiiiiiiii$i !i !i !i*!i !s *Hcds *Hcdi iQi,iR*+I N)B__name__ __module__ __qualname__ZkSecTrustSettingsDomainUserZkSecTrustSettingsDomainAdminZkSecTrustSettingsDomainSystemZkSecTrustResultProceedZkSecTrustResultUnspecifiedZkSecTrustOptionImplicitAnchorsZkSecFormatOpenSSLZkSecItemTypePrivateKeyZkSecItemTypePublicKeyZ"kSSLSessionOptionBreakOnServerAuthZ kSSLProtocol2Z kSSLProtocol3Z kTLSProtocol1ZkTLSProtocol11ZkTLSProtocol12ZkSSLClientSideZkSSLStreamTypeZerrSSLProtocolZerrSSLWouldBlockrrrZerrSSLXCertChainInvalidZ errSSLCryptoZerrSSLInternalZerrSSLCertExpiredZerrSSLCertNotYetValidZerrSSLUnknownRootCertZerrSSLNoRootCertZerrSSLHostNameMismatchZerrSSLPeerHandshakeFailZerrSSLPeerProtocolVersionZerrSSLPeerUserCancelledZerrSSLWeakPeerEphemeralDHKeyZerrSSLServerAuthCompletedZerrSSLRecordOverflowZ!CSSMERR_APPLETP_HOSTNAME_MISMATCHZCSSMERR_TP_CERT_EXPIREDZCSSMERR_TP_CERT_NOT_VALID_YETZCSSMERR_TP_CERT_REVOKEDZCSSMERR_TP_NOT_TRUSTEDZCSSMERR_TP_CERT_SUSPENDEDZCSSM_CERT_X_509v3ZAPPLE_TP_REVOCATION_CRLZAPPLE_TP_REVOCATION_OCSPZCSSM_APPLE_TP_OCSP_OPTS_VERSIONZCSSM_TP_ACTION_OCSP_DISABLE_NETZ&CSSM_TP_ACTION_OCSP_CACHE_READ_DISABLEZCSSM_APPLE_TP_CRL_OPTS_VERSIONZerrSecVerifyFailedZerrSecNoTrustSettingsZerrSecItemNotFoundZerrSecInvalidTrustSettingsZkSecPaddingNoneZkSecPaddingPKCS1ZCSSM_KEYUSE_SIGNZCSSM_KEYUSE_VERIFYZ CSSM_ALGID_DHZCSSM_ALGID_RSAZCSSM_ALGID_DSAZCSSM_ALGID_ECDSAZCSSM_KEYATTR_PERMANENTZCSSM_KEYATTR_EXTRACTABLErrrrrGs~)N) __future__rrrrrrZ_ffirerrorsr r Z_security_cffir r rZ_core_foundation_cffirrZ_security_ctypesZ_core_foundation_ctypes__all__rrZregister_native_mappingZSecPolicyGetTypeIDrrrrrs(    $_mac/__pycache__/_security_cffi.cpython-38.pyc000064400000025515147205106110015305 0ustar00U af*@sddlmZmZmZmZddlZddlmZddlm Z dddgZ e dZ e eee d Zed kred eded fe Zed edkredn eddZeeZeeedS))unicode_literalsdivisionabsolute_importprint_functionN) register_ffi)FFISecurityversion version_info.) z1Only OS X 10.7 and newer are supported, not %s.%sap$ typedef bool Boolean; typedef long CFIndex; typedef int32_t OSStatus; typedef unsigned long CFTypeID; typedef uint32_t SecTrustSettingsDomain; typedef uint32_t SecPadding; typedef uint32_t SecItemImportExportFlags; typedef uint32_t SecKeyImportExportFlags; typedef uint32_t SecExternalFormat; typedef uint32_t SecExternalItemType; typedef uint32_t CSSM_ALGORITHMS; typedef uint64_t CSSM_CC_HANDLE; typedef uint32_t CSSM_KEYUSE; typedef uint32_t CSSM_CERT_TYPE; typedef uint32_t SSLProtocol; typedef uint32_t SSLCipherSuite; typedef uint32_t SecTrustResultType; typedef void *CFTypeRef; typedef CFTypeRef CFArrayRef; typedef CFTypeRef CFDataRef; typedef CFTypeRef CFStringRef; typedef CFTypeRef CFDictionaryRef; typedef CFTypeRef CFErrorRef; typedef CFTypeRef CFAllocatorRef; typedef ... *SecKeyRef; typedef ... *SecCertificateRef; typedef ... *SecTransformRef; typedef ... *SecRandomRef; typedef ... *SecPolicyRef; typedef ... *SecPolicySearchRef; typedef ... *SecAccessRef; typedef struct { uint32_t version; SecKeyImportExportFlags flags; CFTypeRef passphrase; CFStringRef alertTitle; CFStringRef alertPrompt; SecAccessRef accessRef; CFArrayRef keyUsage; CFArrayRef keyAttributes; } SecItemImportExportKeyParameters; typedef ... *SecKeychainRef; typedef ... *SSLContextRef; typedef ... *SecTrustRef; typedef uint32_t SSLConnectionRef; typedef struct { uint32_t Length; char *Data; } CSSM_DATA, CSSM_OID; typedef struct { uint32_t Version; uint32_t Flags; CSSM_DATA *LocalResponder; CSSM_DATA *LocalResponderCert; } CSSM_APPLE_TP_OCSP_OPTIONS; typedef struct { uint32_t Version; uint32_t CrlFlags; void *crlStore; } CSSM_APPLE_TP_CRL_OPTIONS; OSStatus SecKeychainCreate(char *path, uint32_t pass_len, void *pass, Boolean prompt, SecAccessRef initialAccess, SecKeychainRef *keychain); OSStatus SecKeychainDelete(SecKeychainRef keychain); int SecRandomCopyBytes(SecRandomRef rnd, size_t count, char *bytes); SecKeyRef SecKeyCreateFromData(CFDictionaryRef parameters, CFDataRef keyData, CFErrorRef *error); SecTransformRef SecEncryptTransformCreate(SecKeyRef keyRef, CFErrorRef *error); SecTransformRef SecDecryptTransformCreate(SecKeyRef keyRef, CFErrorRef *error); Boolean SecTransformSetAttribute(SecTransformRef transformRef, CFStringRef key, CFTypeRef value, CFErrorRef *error); CFTypeRef SecTransformExecute(SecTransformRef transformRef, CFErrorRef *errorRef); SecTransformRef SecVerifyTransformCreate(SecKeyRef key, CFDataRef signature, CFErrorRef *error); SecTransformRef SecSignTransformCreate(SecKeyRef key, CFErrorRef *error); SecCertificateRef SecCertificateCreateWithData(CFAllocatorRef allocator, CFDataRef data); OSStatus SecCertificateCopyPublicKey(SecCertificateRef certificate, SecKeyRef *key); CFStringRef SecCopyErrorMessageString(OSStatus status, void *reserved); OSStatus SecTrustCopyAnchorCertificates(CFArrayRef *anchors); CFDataRef SecCertificateCopyData(SecCertificateRef certificate); OSStatus SecTrustSettingsCopyCertificates(SecTrustSettingsDomain domain, CFArrayRef *certArray); OSStatus SecTrustSettingsCopyTrustSettings(SecCertificateRef certRef, SecTrustSettingsDomain domain, CFArrayRef *trustSettings); CFDictionaryRef SecPolicyCopyProperties(SecPolicyRef policyRef); CFTypeID SecPolicyGetTypeID(void); OSStatus SecKeyEncrypt(SecKeyRef key, SecPadding padding, const char *plainText, size_t plainTextLen, char *cipherText, size_t *cipherTextLen); OSStatus SecKeyDecrypt(SecKeyRef key, SecPadding padding, const char *cipherText, size_t cipherTextLen, char *plainText, size_t *plainTextLen); OSStatus SecKeyRawSign(SecKeyRef key, SecPadding padding, const char *dataToSign, size_t dataToSignLen, char *sig, size_t * sigLen); OSStatus SecKeyRawVerify(SecKeyRef key, SecPadding padding, const char *signedData, size_t signedDataLen, const char *sig, size_t sigLen); OSStatus SecItemImport(CFDataRef importedData, CFStringRef fileNameOrExtension, SecExternalFormat *inputFormat, SecExternalItemType *itemType, SecItemImportExportFlags flags, const SecItemImportExportKeyParameters *keyParams, SecKeychainRef importKeychain, CFArrayRef *outItems); OSStatus SecItemExport(CFTypeRef secItemOrArray, SecExternalFormat outputFormat, SecItemImportExportFlags flags, const SecItemImportExportKeyParameters *keyParams, CFDataRef *exportedData); OSStatus SecAccessCreate(CFStringRef descriptor, CFArrayRef trustedlist, SecAccessRef *accessRef); OSStatus SecKeyCreatePair(SecKeychainRef keychainRef, CSSM_ALGORITHMS algorithm, uint32_t keySizeInBits, CSSM_CC_HANDLE contextHandle, CSSM_KEYUSE publicKeyUsage, uint32_t publicKeyAttr, CSSM_KEYUSE privateKeyUsage, uint32_t privateKeyAttr, SecAccessRef initialAccess, SecKeyRef* publicKeyRef, SecKeyRef* privateKeyRef); OSStatus SecKeychainItemDelete(SecKeyRef itemRef); typedef OSStatus (*SSLReadFunc)(SSLConnectionRef connection, char *data, size_t *dataLength); typedef OSStatus (*SSLWriteFunc)(SSLConnectionRef connection, const char *data, size_t *dataLength); OSStatus SSLSetIOFuncs(SSLContextRef context, SSLReadFunc readFunc, SSLWriteFunc writeFunc); OSStatus SSLSetPeerID(SSLContextRef context, const char *peerID, size_t peerIDLen); OSStatus SSLSetConnection(SSLContextRef context, SSLConnectionRef connection); OSStatus SSLSetPeerDomainName(SSLContextRef context, const char *peerName, size_t peerNameLen); OSStatus SSLHandshake(SSLContextRef context); OSStatus SSLGetBufferedReadSize(SSLContextRef context, size_t *bufSize); OSStatus SSLRead(SSLContextRef context, char *data, size_t dataLength, size_t *processed); OSStatus SSLWrite(SSLContextRef context, const char *data, size_t dataLength, size_t *processed); OSStatus SSLClose(SSLContextRef context); OSStatus SSLGetNumberSupportedCiphers(SSLContextRef context, size_t *numCiphers); OSStatus SSLGetSupportedCiphers(SSLContextRef context, SSLCipherSuite *ciphers, size_t *numCiphers); OSStatus SSLSetEnabledCiphers(SSLContextRef context, const SSLCipherSuite *ciphers, size_t numCiphers); OSStatus SSLGetNumberEnabledCiphers(SSLContextRef context, size_t *numCiphers); OSStatus SSLGetEnabledCiphers(SSLContextRef context, SSLCipherSuite *ciphers, size_t *numCiphers); OSStatus SSLGetNegotiatedCipher(SSLContextRef context, SSLCipherSuite *cipherSuite); OSStatus SSLGetNegotiatedProtocolVersion(SSLContextRef context, SSLProtocol *protocol); OSStatus SSLCopyPeerTrust(SSLContextRef context, SecTrustRef *trust); OSStatus SecTrustGetCssmResultCode(SecTrustRef trust, OSStatus *resultCode); CFIndex SecTrustGetCertificateCount(SecTrustRef trust); SecCertificateRef SecTrustGetCertificateAtIndex(SecTrustRef trust, CFIndex ix); OSStatus SecTrustSetAnchorCertificates(SecTrustRef trust, CFArrayRef anchorCertificates); OSStatus SecTrustSetAnchorCertificatesOnly(SecTrustRef trust, Boolean anchorCertificatesOnly); OSStatus SecTrustSetPolicies(SecTrustRef trust, CFArrayRef policies); SecPolicyRef SecPolicyCreateSSL(Boolean server, CFStringRef hostname); OSStatus SecPolicySearchCreate(CSSM_CERT_TYPE certType, const CSSM_OID *policyOID, const CSSM_DATA *value, SecPolicySearchRef *searchRef); OSStatus SecPolicySearchCopyNext(SecPolicySearchRef searchRef, SecPolicyRef *policyRef); OSStatus SecPolicySetValue(SecPolicyRef policyRef, const CSSM_DATA *value); OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType *result); extern SecRandomRef kSecRandomDefault; extern CFStringRef kSecPaddingKey; extern CFStringRef kSecPaddingPKCS7Key; extern CFStringRef kSecPaddingPKCS5Key; extern CFStringRef kSecPaddingPKCS1Key; extern CFStringRef kSecPaddingOAEPKey; extern CFStringRef kSecPaddingNoneKey; extern CFStringRef kSecModeCBCKey; extern CFStringRef kSecTransformInputAttributeName; extern CFStringRef kSecDigestTypeAttribute; extern CFStringRef kSecDigestLengthAttribute; extern CFStringRef kSecIVKey; extern CFStringRef kSecAttrIsExtractable; extern CFStringRef kSecDigestSHA1; extern CFStringRef kSecDigestSHA2; extern CFStringRef kSecDigestMD5; extern CFStringRef kSecAttrKeyType; extern CFTypeRef kSecAttrKeyTypeRSA; extern CFTypeRef kSecAttrKeyTypeDSA; extern CFTypeRef kSecAttrKeyTypeECDSA; extern CFStringRef kSecAttrKeySizeInBits; extern CFStringRef kSecAttrLabel; extern CFTypeRef kSecAttrCanSign; extern CFTypeRef kSecAttrCanVerify; extern CFTypeRef kSecAttrKeyTypeAES; extern CFTypeRef kSecAttrKeyTypeRC4; extern CFTypeRef kSecAttrKeyTypeRC2; extern CFTypeRef kSecAttrKeyType3DES; extern CFTypeRef kSecAttrKeyTypeDES; )r aQ OSStatus SSLNewContext(Boolean isServer, SSLContextRef *contextPtr); OSStatus SSLDisposeContext(SSLContextRef context); OSStatus SSLSetEnableCertVerify(SSLContextRef context, Boolean enableVerify); OSStatus SSLSetProtocolVersionEnabled(SSLContextRef context, SSLProtocol protocol, Boolean enable); a8 typedef uint32_t SSLProtocolSide; typedef uint32_t SSLConnectionType; typedef uint32_t SSLSessionOption; SSLContextRef SSLCreateContext(CFAllocatorRef alloc, SSLProtocolSide protocolSide, SSLConnectionType connectionType); OSStatus SSLSetSessionOption(SSLContextRef context, SSLSessionOption option, Boolean value); OSStatus SSLSetProtocolVersionMin(SSLContextRef context, SSLProtocol minVersion); OSStatus SSLSetProtocolVersionMax(SSLContextRef context, SSLProtocol maxVersion); z6/System/Library/Frameworks/Security.framework/Security) __future__rrrrplatformZ_ffirZcffir__all__mac_verr tuplemapintsplitr OSErrorffiZcdefZ security_pathdlopenr rrM/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_mac/_security_cffi.pys(    ;  _mac/__pycache__/_security_ctypes.cpython-38.pyc000064400000020542147205106110015700 0ustar00U af0H @s ddlmZmZmZmZddlZddlmZmZm Z m Z m Z m Z m Z mZmZmZmZddlmZmZmZmZddlmZddd gZedZeeeedd Zed kre d eded fdZ!ee!ddZ"eZ#eZ$eZ%eZ&eZ'eZ(eZ)eZ*eZ+ee*Z,eZ-eZ.ee%Z/ee&Z0ee'Z1ee(Z2ee)Z3eeZ4eeZ5eeZ6eZ7e Z8e Z9e Z:e Z;e Ze Z?eeZ@eZAe ZBe ZCeeZDeeZEeeZFeeZGe ZHe ZIe ZJeZKe ZLGdddeZMeMZNGdddeZOGdddeZPGdddeZQ ze e ee#eDeeEge"jR_Se.e"jR_TeEge"jU_Se.e"jU_Te7e e ge"jV_Se e"jV_Te2e/ee3ge"jW_Se4e"jW_Te4ee3ge"jX_Se6e"jX_Te4ee3ge"jY_Se6e"jY_Te6e0e,ee3ge"jZ_Se#e"jZ_Te6ee3ge"j[_Se,e"j[_Te4e/ee3ge"j\_Se6e"j\_Te4ee3ge"j]_Se6e"j]_Te-e/ge"j^_Se5e"j^_Te5ee4ge"j__Se.e"j__Te.ege"j`_Se0e"j`_Tee1ge"ja_Se.e"ja_Te5ge"jb_Se/e"jb_Te8ee1ge"jc_Se.e"jc_Te5e8ee1ge"jd_Se.e"jd_Te@ge"je_Se2e"je_Tge"jf_Se+e"jf_Te4e=e e e ee ge"jg_Se.e"jg_Te4e=e e e ee ge"jh_Se.e"jh_Te4e=e e e ee ge"ji_Se.e"ji_Te4e=e e e e ge"jj_Se.e"jj_Te0e1eeDge"jk_Se.e"jk_TeEeBe eAeCe eCe eDee4ee4g e"jl_Se.e"jl_Te/e0ee;ee<e9eeQeEee1ge"jm_Se.e"jm_Te,e;e9eeQee/ge"jn_Se.e"jn_Te4ge"jo_Se.e"jo_Tee.eHee ee Zpee.eHee ee ZqeFepeqge"jr_Se.e"jr_TeFe e ge"js_Se.e"js_TeFe,e#ge"jt_Se.e"jt_TeGe1ge"ju_Se.e"ju_Te#e0ge"jv_Se@e"jv_TeLeeNeeMeeKge"jw_Se.e"jw_TeKee@ge"jx_Se.e"jx_Te@eeMge"jy_Se.e"jy_TeFeHge"jz_Se.e"jz_TeFe e ge"j{_Se.e"j{_TeFge"j|_Se.e"j|_TeFee ge"j}_Se.e"j}_TeFe e ee ge"j~_Se.e"j~_TeFe e ee ge"j_Se.e"j_TeFge"j_Se.e"j_TeFee ge"j_Se.e"j_TeFee?ee ge"j_Se.e"j_TeFee?e ge"j_Se.e"j_TeFee ge"j_e.e"j_TeFee?ee ge"j_Se.e"j_TeFee?ge"j_Se.e"j_TeFee>ge"j_Se.e"j_TeFeeGge"j_Se.e"j_TeGee.ge"j_Se.e"j_TeGge"j_Se$e"j_TeGe$ge"j_Se5e"j_TeGe1ge"j_Se.e"j_TeGe#ge"j_e.e"j_TeGeeIge"j_Se.e"j_Tedkre#eeFge"j_Se.e"j_TeFge"j_Se.e"j_TeFe#ge"j_Se.e"j_TeFe>e#ge"j_Se.e"j_Tn`e Ze Ze Ze-eege"j_SeFe"j_TeFee#ge"j_Se.e"j_TeFe>ge"j_Se.e"j_TeFe>ge"j_Se.e"j_Tee"depee"deqee"deFee"de>ee"de?ee"deGee"d eIee"d!e.ee"d"eDee"d#eEee"d$e4ee"d%eKee"d&e@ee"deMee"d'eNee"deOee"dePee"deQee"d(e7e"d(ee"d)e0e"d)ee"d*e0e"d*ee"d+e0e"d+ee"d,e0e"d,ee"d-e0e"d-ee"d.e0e"d.ee"d/e0e"d/ee"d0e0e"d0ee"d1e0e"d1ee"d2e0e"d2ee"d3e0e"d3ee"d4e0e"d4ee"d5e0e"d5ee"d6e0e"d6ee"d7e0e"d7ee"d8e0e"d8ee"d9e,e"d9ee"d:e,e"d:ee"d;e,e"d;ee"de,e"d>ee"d?e,e"d?ee"d@e,e"d@ee"dAe,e"dAee"dBe,e"dBee"dCe,e"dCee"dDe,e"dDWnek redEYnXdS)F)unicode_literalsdivisionabsolute_importprint_functionN) c_void_pc_int32c_char_pc_size_tc_bytec_intc_uint32c_uint64c_ulongc_longc_bool)CDLLPOINTER CFUNCTYPE Structure)FFIEngineErrorSecurityversion version_info.) z1Only OS X 10.7 and newer are supported, not %s.%sz6/System/Library/Frameworks/Security.framework/SecurityT) use_errnoc@seZdZdefdefgZdS) CSSM_DATAZLengthDataN)__name__ __module__ __qualname__r r_fields_r%r%O/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_mac/_security_ctypes.pyrLsrc@s0eZdZdefdefdeefdeefgZdS)CSSM_APPLE_TP_OCSP_OPTIONSVersionFlagsZLocalResponderZLocalResponderCertN)r!r"r#r rrr$r%r%r%r&r'Vs   r'c@s"eZdZdefdefdefgZdS)CSSM_APPLE_TP_CRL_OPTIONSr(ZCrlFlagsZcrlStoreN)r!r"r#r rr$r%r%r%r&r*_sr*c @s@eZdZdefdefdefdefdefdefdefdefgZ d S) SecItemImportExportKeyParametersrflagsZ passphraseZ alertTitleZ alertPromptZ accessRefZkeyUsageZ keyAttributesN) r!r"r#r SecKeyImportExportFlags CFTypeRef CFStringRef SecAccessRef CFArrayRefr$r%r%r%r&r+gsr+)r SSLReadFunc SSLWriteFunc SSLContextRef SSLProtocolSSLCipherSuite SecTrustRefSecTrustResultTypeOSStatusr0SecKeychainRef SecKeyRefSecPolicySearchRef SecPolicyRefCSSM_OIDZkSecRandomDefaultZkSecPaddingKeyZkSecPaddingPKCS7KeyZkSecPaddingPKCS5KeyZkSecPaddingPKCS1KeyZkSecPaddingOAEPKeyZkSecPaddingNoneKeyZkSecModeCBCKeyZkSecTransformInputAttributeNameZkSecDigestTypeAttributeZkSecDigestLengthAttributeZ kSecIVKeyZkSecAttrIsExtractableZkSecDigestSHA1ZkSecDigestSHA2Z kSecDigestMD5ZkSecAttrKeyTypeZkSecAttrKeyTypeRSAZkSecAttrKeyTypeDSAZkSecAttrKeyTypeECDSAZkSecAttrKeySizeInBitsZ kSecAttrLabelZkSecAttrCanSignZkSecAttrCanVerifyZkSecAttrKeyTypeAESZkSecAttrKeyTypeRC4ZkSecAttrKeyTypeRC2ZkSecAttrKeyType3DESZkSecAttrKeyTypeDESzError initializing ctypes) __future__rrrrplatformctypesrrrr r r r r rrrrrrrZ_ffir__all__mac_verrtuplemapintsplitrOSErrorZ security_pathrBooleanZCFIndexZCFDataZCFStringZCFArrayZ CFDictionaryZCFErrorZCFTypeZCFTypeIDr.ZCFAllocatorRefr:Z CFDataRefr/r1ZCFDictionaryRefZ CFErrorRefr<ZSecCertificateRefZSecTransformRefZ SecRandomRefZSecTrustSettingsDomainZSecItemImportExportFlagsr-ZSecExternalFormatZSecExternalItemTypeZ SecPaddingr6r7r>ZCSSM_CC_HANDLEZCSSM_ALGORITHMSZ CSSM_KEYUSEr0r;r5r8ZSSLConnectionRefr9ZSecTrustOptionFlagsr=ZCSSM_CERT_TYPErr?r'r*r+ZSecKeychainCreateargtypesrestypeZSecKeychainDeleteZSecRandomCopyBytesZSecKeyCreateFromDataZSecEncryptTransformCreateZSecDecryptTransformCreateZSecTransformSetAttributeZSecTransformExecuteZSecVerifyTransformCreateZSecSignTransformCreateZSecCertificateCreateWithDataZSecCertificateCopyPublicKeyZSecCopyErrorMessageStringZSecTrustCopyAnchorCertificatesZSecCertificateCopyDataZ SecTrustSettingsCopyCertificatesZ!SecTrustSettingsCopyTrustSettingsZSecPolicyCopyPropertiesZSecPolicyGetTypeIDZ SecKeyEncryptZ SecKeyDecryptZ SecKeyRawSignZSecKeyRawVerifyZSecAccessCreateZSecKeyCreatePairZ SecItemImportZ SecItemExportZSecKeychainItemDeleter3r4Z SSLSetIOFuncsZ SSLSetPeerIDZSSLSetCertificateAuthoritiesZSecTrustSetPoliciesZSecPolicyCreateSSLZSecPolicySearchCreateZSecPolicySearchCopyNextZSecPolicySetValueZSSLSetConnectionZSSLSetPeerDomainNameZ SSLHandshakeZSSLGetBufferedReadSizeZSSLReadZSSLWriteZSSLCloseZSSLGetNumberSupportedCiphersZSSLGetSupportedCiphersZSSLSetEnabledCiphersZSSLGetNumberEnabledCiphersZargtypeZSSLGetEnabledCiphersZSSLGetNegotiatedCipherZSSLGetNegotiatedProtocolVersionZSSLCopyPeerTrustZSecTrustGetCssmResultCodeZSecTrustGetCertificateCountZSecTrustGetCertificateAtIndexZSecTrustSetAnchorCertificatesZ!SecTrustSetAnchorCertificatesOnlyZ argstypesZSecTrustEvaluateZ SSLNewContextZSSLDisposeContextZSSLSetEnableCertVerifyZSSLSetProtocolVersionEnabledZSSLProtocolSideZSSLConnectionTypeZSSLSessionOptionZSSLCreateContextZSSLSetSessionOptionZSSLSetProtocolVersionMinZSSLSetProtocolVersionMaxsetattrin_dllAttributeErrorr%r%r%r&s\4                             _mac/__pycache__/asymmetric.cpython-38.pyc000064400000122736147205106110014470 0ustar00U af@srddlmZmZmZmZddlmZddlZddlZddl Z ddl m Z m Z mZmZmZmZmZmZmZddlmZmZmZmZmZmZmZmZmZddlm Z ddl!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)d d l*m+Z+m,Z,m-Z-m.Z.d d l/m0Z0m1Z1m2Z2d d l3m4Z4dd l5m6Z6m7Z7m8Z8ddl9m:Z:m;Z;mZ>m?Z?m@Z@mAZAddddddddddddddddd d!d"d#d$gZBGd%ddeZCGd&ddeZDGd'ddeZ dHd(dZEd)d*ZFd+dZGd,d-ZHdId.dZId/dZJd0d1ZKdJd2dZLdKd3dZMd4d ZNd5dZOd6dZPd7dZQd8d9ZRd:d;ZSddZVd?dZWd@dAZXdBd!ZYdCd#ZZdDdZ[dEdZ\dFdGZ]dS)L)unicode_literalsdivisionabsolute_importprint_function) b32encodeN) CertificateECDomainParametersIntegerKeyExchangeAlgorithmNullPrivateKeyInfoPublicKeyAlgorithm PublicKeyInfo RSAPublicKey) _CertificateBase _fingerprint _parse_pkcs12_PrivateKeyBase_PublicKeyBase_unwrap_private_key_infoparse_certificate parse_private parse_public)pretty_message)newunwrapbytes_from_bufferbuffer_from_bytesderefnullis_null pointer_set)Security SecurityConsthandle_sec_errorosx_version_info)CoreFoundation CFHelpershandle_cf_error) rand_bytes)AsymmetricKeyErrorIncompleteAsymmetricKeyErrorSignatureError)add_pss_paddingverify_pss_padding"remove_pkcs1v15_encryption_padding) type_namestr_clsbyte_cls int_typesrdsa_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) r@zM Container for the OS crypto library representation of a private key NcCs||_||_t|_dS)z :param sec_key_ref: A Security framework SecKeyRef value from loading/importing the key :param asn1: An asn1crypto.keys.PrivateKeyInfo object N sec_key_refasn1r(_libselfrKrLrPI/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_mac/asymmetric.py__init__Ms zPrivateKey.__init__c CsL|jdkrFd}zttd}t|jddt|}t|t |}t |}t |}|j dkrttdtdt|djd|djdd d }n|j d kr|d d }ttd |dtt|dj|djj|djd }n8|j dkr&ttdtd|jdd|djdd }W5|r:t|Xt||_|jS)z\ :return: A PublicKey object corresponding to this private key. N CFDataRef *rrsa) algorithm parameters private_keymoduluspublic_exponent)rXrY)rU public_keydsaZprivate_key_algorithmrVgpecnamed)namevaluerZ) _public_keyr( CFReleaserr$ SecItemExportrKr r&rr)cf_data_to_bytesrrUrrr rparsedcopyr pownativer curve _load_key)rOcf_data_privatecf_data_private_pointerresultprivate_key_byteskeyZ public_asn1paramsrPrPrQrZ[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)rrLr=rOrPrPrQ fingerprints zPrivateKey.fingerprintcCs$|jr |j|jd|_d|_dSNrKrMrcrrrPrPrQ__del__szPrivateKey.__del__) __name__ __module__ __qualname____doc__rKrbrMrRpropertyrZrsrvrPrPrPrQr@As A c@s(eZdZdZdZdZddZddZdS)rAzL Container for the OS crypto library representation of a public key NcCs||_||_t|_dS)z :param sec_key_ref: A Security framework SecKeyRef value from loading/importing the key :param asn1: An asn1crypto.keys.PublicKeyInfo object NrJrNrPrPrQrRs zPublicKey.__init__cCs$|jr |j|jd|_d|_dSrtrurrrPrPrQrvszPublicKey.__del__)rwrxryrzrKrMrRrvrPrPrPrQrAs c@sPeZdZdZdZdZdZddZeddZ eddZ ed d Z d d Z dS) rzM Container for the OS crypto library representation of a certificate NcCs||_||_dS)z :param sec_certificate_ref: A Security framework SecCertificateRef value from loading/importing the certificate :param asn1: An asn1crypto.x509.Certificate object N)sec_certificate_refrL)rOr|rLrPrPrQrRs zCertificate.__init__cCs|jjS)zF :return: The SecKeyRef of the public key )rZrKrrrPrPrQrKszCertificate.sec_key_refcCs|js|jr|jjdkrF|j}d|dddd<t|}|j}n|j}ttd}t||}t |t |}t ||jdd|_|jS)zh :return: The PublicKey object for the public key this certificate contains rsassa_pssrTtbs_certificateZsubject_public_key_inforU SecKeyRef *) rbr|rLsignature_algorg _load_x509rr$ZSecCertificateCopyPublicKeyr&rrA)rOrLZ temp_certZ sec_cert_refZsec_public_key_ref_pointerresZsec_public_key_refrPrPrQrZs     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_pkcs1v15r}r[Zecdsaz Unable to verify the signature of the certificate since it uses the unsupported algorithm %s Zsignature_valuer~T) _self_signedrL self_signedsetr hash_algorGrIr7r9OSErrorrrZridumpr.)rOrrZ verify_funcrPrPrQrs8      zCertificate.self_signedcCs2|jr|jd|_|jr.t|jd|_dSrt)rbrvr|r(rcrrrPrPrQrv;s   zCertificate.__del__) rwrxryrzr|rbrrRr{rKrZrrvrPrPrPrQrs    +c Cs\|tdddgkr$ttdt||dkrT|tddddgkrttd t|nV|dkr~|tdgkrttd t|n,|dkr|td d d gkrttdt|d}d}d}d}d}d}d} d} d} zt j t j t j d|} |dkrdddd|} n|} ttd}ttd}td}d}td|}|dd}t|ddd}t} tj| |d}ttd}t|||dt|}t|t|} ttd}t|t|}t|t|} t| | | dt j t j!t j"Bt j#t j!t j"B| || }t|t|}t|}ttd}t$|ddt|}t|t|}t%|}ttd}t$|ddt|}t|t|}t%|}t&|}t|t&|}t|W5|rt||rt||rt||rt||rt||rt|| r*t| t| | r:t | | rJt| Xt'|t(|fS)a 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. :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(). rTr[r^zM algorithm must be one of "rsa", "dsa", "ec", not %s iii zX bit_size must be one of 1024, 2048, 3072, 4096, not %s z? bit_size must be 1024, not %s secp256r1 secp384r1 secp521r1zd curve must be one of "secp256r1", "secp384r1", "secp521r1", not %s N)r[r^rTi )rrrrTemporary oscrypto key utf-8SecKeychainRef *FSecAccessRef *rrS))r ValueErrorrreprr(rcr$SecKeychainDeleteshutilrmtreer%ZCSSM_ALGID_DSAZCSSM_ALGID_ECDSAZCSSM_ALGID_RSArr)cf_string_from_unicoder+rdecodetempfilemkdtempospathjoinencodeSecKeychainCreater r&rSecAccessCreateSecKeyCreatePairZCSSM_KEYUSE_VERIFYCSSM_KEYATTR_EXTRACTABLECSSM_KEYATTR_PERMANENTZCSSM_KEYUSE_SIGNrdreSecKeychainItemDeleter>r=)rUbit_sizerjZcf_dictpublic_key_refprivate_key_refcf_data_publicrl cf_stringsec_access_refsec_keychain_reftemp_dirZalg_idZkey_sizeprivate_key_pointerpublic_key_pointerpassphrase_len rand_data passphrase temp_filename temp_pathsec_keychain_ref_pointerrnsec_access_ref_pointerZcf_data_public_pointerZpublic_key_bytesrmrorPrPrQr:Es                            c Cst|tsttdt||dkr,td|dkrs     c CsJ|jdkrD|j\}}|dkr$td|tdddgkrttdnF|jdkrj|jd krjttd |jn |jdkr|jd krttd t|t r|jd kr| }d|dd<| }n| }t j }nt| }t j}d }d }d }z&t|}ttd} t| t jttd} t| |ttd} ttjg}ttd} t| } d| _d| _t| _t| _t| _ t| _!t| _"|| _#t$|t| | d| t| }t%|t| }t&|}|dkrt'|d}t(||t j krt)||W S|t jkrt*||WSW5|r$t||r4t||rDt|Xd S)aN Common code to load public and private keys into PublicKey and PrivateKey objects :param key_object: An asn1crypto.keys.PublicKeyInfo or asn1crypto.keys.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 key is incompatible with the OS crypto library OSError - when an error is returned by the OS crypto library :return: A PublicKey or PrivateKey object r^r_z-OS X only supports EC keys using named curvesrrrz OS X only supports EC keys using the named curves secp256r1, secp384r1 and secp521r1 r[Zsha2z OS X only supports DSA keys based on SHA1 (2048 bits or less) - this key is based on SHA2 and is %s bits Nzz The DSA key does not contain the necessary p, q and g parameters and can not be used r}rTrUz uint32_t *z CFArrayRef *z"SecItemImportExportKeyParameters *r)+rUrjr,rrrrr-rrrgrr%ZkSecItemTypePublicKeyrZkSecItemTypePrivateKeyr(rcr)rrr$r"ZkSecFormatOpenSSLZcf_array_from_listZkSecAttrIsExtractablerversionflagsr rZ alertTitleZ alertPromptZ accessRefZkeyUsageZ keyAttributesZ SecItemImportr&ZCFArrayGetCountZCFArrayGetValueAtIndexZCFRetainrAr@)Z key_objectZ curve_typedetailsZtemp_key_objectrZ item_typerZ keys_arrayZ attr_arrayZformat_pointerZ type_pointerZ keys_pointerZimport_export_params_pointerZimport_export_paramsrlengthrKrPrPrQrks                       rkcCs 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 )rr=)datarrPrPrQr?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|qSrP)r).0inforPrPrQ szload_pkcs12..) rr3rr4rrr2rrr?rkr) rrrZkey_infoZ cert_infoZextra_certs_inforpcertZ extra_certsrPrPrQr<s2      cCst|ttfs ttdt|t|ts Encrypts plaintext using an RSA public key or certificate :param certificate_or_public_key: A Certificate or PublicKey object :param data: The plaintext - a byte string :param padding: The padding mode to use, specified as a kSecPadding*Key value :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 ciphertext rrpadding must be specifiedN CFErrorRef *)rrrArrr2r4rr(rcr)rrr$ZSecEncryptTransformCreaterKr*SecTransformSetAttributekSecPaddingKeykSecTransformInputAttributeNameSecTransformExecutere)rrrcf_data sec_transform error_pointerrrPrPrQrsX     rc Cst|tsttdt|t|ts8ttdt||sDtdd}d}zt |}t td}t |j|}t|t |t j||t|t |t j||t|t ||}t|t |WS|rt||rt|XdS)a 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, specified as a kSecPadding*Key value :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 Y private_key must be an instance of the PrivateKey class, not %s zB ciphertext must be a byte string, not %s rNr)rr@rrr2r4rr(rcr)rrr$ZSecDecryptTransformCreaterKr*rrrrre)rWrrrrr plaintextrPrPrQrsV      rcCs |jdkrtdt||||S)a 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 rT*The key specified is not an RSA public keyrUr_verifyr signaturerhash_algorithmrPrPrQrG9s c Cst|ttfs ttdt|t|tsrkr?r<rErDrCrBrrrGrIr7r9rrFrHr6r8rrPrPrPrQs , , ( u o 5' 8(|  =6>TR"I5"H_mac/__pycache__/symmetric.cpython-38.pyc000064400000037221147205106110014321 0ustar00U afT @sddlmZmZmZmZddlmZddlmZm Z ddl m Z m Z m Z ddlmZddlmZdd lmZmZd d d d ddddddddg Zdd Zdd Zdd Zdd ZddZddZddZddZddZddZd dZ d!dZ!d"d#Z"d$d%Z#d&S)')unicode_literalsdivisionabsolute_importprint_function)pretty_message)newnull)CoreFoundation CFHelpershandle_cf_error)Security) 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_encryptcCst|dkrttdt||s,td}nt|dkrJttdt|t|ddkrlttdt||ttj|||tjfS)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 the OS crypto library :return: A tuple of two byte strings (iv, ciphertext)  c key must be either 16, 24 or 32 bytes (128, 192 or 256 bits) long - is %s r: iv must be 16 bytes long - is %s rzJ data must be a multiple of 16 bytes long - is %s )len ValueErrorrr_encryptrkSecAttrKeyTypeAESkSecPaddingNoneKeykeydataivr-H/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_mac/symmetric.pyrs$   cCsPt|dkrttdt|t|dkrr?Nr@)rArrBrrrr3r%r rCr rDrErFrrGr ZSecDecryptTransformCreaterHrIr rJrKrLrMrN) rOr*r+r,rPrQrRrSrTrUrVrW plaintextr-r-r.r/s|              r/N)$ __future__rrrr_errorsrZ_ffirr Z_core_foundationr r r Z _securityrutilr_typesrr__all__rrrrrrrrrrrrr&r/r-r-r-r.sB   6*-*,)0-,)q_mac/__pycache__/tls.cpython-38.pyc000064400000075575147205106110013125 0ustar00U af @szddlmZmZmZmZddlZddlZddlZddlZ ddl Z ddl Z ddl Z ddl Z ddlmZmZmZmZddlmZmZmZddlmZmZmZddlmZdd lmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,dd l-m.Z.m/Z/m0Z0m1Z1dd l2m3Z3dd l4m5Z5dd l6m7Z7m8Z8m9Z9ddl:m;Z;mZ>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZImJZJmKZKmLZLmMZMddlNmOZOmZddlPmQZQejRdkreSZTejRdkrejUZVnejVZVddgZWejXejYejZej[ej\dZ]ejXdejYdejZdej[dej\diZ^e_dZ`e_dZae bZciZdddZedd Zfd!d"Zge#ed#eeZhe#ed$egZiGd%ddejZkGd&ddejZldS)')unicode_literalsdivisionabsolute_importprint_functionN)Securityosx_version_infohandle_sec_error SecurityConst)CoreFoundationhandle_cf_error CFHelpers) Certificate int_to_bytestimezone)pretty_message)array_from_pointer array_setbuffer_from_bytesbytes_from_buffercallbackcastderefnewnull pointer_setstruct struct_bytesunwrapwrite_to_buffer) type_namestr_clsbyte_cls int_types)CIPHER_SUITE_MAP) rand_bytes)TLSErrorTLSDisconnectErrorTLSGracefulDisconnectError)detect_client_auth_requestdetect_other_protocol extract_chainget_dh_params_lengthparse_session_inforaise_client_authraise_dh_paramsraise_disconnectionraise_expired_not_yet_validraise_handshakeraise_hostnameraise_lifetime_too_longraise_no_issuerraise_protocol_errorraise_protocol_version raise_revokedraise_self_signedraise_verificationraise_weak_signature)load_certificater)parse_certificate))r? TLSSession TLSSocket)SSLv2SSLv3TLSv1TLSv1.1TLSv1.2rCrDrErFrGs( | | )zGanon|PSK|SEED|RC4|MD5|NULL|CAMELLIA|ARIA|SRP|KRB5|EXPORT|(?t|tsttdt|||_|dkr8tdddg}t|trNt|g}nt|tsjttdt||tddddg}|rttdt |||_ g|_ |r0|D]}t|t r|j }nbt|trt|}nNt|trt|d }t|}W5QRXnt|ts"ttd t||j |qtd |_dS) 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 NrErFrGzu protocol must be a unicode string or set of unicode strings, not %s rDz 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 ) isinstancebool TypeErrorrr!_manual_validationr^r" ValueErrorrepr _protocols_extra_trust_rootsrZasn1r#r>openreadAsn1Certificateappendr&_peer_id)rgprotocolmanual_validationZextra_trust_rootsZunsupported_protocolsZextra_trust_rootfrororp__init__ sN          zTLSSession.__init__)NFN) __name__ __module__ __qualname____doc__rZ_ciphersr~rrrrorororprAsc@steZdZdZdZdZdZdZdZdZ dZ dZ dZ dZ dZdZdZdZdZdZdZdZdZed=ddZd>ddZd d Zd d Zd?d dZddZddZddZddZ ddZ!d@ddZ"ddZ#ddZ$dd Z%d!d"Z&d#d$Z'e(d%d&Z)e(d'd(Z*e(d)d*Z+e(d+d,Z,e(d-d.Z-e(d/d0Z.e(d1d2Z/e(d3d4Z0e(d5d6Z1e(d7d8Z2e(d9d:Z3d;d<Z4dS)ArBz8 A wrapper around a socket.socket that adds TLS NFcCst|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) r{rSrhr}rr!r"rArO _hostname _handshake)clsrhhostnamerZ new_socketrororpwraps(  zTLSSocket.wrap cCsd|_d|_d|_d|_|dkr0|dkr0d|_n|t|tsLttdt |t|t shttdt ||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 FrHNzR address must be a unicode string, not %s zI port must be an integer, not %s zJ timeout must be a number, not %s r)r\r]ru_decrypted_bytesrOr{r"r}rr!r$numbersNumberrScreate_connectionrsrA_sessionrr)rgaddressportrirrororprsD    zTLSSocket.__init__c\ Cs d}d}d}d}d}d}d}d} z ztdkrXttd} td| } t| t| }nt t t j t j }t|tt} t| t|d|_|t|j<|jt|j<t||j} t| |jd} t|| t| } t| tdkr|jjp|jj} |jj o|jj} nd} |jj } tdkr|d D]0}t|}||jjk}t |||} t| q.| rt!|d} t| nhd d |jjD}t"|}t#|}t$||} t| t%||} t| | rt&|t j'd} t| ttd }t(||} t| t)|}t*|d }t+td|}t,|||} t| t)|}t-td||}g}|D]<}t.|dd}t/0||}t12|dk}|rV|3|qVt|}ttd|}t4||t+td|} t5|| |} t| |jj6|jd}!t7||!t|!} t| t8|}"|j9dk r(|j9}#d|_9|#|"t j:kr^t8|}"|j9dk r(|j9}#d|_9|#q(tdkrtdkr| o~|"dk}$n| o|"t j;k}$|$rttd}%t<||%} t| t|%}t=>|j}&t?d|&}t|&} t| t@td}'t|'}(tt jA|(_Bt*t jA})t+td|)|(_Cttd}*tDt jE|'t |*} t| t|*}ttd}+tF||+} t| t|+}t@td},t|,}-t jG|-_Ht jIt jJB|-_KtL|,}.t@td}/t|/}0t|.|0_Bt*|.}1t+td|1|0_CtM||/} t| t@td}2t|2}3tt jN|3_Bt*t jN}4t+td|4|3_Cttd}5tDt jE|2t |5} t| t|5}ttd}6tF||6} t| t|6}t@td}7t|7}8t jO|8_Hd|8_PtL|7}9t@td}/t|/}0t|9|0_Bt*|9}:t+td|:|0_CtM||/} t| t=Q|||g}tR||} t| |jjrvg};g}<|jjD]$}=tS|=}>|<3|>|;3|>jTqtU|d} t| t=Q|;}?tV||?} t| ttd}@tW||@} t| t)|@}AtXt jYt jZg}B|A|Bkrt j[}"n$t8|}"|"t j:krt8|}"qd|_\tXt j[t j]t j^t j_t j`t jat jbg}C|"|Ckr|r*t|d}ttd}%t<||%} t| t|%}ttd}Dtc||D} t)|D}Etd|je}Fd}Gd}Hd}Id}Jd}Kd}=d}L|Fr@|Fd}=tS|=}M|Mjf}G|Et jgk}H|G o|Et jhk}K|Et jik}I|Et jjk}J|Et jkk}L|Et jlk}Ntdkr@|=d d!}O|Od"jmjn}P|Od#jmjn}Qtojoptqjr}R|Q|Rk}I|P|Rk}J|Frj|FdjstXd$d%gkrjtt|Fd|Hrxtu|=|Lrtv|=|jnD|Is|Jrtw|=n.|Krtx|=n|Grty|=n|Nrtz|=t{|jert|t}|=|"t j~k rt{|je rt|t|"t jk r t|"t jk r2t|"tXt jt jgk rf|jet|j7_et|je|"tXt jt jgk r|j\ s|jet|j7_et|je rt|jettdk rt|je}S|Sdk r|Sd&k rt|"t j:k}T|"t j;k}U|jj o|U}V|T s|V st|"t||_ttd'}Wt||W} t| t)|W}t||_ttd(}Xt||X} t| t)|X}Yt.|Ydd}Zt/0|Z|Z|_t|je|j}[|[d)|_|[d*|_|[d+|_Wnbttjfk r | r tdk rt|} t| nt|} t| d|_|YnXW5| rBt|} t| d}| r^t|} t| d}| rzt|} t| d}| rt|} t| d}| rt|d}XdS),z2 Perform an initial TLS handshake NrrzzSSLContextRef *Fizutf-8)rrT)rCrDrEcSsg|] }t|qSro)_PROTOCOL_STRING_CONST_MAP).0rrororp _sz(TLSSocket._handshake..size_t *z uint32_t *Zuint32_tr)widthz uint32_t[])rr@r SecTrustRef *ZCSSM_OIDzchar *zSecPolicySearchRef *zSecPolicyRef *ZCSSM_APPLE_TP_OCSP_OPTIONSZ CSSM_DATAZCSSM_APPLE_TP_CRL_OPTIONSzSecTrustResultType *z OSStatus *)r Ztbs_certificatevalidity not_before not_aftermd5Zmd2iz SSLProtocol *zSSLCipherSuite * compression session_idsession_ticket)r CFReleaser rrrZ SSLNewContextr rZSSLCreateContextrr ZkSSLClientSideZkSSLStreamTypeZ SSLSetIOFuncs_read_callback_pointer_write_callback_pointerid_connection_idrLrOrNZSSLSetConnectionrencodeZSSLSetPeerDomainNamerQrr~rrrZSSLSetProtocolVersionEnabledZSSLSetEnableCertVerifyminmaxZSSLSetProtocolVersionMinZSSLSetProtocolVersionMaxZSSLSetSessionOptionZ"kSSLSessionOptionBreakOnServerAuthZSSLGetNumberSupportedCiphersrrrZSSLGetSupportedCiphersrrr%rM_cipher_blacklist_regexsearchrrZSSLSetEnabledCiphersrZ SSLSetPeerIDZ SSLHandshakercraZerrSSLServerAuthCompletedSSLCopyPeerTrustr Zcf_string_from_unicodeZSecPolicyCreateSSLrZAPPLE_TP_REVOCATION_OCSPZLengthDataZSecPolicySearchCreateZCSSM_CERT_X_509v3ZSecPolicySearchCopyNextZCSSM_APPLE_TP_OCSP_OPTS_VERSIONVersionZCSSM_TP_ACTION_OCSP_DISABLE_NETZ&CSSM_TP_ACTION_OCSP_CACHE_READ_DISABLEFlagsrZSecPolicySetValueZAPPLE_TP_REVOCATION_CRLZCSSM_APPLE_TP_CRL_OPTS_VERSIONZCrlFlagsZcf_array_from_listZSecTrustSetPoliciesr=sec_certificate_refZ!SecTrustSetAnchorCertificatesOnlyZSecTrustSetAnchorCertificatesZSecTrustEvaluater^ZkSecTrustResultProceedZkSecTrustResultUnspecifiedZerrSSLXCertChainInvalidr\ZerrSSLCertExpiredZerrSSLCertNotYetValidZerrSSLUnknownRootCertZerrSSLNoRootCertZerrSSLHostNameMismatchZerrSSLInternalZSecTrustGetCssmResultCoder,r] self_signedZCSSMERR_TP_CERT_REVOKEDZCSSMERR_TP_NOT_TRUSTEDZCSSMERR_TP_CERT_EXPIREDZCSSMERR_TP_CERT_NOT_VALID_YETZ!CSSMERR_APPLETP_HOSTNAME_MISMATCHZCSSMERR_TP_CERT_SUSPENDEDZchosenZnativedatetimenowrutcZ hash_algor<r9r4r2r6r:r5r*r/r;ZerrSSLPeerHandshakeFailr3ZerrSSLWeakPeerEphemeralDHKeyr0ZerrSSLPeerProtocolVersionr8ZerrSSLRecordOverflowr`r_r7rXrYr+r1r-r'_session_contextZSSLGetNegotiatedProtocolVersion_PROTOCOL_CONST_STRING_MAP _protocolZSSLGetNegotiatedCipher _cipher_suiter.ru _compression _session_id_session_ticketOSErrorrSrTSSLDisposeContextclose)\rgZsession_contextZssl_policy_refZcrl_search_refZcrl_policy_refZocsp_search_refZocsp_policy_refZpolicy_array_ref trust_refresultZsession_context_pointerZ utf8_domainZdisable_auto_validationZexplicit_validationrZprotocol_constenabledZprotocol_constsZ min_protocolZ max_protocolZsupported_ciphers_pointerZsupported_ciphersZ cipher_bufferZsupported_cipher_suites_pointerZsupported_cipher_suitesZ good_ciphersZsupported_cipher_suite cipher_suiteZcipher_suite_nameZ good_cipherZnum_good_ciphersZgood_ciphers_arrayZgood_ciphers_pointerZpeer_idZhandshake_result exceptionZ do_validationtrust_ref_pointerZcf_string_hostnameZocsp_oid_pointerZocsp_oidZocsp_oid_bufferZocsp_search_ref_pointerZocsp_policy_ref_pointerZocsp_struct_pointerZ ocsp_structZocsp_struct_bytesZcssm_data_pointerZ cssm_dataZocsp_struct_bufferZcrl_oid_pointerZcrl_oidZcrl_oid_bufferZcrl_search_ref_pointerZcrl_policy_ref_pointerZcrl_struct_pointerZ crl_structZcrl_struct_bytesZcrl_struct_bufferZ ca_cert_refsca_certscertZca_certZ array_refZresult_pointerZtrust_result_codeZinvalid_chain_error_codesZhandshake_error_codesZresult_code_pointerZ result_codechainrZrevokedZexpiredZ not_yet_validZ no_issuerZ bad_hostnameZ oscrypto_certZvalidity_too_longrrrutcnowZdh_params_lengthZ would_blockZserver_auth_completerZprotocol_const_pointerZcipher_int_pointerZ cipher_intZ cipher_bytesZ session_inforororprs                                                                                                                 zTLSSocket._handshakec Cslt|tsttdt||jdkrH|jdkr@|j}d|_|S|t|j}||kr||jd|}|j|d|_|S|dkr| ds|j}d|_|S|t|j}t |}t t d}t |j|||}|jdk r|j}d|_||r|ttjtjgkrt|t|r:|tjkr:d|_|d|t|} |jt|| }||d|_|d|S)a 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 oscrypto.errors.TLSDisconnectError - when the connection disconnects oscrypto.errors.TLSGracefulDisconnectError - when the remote end gracefully closed the connection 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 zG max_length must be an integer, not %s NrHrrTF)r{r$r}rr!rr _raise_closedrQ select_readrrrZSSLReadrcr^r raZerrSSLClosedGracefulr r'_gracefully_closed _shutdownrr) rg max_lengthrtZbuffered_lengthto_readZ read_bufferprocessed_pointerrr bytes_readrororprsV        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)rQrrRrO)rgrirkrlrororprQszTLSSocket.select_readc Cst|ts&t|ts&ttdt|d}t|t}t|jdkrP|j}d|_n|pZd}| |}t|}||7}|r| |}|dk r| }qq4t d|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 rHrrrNr)r{r#Patternr}rr!rQr_os_buffered_sizerrendrfind) rgmarkerrtis_regexrmroffsetmatchrstartrororp read_untiles4      zTLSSocket.read_untilcCs(ttd}t|j|}t|t|S)a Returns the number of bytes of decrypted data stored in the Secure Transport read buffer. This amount of data can be read from SSLRead() without calling self._socket.recv(). :return: An integer - the number of available bytes r)rrZSSLGetBufferedReadSizerr r)rgZnum_bytes_pointerrrororprs zTLSSocket._os_buffered_sizecCs |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_regexrgrororp 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 rHr)rrQ)rg num_bytesrt remainingrororp read_exactlys zTLSSocket.read_exactlycCs|jdkr|ttd}t|}|rt|}t|j|||}|jdk r\|j}d|_|t|t t |}||d}t|}|dkr$| q$dS)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 oscrypto.errors.TLSDisconnectError - when the connection disconnects oscrypto.errors.TLSGracefulDisconnectError - when the remote end gracefully closed the connection 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) rrrrrQrZSSLWritercr r'r select_write)rgrjrdata_lenZ write_bufferrrZ bytes_writtenrororpwrites,     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)rRrOrQ)rgrirlZ write_readyrororprs zTLSSocket.select_writecCs|jdkrdSt|j}tdkr8t|j}t|nt|j}t|d|_|r\d|_ z|j t j Wnt jk rYnXdS)z Shuts down the TLS session and then shuts down the underlying socket :param manual: A boolean if the connection was manually shutdown NrT)rrZSSLCloserrr r rr _local_closedrOshutdownrS SHUT_RDWRrT)rgZmanualrrororpr s     zTLSSocket._shutdowncCs|ddS)zV Shuts down the TLS session and then shuts down the underlying socket TN)rrrororpr(szTLSSocket.shutdowncCsXz |W5|jr@z|jWntjk r8YnXd|_|jtkrRt|j=XdS)zN Shuts down the TLS session and socket and forcibly closes it N)rOrrSrTrrNrrrororpr/s  zTLSSocket.closec Csd}d}d}zttd}t|j|}t|t|}t |}g|_ t d|D]`}t ||}t |}t|}t|}t|d}t|} |dkr| |_qP|j | qPW5|rt|}t||rt|}t|XdS)zh Reads end-entity and intermediate certificate information from the TLS session Nrr)r rr rrrrr rZSecTrustGetCertificateCount_intermediatesrangeZSecTrustGetCertificateAtIndexZSecCertificateCopyDatar Zcf_data_to_bytesrload _certificater) rgrZ cf_data_refrrZ number_certsindexrZ cert_datarrororp_read_certificatesBsB        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)rr(rr)rrororprvs   zTLSSocket._raise_closedcCs*|jdkr||jdkr$||jS)zu An asn1crypto.x509.Certificate object of the end-entity certificate presented by the server N)rrrrrrororp certificates   zTLSSocket.certificatecCs*|jdkr||jdkr$||jS)zz A list of asn1crypto.x509.Certificate objects that were presented as intermediates by the server N)rrrrrrrororp intermediatess   zTLSSocket.intermediatescCs|jS)zg A unicode string of the IANA cipher suite name of the negotiated cipher suite )rrrororprszTLSSocket.cipher_suitecCs|jS)zM A unicode string of: "TLSv1.2", "TLSv1.1", "TLSv1", "SSLv3" )rrrororprszTLSSocket.protocolcCs|jS)z5 A boolean if compression is enabled )rrrororprszTLSSocket.compressioncCs|jSzM A unicode string of "new" or "reused" or None for no ticket )rrrororprszTLSSocket.session_idcCs|jSr)rrrororprszTLSSocket.session_ticketcCs|jS)zM The oscrypto.tls.TLSSession object used for this connection )rrrororprszTLSSocket.sessioncCs|jS)zN A unicode string of the TLS server domain name or IP address )rrrororprszTLSSocket.hostnamecCs|jdS)zJ An integer of the port number the socket is connected to r)rh getpeernamerrororprszTLSSocket.portcCs|jdkr||jS)z9 The underlying socket.socket connection N)rrrOrrororprhs zTLSSocket.socketcCs |dS)N)rrrororp__del__szTLSSocket.__del__)N)rN)N)N)5rrrrrOrrcrrrrrrrrrrr\r]rurrr classmethodrrrrrrrrrrrrrrrrpropertyrrrrrrrrrrrhrrorororprB{s~ 3 FkS 8 + 4            )m __future__rrrrrsysrerhrSrRrrUweakrefZ _securityrrr r Z_core_foundationr r r Z_asn1rrrr_errorsrZ_ffirrrrrrrrrrrrrr _typesr!r"r#r$Z_cipher_suitesr%utilr&errorsr'r(r)_tlsr*r+r,r-r.r/r0r1r2r3r4r5r6r7r8r9r:r;r<Z asymmetricr=keysr> version_infoxrangerZ _pattern_typer__all__Z kSSLProtocol2Z kSSLProtocol3Z kTLSProtocol1ZkTLSProtocol11ZkTLSProtocol12rrcompilerrWeakValueDictionaryrLrNrqr_rxrrobjectrArBrorororpsp @  T      [7  g_mac/__pycache__/trust_list.cpython-38.pyc000064400000011252147205106110014515 0ustar00U afb@sddlmZmZmZmZddlZddlZddlmZddl m Z m Z ddl m Z mZddlmZmZmZejd krveZd d gZd d Zddd ZddZddZdS))unicode_literalsdivisionabsolute_importprint_functionN) Certificate)newunwrap)CoreFoundation CFHelpers)Security SecurityConsthandle_sec_error)extract_from_system system_pathcCsdS)NrrrI/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_mac/trust_list.pyrsFcCsttd}t|}t|t|}i}i}d}ttf}t|} td| D]$} t || } t | \} } | || <qPt |t j t jfD]}ttd}t||}|t jkrqt|t|}t|} td| D]l} t || } ttd}t| ||}|t jkrq|t jkrHt | \} } | |krt||| d|| =qt|t|}t}t}t|}td|D]j}t ||}t|}|did|}|dd}|dko|d k}|r||n ||qxt | \} } ||kr| |krs     _mac/__pycache__/util.cpython-38.pyc000064400000016574147205106110013272 0ustar00U af,'@sddlmZmZmZmZddlZddlmZddlm Z m Z m Z m Z ddl mZmZmZmZddlmZdd lmZmZdd lmZd d d gZdZddgZddZddZdd Zde_dd Z z ddl!m"Z"ddZ#dd Z$Wn"ek rddl%m$Z$YnXdS))unicode_literalsdivisionabsolute_importprint_functionN)pretty_message)buffer_from_bytesbytes_from_buffererrnobyte_string_from_buffer) type_namestr_clsbyte_cls int_types)LibraryNotFoundError) CommonCryptoCommonCryptoConst)Securitypbkdf2 pkcs12_kdf rand_bytesutf-8cp1252c Csfz t|tWStk rXtD]2}zt||ddWYStk rPYq Xq YnXt|ddS)Nstrict)errorsreplace)r _encodingUnicodeDecodeError_fallback_encodings)valueencodingr"C/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_mac/util.py _try_decodes r$cCsHt}zt|}Wntk r0t|YSXt|tr@|St|S)z~ Extracts the last OS error message into a python unicode string :return: A unicode string error message )r osstrerror ValueErrorr isinstancer$) error_num error_stringr"r"r#_extract_error*s r+c 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|}tt j|t||t||||| }|dkrttt|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 OSError - when an error is returned by the OS crypto library :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 rz!iterations must be greater than 0z? key_length must be an integer, not %s z!key_length must be greater than 0sha1sha224sha256sha384sha512zz hash_algorithm must be one of "sha1", "sha224", "sha256", "sha384", "sha512", not %s )r,r-r.r/r0r)r(r TypeErrorrr rr'setreprrZkCCPRFHmacAlgSHA1ZkCCPRFHmacAlgSHA224ZkCCPRFHmacAlgSHA256ZkCCPRFHmacAlgSHA384ZkCCPRFHmacAlgSHA512rrZCCKeyDerivationPBKDFZ kCCPBKDF2lenOSErrorr+r )hash_algorithmpasswordsalt iterations key_lengthalgo output_bufferresultr"r"r#r?sh       FcCsnt|tsttdt||dkr,td|dkrs0   e(  |_openssl/__init__.py000064400000000000147205106110010462 0ustar00_openssl/_libcrypto.py000064400000007312147205106110011106 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 _openssl/_libcrypto_cffi.py000064400000023311147205106110012072 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); """) _openssl/_libcrypto_ctypes.py000064400000042415147205106110012500 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) _openssl/_libssl.py000064400000004163147205106110010370 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 _openssl/_libssl_cffi.py000064400000005761147205106110011364 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); """) _openssl/_libssl_ctypes.py000064400000013612147205106110011756 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) _openssl/asymmetric.py000064400000173073147205106110011125 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) _openssl/symmetric.py000064400000055630147205106110010762 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) _openssl/tls.py000064400000126601147205106110007545 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() _openssl/util.py000064400000015346147205106110007723 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) _openssl/__pycache__/__init__.cpython-38.pyc000064400000000246147205106110014764 0ustar00U af@sdS)NrrrK/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_openssl/__init__.py_openssl/__pycache__/_libcrypto.cpython-38.pyc000064400000006170147205106110015375 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      _openssl/__pycache__/_libcrypto_cffi.cpython-38.pyc000064400000022252147205106110016363 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        $_openssl/__pycache__/_libcrypto_ctypes.cpython-38.pyc000064400000016212147205106110016762 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,                            _openssl/__pycache__/_libssl.cpython-38.pyc000064400000004427147205106110014661 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    <_openssl/__pycache__/_libssl_cffi.cpython-38.pyc000064400000006133147205106110015644 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 _openssl/__pycache__/_libssl_ctypes.cpython-38.pyc000064400000006025147205106110016244 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(                _openssl/__pycache__/asymmetric.cpython-38.pyc000064400000120410147205106110015376 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('"" '&!!_openssl/__pycache__/symmetric.cpython-38.pyc000064400000042612147205106110015244 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_openssl/__pycache__/tls.cpython-38.pyc000064400000064774147205106110014047 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_openssl/__pycache__/util.cpython-38.pyc000064400000011712147205106110014202 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_win/__init__.py000064400000000000147205106110007574 0ustar00_win/_advapi32.py000064400000010376147205106110007626 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import sys from .. import ffi from ._decode import _try_decode from ..errors import SignatureError from .._ffi import new, unwrap, null from .._types import str_cls if ffi() == 'cffi': from ._advapi32_cffi import advapi32, get_error else: from ._advapi32_ctypes import advapi32, get_error __all__ = [ 'advapi32', 'Advapi32Const', 'handle_error', ] _gwv = sys.getwindowsversion() _win_version_info = (_gwv[0], _gwv[1]) def open_context_handle(provider, verify_only=True): if provider == Advapi32Const.MS_ENH_RSA_AES_PROV: provider_type = Advapi32Const.PROV_RSA_AES elif provider == Advapi32Const.MS_ENH_DSS_DH_PROV: provider_type = Advapi32Const.PROV_DSS_DH else: raise ValueError('Invalid provider specified: %s' % provider) # The DSS provider needs a container to allow importing and exporting # private keys, but all of the RSA stuff works fine with CRYPT_VERIFYCONTEXT if verify_only or provider != Advapi32Const.MS_ENH_DSS_DH_PROV: container_name = null() flags = Advapi32Const.CRYPT_VERIFYCONTEXT else: container_name = Advapi32Const.CONTAINER_NAME flags = Advapi32Const.CRYPT_NEWKEYSET context_handle_pointer = new(advapi32, 'HCRYPTPROV *') res = advapi32.CryptAcquireContextW( context_handle_pointer, container_name, provider, provider_type, flags ) # If using the DSS provider and the container exists, just open it if not res and get_error()[0] == Advapi32Const.NTE_EXISTS: res = advapi32.CryptAcquireContextW( context_handle_pointer, container_name, provider, provider_type, 0 ) handle_error(res) return unwrap(context_handle_pointer) def close_context_handle(handle): res = advapi32.CryptReleaseContext(handle, 0) handle_error(res) def handle_error(result): """ Extracts the last Windows error message into a python unicode string :param result: A function result, 0 or None indicates failure :return: A unicode string error message """ if result: return code, error_string = get_error() if code == Advapi32Const.NTE_BAD_SIGNATURE: raise SignatureError('Signature is invalid') if not isinstance(error_string, str_cls): error_string = _try_decode(error_string) raise OSError(error_string) class Advapi32Const(): # Name we give to a container used to make DSA private key import/export work CONTAINER_NAME = 'oscrypto temporary DSS keyset' PROV_RSA_AES = 24 PROV_DSS_DH = 13 X509_PUBLIC_KEY_INFO = 8 PKCS_PRIVATE_KEY_INFO = 44 X509_DSS_SIGNATURE = 40 CRYPT_NO_SALT = 0x00000010 MS_ENH_DSS_DH_PROV = "Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider" # This is the name for Windows Server 2003 and newer and Windows Vista and newer MS_ENH_RSA_AES_PROV = "Microsoft Enhanced RSA and AES Cryptographic Provider" CRYPT_EXPORTABLE = 1 CRYPT_NEWKEYSET = 0x00000008 CRYPT_VERIFYCONTEXT = 0xF0000000 CALG_MD5 = 0x00008003 CALG_SHA1 = 0x00008004 CALG_SHA_256 = 0x0000800c CALG_SHA_384 = 0x0000800d CALG_SHA_512 = 0x0000800e CALG_RC2 = 0x00006602 CALG_RC4 = 0x00006801 CALG_DES = 0x00006601 CALG_3DES_112 = 0x00006609 CALG_3DES = 0x00006603 CALG_AES_128 = 0x0000660e CALG_AES_192 = 0x0000660f CALG_AES_256 = 0x00006610 CALG_DSS_SIGN = 0x00002200 CALG_RSA_SIGN = 0x00002400 CALG_RSA_KEYX = 0x0000a400 CRYPT_MODE_CBC = 1 PKCS5_PADDING = 1 CUR_BLOB_VERSION = 2 PUBLICKEYBLOB = 6 PRIVATEKEYBLOB = 7 PLAINTEXTKEYBLOB = 8 KP_IV = 1 KP_PADDING = 3 KP_MODE = 4 KP_EFFECTIVE_KEYLEN = 19 CRYPT_OAEP = 0x00000040 NTE_BAD_SIGNATURE = -2146893818 # 0x80090006 NTE_EXISTS = -2146893809 # 0x8009000F AT_SIGNATURE = 2 RSA1 = 0x31415352 RSA2 = 0x32415352 DSS1 = 0x31535344 DSS2 = 0x32535344 if _win_version_info == (5, 1): # This is the Windows XP name for the provider Advapi32Const.MS_ENH_RSA_AES_PROV = "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)" _win/_advapi32_cffi.py000064400000010770147205106110010613 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from .._ffi import register_ffi from .._types import str_cls from ..errors import LibraryNotFoundError import cffi __all__ = [ 'advapi32', 'get_error', ] ffi = cffi.FFI() if cffi.__version_info__ >= (0, 9): ffi.set_unicode(True) ffi.cdef(""" typedef HANDLE HCRYPTPROV; typedef HANDLE HCRYPTKEY; typedef HANDLE HCRYPTHASH; typedef unsigned int ALG_ID; typedef struct _CRYPTOAPI_BLOB { DWORD cbData; BYTE *pbData; } CRYPT_INTEGER_BLOB, CRYPT_OBJID_BLOB, CRYPT_DER_BLOB, CRYPT_ATTR_BLOB; typedef struct _CRYPT_ALGORITHM_IDENTIFIER { LPSTR pszObjId; CRYPT_OBJID_BLOB Parameters; } CRYPT_ALGORITHM_IDENTIFIER; typedef struct _CRYPT_BIT_BLOB { DWORD cbData; BYTE *pbData; DWORD cUnusedBits; } CRYPT_BIT_BLOB; typedef struct _CERT_PUBLIC_KEY_INFO { CRYPT_ALGORITHM_IDENTIFIER Algorithm; CRYPT_BIT_BLOB PublicKey; } CERT_PUBLIC_KEY_INFO; typedef struct _CRYPT_ATTRIBUTE { LPSTR pszObjId; DWORD cValue; CRYPT_ATTR_BLOB *rgValue; } CRYPT_ATTRIBUTE; typedef struct _CRYPT_ATTRIBUTES { DWORD cAttr; CRYPT_ATTRIBUTE *rgAttr; } CRYPT_ATTRIBUTES; typedef struct _CRYPT_PRIVATE_KEY_INFO { DWORD Version; CRYPT_ALGORITHM_IDENTIFIER Algorithm; CRYPT_DER_BLOB PrivateKey; CRYPT_ATTRIBUTES *pAttributes; } CRYPT_PRIVATE_KEY_INFO; typedef struct _PUBLICKEYSTRUC { BYTE bType; BYTE bVersion; WORD reserved; ALG_ID aiKeyAlg; } BLOBHEADER, PUBLICKEYSTRUC; typedef struct _DSSPUBKEY { DWORD magic; DWORD bitlen; } DSSPUBKEY; typedef struct _DSSBLOBHEADER { PUBLICKEYSTRUC publickeystruc; DSSPUBKEY dsspubkey; } DSSBLOBHEADER; typedef struct _RSAPUBKEY { DWORD magic; DWORD bitlen; DWORD pubexp; } RSAPUBKEY; typedef struct _RSABLOBHEADER { PUBLICKEYSTRUC publickeystruc; RSAPUBKEY rsapubkey; } RSABLOBHEADER; typedef struct _PLAINTEXTKEYBLOB { BLOBHEADER hdr; DWORD dwKeySize; // rgbKeyData omitted since it is a flexible array member } PLAINTEXTKEYBLOB; typedef struct _DSSSEED { DWORD counter; BYTE seed[20]; } DSSSEED; BOOL CryptAcquireContextW(HCRYPTPROV *phProv, LPCWSTR pszContainer, LPCWSTR pszProvider, DWORD dwProvType, DWORD dwFlags); BOOL CryptReleaseContext(HCRYPTPROV hProv, DWORD dwFlags); BOOL CryptImportKey(HCRYPTPROV hProv, BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey); BOOL CryptGenKey(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey); BOOL CryptGetKeyParam(HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags); BOOL CryptSetKeyParam(HCRYPTKEY hKey, DWORD dwParam, void *pbData, DWORD dwFlags); BOOL CryptExportKey(HCRYPTKEY hKey, HCRYPTKEY hExpKey, DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen); BOOL CryptDestroyKey(HCRYPTKEY hKey); BOOL CryptCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash); BOOL CryptHashData(HCRYPTHASH hHash, BYTE *pbData, DWORD dwDataLen, DWORD dwFlags); BOOL CryptSetHashParam(HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD dwFlags); BOOL CryptSignHashW(HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription, DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen); BOOL CryptVerifySignatureW(HCRYPTHASH hHash, BYTE *pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags); BOOL CryptDestroyHash(HCRYPTHASH hHash); BOOL CryptEncrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen); BOOL CryptDecrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen); """) try: advapi32 = ffi.dlopen('advapi32.dll') register_ffi(advapi32, ffi) except (OSError) as e: if str_cls(e).find('cannot load library') != -1: raise LibraryNotFoundError('advapi32.dll could not be found') raise def get_error(): return ffi.getwinerror() _win/_advapi32_ctypes.py000064400000016476147205106110011224 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import ctypes from ctypes import windll, wintypes, POINTER, Structure, c_void_p, c_char_p, c_uint from ctypes.wintypes import BOOL, DWORD from .._ffi import FFIEngineError from .._types import str_cls from ..errors import LibraryNotFoundError __all__ = [ 'advapi32', 'get_error', ] try: advapi32 = windll.advapi32 except (OSError) as e: if str_cls(e).find('The specified module could not be found') != -1: raise LibraryNotFoundError('advapi32.dll could not be found') raise HCRYPTPROV = wintypes.HANDLE HCRYPTKEY = wintypes.HANDLE HCRYPTHASH = wintypes.HANDLE PBYTE = c_char_p ALG_ID = c_uint try: class CRYPTOAPI_BLOB(Structure): # noqa _fields_ = [ ("cbData", DWORD), ("pbData", POINTER(ctypes.c_byte)), ] CRYPT_INTEGER_BLOB = CRYPTOAPI_BLOB CRYPT_OBJID_BLOB = CRYPTOAPI_BLOB CRYPT_DER_BLOB = CRYPTOAPI_BLOB CRYPT_ATTR_BLOB = CRYPTOAPI_BLOB class CRYPT_ALGORITHM_IDENTIFIER(Structure): _fields = [ ('pszObjId', wintypes.LPSTR), ('Parameters', CRYPT_OBJID_BLOB), ] class CRYPT_BIT_BLOB(Structure): _fields_ = [ ('cbData', DWORD), ('pbData', PBYTE), ('cUnusedBits', DWORD), ] class CERT_PUBLIC_KEY_INFO(Structure): _fields_ = [ ('Algorithm', CRYPT_ALGORITHM_IDENTIFIER), ('PublicKey', CRYPT_BIT_BLOB), ] class CRYPT_ATTRIBUTE(Structure): _fields_ = [ ('pszObjId', wintypes.LPSTR), ('cValue', DWORD), ('rgValue', POINTER(CRYPT_ATTR_BLOB)), ] class CRYPT_ATTRIBUTES(Structure): _fields_ = [ ('cAttr', DWORD), ('rgAttr', POINTER(CRYPT_ATTRIBUTE)), ] class CRYPT_PRIVATE_KEY_INFO(Structure): _fields_ = [ ('Version', DWORD), ('Algorithm', CRYPT_ALGORITHM_IDENTIFIER), ('PrivateKey', CRYPT_DER_BLOB), ('pAttributes', POINTER(CRYPT_ATTRIBUTES)), ] class PUBLICKEYSTRUC(Structure): _fields_ = [ ('bType', wintypes.BYTE), ('bVersion', wintypes.BYTE), ('reserved', wintypes.WORD), ('aiKeyAlg', ALG_ID), ] BLOBHEADER = PUBLICKEYSTRUC class DSSPUBKEY(Structure): _fields_ = [ ('magic', DWORD), ('bitlen', DWORD), ] class DSSBLOBHEADER(Structure): _fields_ = [ ('publickeystruc', PUBLICKEYSTRUC), ('dsspubkey', DSSPUBKEY), ] class RSAPUBKEY(Structure): _fields_ = [ ('magic', DWORD), ('bitlen', DWORD), ('pubexp', DWORD), ] class RSABLOBHEADER(Structure): _fields_ = [ ('publickeystruc', PUBLICKEYSTRUC), ('rsapubkey', RSAPUBKEY), ] class PLAINTEXTKEYBLOB(Structure): _fields_ = [ ('hdr', BLOBHEADER), ('dwKeySize', DWORD), # rgbKeyData omitted since it is a flexible array member ] class DSSSEED(Structure): _fields_ = [ ('counter', DWORD), ('seed', wintypes.BYTE * 20), ] advapi32.CryptAcquireContextW.argtypes = [ POINTER(HCRYPTPROV), wintypes.LPCWSTR, wintypes.LPCWSTR, DWORD, DWORD ] advapi32.CryptAcquireContextW.restype = wintypes.BOOL advapi32.CryptReleaseContext.argtypes = [ HCRYPTPROV, DWORD ] advapi32.CryptReleaseContext.restype = wintypes.BOOL advapi32.CryptImportKey.argtypes = [ HCRYPTPROV, PBYTE, DWORD, HCRYPTKEY, DWORD, POINTER(HCRYPTKEY) ] advapi32.CryptImportKey.restype = BOOL advapi32.CryptGenKey.argtypes = [ HCRYPTPROV, ALG_ID, DWORD, POINTER(HCRYPTKEY) ] advapi32.CryptGenKey.restype = wintypes.BOOL advapi32.CryptGetKeyParam.argtypes = [ HCRYPTKEY, DWORD, PBYTE, POINTER(DWORD), DWORD ] advapi32.CryptGetKeyParam.restype = wintypes.BOOL advapi32.CryptSetKeyParam.argtypes = [ HCRYPTKEY, DWORD, c_void_p, DWORD ] advapi32.CryptSetKeyParam.restype = wintypes.BOOL advapi32.CryptExportKey.argtypes = [ HCRYPTKEY, HCRYPTKEY, DWORD, DWORD, PBYTE, POINTER(DWORD) ] advapi32.CryptExportKey.restype = BOOL advapi32.CryptDestroyKey.argtypes = [ HCRYPTKEY ] advapi32.CryptDestroyKey.restype = wintypes.BOOL advapi32.CryptCreateHash.argtypes = [ HCRYPTPROV, ALG_ID, HCRYPTKEY, DWORD, POINTER(HCRYPTHASH) ] advapi32.CryptCreateHash.restype = BOOL advapi32.CryptHashData.argtypes = [ HCRYPTHASH, PBYTE, DWORD, DWORD ] advapi32.CryptHashData.restype = BOOL advapi32.CryptSetHashParam.argtypes = [ HCRYPTHASH, DWORD, PBYTE, DWORD ] advapi32.CryptSetHashParam.restype = BOOL advapi32.CryptSignHashW.argtypes = [ HCRYPTHASH, DWORD, wintypes.LPCWSTR, DWORD, PBYTE, POINTER(DWORD) ] advapi32.CryptSignHashW.restype = BOOL advapi32.CryptVerifySignatureW.argtypes = [ HCRYPTHASH, PBYTE, DWORD, HCRYPTKEY, wintypes.LPCWSTR, DWORD ] advapi32.CryptVerifySignatureW.restype = BOOL advapi32.CryptDestroyHash.argtypes = [ HCRYPTHASH ] advapi32.CryptDestroyHash.restype = wintypes.BOOL advapi32.CryptEncrypt.argtypes = [ HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, PBYTE, POINTER(DWORD), DWORD ] advapi32.CryptEncrypt.restype = BOOL advapi32.CryptDecrypt.argtypes = [ HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, PBYTE, POINTER(DWORD) ] advapi32.CryptDecrypt.restype = BOOL except (AttributeError): raise FFIEngineError('Error initializing ctypes') setattr(advapi32, 'HCRYPTPROV', HCRYPTPROV) setattr(advapi32, 'HCRYPTKEY', HCRYPTKEY) setattr(advapi32, 'HCRYPTHASH', HCRYPTHASH) setattr(advapi32, 'CRYPT_INTEGER_BLOB', CRYPT_INTEGER_BLOB) setattr(advapi32, 'CRYPT_OBJID_BLOB', CRYPT_OBJID_BLOB) setattr(advapi32, 'CRYPT_DER_BLOB', CRYPT_DER_BLOB) setattr(advapi32, 'CRYPT_ATTR_BLOB', CRYPT_ATTR_BLOB) setattr(advapi32, 'CRYPT_ALGORITHM_IDENTIFIER', CRYPT_ALGORITHM_IDENTIFIER) setattr(advapi32, 'CRYPT_BIT_BLOB', CRYPT_BIT_BLOB) setattr(advapi32, 'CERT_PUBLIC_KEY_INFO', CERT_PUBLIC_KEY_INFO) setattr(advapi32, 'CRYPT_PRIVATE_KEY_INFO', CRYPT_PRIVATE_KEY_INFO) setattr(advapi32, 'CRYPT_ATTRIBUTE', CRYPT_ATTRIBUTE) setattr(advapi32, 'CRYPT_ATTRIBUTES', CRYPT_ATTRIBUTES) setattr(advapi32, 'PUBLICKEYSTRUC', PUBLICKEYSTRUC) setattr(advapi32, 'DSSPUBKEY', DSSPUBKEY) setattr(advapi32, 'DSSBLOBHEADER', DSSBLOBHEADER) setattr(advapi32, 'RSAPUBKEY', RSAPUBKEY) setattr(advapi32, 'RSABLOBHEADER', RSABLOBHEADER) setattr(advapi32, 'BLOBHEADER', BLOBHEADER) setattr(advapi32, 'PLAINTEXTKEYBLOB', PLAINTEXTKEYBLOB) setattr(advapi32, 'DSSSEED', DSSSEED) def get_error(): error = ctypes.GetLastError() return (error, ctypes.FormatError(error)) _win/_cng.py000064400000010627147205106110006763 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from .. import ffi from .._ffi import new, null, unwrap if ffi() == 'cffi': from ._cng_cffi import bcrypt else: from ._cng_ctypes import bcrypt __all__ = [ 'bcrypt', 'BcryptConst', 'close_alg_handle', 'handle_error', 'open_alg_handle', ] def open_alg_handle(constant, flags=0): handle_pointer = new(bcrypt, 'BCRYPT_ALG_HANDLE *') res = bcrypt.BCryptOpenAlgorithmProvider(handle_pointer, constant, null(), flags) handle_error(res) return unwrap(handle_pointer) def close_alg_handle(handle): res = bcrypt.BCryptCloseAlgorithmProvider(handle, 0) handle_error(res) def handle_error(error_num): """ Extracts the last Windows error message into a python unicode string :param error_num: The number to get the error string for :return: A unicode string error message """ if error_num == 0: return messages = { BcryptConst.STATUS_NOT_FOUND: 'The object was not found', BcryptConst.STATUS_INVALID_PARAMETER: 'An invalid parameter was passed to a service or function', BcryptConst.STATUS_NO_MEMORY: ( 'Not enough virtual memory or paging file quota is available to complete the specified operation' ), BcryptConst.STATUS_INVALID_HANDLE: 'An invalid HANDLE was specified', BcryptConst.STATUS_INVALID_SIGNATURE: 'The cryptographic signature is invalid', BcryptConst.STATUS_NOT_SUPPORTED: 'The request is not supported', BcryptConst.STATUS_BUFFER_TOO_SMALL: 'The buffer is too small to contain the entry', BcryptConst.STATUS_INVALID_BUFFER_SIZE: 'The size of the buffer is invalid for the specified operation', } output = 'NTSTATUS error 0x%0.2X' % error_num if error_num is not None and error_num in messages: output += ': ' + messages[error_num] raise OSError(output) class BcryptConst(): BCRYPT_RNG_ALGORITHM = 'RNG' BCRYPT_KEY_LENGTH = 'KeyLength' BCRYPT_EFFECTIVE_KEY_LENGTH = 'EffectiveKeyLength' BCRYPT_RSAPRIVATE_BLOB = 'RSAPRIVATEBLOB' BCRYPT_RSAFULLPRIVATE_BLOB = 'RSAFULLPRIVATEBLOB' BCRYPT_RSAPUBLIC_BLOB = 'RSAPUBLICBLOB' BCRYPT_DSA_PRIVATE_BLOB = 'DSAPRIVATEBLOB' BCRYPT_DSA_PUBLIC_BLOB = 'DSAPUBLICBLOB' BCRYPT_ECCPRIVATE_BLOB = 'ECCPRIVATEBLOB' BCRYPT_ECCPUBLIC_BLOB = 'ECCPUBLICBLOB' BCRYPT_RSAPUBLIC_MAGIC = 0x31415352 BCRYPT_RSAPRIVATE_MAGIC = 0x32415352 BCRYPT_RSAFULLPRIVATE_MAGIC = 0x33415352 BCRYPT_DSA_PUBLIC_MAGIC = 0x42505344 BCRYPT_DSA_PRIVATE_MAGIC = 0x56505344 BCRYPT_DSA_PUBLIC_MAGIC_V2 = 0x32425044 BCRYPT_DSA_PRIVATE_MAGIC_V2 = 0x32565044 DSA_HASH_ALGORITHM_SHA1 = 0 DSA_HASH_ALGORITHM_SHA256 = 1 DSA_HASH_ALGORITHM_SHA512 = 2 DSA_FIPS186_2 = 0 DSA_FIPS186_3 = 1 BCRYPT_NO_KEY_VALIDATION = 8 BCRYPT_ECDSA_PUBLIC_P256_MAGIC = 0x31534345 BCRYPT_ECDSA_PRIVATE_P256_MAGIC = 0x32534345 BCRYPT_ECDSA_PUBLIC_P384_MAGIC = 0x33534345 BCRYPT_ECDSA_PRIVATE_P384_MAGIC = 0x34534345 BCRYPT_ECDSA_PUBLIC_P521_MAGIC = 0x35534345 BCRYPT_ECDSA_PRIVATE_P521_MAGIC = 0x36534345 STATUS_SUCCESS = 0x00000000 STATUS_NOT_FOUND = 0xC0000225 STATUS_INVALID_PARAMETER = 0xC000000D STATUS_NO_MEMORY = 0xC0000017 STATUS_INVALID_HANDLE = 0xC0000008 STATUS_INVALID_SIGNATURE = 0xC000A000 STATUS_NOT_SUPPORTED = 0xC00000BB STATUS_BUFFER_TOO_SMALL = 0xC0000023 STATUS_INVALID_BUFFER_SIZE = 0xC0000206 BCRYPT_KEY_DATA_BLOB_MAGIC = 0x4d42444b BCRYPT_KEY_DATA_BLOB_VERSION1 = 0x00000001 BCRYPT_KEY_DATA_BLOB = 'KeyDataBlob' BCRYPT_PAD_PKCS1 = 0x00000002 BCRYPT_PAD_OAEP = 0x00000004 BCRYPT_PAD_PSS = 0x00000008 BCRYPT_3DES_ALGORITHM = '3DES' BCRYPT_3DES_112_ALGORITHM = '3DES_112' BCRYPT_AES_ALGORITHM = 'AES' BCRYPT_DES_ALGORITHM = 'DES' BCRYPT_RC2_ALGORITHM = 'RC2' BCRYPT_RC4_ALGORITHM = 'RC4' BCRYPT_DSA_ALGORITHM = 'DSA' BCRYPT_ECDSA_P256_ALGORITHM = 'ECDSA_P256' BCRYPT_ECDSA_P384_ALGORITHM = 'ECDSA_P384' BCRYPT_ECDSA_P521_ALGORITHM = 'ECDSA_P521' BCRYPT_RSA_ALGORITHM = 'RSA' BCRYPT_MD5_ALGORITHM = 'MD5' BCRYPT_SHA1_ALGORITHM = 'SHA1' BCRYPT_SHA256_ALGORITHM = 'SHA256' BCRYPT_SHA384_ALGORITHM = 'SHA384' BCRYPT_SHA512_ALGORITHM = 'SHA512' BCRYPT_ALG_HANDLE_HMAC_FLAG = 0x00000008 BCRYPT_BLOCK_PADDING = 0x00000001 _win/_cng_cffi.py000064400000010576147205106110007755 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from .._ffi import register_ffi from .._types import str_cls from ..errors import LibraryNotFoundError from cffi import FFI __all__ = [ 'bcrypt', ] ffi = FFI() ffi.cdef(""" typedef HANDLE BCRYPT_ALG_HANDLE; typedef HANDLE BCRYPT_KEY_HANDLE; typedef ULONG NTSTATUS; typedef unsigned char *PUCHAR; typedef unsigned char *PBYTE; typedef struct _BCRYPT_RSAKEY_BLOB { ULONG Magic; ULONG BitLength; ULONG cbPublicExp; ULONG cbModulus; ULONG cbPrime1; ULONG cbPrime2; } BCRYPT_RSAKEY_BLOB; typedef struct _BCRYPT_DSA_KEY_BLOB { ULONG dwMagic; ULONG cbKey; UCHAR Count[4]; UCHAR Seed[20]; UCHAR q[20]; } BCRYPT_DSA_KEY_BLOB; typedef struct _BCRYPT_DSA_KEY_BLOB_V2 { ULONG dwMagic; ULONG cbKey; INT hashAlgorithm; INT standardVersion; ULONG cbSeedLength; ULONG cbGroupSize; UCHAR Count[4]; } BCRYPT_DSA_KEY_BLOB_V2; typedef struct _BCRYPT_ECCKEY_BLOB { ULONG dwMagic; ULONG cbKey; } BCRYPT_ECCKEY_BLOB; typedef struct _BCRYPT_PKCS1_PADDING_INFO { LPCWSTR pszAlgId; } BCRYPT_PKCS1_PADDING_INFO; typedef struct _BCRYPT_PSS_PADDING_INFO { LPCWSTR pszAlgId; ULONG cbSalt; } BCRYPT_PSS_PADDING_INFO; typedef struct _BCRYPT_OAEP_PADDING_INFO { LPCWSTR pszAlgId; PUCHAR pbLabel; ULONG cbLabel; } BCRYPT_OAEP_PADDING_INFO; typedef struct _BCRYPT_KEY_DATA_BLOB_HEADER { ULONG dwMagic; ULONG dwVersion; ULONG cbKeyData; } BCRYPT_KEY_DATA_BLOB_HEADER; NTSTATUS BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE *phAlgorithm, LPCWSTR pszAlgId, LPCWSTR pszImplementation, DWORD dwFlags); NTSTATUS BCryptCloseAlgorithmProvider(BCRYPT_ALG_HANDLE hAlgorithm, DWORD dwFlags); NTSTATUS BCryptSetProperty(HANDLE hObject, LPCWSTR pszProperty, ULONG *pbInput, ULONG cbInput, ULONG dwFlags); NTSTATUS BCryptImportKeyPair(BCRYPT_ALG_HANDLE hAlgorithm, BCRYPT_KEY_HANDLE hImportKey, LPCWSTR pszBlobType, BCRYPT_KEY_HANDLE *phKey, PUCHAR pbInput, ULONG cbInput, ULONG dwFlags); NTSTATUS BCryptImportKey(BCRYPT_ALG_HANDLE hAlgorithm, BCRYPT_KEY_HANDLE hImportKey, LPCWSTR pszBlobType, BCRYPT_KEY_HANDLE *phKey, PUCHAR pbKeyObject, ULONG cbKeyObject, PUCHAR pbInput, ULONG cbInput, ULONG dwFlags); NTSTATUS BCryptDestroyKey(BCRYPT_KEY_HANDLE hKey); NTSTATUS BCryptVerifySignature(BCRYPT_KEY_HANDLE hKey, void *pPaddingInfo, PUCHAR pbHash, ULONG cbHash, PUCHAR pbSignature, ULONG cbSignature, ULONG dwFlags); NTSTATUS BCryptSignHash(BCRYPT_KEY_HANDLE hKey, void * pPaddingInfo, PBYTE pbInput, DWORD cbInput, PBYTE pbOutput, DWORD cbOutput, DWORD *pcbResult, ULONG dwFlags); NTSTATUS BCryptEncrypt(BCRYPT_KEY_HANDLE hKey, PUCHAR pbInput, ULONG cbInput, void *pPaddingInfo, PUCHAR pbIV, ULONG cbIV, PUCHAR pbOutput, ULONG cbOutput, ULONG *pcbResult, ULONG dwFlags); NTSTATUS BCryptDecrypt(BCRYPT_KEY_HANDLE hKey, PUCHAR pbInput, ULONG cbInput, void *pPaddingInfo, PUCHAR pbIV, ULONG cbIV, PUCHAR pbOutput, ULONG cbOutput, ULONG *pcbResult, ULONG dwFlags); NTSTATUS BCryptDeriveKeyPBKDF2(BCRYPT_ALG_HANDLE hPrf, PUCHAR pbPassword, ULONG cbPassword, PUCHAR pbSalt, ULONG cbSalt, ULONGLONG cIterations, PUCHAR pbDerivedKey, ULONG cbDerivedKey, ULONG dwFlags); NTSTATUS BCryptGenRandom(BCRYPT_ALG_HANDLE hAlgorithm, PUCHAR pbBuffer, ULONG cbBuffer, ULONG dwFlags); NTSTATUS BCryptGenerateKeyPair(BCRYPT_ALG_HANDLE hAlgorithm, BCRYPT_KEY_HANDLE *phKey, ULONG dwLength, ULONG dwFlags); NTSTATUS BCryptFinalizeKeyPair(BCRYPT_KEY_HANDLE hKey, ULONG dwFlags); NTSTATUS BCryptExportKey(BCRYPT_KEY_HANDLE hKey, BCRYPT_KEY_HANDLE hExportKey, LPCWSTR pszBlobType, PUCHAR pbOutput, ULONG cbOutput, ULONG *pcbResult, ULONG dwFlags); """) try: bcrypt = ffi.dlopen('bcrypt.dll') register_ffi(bcrypt, ffi) except (OSError) as e: if str_cls(e).find('cannot load library') != -1: raise LibraryNotFoundError('bcrypt.dll could not be found - Windows XP and Server 2003 are not supported') raise _win/_cng_ctypes.py000064400000014013147205106110010343 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from ctypes import windll, wintypes, POINTER, Structure, c_void_p, c_ulonglong, c_char_p, c_byte from ctypes.wintypes import ULONG, DWORD, LPCWSTR from .._ffi import FFIEngineError from .._types import str_cls from ..errors import LibraryNotFoundError __all__ = [ 'bcrypt', ] try: bcrypt = windll.bcrypt except (OSError) as e: if str_cls(e).find('The specified module could not be found') != -1: raise LibraryNotFoundError('bcrypt.dll could not be found - Windows XP and Server 2003 are not supported') raise BCRYPT_ALG_HANDLE = wintypes.HANDLE BCRYPT_KEY_HANDLE = wintypes.HANDLE NTSTATUS = wintypes.ULONG PUCHAR = c_char_p PBYTE = c_char_p try: bcrypt.BCryptOpenAlgorithmProvider.argtypes = [ POINTER(BCRYPT_ALG_HANDLE), LPCWSTR, LPCWSTR, DWORD ] bcrypt.BCryptOpenAlgorithmProvider.restype = NTSTATUS bcrypt.BCryptCloseAlgorithmProvider.argtypes = [ BCRYPT_ALG_HANDLE, ULONG ] bcrypt.BCryptCloseAlgorithmProvider.restype = NTSTATUS bcrypt.BCryptImportKeyPair.argtypes = [ BCRYPT_ALG_HANDLE, BCRYPT_KEY_HANDLE, LPCWSTR, POINTER(BCRYPT_KEY_HANDLE), PUCHAR, ULONG, ULONG ] bcrypt.BCryptImportKeyPair.restype = NTSTATUS bcrypt.BCryptImportKey.argtypes = [ BCRYPT_ALG_HANDLE, BCRYPT_KEY_HANDLE, LPCWSTR, POINTER(BCRYPT_KEY_HANDLE), PUCHAR, ULONG, PUCHAR, ULONG, ULONG ] bcrypt.BCryptImportKey.restype = NTSTATUS bcrypt.BCryptDestroyKey.argtypes = [ BCRYPT_KEY_HANDLE ] bcrypt.BCryptDestroyKey.restype = NTSTATUS bcrypt.BCryptVerifySignature.argtypes = [ BCRYPT_KEY_HANDLE, c_void_p, PUCHAR, ULONG, PUCHAR, ULONG, ULONG ] bcrypt.BCryptVerifySignature.restype = NTSTATUS bcrypt.BCryptSignHash.argtypes = [ BCRYPT_KEY_HANDLE, c_void_p, PBYTE, DWORD, PBYTE, DWORD, POINTER(DWORD), ULONG ] bcrypt.BCryptSignHash.restype = NTSTATUS bcrypt.BCryptSetProperty.argtypes = [ BCRYPT_KEY_HANDLE, LPCWSTR, c_void_p, ULONG, ULONG ] bcrypt.BCryptSetProperty.restype = NTSTATUS bcrypt.BCryptEncrypt.argtypes = [ BCRYPT_KEY_HANDLE, PUCHAR, ULONG, c_void_p, PUCHAR, ULONG, PUCHAR, ULONG, POINTER(ULONG), ULONG ] bcrypt.BCryptEncrypt.restype = NTSTATUS bcrypt.BCryptDecrypt.argtypes = [ BCRYPT_KEY_HANDLE, PUCHAR, ULONG, c_void_p, PUCHAR, ULONG, PUCHAR, ULONG, POINTER(ULONG), ULONG ] bcrypt.BCryptDecrypt.restype = NTSTATUS bcrypt.BCryptDeriveKeyPBKDF2.argtypes = [ BCRYPT_ALG_HANDLE, PUCHAR, ULONG, PUCHAR, ULONG, c_ulonglong, PUCHAR, ULONG, ULONG ] bcrypt.BCryptDeriveKeyPBKDF2.restype = NTSTATUS bcrypt.BCryptGenRandom.argtypes = [ BCRYPT_ALG_HANDLE, PUCHAR, ULONG, ULONG ] bcrypt.BCryptGenRandom.restype = NTSTATUS bcrypt.BCryptGenerateKeyPair.argtypes = [ BCRYPT_ALG_HANDLE, POINTER(BCRYPT_KEY_HANDLE), ULONG, ULONG ] bcrypt.BCryptGenerateKeyPair.restype = NTSTATUS bcrypt.BCryptFinalizeKeyPair.argtypes = [ BCRYPT_KEY_HANDLE, ULONG ] bcrypt.BCryptFinalizeKeyPair.restype = NTSTATUS bcrypt.BCryptExportKey.argtypes = [ BCRYPT_KEY_HANDLE, BCRYPT_KEY_HANDLE, LPCWSTR, PUCHAR, ULONG, POINTER(ULONG), ULONG ] bcrypt.BCryptExportKey.restype = NTSTATUS except (AttributeError): raise FFIEngineError('Error initializing ctypes') class BCRYPT_RSAKEY_BLOB(Structure): # noqa _fields_ = [ ('Magic', ULONG), ('BitLength', ULONG), ('cbPublicExp', ULONG), ('cbModulus', ULONG), ('cbPrime1', ULONG), ('cbPrime2', ULONG), ] class BCRYPT_DSA_KEY_BLOB(Structure): # noqa _fields_ = [ ('dwMagic', ULONG), ('cbKey', ULONG), ('Count', c_byte * 4), ('Seed', c_byte * 20), ('q', c_byte * 20), ] class BCRYPT_DSA_KEY_BLOB_V2(Structure): # noqa _fields_ = [ ('dwMagic', ULONG), ('cbKey', ULONG), ('hashAlgorithm', wintypes.INT), ('standardVersion', wintypes.INT), ('cbSeedLength', ULONG), ('cbGroupSize', ULONG), ('Count', c_byte * 4), ] class BCRYPT_ECCKEY_BLOB(Structure): # noqa _fields_ = [ ('dwMagic', ULONG), ('cbKey', ULONG), ] class BCRYPT_PKCS1_PADDING_INFO(Structure): # noqa _fields_ = [ ('pszAlgId', LPCWSTR), ] class BCRYPT_PSS_PADDING_INFO(Structure): # noqa _fields_ = [ ('pszAlgId', LPCWSTR), ('cbSalt', ULONG), ] class BCRYPT_OAEP_PADDING_INFO(Structure): # noqa _fields_ = [ ('pszAlgId', LPCWSTR), ('pbLabel', PUCHAR), ('cbLabel', ULONG), ] class BCRYPT_KEY_DATA_BLOB_HEADER(Structure): # noqa _fields_ = [ ('dwMagic', ULONG), ('dwVersion', ULONG), ('cbKeyData', ULONG), ] setattr(bcrypt, 'BCRYPT_ALG_HANDLE', BCRYPT_ALG_HANDLE) setattr(bcrypt, 'BCRYPT_KEY_HANDLE', BCRYPT_KEY_HANDLE) setattr(bcrypt, 'BCRYPT_RSAKEY_BLOB', BCRYPT_RSAKEY_BLOB) setattr(bcrypt, 'BCRYPT_DSA_KEY_BLOB', BCRYPT_DSA_KEY_BLOB) setattr(bcrypt, 'BCRYPT_DSA_KEY_BLOB_V2', BCRYPT_DSA_KEY_BLOB_V2) setattr(bcrypt, 'BCRYPT_ECCKEY_BLOB', BCRYPT_ECCKEY_BLOB) setattr(bcrypt, 'BCRYPT_PKCS1_PADDING_INFO', BCRYPT_PKCS1_PADDING_INFO) setattr(bcrypt, 'BCRYPT_PSS_PADDING_INFO', BCRYPT_PSS_PADDING_INFO) setattr(bcrypt, 'BCRYPT_OAEP_PADDING_INFO', BCRYPT_OAEP_PADDING_INFO) setattr(bcrypt, 'BCRYPT_KEY_DATA_BLOB_HEADER', BCRYPT_KEY_DATA_BLOB_HEADER) _win/_crypt32.py000064400000003551147205106110007520 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from .. import ffi from ._decode import _try_decode from .._ffi import buffer_from_bytes from .._types import str_cls if ffi() == 'cffi': from ._crypt32_cffi import crypt32, get_error else: from ._crypt32_ctypes import crypt32, get_error __all__ = [ 'crypt32', 'Crypt32Const', 'handle_error', ] def handle_error(result): """ Extracts the last Windows error message into a python unicode string :param result: A function result, 0 or None indicates failure :return: A unicode string error message """ if result: return _, error_string = get_error() if not isinstance(error_string, str_cls): error_string = _try_decode(error_string) raise OSError(error_string) class Crypt32Const(): X509_ASN_ENCODING = 1 ERROR_INSUFFICIENT_BUFFER = 122 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG = 0x4 CRYPT_E_NOT_FOUND = -2146885628 CERT_STORE_PROV_MEMORY = b'Memory' CERT_STORE_CREATE_NEW_FLAG = 0x00002000 CERT_STORE_ADD_USE_EXISTING = 2 USAGE_MATCH_TYPE_OR = 1 CERT_CHAIN_POLICY_SSL = 4 AUTHTYPE_SERVER = 2 CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG = 0x00000010 CERT_CHAIN_POLICY_IGNORE_ALL_REV_UNKNOWN_FLAGS = 0x00000F00 CERT_CHAIN_CACHE_END_CERT = 1 CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY = 0x80000000 TRUST_E_CERT_SIGNATURE = 0x80096004 CERT_E_EXPIRED = 0x800B0101 CERT_E_ROLE = 0x800B0103 CERT_E_PURPOSE = 0x800B0106 CERT_E_UNTRUSTEDROOT = 0x800B0109 CERT_E_CN_NO_MATCH = 0x800B010F CRYPT_E_REVOKED = 0x80092010 PKIX_KP_SERVER_AUTH = buffer_from_bytes(b"1.3.6.1.5.5.7.3.1\x00") SERVER_GATED_CRYPTO = buffer_from_bytes(b"1.3.6.1.4.1.311.10.3.3\x00") SGC_NETSCAPE = buffer_from_bytes(b"2.16.840.1.113730.4.1\x00") _win/_crypt32_cffi.py000064400000013440147205106110010505 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import sys from .._ffi import register_ffi from .._types import str_cls from ..errors import LibraryNotFoundError import cffi __all__ = [ 'crypt32', 'get_error', ] ffi = cffi.FFI() if cffi.__version_info__ >= (0, 9): ffi.set_unicode(True) if sys.maxsize > 2 ** 32: ffi.cdef("typedef uint64_t ULONG_PTR;") else: ffi.cdef("typedef unsigned long ULONG_PTR;") ffi.cdef(""" typedef HANDLE HCERTSTORE; typedef unsigned char *PBYTE; typedef struct _CRYPTOAPI_BLOB { DWORD cbData; PBYTE pbData; } CRYPTOAPI_BLOB; typedef CRYPTOAPI_BLOB CRYPT_INTEGER_BLOB; typedef CRYPTOAPI_BLOB CERT_NAME_BLOB; typedef CRYPTOAPI_BLOB CRYPT_BIT_BLOB; typedef CRYPTOAPI_BLOB CRYPT_OBJID_BLOB; typedef struct _CRYPT_ALGORITHM_IDENTIFIER { LPSTR pszObjId; CRYPT_OBJID_BLOB Parameters; } CRYPT_ALGORITHM_IDENTIFIER; typedef struct _FILETIME { DWORD dwLowDateTime; DWORD dwHighDateTime; } FILETIME; typedef struct _CERT_PUBLIC_KEY_INFO { CRYPT_ALGORITHM_IDENTIFIER Algorithm; CRYPT_BIT_BLOB PublicKey; } CERT_PUBLIC_KEY_INFO; typedef struct _CERT_EXTENSION { LPSTR pszObjId; BOOL fCritical; CRYPT_OBJID_BLOB Value; } CERT_EXTENSION, *PCERT_EXTENSION; typedef struct _CERT_INFO { DWORD dwVersion; CRYPT_INTEGER_BLOB SerialNumber; CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm; CERT_NAME_BLOB Issuer; FILETIME NotBefore; FILETIME NotAfter; CERT_NAME_BLOB Subject; CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo; CRYPT_BIT_BLOB IssuerUniqueId; CRYPT_BIT_BLOB SubjectUniqueId; DWORD cExtension; PCERT_EXTENSION *rgExtension; } CERT_INFO, *PCERT_INFO; typedef struct _CERT_CONTEXT { DWORD dwCertEncodingType; PBYTE pbCertEncoded; DWORD cbCertEncoded; PCERT_INFO pCertInfo; HCERTSTORE hCertStore; } CERT_CONTEXT, *PCERT_CONTEXT; typedef struct _CERT_TRUST_STATUS { DWORD dwErrorStatus; DWORD dwInfoStatus; } CERT_TRUST_STATUS, *PCERT_TRUST_STATUS; typedef struct _CERT_ENHKEY_USAGE { DWORD cUsageIdentifier; LPSTR *rgpszUsageIdentifier; } CERT_ENHKEY_USAGE, *PCERT_ENHKEY_USAGE; typedef struct _CERT_CHAIN_ELEMENT { DWORD cbSize; PCERT_CONTEXT pCertContext; CERT_TRUST_STATUS TrustStatus; void *pRevocationInfo; PCERT_ENHKEY_USAGE pIssuanceUsage; PCERT_ENHKEY_USAGE pApplicationUsage; LPCWSTR pwszExtendedErrorInfo; } CERT_CHAIN_ELEMENT, *PCERT_CHAIN_ELEMENT; typedef struct _CERT_SIMPLE_CHAIN { DWORD cbSize; CERT_TRUST_STATUS TrustStatus; DWORD cElement; PCERT_CHAIN_ELEMENT *rgpElement; void *pTrustListInfo; BOOL fHasRevocationFreshnessTime; DWORD dwRevocationFreshnessTime; } CERT_SIMPLE_CHAIN, *PCERT_SIMPLE_CHAIN; typedef struct _CERT_CHAIN_CONTEXT { DWORD cbSize; CERT_TRUST_STATUS TrustStatus; DWORD cChain; PCERT_SIMPLE_CHAIN *rgpChain; DWORD cLowerQualityChainContext; void *rgpLowerQualityChainContext; BOOL fHasRevocationFreshnessTime; DWORD dwRevocationFreshnessTime; } CERT_CHAIN_CONTEXT, *PCERT_CHAIN_CONTEXT; typedef struct _CERT_USAGE_MATCH { DWORD dwType; CERT_ENHKEY_USAGE Usage; } CERT_USAGE_MATCH; typedef struct _CERT_CHAIN_PARA { DWORD cbSize; CERT_USAGE_MATCH RequestedUsage; } CERT_CHAIN_PARA; typedef struct _CERT_CHAIN_POLICY_PARA { DWORD cbSize; DWORD dwFlags; void *pvExtraPolicyPara; } CERT_CHAIN_POLICY_PARA; typedef struct _HTTPSPolicyCallbackData { DWORD cbSize; DWORD dwAuthType; DWORD fdwChecks; WCHAR *pwszServerName; } SSL_EXTRA_CERT_CHAIN_POLICY_PARA; typedef struct _CERT_CHAIN_POLICY_STATUS { DWORD cbSize; DWORD dwError; LONG lChainIndex; LONG lElementIndex; void *pvExtraPolicyStatus; } CERT_CHAIN_POLICY_STATUS; typedef HANDLE HCERTCHAINENGINE; typedef HANDLE HCRYPTPROV; HCERTSTORE CertOpenStore(LPCSTR lpszStoreProvider, DWORD dwMsgAndCertEncodingType, HCRYPTPROV hCryptProv, DWORD dwFlags, void *pvPara); BOOL CertAddEncodedCertificateToStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, BYTE *pbCertEncoded, DWORD cbCertEncoded, DWORD dwAddDisposition, PCERT_CONTEXT *ppCertContext); BOOL CertGetCertificateChain(HCERTCHAINENGINE hChainEngine, CERT_CONTEXT *pCertContext, FILETIME *pTime, HCERTSTORE hAdditionalStore, CERT_CHAIN_PARA *pChainPara, DWORD dwFlags, void *pvReserved, PCERT_CHAIN_CONTEXT *ppChainContext); BOOL CertVerifyCertificateChainPolicy(ULONG_PTR pszPolicyOID, PCERT_CHAIN_CONTEXT pChainContext, CERT_CHAIN_POLICY_PARA *pPolicyPara, CERT_CHAIN_POLICY_STATUS *pPolicyStatus); void CertFreeCertificateChain(PCERT_CHAIN_CONTEXT pChainContext); HCERTSTORE CertOpenSystemStoreW(HANDLE hprov, LPCWSTR szSubsystemProtocol); PCERT_CONTEXT CertEnumCertificatesInStore(HCERTSTORE hCertStore, CERT_CONTEXT *pPrevCertContext); BOOL CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags); BOOL CertGetEnhancedKeyUsage(CERT_CONTEXT *pCertContext, DWORD dwFlags, CERT_ENHKEY_USAGE *pUsage, DWORD *pcbUsage); """) try: crypt32 = ffi.dlopen('crypt32.dll') register_ffi(crypt32, ffi) except (OSError) as e: if str_cls(e).find('cannot load library') != -1: raise LibraryNotFoundError('crypt32.dll could not be found') raise def get_error(): return ffi.getwinerror() _win/_crypt32_ctypes.py000064400000020034147205106110011102 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import sys import ctypes from ctypes import windll, wintypes, POINTER, Structure, c_void_p, c_char_p from ctypes.wintypes import DWORD from .._ffi import FFIEngineError from .._types import str_cls from ..errors import LibraryNotFoundError from ._kernel32 import kernel32 __all__ = [ 'crypt32', 'get_error', ] try: crypt32 = windll.crypt32 except (OSError) as e: if str_cls(e).find('The specified module could not be found') != -1: raise LibraryNotFoundError('crypt32.dll could not be found') raise HCERTSTORE = wintypes.HANDLE HCERTCHAINENGINE = wintypes.HANDLE HCRYPTPROV = wintypes.HANDLE HCRYPTKEY = wintypes.HANDLE PBYTE = c_char_p if sys.maxsize > 2 ** 32: ULONG_PTR = ctypes.c_uint64 else: ULONG_PTR = ctypes.c_ulong try: class CRYPTOAPI_BLOB(Structure): # noqa _fields_ = [ ("cbData", DWORD), ("pbData", c_void_p), ] CRYPT_INTEGER_BLOB = CRYPTOAPI_BLOB CERT_NAME_BLOB = CRYPTOAPI_BLOB CRYPT_BIT_BLOB = CRYPTOAPI_BLOB CRYPT_OBJID_BLOB = CRYPTOAPI_BLOB class CRYPT_ALGORITHM_IDENTIFIER(Structure): # noqa _fields_ = [ ("pszObjId", wintypes.LPSTR), ("Parameters", CRYPT_OBJID_BLOB), ] class CERT_PUBLIC_KEY_INFO(Structure): # noqa _fields_ = [ ("Algorithm", CRYPT_ALGORITHM_IDENTIFIER), ("PublicKey", CRYPT_BIT_BLOB), ] class CERT_EXTENSION(Structure): # noqa _fields_ = [ ("pszObjId", wintypes.LPSTR), ("fCritical", wintypes.BOOL), ("Value", CRYPT_OBJID_BLOB), ] PCERT_EXTENSION = POINTER(CERT_EXTENSION) class CERT_INFO(Structure): # noqa _fields_ = [ ("dwVersion", DWORD), ("SerialNumber", CRYPT_INTEGER_BLOB), ("SignatureAlgorithm", CRYPT_ALGORITHM_IDENTIFIER), ("Issuer", CERT_NAME_BLOB), ("NotBefore", kernel32.FILETIME), ("NotAfter", kernel32.FILETIME), ("Subject", CERT_NAME_BLOB), ("SubjectPublicKeyInfo", CERT_PUBLIC_KEY_INFO), ("IssuerUniqueId", CRYPT_BIT_BLOB), ("SubjectUniqueId", CRYPT_BIT_BLOB), ("cExtension", DWORD), ("rgExtension", POINTER(PCERT_EXTENSION)), ] PCERT_INFO = POINTER(CERT_INFO) class CERT_CONTEXT(Structure): # noqa _fields_ = [ ("dwCertEncodingType", DWORD), ("pbCertEncoded", c_void_p), ("cbCertEncoded", DWORD), ("pCertInfo", PCERT_INFO), ("hCertStore", HCERTSTORE) ] PCERT_CONTEXT = POINTER(CERT_CONTEXT) class CERT_ENHKEY_USAGE(Structure): # noqa _fields_ = [ ('cUsageIdentifier', DWORD), ('rgpszUsageIdentifier', POINTER(POINTER(wintypes.BYTE))), ] PCERT_ENHKEY_USAGE = POINTER(CERT_ENHKEY_USAGE) class CERT_TRUST_STATUS(Structure): # noqa _fields_ = [ ('dwErrorStatus', DWORD), ('dwInfoStatus', DWORD), ] class CERT_CHAIN_ELEMENT(Structure): # noqa _fields_ = [ ('cbSize', DWORD), ('pCertContext', PCERT_CONTEXT), ('TrustStatus', CERT_TRUST_STATUS), ('pRevocationInfo', c_void_p), ('pIssuanceUsage', PCERT_ENHKEY_USAGE), ('pApplicationUsage', PCERT_ENHKEY_USAGE), ('pwszExtendedErrorInfo', wintypes.LPCWSTR), ] PCERT_CHAIN_ELEMENT = POINTER(CERT_CHAIN_ELEMENT) class CERT_SIMPLE_CHAIN(Structure): # noqa _fields_ = [ ('cbSize', DWORD), ('TrustStatus', CERT_TRUST_STATUS), ('cElement', DWORD), ('rgpElement', POINTER(PCERT_CHAIN_ELEMENT)), ('pTrustListInfo', c_void_p), ('fHasRevocationFreshnessTime', wintypes.BOOL), ('dwRevocationFreshnessTime', DWORD), ] PCERT_SIMPLE_CHAIN = POINTER(CERT_SIMPLE_CHAIN) class CERT_CHAIN_CONTEXT(Structure): # noqa _fields_ = [ ('cbSize', DWORD), ('TrustStatus', CERT_TRUST_STATUS), ('cChain', DWORD), ('rgpChain', POINTER(PCERT_SIMPLE_CHAIN)), ('cLowerQualityChainContext', DWORD), ('rgpLowerQualityChainContext', c_void_p), ('fHasRevocationFreshnessTime', wintypes.BOOL), ('dwRevocationFreshnessTime', DWORD), ] PCERT_CHAIN_CONTEXT = POINTER(CERT_CHAIN_CONTEXT) class CERT_USAGE_MATCH(Structure): # noqa _fields_ = [ ('dwType', DWORD), ('Usage', CERT_ENHKEY_USAGE), ] class CERT_CHAIN_PARA(Structure): # noqa _fields_ = [ ('cbSize', DWORD), ('RequestedUsage', CERT_USAGE_MATCH), ] class CERT_CHAIN_POLICY_PARA(Structure): # noqa _fields_ = [ ('cbSize', DWORD), ('dwFlags', DWORD), ('pvExtraPolicyPara', c_void_p), ] class SSL_EXTRA_CERT_CHAIN_POLICY_PARA(Structure): # noqa _fields_ = [ ('cbSize', DWORD), ('dwAuthType', DWORD), ('fdwChecks', DWORD), ('pwszServerName', wintypes.LPCWSTR), ] class CERT_CHAIN_POLICY_STATUS(Structure): # noqa _fields_ = [ ('cbSize', DWORD), ('dwError', DWORD), ('lChainIndex', wintypes.LONG), ('lElementIndex', wintypes.LONG), ('pvExtraPolicyStatus', c_void_p), ] crypt32.CertOpenStore.argtypes = [ wintypes.LPCSTR, DWORD, HCRYPTPROV, DWORD, c_void_p ] crypt32.CertOpenStore.restype = HCERTSTORE crypt32.CertAddEncodedCertificateToStore.argtypes = [ HCERTSTORE, DWORD, PBYTE, DWORD, DWORD, POINTER(PCERT_CONTEXT) ] crypt32.CertAddEncodedCertificateToStore.restype = wintypes.BOOL crypt32.CertGetCertificateChain.argtypes = [ HCERTCHAINENGINE, PCERT_CONTEXT, POINTER(kernel32.FILETIME), HCERTSTORE, POINTER(CERT_CHAIN_PARA), DWORD, c_void_p, POINTER(PCERT_CHAIN_CONTEXT) ] crypt32.CertGetCertificateChain.restype = wintypes.BOOL crypt32.CertVerifyCertificateChainPolicy.argtypes = [ ULONG_PTR, PCERT_CHAIN_CONTEXT, POINTER(CERT_CHAIN_POLICY_PARA), POINTER(CERT_CHAIN_POLICY_STATUS) ] crypt32.CertVerifyCertificateChainPolicy.restype = wintypes.BOOL crypt32.CertFreeCertificateChain.argtypes = [ PCERT_CHAIN_CONTEXT ] crypt32.CertFreeCertificateChain.restype = None crypt32.CertOpenSystemStoreW.argtypes = [ wintypes.HANDLE, wintypes.LPCWSTR ] crypt32.CertOpenSystemStoreW.restype = HCERTSTORE crypt32.CertEnumCertificatesInStore.argtypes = [ HCERTSTORE, PCERT_CONTEXT ] crypt32.CertEnumCertificatesInStore.restype = PCERT_CONTEXT crypt32.CertCloseStore.argtypes = [ HCERTSTORE, DWORD ] crypt32.CertCloseStore.restype = wintypes.BOOL crypt32.CertGetEnhancedKeyUsage.argtypes = [ PCERT_CONTEXT, DWORD, c_void_p, POINTER(DWORD) ] crypt32.CertGetEnhancedKeyUsage.restype = wintypes.BOOL except (AttributeError): raise FFIEngineError('Error initializing ctypes') setattr(crypt32, 'FILETIME', kernel32.FILETIME) setattr(crypt32, 'CERT_ENHKEY_USAGE', CERT_ENHKEY_USAGE) setattr(crypt32, 'CERT_CONTEXT', CERT_CONTEXT) setattr(crypt32, 'PCERT_CONTEXT', PCERT_CONTEXT) setattr(crypt32, 'CERT_USAGE_MATCH', CERT_USAGE_MATCH) setattr(crypt32, 'CERT_CHAIN_PARA', CERT_CHAIN_PARA) setattr(crypt32, 'CERT_CHAIN_POLICY_PARA', CERT_CHAIN_POLICY_PARA) setattr(crypt32, 'SSL_EXTRA_CERT_CHAIN_POLICY_PARA', SSL_EXTRA_CERT_CHAIN_POLICY_PARA) setattr(crypt32, 'CERT_CHAIN_POLICY_STATUS', CERT_CHAIN_POLICY_STATUS) setattr(crypt32, 'PCERT_CHAIN_CONTEXT', PCERT_CHAIN_CONTEXT) def get_error(): error = ctypes.GetLastError() return (error, ctypes.FormatError(error)) _win/_decode.py000064400000001621147205106110007431 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import locale from .._types import str_cls _encoding = locale.getpreferredencoding() _fallback_encodings = ['utf-8', 'cp1252'] def _try_decode(byte_string): """ Tries decoding a byte string from the OS into a unicode string :param byte_string: A byte string :return: A unicode string """ try: return str_cls(byte_string, _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(byte_string, encoding, errors='strict') except (UnicodeDecodeError): pass return str_cls(byte_string, errors='replace') _win/_kernel32.py000064400000001446147205106110007640 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from .. import ffi from ._decode import _try_decode from .._types import str_cls if ffi() == 'cffi': from ._kernel32_cffi import kernel32, get_error else: from ._kernel32_ctypes import kernel32, get_error __all__ = [ 'handle_error', 'kernel32', ] def handle_error(result): """ Extracts the last Windows error message into a python unicode string :param result: A function result, 0 or None indicates failure :return: A unicode string error message """ if result: return _, error_string = get_error() if not isinstance(error_string, str_cls): error_string = _try_decode(error_string) raise OSError(error_string) _win/_kernel32_cffi.py000064400000001644147205106110010627 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from .._ffi import register_ffi from .._types import str_cls from ..errors import LibraryNotFoundError import cffi __all__ = [ 'get_error', 'kernel32', ] ffi = cffi.FFI() if cffi.__version_info__ >= (0, 9): ffi.set_unicode(True) ffi.cdef(""" typedef long long LARGE_INTEGER; BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount); typedef struct _FILETIME { DWORD dwLowDateTime; DWORD dwHighDateTime; } FILETIME; void GetSystemTimeAsFileTime(FILETIME *lpSystemTimeAsFileTime); """) try: kernel32 = ffi.dlopen('kernel32.dll') register_ffi(kernel32, ffi) except (OSError) as e: if str_cls(e).find('cannot load library') != -1: raise LibraryNotFoundError('kernel32.dll could not be found') raise def get_error(): return ffi.getwinerror() _win/_kernel32_ctypes.py000064400000002365147205106110011230 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import ctypes from ctypes import windll, wintypes, POINTER, c_longlong, Structure from .._ffi import FFIEngineError from .._types import str_cls from ..errors import LibraryNotFoundError __all__ = [ 'get_error', 'kernel32', ] try: kernel32 = windll.kernel32 except (OSError) as e: if str_cls(e).find('The specified module could not be found') != -1: raise LibraryNotFoundError('kernel32.dll could not be found') raise LARGE_INTEGER = c_longlong try: kernel32.QueryPerformanceCounter.argtypes = [POINTER(LARGE_INTEGER)] kernel32.QueryPerformanceCounter.restype = wintypes.BOOL class FILETIME(Structure): _fields_ = [ ("dwLowDateTime", wintypes.DWORD), ("dwHighDateTime", wintypes.DWORD), ] kernel32.GetSystemTimeAsFileTime.argtypes = [POINTER(FILETIME)] kernel32.GetSystemTimeAsFileTime.restype = None except (AttributeError): raise FFIEngineError('Error initializing ctypes') setattr(kernel32, 'LARGE_INTEGER', LARGE_INTEGER) setattr(kernel32, 'FILETIME', FILETIME) def get_error(): error = ctypes.GetLastError() return (error, ctypes.FormatError(error)) _win/_secur32.py000064400000007601147205106110007500 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from .. import ffi from ._decode import _try_decode from ..errors import TLSError from .._types import str_cls if ffi() == 'cffi': from ._secur32_cffi import secur32, get_error else: from ._secur32_ctypes import secur32, get_error __all__ = [ 'handle_error', 'secur32', 'Secur32Const', ] def handle_error(result, exception_class=None): """ Extracts the last Windows error message into a python unicode string :param result: A function result, 0 or None indicates failure :param exception_class: The exception class to use for the exception if an error occurred :return: A unicode string error message """ if result == 0: return if result == Secur32Const.SEC_E_OUT_OF_SEQUENCE: raise TLSError('A packet was received out of order') if result == Secur32Const.SEC_E_MESSAGE_ALTERED: raise TLSError('A packet was received altered') if result == Secur32Const.SEC_E_CONTEXT_EXPIRED: raise TLSError('The TLS session expired') _, error_string = get_error() if not isinstance(error_string, str_cls): error_string = _try_decode(error_string) if exception_class is None: exception_class = OSError raise exception_class(('SECURITY_STATUS error 0x%0.2X: ' % result) + error_string) class Secur32Const(): SCHANNEL_CRED_VERSION = 4 SECPKG_CRED_OUTBOUND = 0x00000002 UNISP_NAME = "Microsoft Unified Security Protocol Provider" SCH_CRED_MANUAL_CRED_VALIDATION = 0x00000008 SCH_CRED_AUTO_CRED_VALIDATION = 0x00000020 SCH_USE_STRONG_CRYPTO = 0x00400000 SCH_CRED_NO_DEFAULT_CREDS = 0x00000010 SECBUFFER_VERSION = 0 SEC_E_OK = 0x00000000 SEC_I_CONTINUE_NEEDED = 0x00090312 SEC_I_CONTEXT_EXPIRED = 0x00090317 SEC_I_RENEGOTIATE = 0x00090321 SEC_E_INCOMPLETE_MESSAGE = 0x80090318 SEC_E_INVALID_TOKEN = 0x80090308 SEC_E_OUT_OF_SEQUENCE = 0x8009031 SEC_E_MESSAGE_ALTERED = 0x8009030F SEC_E_CONTEXT_EXPIRED = 0x80090317 SEC_E_INVALID_PARAMETER = 0x8009035D SEC_E_WRONG_PRINCIPAL = 0x80090322 # Domain name mismatch SEC_E_UNTRUSTED_ROOT = 0x80090325 SEC_E_CERT_EXPIRED = 0x80090328 SEC_E_ILLEGAL_MESSAGE = 0x80090326 # Handshake error SEC_E_INTERNAL_ERROR = 0x80090304 # Occurs when DH params are too small SEC_E_BUFFER_TOO_SMALL = 0x80090321 SEC_I_INCOMPLETE_CREDENTIALS = 0x00090320 ISC_REQ_REPLAY_DETECT = 4 ISC_REQ_SEQUENCE_DETECT = 8 ISC_REQ_CONFIDENTIALITY = 16 ISC_REQ_ALLOCATE_MEMORY = 256 ISC_REQ_INTEGRITY = 65536 ISC_REQ_STREAM = 0x00008000 ISC_REQ_USE_SUPPLIED_CREDS = 0x00000080 ISC_RET_REPLAY_DETECT = 4 ISC_RET_SEQUENCE_DETECT = 8 ISC_RET_CONFIDENTIALITY = 16 ISC_RET_ALLOCATED_MEMORY = 256 ISC_RET_INTEGRITY = 65536 ISC_RET_STREAM = 0x00008000 SECBUFFER_ALERT = 17 SECBUFFER_STREAM_HEADER = 7 SECBUFFER_STREAM_TRAILER = 6 SECBUFFER_EXTRA = 5 SECBUFFER_TOKEN = 2 SECBUFFER_DATA = 1 SECBUFFER_EMPTY = 0 SECPKG_ATTR_STREAM_SIZES = 0x04 SECPKG_ATTR_CONNECTION_INFO = 0x5A SECPKG_ATTR_REMOTE_CERT_CONTEXT = 0x53 SP_PROT_TLS1_2_CLIENT = 0x800 SP_PROT_TLS1_1_CLIENT = 0x200 SP_PROT_TLS1_CLIENT = 0x80 SP_PROT_SSL3_CLIENT = 0x20 SP_PROT_SSL2_CLIENT = 0x8 CALG_AES_256 = 0x00006610 CALG_AES_128 = 0x0000660E CALG_3DES = 0x00006603 CALG_RC4 = 0x00006801 CALG_RC2 = 0x00006602 CALG_DES = 0x00006601 CALG_MD5 = 0x00008003 CALG_SHA1 = 0x00008004 CALG_SHA256 = 0x0000800C CALG_SHA384 = 0x0000800D CALG_SHA512 = 0x0000800E CALG_DH_SF = 0x0000AA01 CALG_DH_EPHEM = 0x0000AA02 CALG_ECDH = 0x0000AA05 CALG_ECDHE = 0x0000AE06 CALG_RSA_KEYX = 0x0000A400 CALG_RSA_SIGN = 0x00002400 CALG_ECDSA = 0x00002203 CALG_DSS_SIGN = 0x00002200 _win/_secur32_cffi.py000064400000007577147205106110010503 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import sys from .._ffi import register_ffi from .._types import str_cls from ..errors import LibraryNotFoundError import cffi __all__ = [ 'get_error', 'secur32', ] ffi = cffi.FFI() if cffi.__version_info__ >= (0, 9): ffi.set_unicode(True) if sys.maxsize > 2 ** 32: ffi.cdef("typedef uint64_t ULONG_PTR;") else: ffi.cdef("typedef unsigned long ULONG_PTR;") ffi.cdef(""" typedef HANDLE HCERTSTORE; typedef unsigned int ALG_ID; typedef WCHAR SEC_WCHAR; typedef unsigned long SECURITY_STATUS; typedef void *LUID; typedef void *SEC_GET_KEY_FN; typedef struct _SecHandle { ULONG_PTR dwLower; ULONG_PTR dwUpper; } SecHandle; typedef SecHandle CredHandle; typedef SecHandle CtxtHandle; typedef struct _SCHANNEL_CRED { DWORD dwVersion; DWORD cCreds; void *paCred; HCERTSTORE hRootStore; DWORD cMappers; void **aphMappers; DWORD cSupportedAlgs; ALG_ID *palgSupportedAlgs; DWORD grbitEnabledProtocols; DWORD dwMinimumCipherStrength; DWORD dwMaximumCipherStrength; DWORD dwSessionLifespan; DWORD dwFlags; DWORD dwCredFormat; } SCHANNEL_CRED; typedef struct _TimeStamp { DWORD dwLowDateTime; DWORD dwHighDateTime; } TimeStamp; typedef struct _SecBuffer { ULONG cbBuffer; ULONG BufferType; BYTE *pvBuffer; } SecBuffer; typedef struct _SecBufferDesc { ULONG ulVersion; ULONG cBuffers; SecBuffer *pBuffers; } SecBufferDesc; typedef struct _SecPkgContext_StreamSizes { ULONG cbHeader; ULONG cbTrailer; ULONG cbMaximumMessage; ULONG cBuffers; ULONG cbBlockSize; } SecPkgContext_StreamSizes; typedef struct _CERT_CONTEXT { DWORD dwCertEncodingType; BYTE *pbCertEncoded; DWORD cbCertEncoded; void *pCertInfo; HCERTSTORE hCertStore; } CERT_CONTEXT; typedef struct _SecPkgContext_ConnectionInfo { DWORD dwProtocol; ALG_ID aiCipher; DWORD dwCipherStrength; ALG_ID aiHash; DWORD dwHashStrength; ALG_ID aiExch; DWORD dwExchStrength; } SecPkgContext_ConnectionInfo; SECURITY_STATUS AcquireCredentialsHandleW(SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse, LUID *pvLogonID, void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument, CredHandle *phCredential, TimeStamp *ptsExpiry); SECURITY_STATUS FreeCredentialsHandle(CredHandle *phCredential); SECURITY_STATUS InitializeSecurityContextW(CredHandle *phCredential, CtxtHandle *phContext, SEC_WCHAR *pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, SecBufferDesc *pInput, ULONG Reserved2, CtxtHandle *phNewContext, SecBufferDesc *pOutput, ULONG *pfContextAttr, TimeStamp *ptsExpiry); SECURITY_STATUS FreeContextBuffer(void *pvContextBuffer); SECURITY_STATUS ApplyControlToken(CtxtHandle *phContext, SecBufferDesc *pInput); SECURITY_STATUS DeleteSecurityContext(CtxtHandle *phContext); SECURITY_STATUS QueryContextAttributesW(CtxtHandle *phContext, ULONG ulAttribute, void *pBuffer); SECURITY_STATUS EncryptMessage(CtxtHandle *phContext, ULONG fQOP, SecBufferDesc *pMessage, ULONG MessageSeqNo); SECURITY_STATUS DecryptMessage(CtxtHandle *phContext, SecBufferDesc *pMessage, ULONG MessageSeqNo, ULONG *pfQOP); """) try: secur32 = ffi.dlopen('secur32.dll') register_ffi(secur32, ffi) except (OSError) as e: if str_cls(e).find('cannot load library') != -1: raise LibraryNotFoundError('secur32.dll could not be found') raise def get_error(): return ffi.getwinerror() _win/_secur32_ctypes.py000064400000012271147205106110011066 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import sys import ctypes from ctypes import windll, wintypes, POINTER, c_void_p, c_uint, Structure from ctypes.wintypes import DWORD, ULONG from .._ffi import FFIEngineError from .._types import str_cls from ..errors import LibraryNotFoundError __all__ = [ 'get_error', 'secur32', ] try: secur32 = windll.secur32 except (OSError) as e: if str_cls(e).find('The specified module could not be found') != -1: raise LibraryNotFoundError('secur32.dll could not be found') raise HCERTSTORE = wintypes.HANDLE ALG_ID = c_uint if sys.maxsize > 2 ** 32: ULONG_PTR = ctypes.c_uint64 else: ULONG_PTR = ctypes.c_ulong SEC_GET_KEY_FN = c_void_p LUID = c_void_p SECURITY_STATUS = ctypes.c_ulong SEC_WCHAR = wintypes.WCHAR try: class SecHandle(Structure): _fields_ = [ ('dwLower', ULONG_PTR), ('dwUpper', ULONG_PTR), ] CredHandle = SecHandle CtxtHandle = SecHandle class SCHANNEL_CRED(Structure): # noqa _fields_ = [ ('dwVersion', DWORD), ('cCreds', DWORD), ('paCred', c_void_p), ('hRootStore', HCERTSTORE), ('cMappers', DWORD), ('aphMappers', POINTER(c_void_p)), ('cSupportedAlgs', DWORD), ('palgSupportedAlgs', POINTER(ALG_ID)), ('grbitEnabledProtocols', DWORD), ('dwMinimumCipherStrength', DWORD), ('dwMaximumCipherStrength', DWORD), ('dwSessionLifespan', DWORD), ('dwFlags', DWORD), ('dwCredFormat', DWORD), ] class TimeStamp(Structure): _fields_ = [ ('dwLowDateTime', DWORD), ('dwHighDateTime', DWORD), ] class SecBuffer(Structure): _fields_ = [ ('cbBuffer', ULONG), ('BufferType', ULONG), ('pvBuffer', POINTER(ctypes.c_byte)), ] PSecBuffer = POINTER(SecBuffer) class SecBufferDesc(Structure): _fields_ = [ ('ulVersion', ULONG), ('cBuffers', ULONG), ('pBuffers', PSecBuffer), ] class SecPkgContext_StreamSizes(Structure): # noqa _fields_ = [ ('cbHeader', ULONG), ('cbTrailer', ULONG), ('cbMaximumMessage', ULONG), ('cBuffers', ULONG), ('cbBlockSize', ULONG), ] class SecPkgContext_ConnectionInfo(Structure): # noqa _fields_ = [ ('dwProtocol', DWORD), ('aiCipher', ALG_ID), ('dwCipherStrength', DWORD), ('aiHash', ALG_ID), ('dwHashStrength', DWORD), ('aiExch', ALG_ID), ('dwExchStrength', DWORD), ] secur32.AcquireCredentialsHandleW.argtypes = [ POINTER(SEC_WCHAR), POINTER(SEC_WCHAR), ULONG, POINTER(LUID), c_void_p, SEC_GET_KEY_FN, c_void_p, POINTER(CredHandle), POINTER(TimeStamp) ] secur32.AcquireCredentialsHandleW.restype = SECURITY_STATUS secur32.FreeCredentialsHandle.argtypes = [ POINTER(CredHandle) ] secur32.FreeCredentialsHandle.restype = SECURITY_STATUS secur32.InitializeSecurityContextW.argtypes = [ POINTER(CredHandle), POINTER(CtxtHandle), POINTER(SEC_WCHAR), ULONG, ULONG, ULONG, POINTER(SecBufferDesc), ULONG, POINTER(CtxtHandle), POINTER(SecBufferDesc), POINTER(ULONG), POINTER(TimeStamp) ] secur32.InitializeSecurityContextW.restype = SECURITY_STATUS secur32.FreeContextBuffer.argtypes = [ c_void_p ] secur32.FreeContextBuffer.restype = SECURITY_STATUS secur32.ApplyControlToken.argtypes = [ POINTER(CtxtHandle), POINTER(SecBufferDesc) ] secur32.ApplyControlToken.restype = SECURITY_STATUS secur32.DeleteSecurityContext.argtypes = [ POINTER(CtxtHandle) ] secur32.DeleteSecurityContext.restype = SECURITY_STATUS secur32.QueryContextAttributesW.argtypes = [ POINTER(CtxtHandle), ULONG, c_void_p ] secur32.QueryContextAttributesW.restype = SECURITY_STATUS secur32.EncryptMessage.argtypes = [ POINTER(CtxtHandle), ULONG, POINTER(SecBufferDesc), ULONG ] secur32.EncryptMessage.restype = SECURITY_STATUS secur32.DecryptMessage.argtypes = [ POINTER(CtxtHandle), POINTER(SecBufferDesc), ULONG, POINTER(ULONG) ] secur32.DecryptMessage.restype = SECURITY_STATUS except (AttributeError): raise FFIEngineError('Error initializing ctypes') setattr(secur32, 'ALG_ID', ALG_ID) setattr(secur32, 'CredHandle', CredHandle) setattr(secur32, 'CtxtHandle', CtxtHandle) setattr(secur32, 'SecBuffer', SecBuffer) setattr(secur32, 'SecBufferDesc', SecBufferDesc) setattr(secur32, 'SecPkgContext_StreamSizes', SecPkgContext_StreamSizes) setattr(secur32, 'SecPkgContext_ConnectionInfo', SecPkgContext_ConnectionInfo) setattr(secur32, 'SCHANNEL_CRED', SCHANNEL_CRED) def get_error(): error = ctypes.GetLastError() return (error, ctypes.FormatError(error)) _win/asymmetric.py000064400000356713147205106110010243 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import os import sys import hashlib import random from .._asn1 import ( Certificate as Asn1Certificate, DHParameters, DSAParams, DSASignature, ECDomainParameters, ECPrivateKey, Integer, int_from_bytes, int_to_bytes, PrivateKeyAlgorithm, PrivateKeyInfo, PublicKeyAlgorithm, PublicKeyInfo, RSAPrivateKey, RSAPublicKey, ) 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_from_unicode, byte_array, bytes_from_buffer, cast, deref, native, new, null, pointer_set, sizeof, struct, struct_bytes, struct_from_buffer, unwrap, write_to_buffer, ) from .. import backend from .._int import fill_width from ..errors import AsymmetricKeyError, IncompleteAsymmetricKeyError, SignatureError from .._types import type_name, str_cls, byte_cls, int_types from .._pkcs1 import ( add_pkcs1v15_signature_padding, add_pss_padding, raw_rsa_private_crypt, raw_rsa_public_crypt, remove_pkcs1v15_signature_padding, verify_pss_padding, ) from ..util import constant_compare _gwv = sys.getwindowsversion() _win_version_info = (_gwv[0], _gwv[1]) _backend = backend() if _backend == 'winlegacy': from ._advapi32 import advapi32, Advapi32Const, handle_error, open_context_handle, close_context_handle from .._ecdsa import ( ec_generate_pair as _pure_python_ec_generate_pair, ec_compute_public_key_point as _pure_python_ec_compute_public_key_point, ec_public_key_info, ecdsa_sign as _pure_python_ecdsa_sign, ecdsa_verify as _pure_python_ecdsa_verify, ) else: from ._cng import bcrypt, BcryptConst, handle_error, open_alg_handle, close_alg_handle __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', ] # A list of primes from OpenSSL's bn_prime.h to use when testing primality of a # large integer _SMALL_PRIMES = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161, 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037, 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, 10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163, 10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247, 10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303, 10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369, 10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459, 10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531, 10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, 10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691, 10709, 10711, 10723, 10729, 10733, 10739, 10753, 10771, 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859, 10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937, 10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003, 11027, 11047, 11057, 11059, 11069, 11071, 11083, 11087, 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161, 11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251, 11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317, 11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399, 11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483, 11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551, 11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657, 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731, 11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813, 11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887, 11897, 11903, 11909, 11923, 11927, 11933, 11939, 11941, 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, 12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101, 12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161, 12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251, 12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323, 12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401, 12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473, 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527, 12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589, 12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653, 12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739, 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, 12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907, 12911, 12917, 12919, 12923, 12941, 12953, 12959, 12967, 12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033, 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, 13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177, 13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259, 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337, 13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421, 13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499, 13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597, 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, 13687, 13691, 13693, 13697, 13709, 13711, 13721, 13723, 13729, 13751, 13757, 13759, 13763, 13781, 13789, 13799, 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879, 13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, 13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033, 14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143, 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221, 14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323, 14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407, 14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461, 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549, 14551, 14557, 14561, 14563, 14591, 14593, 14621, 14627, 14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699, 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753, 14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, 14827, 14831, 14843, 14851, 14867, 14869, 14879, 14887, 14891, 14897, 14923, 14929, 14939, 14947, 14951, 14957, 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073, 15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137, 15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217, 15227, 15233, 15241, 15259, 15263, 15269, 15271, 15277, 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331, 15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401, 15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473, 15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569, 15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643, 15647, 15649, 15661, 15667, 15671, 15679, 15683, 15727, 15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773, 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859, 15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919, 15923, 15937, 15959, 15971, 15973, 15991, 16001, 16007, 16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087, 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, 16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249, 16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349, 16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427, 16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493, 16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603, 16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661, 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747, 16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843, 16871, 16879, 16883, 16889, 16901, 16903, 16921, 16927, 16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993, 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, 17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159, 17167, 17183, 17189, 17191, 17203, 17207, 17209, 17231, 17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327, 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, 17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467, 17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519, 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599, 17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683, 17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783, 17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863, ] class _WinKey(): # A CNG BCRYPT_KEY_HANDLE on Vista and newer, an HCRYPTKEY on XP and 2003 key_handle = None # On XP and 2003, we have to carry around more info context_handle = None ex_key_handle = 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, key_handle, asn1): """ :param key_handle: A CNG BCRYPT_KEY_HANDLE value (Vista and newer) or an HCRYPTKEY (XP and 2003) from loading/importing the key :param asn1: An asn1crypto object for the concrete type """ self.key_handle = key_handle self.asn1 = asn1 if _backend == 'winlegacy': self._lib = advapi32 else: self._lib = bcrypt def __del__(self): if self.key_handle: if _backend == 'winlegacy': res = self._lib.CryptDestroyKey(self.key_handle) else: res = self._lib.BCryptDestroyKey(self.key_handle) handle_error(res) self.key_handle = None if self.context_handle and _backend == 'winlegacy': close_context_handle(self.context_handle) self.context_handle = None self._lib = None class PrivateKey(_WinKey, _PrivateKeyBase): """ Container for the OS crypto library representation of a private key """ _public_key = None def __init__(self, key_handle, asn1): """ :param key_handle: A CNG BCRYPT_KEY_HANDLE value (Vista and newer) or an HCRYPTKEY (XP and 2003) from loading/importing the key :param asn1: An asn1crypto.keys.PrivateKeyInfo object """ _WinKey.__init__(self, key_handle, asn1) @property def public_key(self): """ :return: A PublicKey object corresponding to this private key. """ if _backend == 'winlegacy': if self.algorithm == 'ec': pub_point = _pure_python_ec_compute_public_key_point(self.asn1) self._public_key = PublicKey(None, ec_public_key_info(pub_point, self.curve)) elif self.algorithm == 'dsa': # The DSA provider won't allow exporting the private key with # CryptoImportKey flags set to 0 and won't allow flags to be set # to CRYPT_EXPORTABLE, so we manually recreated the public key # ASN.1 params = self.asn1['private_key_algorithm']['parameters'] pub_asn1 = PublicKeyInfo({ 'algorithm': PublicKeyAlgorithm({ 'algorithm': 'dsa', 'parameters': params }), 'public_key': Integer(pow( params['g'].native, self.asn1['private_key'].parsed.native, params['p'].native )) }) self._public_key = load_public_key(pub_asn1) else: # This suffers from similar problems as above, although not # as insurmountable. This is just a simpler/faster solution # since the private key has all of the data we need anyway parsed = self.asn1['private_key'].parsed pub_asn1 = PublicKeyInfo({ 'algorithm': PublicKeyAlgorithm({ 'algorithm': 'rsa' }), 'public_key': RSAPublicKey({ 'modulus': parsed['modulus'], 'public_exponent': parsed['public_exponent'] }) }) self._public_key = load_public_key(pub_asn1) else: pub_asn1, _ = _bcrypt_key_handle_to_asn1(self.algorithm, self.bit_size, self.key_handle) self._public_key = load_public_key(pub_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 class PublicKey(_WinKey, _PublicKeyBase): """ Container for the OS crypto library representation of a public key """ def __init__(self, key_handle, asn1): """ :param key_handle: A CNG BCRYPT_KEY_HANDLE value (Vista and newer) or an HCRYPTKEY (XP and 2003) from loading/importing the key :param asn1: An asn1crypto.keys.PublicKeyInfo object """ _WinKey.__init__(self, key_handle, asn1) class Certificate(_WinKey, _CertificateBase): """ Container for the OS crypto library representation of a certificate """ _public_key = None _self_signed = None def __init__(self, key_handle, asn1): """ :param key_handle: A CNG BCRYPT_KEY_HANDLE value (Vista and newer) or an HCRYPTKEY (XP and 2003) from loading/importing the certificate :param asn1: An asn1crypto.x509.Certificate object """ _WinKey.__init__(self, key_handle, asn1) @property def public_key(self): """ :return: The PublicKey object for the public key this certificate contains """ if self._public_key is None: self._public_key = load_public_key(self.asn1['tbs_certificate']['subject_public_key_info']) 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, self.asn1['signature_value'].native, self.asn1['tbs_certificate'].dump(), hash_algo ) self._self_signed = True except (SignatureError): pass return self._self_signed 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 on Windows 8 or newer. :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': # Windows Vista and 7 only support SHA1-based DSA keys if _win_version_info < (6, 2) or _backend == 'winlegacy': 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 _backend == 'winlegacy': if algorithm == 'ec': pub_info, priv_info = _pure_python_ec_generate_pair(curve) return (PublicKey(None, pub_info), PrivateKey(None, priv_info)) return _advapi32_generate_pair(algorithm, bit_size) else: return _bcrypt_generate_pair(algorithm, bit_size, curve) def _advapi32_key_handle_to_asn1(algorithm, bit_size, key_handle): """ Accepts an key handle and exports it to ASN.1 :param algorithm: The key algorithm - "rsa" or "dsa" :param bit_size: An integer - only used when algorithm is "rsa" :param key_handle: The handle to export :return: A 2-element tuple of asn1crypto.keys.PrivateKeyInfo and asn1crypto.keys.PublicKeyInfo """ if algorithm == 'rsa': struct_type = 'RSABLOBHEADER' else: struct_type = 'DSSBLOBHEADER' out_len = new(advapi32, 'DWORD *') res = advapi32.CryptExportKey( key_handle, null(), Advapi32Const.PRIVATEKEYBLOB, 0, null(), out_len ) handle_error(res) buffer_length = deref(out_len) buffer_ = buffer_from_bytes(buffer_length) res = advapi32.CryptExportKey( key_handle, null(), Advapi32Const.PRIVATEKEYBLOB, 0, buffer_, out_len ) handle_error(res) blob_struct_pointer = struct_from_buffer(advapi32, struct_type, buffer_) blob_struct = unwrap(blob_struct_pointer) struct_size = sizeof(advapi32, blob_struct) private_blob = bytes_from_buffer(buffer_, buffer_length)[struct_size:] if algorithm == 'rsa': public_info, private_info = _advapi32_interpret_rsa_key_blob(bit_size, blob_struct, private_blob) else: # The public key for a DSA key is not available in from the private # key blob, so we have to separately export the public key public_out_len = new(advapi32, 'DWORD *') res = advapi32.CryptExportKey( key_handle, null(), Advapi32Const.PUBLICKEYBLOB, 0, null(), public_out_len ) handle_error(res) public_buffer_length = deref(public_out_len) public_buffer = buffer_from_bytes(public_buffer_length) res = advapi32.CryptExportKey( key_handle, null(), Advapi32Const.PUBLICKEYBLOB, 0, public_buffer, public_out_len ) handle_error(res) public_blob = bytes_from_buffer(public_buffer, public_buffer_length)[struct_size:] public_info, private_info = _advapi32_interpret_dsa_key_blob(bit_size, public_blob, private_blob) return (public_info, private_info) def _advapi32_generate_pair(algorithm, bit_size=None): """ Generates a public/private key pair using CryptoAPI :param algorithm: The key algorithm - "rsa" or "dsa" :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. :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 == 'rsa': provider = Advapi32Const.MS_ENH_RSA_AES_PROV algorithm_id = Advapi32Const.CALG_RSA_SIGN else: provider = Advapi32Const.MS_ENH_DSS_DH_PROV algorithm_id = Advapi32Const.CALG_DSS_SIGN context_handle = None key_handle = None try: context_handle = open_context_handle(provider, verify_only=False) key_handle_pointer = new(advapi32, 'HCRYPTKEY *') flags = (bit_size << 16) | Advapi32Const.CRYPT_EXPORTABLE res = advapi32.CryptGenKey(context_handle, algorithm_id, flags, key_handle_pointer) handle_error(res) key_handle = unwrap(key_handle_pointer) public_info, private_info = _advapi32_key_handle_to_asn1(algorithm, bit_size, key_handle) return (load_public_key(public_info), load_private_key(private_info)) finally: if context_handle: close_context_handle(context_handle) if key_handle: advapi32.CryptDestroyKey(key_handle) def _bcrypt_key_handle_to_asn1(algorithm, bit_size, key_handle): """ Accepts an key handle and exports it to ASN.1 :param algorithm: The key algorithm - "rsa", "dsa" or "ec" :param bit_size: An integer - only used when algorithm is "dsa" :param key_handle: The handle to export :return: A 2-element tuple of asn1crypto.keys.PrivateKeyInfo and asn1crypto.keys.PublicKeyInfo """ if algorithm == 'rsa': struct_type = 'BCRYPT_RSAKEY_BLOB' private_blob_type = BcryptConst.BCRYPT_RSAFULLPRIVATE_BLOB public_blob_type = BcryptConst.BCRYPT_RSAPUBLIC_BLOB elif algorithm == 'dsa': if bit_size > 1024: struct_type = 'BCRYPT_DSA_KEY_BLOB_V2' else: struct_type = 'BCRYPT_DSA_KEY_BLOB' private_blob_type = BcryptConst.BCRYPT_DSA_PRIVATE_BLOB public_blob_type = BcryptConst.BCRYPT_DSA_PUBLIC_BLOB else: struct_type = 'BCRYPT_ECCKEY_BLOB' private_blob_type = BcryptConst.BCRYPT_ECCPRIVATE_BLOB public_blob_type = BcryptConst.BCRYPT_ECCPUBLIC_BLOB private_out_len = new(bcrypt, 'ULONG *') res = bcrypt.BCryptExportKey(key_handle, null(), private_blob_type, null(), 0, private_out_len, 0) handle_error(res) private_buffer_length = deref(private_out_len) private_buffer = buffer_from_bytes(private_buffer_length) res = bcrypt.BCryptExportKey( key_handle, null(), private_blob_type, private_buffer, private_buffer_length, private_out_len, 0 ) handle_error(res) private_blob_struct_pointer = struct_from_buffer(bcrypt, struct_type, private_buffer) private_blob_struct = unwrap(private_blob_struct_pointer) struct_size = sizeof(bcrypt, private_blob_struct) private_blob = bytes_from_buffer(private_buffer, private_buffer_length)[struct_size:] if algorithm == 'rsa': private_key = _bcrypt_interpret_rsa_key_blob('private', private_blob_struct, private_blob) elif algorithm == 'dsa': if bit_size > 1024: private_key = _bcrypt_interpret_dsa_key_blob('private', 2, private_blob_struct, private_blob) else: private_key = _bcrypt_interpret_dsa_key_blob('private', 1, private_blob_struct, private_blob) else: private_key = _bcrypt_interpret_ec_key_blob('private', private_blob_struct, private_blob) public_out_len = new(bcrypt, 'ULONG *') res = bcrypt.BCryptExportKey(key_handle, null(), public_blob_type, null(), 0, public_out_len, 0) handle_error(res) public_buffer_length = deref(public_out_len) public_buffer = buffer_from_bytes(public_buffer_length) res = bcrypt.BCryptExportKey( key_handle, null(), public_blob_type, public_buffer, public_buffer_length, public_out_len, 0 ) handle_error(res) public_blob_struct_pointer = struct_from_buffer(bcrypt, struct_type, public_buffer) public_blob_struct = unwrap(public_blob_struct_pointer) struct_size = sizeof(bcrypt, public_blob_struct) public_blob = bytes_from_buffer(public_buffer, public_buffer_length)[struct_size:] if algorithm == 'rsa': public_key = _bcrypt_interpret_rsa_key_blob('public', public_blob_struct, public_blob) elif algorithm == 'dsa': if bit_size > 1024: public_key = _bcrypt_interpret_dsa_key_blob('public', 2, public_blob_struct, public_blob) else: public_key = _bcrypt_interpret_dsa_key_blob('public', 1, public_blob_struct, public_blob) else: public_key = _bcrypt_interpret_ec_key_blob('public', public_blob_struct, public_blob) return (public_key, private_key) def _bcrypt_generate_pair(algorithm, bit_size=None, curve=None): """ Generates a public/private key pair using CNG :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 on Windows 8 or newer. :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 == 'rsa': alg_constant = BcryptConst.BCRYPT_RSA_ALGORITHM elif algorithm == 'dsa': alg_constant = BcryptConst.BCRYPT_DSA_ALGORITHM else: alg_constant = { 'secp256r1': BcryptConst.BCRYPT_ECDSA_P256_ALGORITHM, 'secp384r1': BcryptConst.BCRYPT_ECDSA_P384_ALGORITHM, 'secp521r1': BcryptConst.BCRYPT_ECDSA_P521_ALGORITHM, }[curve] bit_size = { 'secp256r1': 256, 'secp384r1': 384, 'secp521r1': 521, }[curve] key_handle = None try: alg_handle = open_alg_handle(alg_constant) key_handle_pointer = new(bcrypt, 'BCRYPT_KEY_HANDLE *') res = bcrypt.BCryptGenerateKeyPair(alg_handle, key_handle_pointer, bit_size, 0) handle_error(res) key_handle = unwrap(key_handle_pointer) res = bcrypt.BCryptFinalizeKeyPair(key_handle, 0) handle_error(res) public_key, private_key = _bcrypt_key_handle_to_asn1(algorithm, bit_size, key_handle) finally: if key_handle: bcrypt.BCryptDestroyKey(key_handle) return (load_public_key(public_key), load_private_key(private_key)) 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') alg_handle = None # The following algorithm has elements taken from OpenSSL. In short, it # generates random numbers and then ensures that they are valid for the # hardcoded generator of 2, and then ensures the number is a "safe" prime # by ensuring p//2 is prime also. # OpenSSL allows use of generator 2 or 5, but we hardcode 2 since it is # the default, and what is used by Security.framework on OS X also. g = 2 try: byte_size = bit_size // 8 if _backend == 'win': alg_handle = open_alg_handle(BcryptConst.BCRYPT_RNG_ALGORITHM) buffer = buffer_from_bytes(byte_size) while True: if _backend == 'winlegacy': rb = os.urandom(byte_size) else: res = bcrypt.BCryptGenRandom(alg_handle, buffer, byte_size, 0) handle_error(res) rb = bytes_from_buffer(buffer) p = int_from_bytes(rb) # If a number is even, it can't be prime if p % 2 == 0: continue # Perform the generator checks outlined in OpenSSL's # dh_builtin_genparams() located in dh_gen.c if g == 2: if p % 24 != 11: continue elif g == 5: rem = p % 10 if rem != 3 and rem != 7: continue divisible = False for prime in _SMALL_PRIMES: if p % prime == 0: divisible = True break # If the number is not divisible by any of the small primes, then # move on to the full Miller-Rabin test. if not divisible and _is_prime(bit_size, p): q = p // 2 if _is_prime(bit_size, q): return DHParameters({'p': p, 'g': g}) finally: if alg_handle: close_alg_handle(alg_handle) def _is_prime(bit_size, n): """ An implementation of Miller–Rabin for checking if a number is prime. :param bit_size: An integer of the number of bits in the prime number :param n: An integer, the prime number :return: A boolean """ r = 0 s = n - 1 while s % 2 == 0: r += 1 s //= 2 if bit_size >= 1300: k = 2 elif bit_size >= 850: k = 3 elif bit_size >= 650: k = 4 elif bit_size >= 550: k = 5 elif bit_size >= 450: k = 6 for _ in range(k): a = random.randrange(2, n - 1) x = pow(a, s, n) if x == 1 or x == n - 1: continue for _ in range(r - 1): x = pow(x, 2, n) if x == n - 1: break else: return False return True def _advapi32_interpret_rsa_key_blob(bit_size, blob_struct, blob): """ Takes a CryptoAPI RSA private key blob and converts it into the ASN.1 structures for the public and private keys :param bit_size: The integer bit size of the key :param blob_struct: An instance of the advapi32.RSAPUBKEY struct :param blob: A byte string of the binary data after the header :return: A 2-element tuple of (asn1crypto.keys.PublicKeyInfo, asn1crypto.keys.PrivateKeyInfo) """ len1 = bit_size // 8 len2 = bit_size // 16 prime1_offset = len1 prime2_offset = prime1_offset + len2 exponent1_offset = prime2_offset + len2 exponent2_offset = exponent1_offset + len2 coefficient_offset = exponent2_offset + len2 private_exponent_offset = coefficient_offset + len2 public_exponent = blob_struct.rsapubkey.pubexp modulus = int_from_bytes(blob[0:prime1_offset][::-1]) prime1 = int_from_bytes(blob[prime1_offset:prime2_offset][::-1]) prime2 = int_from_bytes(blob[prime2_offset:exponent1_offset][::-1]) exponent1 = int_from_bytes(blob[exponent1_offset:exponent2_offset][::-1]) exponent2 = int_from_bytes(blob[exponent2_offset:coefficient_offset][::-1]) coefficient = int_from_bytes(blob[coefficient_offset:private_exponent_offset][::-1]) private_exponent = int_from_bytes(blob[private_exponent_offset:private_exponent_offset + len1][::-1]) public_key_info = PublicKeyInfo({ 'algorithm': PublicKeyAlgorithm({ 'algorithm': 'rsa', }), 'public_key': RSAPublicKey({ 'modulus': modulus, 'public_exponent': public_exponent, }), }) rsa_private_key = RSAPrivateKey({ 'version': 'two-prime', 'modulus': modulus, 'public_exponent': public_exponent, 'private_exponent': private_exponent, 'prime1': prime1, 'prime2': prime2, 'exponent1': exponent1, 'exponent2': exponent2, 'coefficient': coefficient, }) private_key_info = PrivateKeyInfo({ 'version': 0, 'private_key_algorithm': PrivateKeyAlgorithm({ 'algorithm': 'rsa', }), 'private_key': rsa_private_key, }) return (public_key_info, private_key_info) def _advapi32_interpret_dsa_key_blob(bit_size, public_blob, private_blob): """ Takes a CryptoAPI DSS private key blob and converts it into the ASN.1 structures for the public and private keys :param bit_size: The integer bit size of the key :param public_blob: A byte string of the binary data after the public key header :param private_blob: A byte string of the binary data after the private key header :return: A 2-element tuple of (asn1crypto.keys.PublicKeyInfo, asn1crypto.keys.PrivateKeyInfo) """ len1 = 20 len2 = bit_size // 8 q_offset = len2 g_offset = q_offset + len1 x_offset = g_offset + len2 y_offset = x_offset p = int_from_bytes(private_blob[0:q_offset][::-1]) q = int_from_bytes(private_blob[q_offset:g_offset][::-1]) g = int_from_bytes(private_blob[g_offset:x_offset][::-1]) x = int_from_bytes(private_blob[x_offset:x_offset + len1][::-1]) y = int_from_bytes(public_blob[y_offset:y_offset + len2][::-1]) public_key_info = PublicKeyInfo({ 'algorithm': PublicKeyAlgorithm({ 'algorithm': 'dsa', 'parameters': DSAParams({ 'p': p, 'q': q, 'g': g, }) }), 'public_key': Integer(y), }) private_key_info = PrivateKeyInfo({ 'version': 0, 'private_key_algorithm': PrivateKeyAlgorithm({ 'algorithm': 'dsa', 'parameters': DSAParams({ 'p': p, 'q': q, 'g': g, }) }), 'private_key': Integer(x), }) return (public_key_info, private_key_info) def _bcrypt_interpret_rsa_key_blob(key_type, blob_struct, blob): """ Take a CNG BCRYPT_RSAFULLPRIVATE_BLOB and converts it into an ASN.1 structure :param key_type: A unicode string of "private" or "public" :param blob_struct: An instance of BCRYPT_RSAKEY_BLOB :param blob: A byte string of the binary data contained after the struct :return: An asn1crypto.keys.PrivateKeyInfo or asn1crypto.keys.PublicKeyInfo object, based on the key_type param """ public_exponent_byte_length = native(int, blob_struct.cbPublicExp) modulus_byte_length = native(int, blob_struct.cbModulus) modulus_offset = public_exponent_byte_length public_exponent = int_from_bytes(blob[0:modulus_offset]) modulus = int_from_bytes(blob[modulus_offset:modulus_offset + modulus_byte_length]) if key_type == 'public': return PublicKeyInfo({ 'algorithm': PublicKeyAlgorithm({ 'algorithm': 'rsa', }), 'public_key': RSAPublicKey({ 'modulus': modulus, 'public_exponent': public_exponent, }), }) elif key_type == 'private': prime1_byte_length = native(int, blob_struct.cbPrime1) prime2_byte_length = native(int, blob_struct.cbPrime2) prime1_offset = modulus_offset + modulus_byte_length prime2_offset = prime1_offset + prime1_byte_length exponent1_offset = prime2_offset + prime2_byte_length exponent2_offset = exponent1_offset + prime2_byte_length coefficient_offset = exponent2_offset + prime2_byte_length private_exponent_offset = coefficient_offset + prime1_byte_length prime1 = int_from_bytes(blob[prime1_offset:prime2_offset]) prime2 = int_from_bytes(blob[prime2_offset:exponent1_offset]) exponent1 = int_from_bytes(blob[exponent1_offset:exponent2_offset]) exponent2 = int_from_bytes(blob[exponent2_offset:coefficient_offset]) coefficient = int_from_bytes(blob[coefficient_offset:private_exponent_offset]) private_exponent = int_from_bytes(blob[private_exponent_offset:private_exponent_offset + modulus_byte_length]) rsa_private_key = RSAPrivateKey({ 'version': 'two-prime', 'modulus': modulus, 'public_exponent': public_exponent, 'private_exponent': private_exponent, 'prime1': prime1, 'prime2': prime2, 'exponent1': exponent1, 'exponent2': exponent2, 'coefficient': coefficient, }) return PrivateKeyInfo({ 'version': 0, 'private_key_algorithm': PrivateKeyAlgorithm({ 'algorithm': 'rsa', }), 'private_key': rsa_private_key, }) else: raise ValueError(pretty_message( ''' key_type must be one of "public", "private", not %s ''', repr(key_type) )) def _bcrypt_interpret_dsa_key_blob(key_type, version, blob_struct, blob): """ Take a CNG BCRYPT_DSA_KEY_BLOB or BCRYPT_DSA_KEY_BLOB_V2 and converts it into an ASN.1 structure :param key_type: A unicode string of "private" or "public" :param version: An integer - 1 or 2, indicating the blob is BCRYPT_DSA_KEY_BLOB or BCRYPT_DSA_KEY_BLOB_V2 :param blob_struct: An instance of BCRYPT_DSA_KEY_BLOB or BCRYPT_DSA_KEY_BLOB_V2 :param blob: A byte string of the binary data contained after the struct :return: An asn1crypto.keys.PrivateKeyInfo or asn1crypto.keys.PublicKeyInfo object, based on the key_type param """ key_byte_length = native(int, blob_struct.cbKey) if version == 1: q = int_from_bytes(native(byte_cls, blob_struct.q)) g_offset = key_byte_length public_offset = g_offset + key_byte_length private_offset = public_offset + key_byte_length p = int_from_bytes(blob[0:g_offset]) g = int_from_bytes(blob[g_offset:public_offset]) elif version == 2: seed_byte_length = native(int, blob_struct.cbSeedLength) group_byte_length = native(int, blob_struct.cbGroupSize) q_offset = seed_byte_length p_offset = q_offset + group_byte_length g_offset = p_offset + key_byte_length public_offset = g_offset + key_byte_length private_offset = public_offset + key_byte_length # The seed is skipped since it is not part of the ASN.1 structure q = int_from_bytes(blob[q_offset:p_offset]) p = int_from_bytes(blob[p_offset:g_offset]) g = int_from_bytes(blob[g_offset:public_offset]) else: raise ValueError('version must be 1 or 2, not %s' % repr(version)) if key_type == 'public': public = int_from_bytes(blob[public_offset:private_offset]) return PublicKeyInfo({ 'algorithm': PublicKeyAlgorithm({ 'algorithm': 'dsa', 'parameters': DSAParams({ 'p': p, 'q': q, 'g': g, }) }), 'public_key': Integer(public), }) elif key_type == 'private': private = int_from_bytes(blob[private_offset:private_offset + key_byte_length]) return PrivateKeyInfo({ 'version': 0, 'private_key_algorithm': PrivateKeyAlgorithm({ 'algorithm': 'dsa', 'parameters': DSAParams({ 'p': p, 'q': q, 'g': g, }) }), 'private_key': Integer(private), }) else: raise ValueError(pretty_message( ''' key_type must be one of "public", "private", not %s ''', repr(key_type) )) def _bcrypt_interpret_ec_key_blob(key_type, blob_struct, blob): """ Take a CNG BCRYPT_ECCKEY_BLOB and converts it into an ASN.1 structure :param key_type: A unicode string of "private" or "public" :param blob_struct: An instance of BCRYPT_ECCKEY_BLOB :param blob: A byte string of the binary data contained after the struct :return: An asn1crypto.keys.PrivateKeyInfo or asn1crypto.keys.PublicKeyInfo object, based on the key_type param """ magic = native(int, blob_struct.dwMagic) key_byte_length = native(int, blob_struct.cbKey) curve = { BcryptConst.BCRYPT_ECDSA_PRIVATE_P256_MAGIC: 'secp256r1', BcryptConst.BCRYPT_ECDSA_PRIVATE_P384_MAGIC: 'secp384r1', BcryptConst.BCRYPT_ECDSA_PRIVATE_P521_MAGIC: 'secp521r1', BcryptConst.BCRYPT_ECDSA_PUBLIC_P256_MAGIC: 'secp256r1', BcryptConst.BCRYPT_ECDSA_PUBLIC_P384_MAGIC: 'secp384r1', BcryptConst.BCRYPT_ECDSA_PUBLIC_P521_MAGIC: 'secp521r1', }[magic] public = b'\x04' + blob[0:key_byte_length * 2] if key_type == 'public': return PublicKeyInfo({ 'algorithm': PublicKeyAlgorithm({ 'algorithm': 'ec', 'parameters': ECDomainParameters( name='named', value=curve ) }), 'public_key': public, }) elif key_type == 'private': private = int_from_bytes(blob[key_byte_length * 2:key_byte_length * 3]) return PrivateKeyInfo({ 'version': 0, 'private_key_algorithm': PrivateKeyAlgorithm({ 'algorithm': 'ec', 'parameters': ECDomainParameters( name='named', value=curve ) }), 'private_key': ECPrivateKey({ 'version': 'ecPrivkeyVer1', 'private_key': private, 'public_key': public, }), }) else: raise ValueError(pretty_message( ''' key_type must be one of "public", "private", not %s ''', repr(key_type) )) def load_certificate(source): """ Loads an x509 certificate into a Certificate object :param source: A byte string of file contents or a unicode string filename :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_key(certificate, Certificate) def _load_key(key_object, container): """ Loads a certificate, public key or private key into a Certificate, PublicKey or PrivateKey object :param key_object: An asn1crypto.x509.Certificate, asn1crypto.keys.PublicKeyInfo or asn1crypto.keys.PrivateKeyInfo object :param container: The class of the object to hold the key_handle :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 key is incompatible with the OS crypto library OSError - when an error is returned by the OS crypto library :return: A PrivateKey, PublicKey or Certificate object, based on container """ key_info = key_object if isinstance(key_object, Asn1Certificate): key_info = key_object['tbs_certificate']['subject_public_key_info'] algo = key_info.algorithm curve_name = None if algo == 'ec': curve_type, curve_name = key_info.curve if curve_type != 'named': raise AsymmetricKeyError(pretty_message( ''' Windows only supports EC keys using named curves ''' )) if curve_name not in set(['secp256r1', 'secp384r1', 'secp521r1']): raise AsymmetricKeyError(pretty_message( ''' Windows only supports EC keys using the named curves secp256r1, secp384r1 and secp521r1 ''' )) elif algo == 'dsa': if key_info.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 ''' )) elif key_info.bit_size > 1024 and (_win_version_info < (6, 2) or _backend == 'winlegacy'): raise AsymmetricKeyError(pretty_message( ''' Windows XP, 2003, Vista, 7 and Server 2008 only support DSA keys based on SHA1 (1024 bits or less) - this key is based on %s and is %s bits ''', key_info.hash_algo.upper(), key_info.bit_size )) elif key_info.bit_size == 2048 and key_info.hash_algo == 'sha1': raise AsymmetricKeyError(pretty_message( ''' Windows only supports 2048 bit DSA keys based on SHA2 - this key is 2048 bits and based on SHA1, a non-standard combination that is usually generated by old versions of OpenSSL ''' )) if _backend == 'winlegacy': if algo == 'ec': return container(None, key_object) return _advapi32_load_key(key_object, key_info, container) return _bcrypt_load_key(key_object, key_info, container, curve_name) def _advapi32_load_key(key_object, key_info, container): """ Loads a certificate, public key or private key into a Certificate, PublicKey or PrivateKey object via CryptoAPI :param key_object: An asn1crypto.x509.Certificate, asn1crypto.keys.PublicKeyInfo or asn1crypto.keys.PrivateKeyInfo object :param key_info: An asn1crypto.keys.PublicKeyInfo or asn1crypto.keys.PrivateKeyInfo object :param container: The class of the object to hold the key_handle :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 key is incompatible with the OS crypto library OSError - when an error is returned by the OS crypto library :return: A PrivateKey, PublicKey or Certificate object, based on container """ key_type = 'public' if isinstance(key_info, PublicKeyInfo) else 'private' algo = key_info.algorithm if algo == 'rsassa_pss': algo = 'rsa' if algo == 'rsa' or algo == 'rsassa_pss': provider = Advapi32Const.MS_ENH_RSA_AES_PROV else: provider = Advapi32Const.MS_ENH_DSS_DH_PROV context_handle = None key_handle = None try: context_handle = open_context_handle(provider, verify_only=key_type == 'public') blob = _advapi32_create_blob(key_info, key_type, algo) buffer_ = buffer_from_bytes(blob) key_handle_pointer = new(advapi32, 'HCRYPTKEY *') res = advapi32.CryptImportKey( context_handle, buffer_, len(blob), null(), 0, key_handle_pointer ) handle_error(res) key_handle = unwrap(key_handle_pointer) output = container(key_handle, key_object) output.context_handle = context_handle if algo == 'rsa': ex_blob = _advapi32_create_blob(key_info, key_type, algo, signing=False) ex_buffer = buffer_from_bytes(ex_blob) ex_key_handle_pointer = new(advapi32, 'HCRYPTKEY *') res = advapi32.CryptImportKey( context_handle, ex_buffer, len(ex_blob), null(), 0, ex_key_handle_pointer ) handle_error(res) output.ex_key_handle = unwrap(ex_key_handle_pointer) return output except (Exception): if key_handle: advapi32.CryptDestroyKey(key_handle) if context_handle: close_context_handle(context_handle) raise def _advapi32_create_blob(key_info, key_type, algo, signing=True): """ Generates a blob for importing a key to CryptoAPI :param key_info: An asn1crypto.keys.PublicKeyInfo or asn1crypto.keys.PrivateKeyInfo object :param key_type: A unicode string of "public" or "private" :param algo: A unicode string of "rsa" or "dsa" :param signing: If the key handle is for signing - may only be False for rsa keys :return: A byte string of a blob to pass to advapi32.CryptImportKey() """ if key_type == 'public': blob_type = Advapi32Const.PUBLICKEYBLOB else: blob_type = Advapi32Const.PRIVATEKEYBLOB if algo == 'rsa': struct_type = 'RSABLOBHEADER' if signing: algorithm_id = Advapi32Const.CALG_RSA_SIGN else: algorithm_id = Advapi32Const.CALG_RSA_KEYX else: struct_type = 'DSSBLOBHEADER' algorithm_id = Advapi32Const.CALG_DSS_SIGN blob_header_pointer = struct(advapi32, 'BLOBHEADER') blob_header = unwrap(blob_header_pointer) blob_header.bType = blob_type blob_header.bVersion = Advapi32Const.CUR_BLOB_VERSION blob_header.reserved = 0 blob_header.aiKeyAlg = algorithm_id blob_struct_pointer = struct(advapi32, struct_type) blob_struct = unwrap(blob_struct_pointer) blob_struct.publickeystruc = blob_header bit_size = key_info.bit_size len1 = bit_size // 8 len2 = bit_size // 16 if algo == 'rsa': pubkey_pointer = struct(advapi32, 'RSAPUBKEY') pubkey = unwrap(pubkey_pointer) pubkey.bitlen = bit_size if key_type == 'public': parsed_key_info = key_info['public_key'].parsed pubkey.magic = Advapi32Const.RSA1 pubkey.pubexp = parsed_key_info['public_exponent'].native blob_data = int_to_bytes(parsed_key_info['modulus'].native, signed=False, width=len1)[::-1] else: parsed_key_info = key_info['private_key'].parsed pubkey.magic = Advapi32Const.RSA2 pubkey.pubexp = parsed_key_info['public_exponent'].native blob_data = int_to_bytes(parsed_key_info['modulus'].native, signed=False, width=len1)[::-1] blob_data += int_to_bytes(parsed_key_info['prime1'].native, signed=False, width=len2)[::-1] blob_data += int_to_bytes(parsed_key_info['prime2'].native, signed=False, width=len2)[::-1] blob_data += int_to_bytes(parsed_key_info['exponent1'].native, signed=False, width=len2)[::-1] blob_data += int_to_bytes(parsed_key_info['exponent2'].native, signed=False, width=len2)[::-1] blob_data += int_to_bytes(parsed_key_info['coefficient'].native, signed=False, width=len2)[::-1] blob_data += int_to_bytes(parsed_key_info['private_exponent'].native, signed=False, width=len1)[::-1] blob_struct.rsapubkey = pubkey else: pubkey_pointer = struct(advapi32, 'DSSPUBKEY') pubkey = unwrap(pubkey_pointer) pubkey.bitlen = bit_size if key_type == 'public': pubkey.magic = Advapi32Const.DSS1 params = key_info['algorithm']['parameters'].native key_data = int_to_bytes(key_info['public_key'].parsed.native, signed=False, width=len1)[::-1] else: pubkey.magic = Advapi32Const.DSS2 params = key_info['private_key_algorithm']['parameters'].native key_data = int_to_bytes(key_info['private_key'].parsed.native, signed=False, width=20)[::-1] blob_struct.dsspubkey = pubkey blob_data = int_to_bytes(params['p'], signed=False, width=len1)[::-1] blob_data += int_to_bytes(params['q'], signed=False, width=20)[::-1] blob_data += int_to_bytes(params['g'], signed=False, width=len1)[::-1] blob_data += key_data dssseed_pointer = struct(advapi32, 'DSSSEED') dssseed = unwrap(dssseed_pointer) # This indicates no counter or seed info is available dssseed.counter = 0xffffffff blob_data += struct_bytes(dssseed_pointer) return struct_bytes(blob_struct_pointer) + blob_data def _bcrypt_load_key(key_object, key_info, container, curve_name): """ Loads a certificate, public key or private key into a Certificate, PublicKey or PrivateKey object via CNG :param key_object: An asn1crypto.x509.Certificate, asn1crypto.keys.PublicKeyInfo or asn1crypto.keys.PrivateKeyInfo object :param key_info: An asn1crypto.keys.PublicKeyInfo or asn1crypto.keys.PrivateKeyInfo object :param container: The class of the object to hold the key_handle :param curve_name: None or a unicode string of the curve name for an EC key :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 key is incompatible with the OS crypto library OSError - when an error is returned by the OS crypto library :return: A PrivateKey, PublicKey or Certificate object, based on container """ alg_handle = None key_handle = None key_type = 'public' if isinstance(key_info, PublicKeyInfo) else 'private' algo = key_info.algorithm if algo == 'rsassa_pss': algo = 'rsa' try: alg_selector = key_info.curve[1] if algo == 'ec' else algo alg_constant = { 'rsa': BcryptConst.BCRYPT_RSA_ALGORITHM, 'dsa': BcryptConst.BCRYPT_DSA_ALGORITHM, 'secp256r1': BcryptConst.BCRYPT_ECDSA_P256_ALGORITHM, 'secp384r1': BcryptConst.BCRYPT_ECDSA_P384_ALGORITHM, 'secp521r1': BcryptConst.BCRYPT_ECDSA_P521_ALGORITHM, }[alg_selector] alg_handle = open_alg_handle(alg_constant) if algo == 'rsa': if key_type == 'public': blob_type = BcryptConst.BCRYPT_RSAPUBLIC_BLOB magic = BcryptConst.BCRYPT_RSAPUBLIC_MAGIC parsed_key = key_info['public_key'].parsed prime1_size = 0 prime2_size = 0 else: blob_type = BcryptConst.BCRYPT_RSAFULLPRIVATE_BLOB magic = BcryptConst.BCRYPT_RSAFULLPRIVATE_MAGIC parsed_key = key_info['private_key'].parsed prime1 = int_to_bytes(parsed_key['prime1'].native) prime2 = int_to_bytes(parsed_key['prime2'].native) exponent1 = int_to_bytes(parsed_key['exponent1'].native) exponent2 = int_to_bytes(parsed_key['exponent2'].native) coefficient = int_to_bytes(parsed_key['coefficient'].native) private_exponent = int_to_bytes(parsed_key['private_exponent'].native) prime1_size = len(prime1) prime2_size = len(prime2) public_exponent = int_to_bytes(parsed_key['public_exponent'].native) modulus = int_to_bytes(parsed_key['modulus'].native) blob_struct_pointer = struct(bcrypt, 'BCRYPT_RSAKEY_BLOB') blob_struct = unwrap(blob_struct_pointer) blob_struct.Magic = magic blob_struct.BitLength = key_info.bit_size blob_struct.cbPublicExp = len(public_exponent) blob_struct.cbModulus = len(modulus) blob_struct.cbPrime1 = prime1_size blob_struct.cbPrime2 = prime2_size blob = struct_bytes(blob_struct_pointer) + public_exponent + modulus if key_type == 'private': blob += prime1 + prime2 blob += fill_width(exponent1, prime1_size) blob += fill_width(exponent2, prime2_size) blob += fill_width(coefficient, prime1_size) blob += fill_width(private_exponent, len(modulus)) elif algo == 'dsa': if key_type == 'public': blob_type = BcryptConst.BCRYPT_DSA_PUBLIC_BLOB public_key = key_info['public_key'].parsed.native params = key_info['algorithm']['parameters'] else: blob_type = BcryptConst.BCRYPT_DSA_PRIVATE_BLOB public_key = _unwrap_private_key_info(key_info)['public_key'].native private_bytes = int_to_bytes(key_info['private_key'].parsed.native) params = key_info['private_key_algorithm']['parameters'] public_bytes = int_to_bytes(public_key) p = int_to_bytes(params['p'].native) g = int_to_bytes(params['g'].native) q = int_to_bytes(params['q'].native) if key_info.bit_size > 1024: q_len = len(q) else: q_len = 20 key_width = max(len(public_bytes), len(g), len(p)) public_bytes = fill_width(public_bytes, key_width) p = fill_width(p, key_width) g = fill_width(g, key_width) q = fill_width(q, q_len) # We don't know the count or seed, so we set them to the max value # since setting them to 0 results in a parameter error count = b'\xff' * 4 seed = b'\xff' * q_len if key_info.bit_size > 1024: if key_type == 'public': magic = BcryptConst.BCRYPT_DSA_PUBLIC_MAGIC_V2 else: magic = BcryptConst.BCRYPT_DSA_PRIVATE_MAGIC_V2 blob_struct_pointer = struct(bcrypt, 'BCRYPT_DSA_KEY_BLOB_V2') blob_struct = unwrap(blob_struct_pointer) blob_struct.dwMagic = magic blob_struct.cbKey = key_width # We don't know if SHA256 was used here, but the output is long # enough for the generation of q for the supported 2048/224, # 2048/256 and 3072/256 FIPS approved pairs blob_struct.hashAlgorithm = BcryptConst.DSA_HASH_ALGORITHM_SHA256 blob_struct.standardVersion = BcryptConst.DSA_FIPS186_3 blob_struct.cbSeedLength = q_len blob_struct.cbGroupSize = q_len blob_struct.Count = byte_array(count) blob = struct_bytes(blob_struct_pointer) blob += seed + q + p + g + public_bytes if key_type == 'private': blob += fill_width(private_bytes, q_len) else: if key_type == 'public': magic = BcryptConst.BCRYPT_DSA_PUBLIC_MAGIC else: magic = BcryptConst.BCRYPT_DSA_PRIVATE_MAGIC blob_struct_pointer = struct(bcrypt, 'BCRYPT_DSA_KEY_BLOB') blob_struct = unwrap(blob_struct_pointer) blob_struct.dwMagic = magic blob_struct.cbKey = key_width blob_struct.Count = byte_array(count) blob_struct.Seed = byte_array(seed) blob_struct.q = byte_array(q) blob = struct_bytes(blob_struct_pointer) + p + g + public_bytes if key_type == 'private': blob += fill_width(private_bytes, q_len) elif algo == 'ec': if key_type == 'public': blob_type = BcryptConst.BCRYPT_ECCPUBLIC_BLOB x, y = key_info['public_key'].to_coords() else: blob_type = BcryptConst.BCRYPT_ECCPRIVATE_BLOB public_key = key_info['private_key'].parsed['public_key'] # We aren't guaranteed to get the public key coords with the # key info structure, but BCrypt doesn't seem to have an issue # importing the private key with 0 values, which can only be # presumed that it is generating the x and y points from the # private key value and base point if public_key: x, y = public_key.to_coords() else: x = 0 y = 0 private_bytes = int_to_bytes(key_info['private_key'].parsed['private_key'].native) blob_struct_pointer = struct(bcrypt, 'BCRYPT_ECCKEY_BLOB') blob_struct = unwrap(blob_struct_pointer) magic = { ('public', 'secp256r1'): BcryptConst.BCRYPT_ECDSA_PUBLIC_P256_MAGIC, ('public', 'secp384r1'): BcryptConst.BCRYPT_ECDSA_PUBLIC_P384_MAGIC, ('public', 'secp521r1'): BcryptConst.BCRYPT_ECDSA_PUBLIC_P521_MAGIC, ('private', 'secp256r1'): BcryptConst.BCRYPT_ECDSA_PRIVATE_P256_MAGIC, ('private', 'secp384r1'): BcryptConst.BCRYPT_ECDSA_PRIVATE_P384_MAGIC, ('private', 'secp521r1'): BcryptConst.BCRYPT_ECDSA_PRIVATE_P521_MAGIC, }[(key_type, curve_name)] key_width = { 'secp256r1': 32, 'secp384r1': 48, 'secp521r1': 66 }[curve_name] x_bytes = int_to_bytes(x) y_bytes = int_to_bytes(y) x_bytes = fill_width(x_bytes, key_width) y_bytes = fill_width(y_bytes, key_width) blob_struct.dwMagic = magic blob_struct.cbKey = key_width blob = struct_bytes(blob_struct_pointer) + x_bytes + y_bytes if key_type == 'private': blob += fill_width(private_bytes, key_width) key_handle_pointer = new(bcrypt, 'BCRYPT_KEY_HANDLE *') res = bcrypt.BCryptImportKeyPair( alg_handle, null(), blob_type, key_handle_pointer, blob, len(blob), BcryptConst.BCRYPT_NO_KEY_VALIDATION ) handle_error(res) key_handle = unwrap(key_handle_pointer) return container(key_handle, key_object) finally: if alg_handle: close_alg_handle(alg_handle) 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, PrivateKey) 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(public_key) )) return _load_key(public_key, PublicKey) 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, PrivateKey) if cert_info: cert = _load_key(cert_info.public_key, Certificate) extra_certs = [_load_key(info.public_key, Certificate) for info in extra_certs_info] return (key, cert, extra_certs) 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", "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('The key specified is not an RSA public key') 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", "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('The key specified is not an RSA public key') 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", "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('The key specified is not a DSA public key') 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", "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('The key specified is not an EC public key') 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", "sha256", "sha384", "sha512" or "raw" :param rsa_pss_padding: If PSS padding should be used for RSA keys :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', '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", "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 is not False: raise ValueError(pretty_message( ''' PSS padding may only be used with RSA keys - signing via a %s key was requested ''', cp_alg.upper() )) if 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) )) if _backend == 'winlegacy': if certificate_or_public_key.algorithm == 'ec': return _pure_python_ecdsa_verify(certificate_or_public_key, signature, data, hash_algorithm) return _advapi32_verify(certificate_or_public_key, signature, data, hash_algorithm, rsa_pss_padding) return _bcrypt_verify(certificate_or_public_key, signature, data, hash_algorithm, rsa_pss_padding) def _advapi32_verify(certificate_or_public_key, signature, data, hash_algorithm, rsa_pss_padding=False): """ Verifies an RSA, DSA or ECDSA signature via CryptoAPI :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", "sha256", "sha384", "sha512" or "raw" :param rsa_pss_padding: If PSS padding should be used for RSA keys :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 """ algo = certificate_or_public_key.algorithm algo_is_rsa = algo == 'rsa' or algo == 'rsassa_pss' if algo_is_rsa and rsa_pss_padding: hash_length = { 'sha1': 20, 'sha224': 28, 'sha256': 32, 'sha384': 48, 'sha512': 64 }.get(hash_algorithm, 0) decrypted_signature = raw_rsa_public_crypt(certificate_or_public_key, signature) key_size = certificate_or_public_key.bit_size if not verify_pss_padding(hash_algorithm, hash_length, key_size, data, decrypted_signature): raise SignatureError('Signature is invalid') return if algo_is_rsa and hash_algorithm == 'raw': padded_plaintext = raw_rsa_public_crypt(certificate_or_public_key, signature) try: plaintext = remove_pkcs1v15_signature_padding(certificate_or_public_key.byte_size, padded_plaintext) if not constant_compare(plaintext, data): raise ValueError() except (ValueError): raise SignatureError('Signature is invalid') return hash_handle = None try: alg_id = { 'md5': Advapi32Const.CALG_MD5, 'sha1': Advapi32Const.CALG_SHA1, 'sha256': Advapi32Const.CALG_SHA_256, 'sha384': Advapi32Const.CALG_SHA_384, 'sha512': Advapi32Const.CALG_SHA_512, }[hash_algorithm] hash_handle_pointer = new(advapi32, 'HCRYPTHASH *') res = advapi32.CryptCreateHash( certificate_or_public_key.context_handle, alg_id, null(), 0, hash_handle_pointer ) handle_error(res) hash_handle = unwrap(hash_handle_pointer) res = advapi32.CryptHashData(hash_handle, data, len(data), 0) handle_error(res) if algo == 'dsa': # Windows doesn't use the ASN.1 Sequence for DSA signatures, # so we have to convert it here for the verification to work try: signature = DSASignature.load(signature).to_p1363() # Switch the two integers so that the reversal later will # result in the correct order half_len = len(signature) // 2 signature = signature[half_len:] + signature[:half_len] except (ValueError, OverflowError, TypeError): raise SignatureError('Signature is invalid') # The CryptoAPI expects signatures to be in little endian byte order, # which is the opposite of other systems, so we must reverse it reversed_signature = signature[::-1] res = advapi32.CryptVerifySignatureW( hash_handle, reversed_signature, len(signature), certificate_or_public_key.key_handle, null(), 0 ) handle_error(res) finally: if hash_handle: advapi32.CryptDestroyHash(hash_handle) def _bcrypt_verify(certificate_or_public_key, signature, data, hash_algorithm, rsa_pss_padding=False): """ Verifies an RSA, DSA or ECDSA signature via CNG :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", "sha256", "sha384", "sha512" or "raw" :param rsa_pss_padding: If PSS padding should be used for RSA keys :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 hash_algorithm == 'raw': digest = data else: hash_constant = { 'md5': BcryptConst.BCRYPT_MD5_ALGORITHM, 'sha1': BcryptConst.BCRYPT_SHA1_ALGORITHM, 'sha256': BcryptConst.BCRYPT_SHA256_ALGORITHM, 'sha384': BcryptConst.BCRYPT_SHA384_ALGORITHM, 'sha512': BcryptConst.BCRYPT_SHA512_ALGORITHM }[hash_algorithm] digest = getattr(hashlib, hash_algorithm)(data).digest() padding_info = null() flags = 0 cp_alg = certificate_or_public_key.algorithm cp_is_rsa = cp_alg == 'rsa' or cp_alg == 'rsassa_pss' if cp_is_rsa: if rsa_pss_padding: flags = BcryptConst.BCRYPT_PAD_PSS padding_info_struct_pointer = struct(bcrypt, 'BCRYPT_PSS_PADDING_INFO') padding_info_struct = unwrap(padding_info_struct_pointer) # This has to be assigned to a variable to prevent cffi from gc'ing it hash_buffer = buffer_from_unicode(hash_constant) padding_info_struct.pszAlgId = cast(bcrypt, 'wchar_t *', hash_buffer) padding_info_struct.cbSalt = len(digest) else: flags = BcryptConst.BCRYPT_PAD_PKCS1 padding_info_struct_pointer = struct(bcrypt, 'BCRYPT_PKCS1_PADDING_INFO') padding_info_struct = unwrap(padding_info_struct_pointer) # This has to be assigned to a variable to prevent cffi from gc'ing it if hash_algorithm == 'raw': padding_info_struct.pszAlgId = null() else: hash_buffer = buffer_from_unicode(hash_constant) padding_info_struct.pszAlgId = cast(bcrypt, 'wchar_t *', hash_buffer) padding_info = cast(bcrypt, 'void *', padding_info_struct_pointer) else: # Windows doesn't use the ASN.1 Sequence for DSA/ECDSA signatures, # so we have to convert it here for the verification to work try: signature = DSASignature.load(signature).to_p1363() except (ValueError, OverflowError, TypeError): raise SignatureError('Signature is invalid') res = bcrypt.BCryptVerifySignature( certificate_or_public_key.key_handle, padding_info, digest, len(digest), signature, len(signature), flags ) failure = res == BcryptConst.STATUS_INVALID_SIGNATURE failure = failure or res == BcryptConst.STATUS_INVALID_PARAMETER if failure: raise SignatureError('Signature is invalid') handle_error(res) 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", "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('The key specified is not an RSA private key') 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", "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('The key specified is not an RSA private key') 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", "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('The key specified is not a DSA private key') 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", "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('The key specified is not an EC private key') 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", "sha256", "sha384", "sha512" or "raw" :param rsa_pss_padding: If PSS padding should be used for RSA keys :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', 'sha256', 'sha384', 'sha512']) if private_key.algorithm == '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", "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 is not False: raise ValueError(pretty_message( ''' PSS padding may only be used with RSA keys - signing via a %s key was requested ''', pkey_alg.upper() )) if 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) )) if _backend == 'winlegacy': if private_key.algorithm == 'ec': return _pure_python_ecdsa_sign(private_key, data, hash_algorithm) return _advapi32_sign(private_key, data, hash_algorithm, rsa_pss_padding) return _bcrypt_sign(private_key, data, hash_algorithm, rsa_pss_padding) def _advapi32_sign(private_key, data, hash_algorithm, rsa_pss_padding=False): """ Generates an RSA, DSA or ECDSA signature via CryptoAPI :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", "sha256", "sha384", "sha512" or "raw" :param rsa_pss_padding: If PSS padding should be used for RSA keys :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 """ algo = private_key.algorithm algo_is_rsa = algo == 'rsa' or algo == 'rsassa_pss' if algo_is_rsa and hash_algorithm == 'raw': padded_data = add_pkcs1v15_signature_padding(private_key.byte_size, data) return raw_rsa_private_crypt(private_key, padded_data) if algo_is_rsa and rsa_pss_padding: hash_length = { 'sha1': 20, 'sha224': 28, 'sha256': 32, 'sha384': 48, 'sha512': 64 }.get(hash_algorithm, 0) padded_data = add_pss_padding(hash_algorithm, hash_length, private_key.bit_size, data) return raw_rsa_private_crypt(private_key, padded_data) if private_key.algorithm == 'dsa' and hash_algorithm == 'md5': raise ValueError(pretty_message( ''' Windows does not support md5 signatures with DSA keys ''' )) hash_handle = None try: alg_id = { 'md5': Advapi32Const.CALG_MD5, 'sha1': Advapi32Const.CALG_SHA1, 'sha256': Advapi32Const.CALG_SHA_256, 'sha384': Advapi32Const.CALG_SHA_384, 'sha512': Advapi32Const.CALG_SHA_512, }[hash_algorithm] hash_handle_pointer = new(advapi32, 'HCRYPTHASH *') res = advapi32.CryptCreateHash( private_key.context_handle, alg_id, null(), 0, hash_handle_pointer ) handle_error(res) hash_handle = unwrap(hash_handle_pointer) res = advapi32.CryptHashData(hash_handle, data, len(data), 0) handle_error(res) out_len = new(advapi32, 'DWORD *') res = advapi32.CryptSignHashW( hash_handle, Advapi32Const.AT_SIGNATURE, null(), 0, null(), out_len ) handle_error(res) buffer_length = deref(out_len) buffer_ = buffer_from_bytes(buffer_length) res = advapi32.CryptSignHashW( hash_handle, Advapi32Const.AT_SIGNATURE, null(), 0, buffer_, out_len ) handle_error(res) output = bytes_from_buffer(buffer_, deref(out_len)) # CryptoAPI outputs the signature in little endian byte order, so we # must swap it for compatibility with other systems output = output[::-1] if algo == 'dsa': # Switch the two integers because the reversal just before switched # then half_len = len(output) // 2 output = output[half_len:] + output[:half_len] # Windows doesn't use the ASN.1 Sequence for DSA signatures, # so we have to convert it here for the verification to work output = DSASignature.from_p1363(output).dump() return output finally: if hash_handle: advapi32.CryptDestroyHash(hash_handle) def _bcrypt_sign(private_key, data, hash_algorithm, rsa_pss_padding=False): """ Generates an RSA, DSA or ECDSA signature via CNG :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", "sha256", "sha384", "sha512" or "raw" :param rsa_pss_padding: If PSS padding should be used for RSA keys :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 hash_algorithm == 'raw': digest = data else: hash_constant = { 'md5': BcryptConst.BCRYPT_MD5_ALGORITHM, 'sha1': BcryptConst.BCRYPT_SHA1_ALGORITHM, 'sha256': BcryptConst.BCRYPT_SHA256_ALGORITHM, 'sha384': BcryptConst.BCRYPT_SHA384_ALGORITHM, 'sha512': BcryptConst.BCRYPT_SHA512_ALGORITHM }[hash_algorithm] digest = getattr(hashlib, hash_algorithm)(data).digest() padding_info = null() flags = 0 pkey_alg = private_key.algorithm pkey_is_rsa = pkey_alg == 'rsa' or pkey_alg == 'rsassa_pss' if pkey_is_rsa: if rsa_pss_padding: hash_length = { 'md5': 16, 'sha1': 20, 'sha256': 32, 'sha384': 48, 'sha512': 64 }[hash_algorithm] flags = BcryptConst.BCRYPT_PAD_PSS padding_info_struct_pointer = struct(bcrypt, 'BCRYPT_PSS_PADDING_INFO') padding_info_struct = unwrap(padding_info_struct_pointer) # This has to be assigned to a variable to prevent cffi from gc'ing it hash_buffer = buffer_from_unicode(hash_constant) padding_info_struct.pszAlgId = cast(bcrypt, 'wchar_t *', hash_buffer) padding_info_struct.cbSalt = hash_length else: flags = BcryptConst.BCRYPT_PAD_PKCS1 padding_info_struct_pointer = struct(bcrypt, 'BCRYPT_PKCS1_PADDING_INFO') padding_info_struct = unwrap(padding_info_struct_pointer) # This has to be assigned to a variable to prevent cffi from gc'ing it if hash_algorithm == 'raw': padding_info_struct.pszAlgId = null() else: hash_buffer = buffer_from_unicode(hash_constant) padding_info_struct.pszAlgId = cast(bcrypt, 'wchar_t *', hash_buffer) padding_info = cast(bcrypt, 'void *', padding_info_struct_pointer) if pkey_alg == 'dsa' and private_key.bit_size > 1024 and hash_algorithm in set(['md5', 'sha1']): raise ValueError(pretty_message( ''' Windows does not support sha1 signatures with DSA keys based on sha224, sha256 or sha512 ''' )) out_len = new(bcrypt, 'DWORD *') res = bcrypt.BCryptSignHash( private_key.key_handle, padding_info, digest, len(digest), null(), 0, out_len, flags ) handle_error(res) buffer_len = deref(out_len) buffer = buffer_from_bytes(buffer_len) if pkey_is_rsa: padding_info = cast(bcrypt, 'void *', padding_info_struct_pointer) res = bcrypt.BCryptSignHash( private_key.key_handle, padding_info, digest, len(digest), buffer, buffer_len, out_len, flags ) handle_error(res) signature = bytes_from_buffer(buffer, deref(out_len)) if not pkey_is_rsa: # Windows doesn't use the ASN.1 Sequence for DSA/ECDSA signatures, # so we have to convert it here for the verification to work signature = DSASignature.from_p1363(signature).dump() return signature def _encrypt(certificate_or_public_key, data, rsa_oaep_padding=False): """ Encrypts a value using an RSA public key :param certificate_or_public_key: A Certificate or PublicKey instance to encrypt with :param data: A byte string of the data to encrypt :param rsa_oaep_padding: If OAEP padding should be used instead of PKCS#1 v1.5 :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 ciphertext """ 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) )) if not isinstance(rsa_oaep_padding, bool): raise TypeError(pretty_message( ''' rsa_oaep_padding must be a bool, not %s ''', type_name(rsa_oaep_padding) )) if _backend == 'winlegacy': return _advapi32_encrypt(certificate_or_public_key, data, rsa_oaep_padding) return _bcrypt_encrypt(certificate_or_public_key, data, rsa_oaep_padding) def _advapi32_encrypt(certificate_or_public_key, data, rsa_oaep_padding=False): """ Encrypts a value using an RSA public key via CryptoAPI :param certificate_or_public_key: A Certificate or PublicKey instance to encrypt with :param data: A byte string of the data to encrypt :param rsa_oaep_padding: If OAEP padding should be used instead of PKCS#1 v1.5 :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 ciphertext """ flags = 0 if rsa_oaep_padding: flags = Advapi32Const.CRYPT_OAEP out_len = new(advapi32, 'DWORD *', len(data)) res = advapi32.CryptEncrypt( certificate_or_public_key.ex_key_handle, null(), True, flags, null(), out_len, 0 ) handle_error(res) buffer_len = deref(out_len) buffer = buffer_from_bytes(buffer_len) write_to_buffer(buffer, data) pointer_set(out_len, len(data)) res = advapi32.CryptEncrypt( certificate_or_public_key.ex_key_handle, null(), True, flags, buffer, out_len, buffer_len ) handle_error(res) return bytes_from_buffer(buffer, deref(out_len))[::-1] def _bcrypt_encrypt(certificate_or_public_key, data, rsa_oaep_padding=False): """ Encrypts a value using an RSA public key via CNG :param certificate_or_public_key: A Certificate or PublicKey instance to encrypt with :param data: A byte string of the data to encrypt :param rsa_oaep_padding: If OAEP padding should be used instead of PKCS#1 v1.5 :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 ciphertext """ flags = BcryptConst.BCRYPT_PAD_PKCS1 if rsa_oaep_padding is True: flags = BcryptConst.BCRYPT_PAD_OAEP padding_info_struct_pointer = struct(bcrypt, 'BCRYPT_OAEP_PADDING_INFO') padding_info_struct = unwrap(padding_info_struct_pointer) # This has to be assigned to a variable to prevent cffi from gc'ing it hash_buffer = buffer_from_unicode(BcryptConst.BCRYPT_SHA1_ALGORITHM) padding_info_struct.pszAlgId = cast(bcrypt, 'wchar_t *', hash_buffer) padding_info_struct.pbLabel = null() padding_info_struct.cbLabel = 0 padding_info = cast(bcrypt, 'void *', padding_info_struct_pointer) else: padding_info = null() out_len = new(bcrypt, 'ULONG *') res = bcrypt.BCryptEncrypt( certificate_or_public_key.key_handle, data, len(data), padding_info, null(), 0, null(), 0, out_len, flags ) handle_error(res) buffer_len = deref(out_len) buffer = buffer_from_bytes(buffer_len) res = bcrypt.BCryptEncrypt( certificate_or_public_key.key_handle, data, len(data), padding_info, null(), 0, buffer, buffer_len, out_len, flags ) handle_error(res) return bytes_from_buffer(buffer, deref(out_len)) def _decrypt(private_key, ciphertext, rsa_oaep_padding=False): """ Encrypts a value using an RSA private key :param private_key: A PrivateKey instance to decrypt with :param ciphertext: A byte string of the data to decrypt :param rsa_oaep_padding: If OAEP padding should be used instead of PKCS#1 v1.5 :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) )) if not isinstance(rsa_oaep_padding, bool): raise TypeError(pretty_message( ''' rsa_oaep_padding must be a bool, not %s ''', type_name(rsa_oaep_padding) )) if _backend == 'winlegacy': return _advapi32_decrypt(private_key, ciphertext, rsa_oaep_padding) return _bcrypt_decrypt(private_key, ciphertext, rsa_oaep_padding) def _advapi32_decrypt(private_key, ciphertext, rsa_oaep_padding=False): """ Encrypts a value using an RSA private key via CryptoAPI :param private_key: A PrivateKey instance to decrypt with :param ciphertext: A byte string of the data to decrypt :param rsa_oaep_padding: If OAEP padding should be used instead of PKCS#1 v1.5 :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 """ flags = 0 if rsa_oaep_padding: flags = Advapi32Const.CRYPT_OAEP ciphertext = ciphertext[::-1] buffer = buffer_from_bytes(ciphertext) out_len = new(advapi32, 'DWORD *', len(ciphertext)) res = advapi32.CryptDecrypt( private_key.ex_key_handle, null(), True, flags, buffer, out_len ) handle_error(res) return bytes_from_buffer(buffer, deref(out_len)) def _bcrypt_decrypt(private_key, ciphertext, rsa_oaep_padding=False): """ Encrypts a value using an RSA private key via CNG :param private_key: A PrivateKey instance to decrypt with :param ciphertext: A byte string of the data to decrypt :param rsa_oaep_padding: If OAEP padding should be used instead of PKCS#1 v1.5 :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 """ flags = BcryptConst.BCRYPT_PAD_PKCS1 if rsa_oaep_padding is True: flags = BcryptConst.BCRYPT_PAD_OAEP padding_info_struct_pointer = struct(bcrypt, 'BCRYPT_OAEP_PADDING_INFO') padding_info_struct = unwrap(padding_info_struct_pointer) # This has to be assigned to a variable to prevent cffi from gc'ing it hash_buffer = buffer_from_unicode(BcryptConst.BCRYPT_SHA1_ALGORITHM) padding_info_struct.pszAlgId = cast(bcrypt, 'wchar_t *', hash_buffer) padding_info_struct.pbLabel = null() padding_info_struct.cbLabel = 0 padding_info = cast(bcrypt, 'void *', padding_info_struct_pointer) else: padding_info = null() out_len = new(bcrypt, 'ULONG *') res = bcrypt.BCryptDecrypt( private_key.key_handle, ciphertext, len(ciphertext), padding_info, null(), 0, null(), 0, out_len, flags ) handle_error(res) buffer_len = deref(out_len) buffer = buffer_from_bytes(buffer_len) res = bcrypt.BCryptDecrypt( private_key.key_handle, ciphertext, len(ciphertext), padding_info, null(), 0, buffer, buffer_len, out_len, flags ) handle_error(res) return bytes_from_buffer(buffer, deref(out_len)) 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) 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) 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, rsa_oaep_padding=True) 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, rsa_oaep_padding=True) _win/symmetric.py000064400000074233147205106110010074 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, deref, new, null, pointer_set, struct, struct_bytes, unwrap, write_to_buffer, ) from .util import rand_bytes from .. import backend from .._types import type_name, byte_cls _backend = backend() if _backend == 'winlegacy': from ._advapi32 import advapi32, Advapi32Const, handle_error, open_context_handle, close_context_handle else: from ._cng import bcrypt, BcryptConst, handle_error, open_alg_handle, close_alg_handle __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 the OS crypto library :return: A tuple of two byte strings (iv, ciphertext) """ 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 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('aes', 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 the OS crypto library :return: A byte string of the plaintext """ 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(iv) != 16: raise ValueError(pretty_message( ''' iv must be 16 bytes long - is %s ''', len(iv) )) return _decrypt('aes', 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 the OS crypto library :return: A tuple of two byte strings (iv, ciphertext) """ 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 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('aes', 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 the OS crypto library :return: A byte string of the plaintext """ 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(iv) != 16: raise ValueError(pretty_message( ''' iv must be 16 bytes long - is %s ''', len(iv) )) return _decrypt('aes', key, data, iv, True) 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 the OS crypto library :return: A byte string of the ciphertext """ 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 the OS crypto library :return: A byte string of the plaintext """ 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 with a 64 bit key :param key: The encryption key - a byte string 8 bytes long :param data: The plaintext - a byte string :param iv: The 8-byte initialization vector to use - a byte string - set as None to generate an appropriate one :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 tuple of two byte strings (iv, ciphertext) """ 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 using a 64 bit key :param key: The encryption key - a byte string 8 bytes long :param data: The ciphertext - a byte string :param iv: The initialization vector used for encryption - 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 the OS crypto library :return: A byte string of the plaintext """ 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 either 2 or 3 key mode :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 8-byte initialization vector to use - a byte string - set as None to generate an appropriate one :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 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 - 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) )) cipher = 'tripledes_3key' if len(key) == 16: cipher = 'tripledes_2key' return (iv, _encrypt(cipher, key, data, iv, True)) def tripledes_cbc_pkcs5_decrypt(key, data, iv): """ Decrypts 3DES ciphertext in either 2 or 3 key mode :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 used for encryption - 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 the OS crypto library :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' if len(key) == 16: cipher = 'tripledes_2key' return _decrypt(cipher, key, data, iv, True) def des_cbc_pkcs5_encrypt(key, data, iv): """ Encrypts plaintext using DES with a 56 bit key :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 8-byte initialization vector to use - a byte string - set as None to generate an appropriate one :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 tuple of two byte strings (iv, ciphertext) """ 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 using a 56 bit key :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 used for encryption - 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 the OS crypto library :return: A byte string of the plaintext """ 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 _advapi32_create_handles(cipher, key, iv): """ Creates an HCRYPTPROV and HCRYPTKEY for symmetric encryption/decryption. The HCRYPTPROV must be released by close_context_handle() and the HCRYPTKEY must be released by advapi32.CryptDestroyKey() when done. :param cipher: A unicode string of "aes", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: A byte string of the symmetric key :param iv: The initialization vector - a byte string - unused for RC4 :return: A tuple of (HCRYPTPROV, HCRYPTKEY) """ context_handle = None if cipher == 'aes': algorithm_id = { 16: Advapi32Const.CALG_AES_128, 24: Advapi32Const.CALG_AES_192, 32: Advapi32Const.CALG_AES_256, }[len(key)] else: algorithm_id = { 'des': Advapi32Const.CALG_DES, 'tripledes_2key': Advapi32Const.CALG_3DES_112, 'tripledes_3key': Advapi32Const.CALG_3DES, 'rc2': Advapi32Const.CALG_RC2, 'rc4': Advapi32Const.CALG_RC4, }[cipher] provider = Advapi32Const.MS_ENH_RSA_AES_PROV context_handle = open_context_handle(provider, verify_only=False) blob_header_pointer = struct(advapi32, 'BLOBHEADER') blob_header = unwrap(blob_header_pointer) blob_header.bType = Advapi32Const.PLAINTEXTKEYBLOB blob_header.bVersion = Advapi32Const.CUR_BLOB_VERSION blob_header.reserved = 0 blob_header.aiKeyAlg = algorithm_id blob_struct_pointer = struct(advapi32, 'PLAINTEXTKEYBLOB') blob_struct = unwrap(blob_struct_pointer) blob_struct.hdr = blob_header blob_struct.dwKeySize = len(key) blob = struct_bytes(blob_struct_pointer) + key flags = 0 if cipher in set(['rc2', 'rc4']) and len(key) == 5: flags = Advapi32Const.CRYPT_NO_SALT key_handle_pointer = new(advapi32, 'HCRYPTKEY *') res = advapi32.CryptImportKey( context_handle, blob, len(blob), null(), flags, key_handle_pointer ) handle_error(res) key_handle = unwrap(key_handle_pointer) if cipher == 'rc2': buf = new(advapi32, 'DWORD *', len(key) * 8) res = advapi32.CryptSetKeyParam( key_handle, Advapi32Const.KP_EFFECTIVE_KEYLEN, buf, 0 ) handle_error(res) if cipher != 'rc4': res = advapi32.CryptSetKeyParam( key_handle, Advapi32Const.KP_IV, iv, 0 ) handle_error(res) buf = new(advapi32, 'DWORD *', Advapi32Const.CRYPT_MODE_CBC) res = advapi32.CryptSetKeyParam( key_handle, Advapi32Const.KP_MODE, buf, 0 ) handle_error(res) buf = new(advapi32, 'DWORD *', Advapi32Const.PKCS5_PADDING) res = advapi32.CryptSetKeyParam( key_handle, Advapi32Const.KP_PADDING, buf, 0 ) handle_error(res) return (context_handle, key_handle) def _bcrypt_create_key_handle(cipher, key): """ Creates a BCRYPT_KEY_HANDLE for symmetric encryption/decryption. The handle must be released by bcrypt.BCryptDestroyKey() when done. :param cipher: A unicode string of "aes", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: A byte string of the symmetric key :return: A BCRYPT_KEY_HANDLE """ alg_handle = None alg_constant = { 'aes': BcryptConst.BCRYPT_AES_ALGORITHM, 'des': BcryptConst.BCRYPT_DES_ALGORITHM, 'tripledes_2key': BcryptConst.BCRYPT_3DES_112_ALGORITHM, 'tripledes_3key': BcryptConst.BCRYPT_3DES_ALGORITHM, 'rc2': BcryptConst.BCRYPT_RC2_ALGORITHM, 'rc4': BcryptConst.BCRYPT_RC4_ALGORITHM, }[cipher] try: alg_handle = open_alg_handle(alg_constant) blob_type = BcryptConst.BCRYPT_KEY_DATA_BLOB blob_struct_pointer = struct(bcrypt, 'BCRYPT_KEY_DATA_BLOB_HEADER') blob_struct = unwrap(blob_struct_pointer) blob_struct.dwMagic = BcryptConst.BCRYPT_KEY_DATA_BLOB_MAGIC blob_struct.dwVersion = BcryptConst.BCRYPT_KEY_DATA_BLOB_VERSION1 blob_struct.cbKeyData = len(key) blob = struct_bytes(blob_struct_pointer) + key if cipher == 'rc2': buf = new(bcrypt, 'DWORD *', len(key) * 8) res = bcrypt.BCryptSetProperty( alg_handle, BcryptConst.BCRYPT_EFFECTIVE_KEY_LENGTH, buf, 4, 0 ) handle_error(res) key_handle_pointer = new(bcrypt, 'BCRYPT_KEY_HANDLE *') res = bcrypt.BCryptImportKey( alg_handle, null(), blob_type, key_handle_pointer, null(), 0, blob, len(blob), 0 ) handle_error(res) return unwrap(key_handle_pointer) finally: if alg_handle: close_alg_handle(alg_handle) def _encrypt(cipher, key, data, iv, padding): """ Encrypts plaintext :param cipher: A unicode string of "aes", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: The encryption key - a byte string 5-16 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 the OS crypto library :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 if not (cipher == 'aes' and len(data) % 16 == 0): raise ValueError('padding must be specified') if _backend == 'winlegacy': return _advapi32_encrypt(cipher, key, data, iv, padding) return _bcrypt_encrypt(cipher, key, data, iv, padding) def _advapi32_encrypt(cipher, key, data, iv, padding): """ Encrypts plaintext via CryptoAPI :param cipher: A unicode string of "aes", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: The encryption key - a byte string 5-16 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 the OS crypto library :return: A byte string of the ciphertext """ context_handle = None key_handle = None try: context_handle, key_handle = _advapi32_create_handles(cipher, key, iv) out_len = new(advapi32, 'DWORD *', len(data)) res = advapi32.CryptEncrypt( key_handle, null(), True, 0, null(), out_len, 0 ) handle_error(res) buffer_len = deref(out_len) buffer = buffer_from_bytes(buffer_len) write_to_buffer(buffer, data) pointer_set(out_len, len(data)) res = advapi32.CryptEncrypt( key_handle, null(), True, 0, buffer, out_len, buffer_len ) handle_error(res) output = bytes_from_buffer(buffer, deref(out_len)) # Remove padding when not required. CryptoAPI doesn't support this, so # we just manually remove it. if cipher == 'aes' and not padding and len(output) == len(data) + 16: output = output[:-16] return output finally: if key_handle: advapi32.CryptDestroyKey(key_handle) if context_handle: close_context_handle(context_handle) def _bcrypt_encrypt(cipher, key, data, iv, padding): """ Encrypts plaintext via CNG :param cipher: A unicode string of "aes", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: The encryption key - a byte string 5-16 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 the OS crypto library :return: A byte string of the ciphertext """ key_handle = None try: key_handle = _bcrypt_create_key_handle(cipher, key) if iv is None: iv_len = 0 else: iv_len = len(iv) flags = 0 if padding is True: flags = BcryptConst.BCRYPT_BLOCK_PADDING out_len = new(bcrypt, 'ULONG *') res = bcrypt.BCryptEncrypt( key_handle, data, len(data), null(), null(), 0, null(), 0, out_len, flags ) handle_error(res) buffer_len = deref(out_len) buffer = buffer_from_bytes(buffer_len) iv_buffer = buffer_from_bytes(iv) if iv else null() res = bcrypt.BCryptEncrypt( key_handle, data, len(data), null(), iv_buffer, iv_len, buffer, buffer_len, out_len, flags ) handle_error(res) return bytes_from_buffer(buffer, deref(out_len)) finally: if key_handle: bcrypt.BCryptDestroyKey(key_handle) def _decrypt(cipher, key, data, iv, padding): """ Decrypts AES/RC4/RC2/3DES/DES ciphertext :param cipher: A unicode string of "aes", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: The encryption key - a byte string 5-16 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 the OS crypto library :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', 'aes']) and not padding: raise ValueError('padding must be specified') if _backend == 'winlegacy': return _advapi32_decrypt(cipher, key, data, iv, padding) return _bcrypt_decrypt(cipher, key, data, iv, padding) def _advapi32_decrypt(cipher, key, data, iv, padding): """ Decrypts AES/RC4/RC2/3DES/DES ciphertext via CryptoAPI :param cipher: A unicode string of "aes", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: The encryption key - a byte string 5-16 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 the OS crypto library :return: A byte string of the plaintext """ context_handle = None key_handle = None try: context_handle, key_handle = _advapi32_create_handles(cipher, key, iv) if cipher == 'aes' and not padding and len(data) % 16 != 0: raise ValueError('Invalid data - ciphertext length must be a multiple of 16') buffer = buffer_from_bytes(data) out_len = new(advapi32, 'DWORD *', len(data)) res = advapi32.CryptDecrypt( key_handle, null(), # To skip padding, we have to tell the API that this is not # the final block False if cipher == 'aes' and not padding else True, 0, buffer, out_len ) handle_error(res) return bytes_from_buffer(buffer, deref(out_len)) finally: if key_handle: advapi32.CryptDestroyKey(key_handle) if context_handle: close_context_handle(context_handle) def _bcrypt_decrypt(cipher, key, data, iv, padding): """ Decrypts AES/RC4/RC2/3DES/DES ciphertext via CNG :param cipher: A unicode string of "aes", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: The encryption key - a byte string 5-16 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 the OS crypto library :return: A byte string of the plaintext """ key_handle = None try: key_handle = _bcrypt_create_key_handle(cipher, key) if iv is None: iv_len = 0 else: iv_len = len(iv) flags = 0 if padding is True: flags = BcryptConst.BCRYPT_BLOCK_PADDING out_len = new(bcrypt, 'ULONG *') res = bcrypt.BCryptDecrypt( key_handle, data, len(data), null(), null(), 0, null(), 0, out_len, flags ) handle_error(res) buffer_len = deref(out_len) buffer = buffer_from_bytes(buffer_len) iv_buffer = buffer_from_bytes(iv) if iv else null() res = bcrypt.BCryptDecrypt( key_handle, data, len(data), null(), iv_buffer, iv_len, buffer, buffer_len, out_len, flags ) handle_error(res) return bytes_from_buffer(buffer, deref(out_len)) finally: if key_handle: bcrypt.BCryptDestroyKey(key_handle) _win/tls.py000064400000163242147205106110006661 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 .._asn1 import Certificate as Asn1Certificate from .._errors import pretty_message from .._ffi import ( buffer_from_bytes, buffer_from_unicode, bytes_from_buffer, cast, deref, is_null, native, new, null, ref, sizeof, struct, unwrap, write_to_buffer, ) from ._secur32 import secur32, Secur32Const, handle_error from ._crypt32 import crypt32, Crypt32Const, handle_error as handle_crypt32_error from ._kernel32 import kernel32 from .._types import type_name, str_cls, byte_cls, int_types from ..errors import TLSError, TLSVerificationError, TLSDisconnectError, TLSGracefulDisconnectError from .._tls import ( detect_client_auth_request, detect_other_protocol, extract_chain, get_dh_params_length, parse_alert, 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_revoked, raise_self_signed, raise_verification, raise_weak_signature, ) from .asymmetric import load_certificate, Certificate from ..keys import parse_certificate if sys.version_info < (3,): range = xrange # noqa socket_error_cls = socket_.error else: socket_error_cls = WindowsError if sys.version_info < (3, 7): Pattern = re._pattern_type else: Pattern = re.Pattern __all__ = [ 'TLSSession', 'TLSSocket', ] _line_regex = re.compile(b'(\r\n|\r|\n)') _gwv = sys.getwindowsversion() _win_version_info = (_gwv[0], _gwv[1]) class _TLSDowngradeError(TLSVerificationError): pass class _TLSRetryError(TLSError): """ TLSv1.2 on Windows 7 and 8 seems to have isuses with some DHE_RSA ServerKeyExchange messages due to variable length integer encoding. This exception is used to trigger a reconnection to attempt the handshake again. """ pass 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 _credentials_handle = 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) )) unsupported_protocols = protocol - set(['SSLv3', 'TLSv1', 'TLSv1.1', 'TLSv1.2']) 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) self._obtain_credentials() def _obtain_credentials(self): """ Obtains a credentials handle from secur32.dll for use with SChannel """ protocol_values = { 'SSLv3': Secur32Const.SP_PROT_SSL3_CLIENT, 'TLSv1': Secur32Const.SP_PROT_TLS1_CLIENT, 'TLSv1.1': Secur32Const.SP_PROT_TLS1_1_CLIENT, 'TLSv1.2': Secur32Const.SP_PROT_TLS1_2_CLIENT, } protocol_bit_mask = 0 for key, value in protocol_values.items(): if key in self._protocols: protocol_bit_mask |= value algs = [ Secur32Const.CALG_AES_128, Secur32Const.CALG_AES_256, Secur32Const.CALG_3DES, Secur32Const.CALG_SHA1, Secur32Const.CALG_ECDHE, Secur32Const.CALG_DH_EPHEM, Secur32Const.CALG_RSA_KEYX, Secur32Const.CALG_RSA_SIGN, Secur32Const.CALG_ECDSA, Secur32Const.CALG_DSS_SIGN, ] if 'TLSv1.2' in self._protocols: algs.extend([ Secur32Const.CALG_SHA512, Secur32Const.CALG_SHA384, Secur32Const.CALG_SHA256, ]) alg_array = new(secur32, 'ALG_ID[%s]' % len(algs)) for index, alg in enumerate(algs): alg_array[index] = alg flags = Secur32Const.SCH_USE_STRONG_CRYPTO | Secur32Const.SCH_CRED_NO_DEFAULT_CREDS if not self._manual_validation and not self._extra_trust_roots: flags |= Secur32Const.SCH_CRED_AUTO_CRED_VALIDATION else: flags |= Secur32Const.SCH_CRED_MANUAL_CRED_VALIDATION schannel_cred_pointer = struct(secur32, 'SCHANNEL_CRED') schannel_cred = unwrap(schannel_cred_pointer) schannel_cred.dwVersion = Secur32Const.SCHANNEL_CRED_VERSION schannel_cred.cCreds = 0 schannel_cred.paCred = null() schannel_cred.hRootStore = null() schannel_cred.cMappers = 0 schannel_cred.aphMappers = null() schannel_cred.cSupportedAlgs = len(alg_array) schannel_cred.palgSupportedAlgs = alg_array schannel_cred.grbitEnabledProtocols = protocol_bit_mask schannel_cred.dwMinimumCipherStrength = 0 schannel_cred.dwMaximumCipherStrength = 0 # Default session lifetime is 10 hours schannel_cred.dwSessionLifespan = 0 schannel_cred.dwFlags = flags schannel_cred.dwCredFormat = 0 cred_handle_pointer = new(secur32, 'CredHandle *') result = secur32.AcquireCredentialsHandleW( null(), Secur32Const.UNISP_NAME, Secur32Const.SECPKG_CRED_OUTBOUND, null(), schannel_cred_pointer, null(), null(), cred_handle_pointer, null() ) handle_error(result) self._credentials_handle = cred_handle_pointer def __del__(self): if self._credentials_handle: result = secur32.FreeCredentialsHandle(self._credentials_handle) handle_error(result) self._credentials_handle = None class TLSSocket(object): """ A wrapper around a socket.socket that adds TLS """ _socket = None _session = None _context_handle_pointer = None _context_flags = None _hostname = None _header_size = None _message_size = None _trailer_size = None _received_bytes = None _decrypted_bytes = None _encrypt_desc = None _encrypt_buffers = None _encrypt_data_buffer = None _decrypt_desc = None _decrypt_buffers = None _decrypt_data_buffer = None _certificate = None _intermediates = None _protocol = None _cipher_suite = None _compression = None _session_id = None _session_ticket = None _remote_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 # Since we don't create the socket connection here, we can't try to # reconnect with a lower version of the TLS protocol, so we just # move the data to public exception type TLSVerificationError() try: new_socket._handshake() except (_TLSDowngradeError) as e: new_e = TLSVerificationError(e.message, e.certificate) raise new_e except (_TLSRetryError) as e: new_e = TLSError(e.message) raise new_e 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._received_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 try: self._handshake() except (_TLSDowngradeError): self.close() new_session = TLSSession( session._protocols - set(['TLSv1.2']), session._manual_validation, session._extra_trust_roots ) session.__del__() self._received_bytes = b'' self._session = new_session self._socket = socket_.create_connection((address, port), timeout) self._socket.settimeout(timeout) self._handshake() except (_TLSRetryError): self._received_bytes = b'' self._socket = socket_.create_connection((address, port), timeout) self._socket.settimeout(timeout) self._handshake() def _create_buffers(self, number): """ Creates a SecBufferDesc struct and contained SecBuffer structs :param number: The number of contains SecBuffer objects to create :return: A tuple of (SecBufferDesc pointer, SecBuffer array) """ buffers = new(secur32, 'SecBuffer[%d]' % number) for index in range(0, number): buffers[index].cbBuffer = 0 buffers[index].BufferType = Secur32Const.SECBUFFER_EMPTY buffers[index].pvBuffer = null() sec_buffer_desc_pointer = struct(secur32, 'SecBufferDesc') sec_buffer_desc = unwrap(sec_buffer_desc_pointer) sec_buffer_desc.ulVersion = Secur32Const.SECBUFFER_VERSION sec_buffer_desc.cBuffers = number sec_buffer_desc.pBuffers = buffers return (sec_buffer_desc_pointer, buffers) def _extra_trust_root_validation(self): """ Manually invoked windows certificate chain builder and verification step when there are extra trust roots to include in the search process """ store = None cert_chain_context_pointer = None try: # We set up an in-memory store to pass as an extra store to grab # certificates from when performing the verification store = crypt32.CertOpenStore( Crypt32Const.CERT_STORE_PROV_MEMORY, Crypt32Const.X509_ASN_ENCODING, null(), 0, null() ) if is_null(store): handle_crypt32_error(0) cert_hashes = set() for cert in self._session._extra_trust_roots: cert_data = cert.dump() result = crypt32.CertAddEncodedCertificateToStore( store, Crypt32Const.X509_ASN_ENCODING, cert_data, len(cert_data), Crypt32Const.CERT_STORE_ADD_USE_EXISTING, null() ) if not result: handle_crypt32_error(0) cert_hashes.add(cert.sha256) cert_context_pointer_pointer = new(crypt32, 'PCERT_CONTEXT *') result = secur32.QueryContextAttributesW( self._context_handle_pointer, Secur32Const.SECPKG_ATTR_REMOTE_CERT_CONTEXT, cert_context_pointer_pointer ) handle_error(result) cert_context_pointer = unwrap(cert_context_pointer_pointer) cert_context_pointer = cast(crypt32, 'PCERT_CONTEXT', cert_context_pointer) # We have to do a funky shuffle here because FILETIME from kernel32 # is different than FILETIME from crypt32 when using cffi. If we # overwrite the "now_pointer" variable, cffi releases the backing # memory and we end up getting a validation error about certificate # expiration time. orig_now_pointer = new(kernel32, 'FILETIME *') kernel32.GetSystemTimeAsFileTime(orig_now_pointer) now_pointer = cast(crypt32, 'FILETIME *', orig_now_pointer) usage_identifiers = new(crypt32, 'char *[3]') usage_identifiers[0] = cast(crypt32, 'char *', Crypt32Const.PKIX_KP_SERVER_AUTH) usage_identifiers[1] = cast(crypt32, 'char *', Crypt32Const.SERVER_GATED_CRYPTO) usage_identifiers[2] = cast(crypt32, 'char *', Crypt32Const.SGC_NETSCAPE) cert_enhkey_usage_pointer = struct(crypt32, 'CERT_ENHKEY_USAGE') cert_enhkey_usage = unwrap(cert_enhkey_usage_pointer) cert_enhkey_usage.cUsageIdentifier = 3 cert_enhkey_usage.rgpszUsageIdentifier = cast(crypt32, 'char **', usage_identifiers) cert_usage_match_pointer = struct(crypt32, 'CERT_USAGE_MATCH') cert_usage_match = unwrap(cert_usage_match_pointer) cert_usage_match.dwType = Crypt32Const.USAGE_MATCH_TYPE_OR cert_usage_match.Usage = cert_enhkey_usage cert_chain_para_pointer = struct(crypt32, 'CERT_CHAIN_PARA') cert_chain_para = unwrap(cert_chain_para_pointer) cert_chain_para.RequestedUsage = cert_usage_match cert_chain_para_size = sizeof(crypt32, cert_chain_para) cert_chain_para.cbSize = cert_chain_para_size cert_chain_context_pointer_pointer = new(crypt32, 'PCERT_CHAIN_CONTEXT *') result = crypt32.CertGetCertificateChain( null(), cert_context_pointer, now_pointer, store, cert_chain_para_pointer, Crypt32Const.CERT_CHAIN_CACHE_END_CERT | Crypt32Const.CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY, null(), cert_chain_context_pointer_pointer ) handle_crypt32_error(result) cert_chain_policy_para_flags = Crypt32Const.CERT_CHAIN_POLICY_IGNORE_ALL_REV_UNKNOWN_FLAGS cert_chain_context_pointer = unwrap(cert_chain_context_pointer_pointer) # Unwrap the chain and if the final element in the chain is one of # extra trust roots, set flags so that we trust the certificate even # though it is not in the Trusted Roots store cert_chain_context = unwrap(cert_chain_context_pointer) num_chains = native(int, cert_chain_context.cChain) if num_chains == 1: first_simple_chain_pointer = unwrap(cert_chain_context.rgpChain) first_simple_chain = unwrap(first_simple_chain_pointer) num_elements = native(int, first_simple_chain.cElement) last_element_pointer = first_simple_chain.rgpElement[num_elements - 1] last_element = unwrap(last_element_pointer) last_element_cert = unwrap(last_element.pCertContext) last_element_cert_data = bytes_from_buffer( last_element_cert.pbCertEncoded, native(int, last_element_cert.cbCertEncoded) ) last_cert = Asn1Certificate.load(last_element_cert_data) if last_cert.sha256 in cert_hashes: cert_chain_policy_para_flags |= Crypt32Const.CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG ssl_extra_cert_chain_policy_para_pointer = struct(crypt32, 'SSL_EXTRA_CERT_CHAIN_POLICY_PARA') ssl_extra_cert_chain_policy_para = unwrap(ssl_extra_cert_chain_policy_para_pointer) ssl_extra_cert_chain_policy_para.cbSize = sizeof(crypt32, ssl_extra_cert_chain_policy_para) ssl_extra_cert_chain_policy_para.dwAuthType = Crypt32Const.AUTHTYPE_SERVER ssl_extra_cert_chain_policy_para.fdwChecks = 0 ssl_extra_cert_chain_policy_para.pwszServerName = cast( crypt32, 'wchar_t *', buffer_from_unicode(self._hostname) ) cert_chain_policy_para_pointer = struct(crypt32, 'CERT_CHAIN_POLICY_PARA') cert_chain_policy_para = unwrap(cert_chain_policy_para_pointer) cert_chain_policy_para.cbSize = sizeof(crypt32, cert_chain_policy_para) cert_chain_policy_para.dwFlags = cert_chain_policy_para_flags cert_chain_policy_para.pvExtraPolicyPara = cast(crypt32, 'void *', ssl_extra_cert_chain_policy_para_pointer) cert_chain_policy_status_pointer = struct(crypt32, 'CERT_CHAIN_POLICY_STATUS') cert_chain_policy_status = unwrap(cert_chain_policy_status_pointer) cert_chain_policy_status.cbSize = sizeof(crypt32, cert_chain_policy_status) result = crypt32.CertVerifyCertificateChainPolicy( Crypt32Const.CERT_CHAIN_POLICY_SSL, cert_chain_context_pointer, cert_chain_policy_para_pointer, cert_chain_policy_status_pointer ) handle_crypt32_error(result) cert_context = unwrap(cert_context_pointer) cert_data = bytes_from_buffer(cert_context.pbCertEncoded, native(int, cert_context.cbCertEncoded)) cert = Asn1Certificate.load(cert_data) error = cert_chain_policy_status.dwError if error: if error == Crypt32Const.CERT_E_EXPIRED: raise_expired_not_yet_valid(cert) if error == Crypt32Const.CERT_E_UNTRUSTEDROOT: oscrypto_cert = load_certificate(cert) if oscrypto_cert.self_signed: raise_self_signed(cert) else: raise_no_issuer(cert) if error == Crypt32Const.CERT_E_CN_NO_MATCH: raise_hostname(cert, self._hostname) if error == Crypt32Const.TRUST_E_CERT_SIGNATURE: raise_weak_signature(cert) if error == Crypt32Const.CRYPT_E_REVOKED: raise_revoked(cert) raise_verification(cert) if cert.hash_algo in set(['md5', 'md2']): raise_weak_signature(cert) finally: if store: crypt32.CertCloseStore(store, 0) if cert_chain_context_pointer: crypt32.CertFreeCertificateChain(cert_chain_context_pointer) def _handshake(self, renegotiate=False): """ Perform an initial TLS handshake, or a renegotiation :param renegotiate: If the handshake is for a renegotiation """ in_buffers = None out_buffers = None new_context_handle_pointer = None try: if renegotiate: temp_context_handle_pointer = self._context_handle_pointer else: new_context_handle_pointer = new(secur32, 'CtxtHandle *') temp_context_handle_pointer = new_context_handle_pointer requested_flags = { Secur32Const.ISC_REQ_REPLAY_DETECT: 'replay detection', Secur32Const.ISC_REQ_SEQUENCE_DETECT: 'sequence detection', Secur32Const.ISC_REQ_CONFIDENTIALITY: 'confidentiality', Secur32Const.ISC_REQ_ALLOCATE_MEMORY: 'memory allocation', Secur32Const.ISC_REQ_INTEGRITY: 'integrity', Secur32Const.ISC_REQ_STREAM: 'stream orientation', Secur32Const.ISC_REQ_USE_SUPPLIED_CREDS: 'disable automatic client auth', } self._context_flags = 0 for flag in requested_flags: self._context_flags |= flag in_sec_buffer_desc_pointer, in_buffers = self._create_buffers(2) in_buffers[0].BufferType = Secur32Const.SECBUFFER_TOKEN out_sec_buffer_desc_pointer, out_buffers = self._create_buffers(2) out_buffers[0].BufferType = Secur32Const.SECBUFFER_TOKEN out_buffers[1].BufferType = Secur32Const.SECBUFFER_ALERT output_context_flags_pointer = new(secur32, 'ULONG *') if renegotiate: first_handle = temp_context_handle_pointer second_handle = null() else: first_handle = null() second_handle = temp_context_handle_pointer result = secur32.InitializeSecurityContextW( self._session._credentials_handle, first_handle, self._hostname, self._context_flags, 0, 0, null(), 0, second_handle, out_sec_buffer_desc_pointer, output_context_flags_pointer, null() ) if result not in set([Secur32Const.SEC_E_OK, Secur32Const.SEC_I_CONTINUE_NEEDED]): handle_error(result, TLSError) if not renegotiate: temp_context_handle_pointer = second_handle else: temp_context_handle_pointer = first_handle handshake_server_bytes = b'' handshake_client_bytes = b'' if out_buffers[0].cbBuffer > 0: token = bytes_from_buffer(out_buffers[0].pvBuffer, out_buffers[0].cbBuffer) handshake_client_bytes += token self._socket.send(token) out_buffers[0].cbBuffer = 0 secur32.FreeContextBuffer(out_buffers[0].pvBuffer) out_buffers[0].pvBuffer = null() in_data_buffer = buffer_from_bytes(32768) in_buffers[0].pvBuffer = cast(secur32, 'BYTE *', in_data_buffer) bytes_read = b'' while result != Secur32Const.SEC_E_OK: try: fail_late = False bytes_read = self._socket.recv(8192) if bytes_read == b'': raise_disconnection() except (socket_error_cls): fail_late = True handshake_server_bytes += bytes_read self._received_bytes += bytes_read in_buffers[0].cbBuffer = len(self._received_bytes) write_to_buffer(in_data_buffer, self._received_bytes) result = secur32.InitializeSecurityContextW( self._session._credentials_handle, temp_context_handle_pointer, self._hostname, self._context_flags, 0, 0, in_sec_buffer_desc_pointer, 0, null(), out_sec_buffer_desc_pointer, output_context_flags_pointer, null() ) if result == Secur32Const.SEC_E_INCOMPLETE_MESSAGE: in_buffers[0].BufferType = Secur32Const.SECBUFFER_TOKEN # Windows 10 seems to fill the second input buffer with # a BufferType of SECBUFFER_MISSING (4), which if not # cleared causes the handshake to fail. if in_buffers[1].BufferType != Secur32Const.SECBUFFER_EMPTY: in_buffers[1].BufferType = Secur32Const.SECBUFFER_EMPTY in_buffers[1].cbBuffer = 0 if not is_null(in_buffers[1].pvBuffer): secur32.FreeContextBuffer(in_buffers[1].pvBuffer) in_buffers[1].pvBuffer = null() if fail_late: raise_disconnection() continue if result == Secur32Const.SEC_E_ILLEGAL_MESSAGE: if detect_client_auth_request(handshake_server_bytes): raise_client_auth() alert_info = parse_alert(handshake_server_bytes) if alert_info and alert_info == (2, 70): raise_protocol_version() raise_handshake() if result == Secur32Const.SEC_E_WRONG_PRINCIPAL: chain = extract_chain(handshake_server_bytes) raise_hostname(chain[0], self._hostname) if result == Secur32Const.SEC_E_CERT_EXPIRED: chain = extract_chain(handshake_server_bytes) raise_expired_not_yet_valid(chain[0]) if result == Secur32Const.SEC_E_UNTRUSTED_ROOT: chain = extract_chain(handshake_server_bytes) cert = chain[0] oscrypto_cert = load_certificate(cert) if not oscrypto_cert.self_signed: raise_no_issuer(cert) raise_self_signed(cert) if result == Secur32Const.SEC_E_INTERNAL_ERROR: if get_dh_params_length(handshake_server_bytes) < 1024: raise_dh_params() if result == Secur32Const.SEC_I_INCOMPLETE_CREDENTIALS: raise_client_auth() if result == Crypt32Const.TRUST_E_CERT_SIGNATURE: raise_weak_signature(cert) if result == Secur32Const.SEC_E_INVALID_TOKEN: # If an alert it present, there may have been a handshake # error due to the server using a certificate path with a # trust root using MD2 or MD5 combined with TLS 1.2. To # work around this, if the user allows anything other than # TLS 1.2, we just remove it from the acceptable protocols # and try again. if out_buffers[1].cbBuffer > 0: alert_bytes = bytes_from_buffer(out_buffers[1].pvBuffer, out_buffers[1].cbBuffer) handshake_client_bytes += alert_bytes alert_number = alert_bytes[6:7] if alert_number == b'\x28' or alert_number == b'\x2b': if 'TLSv1.2' in self._session._protocols and len(self._session._protocols) > 1: chain = extract_chain(handshake_server_bytes) raise _TLSDowngradeError( 'Server certificate verification failed - weak certificate signature algorithm', chain[0] ) if detect_client_auth_request(handshake_server_bytes): raise_client_auth() if detect_other_protocol(handshake_server_bytes): raise_protocol_error(handshake_server_bytes) raise_handshake() # These are semi-common errors with TLSv1.2 on Windows 7 an 8 # that appears to be due to poor handling of the # ServerKeyExchange for DHE_RSA cipher suites. The solution # is to retry the handshake. if result == Secur32Const.SEC_E_BUFFER_TOO_SMALL or result == Secur32Const.SEC_E_MESSAGE_ALTERED: if 'TLSv1.2' in self._session._protocols: raise _TLSRetryError('TLS handshake failed') if fail_late: raise_disconnection() if result == Secur32Const.SEC_E_INVALID_PARAMETER: if get_dh_params_length(handshake_server_bytes) < 1024: raise_dh_params() if result not in set([Secur32Const.SEC_E_OK, Secur32Const.SEC_I_CONTINUE_NEEDED]): handle_error(result, TLSError) if out_buffers[0].cbBuffer > 0: token = bytes_from_buffer(out_buffers[0].pvBuffer, out_buffers[0].cbBuffer) handshake_client_bytes += token self._socket.send(token) out_buffers[0].cbBuffer = 0 secur32.FreeContextBuffer(out_buffers[0].pvBuffer) out_buffers[0].pvBuffer = null() if in_buffers[1].BufferType == Secur32Const.SECBUFFER_EXTRA: extra_amount = in_buffers[1].cbBuffer self._received_bytes = self._received_bytes[-extra_amount:] in_buffers[1].BufferType = Secur32Const.SECBUFFER_EMPTY in_buffers[1].cbBuffer = 0 secur32.FreeContextBuffer(in_buffers[1].pvBuffer) in_buffers[1].pvBuffer = null() # The handshake is complete, so discard any extra bytes if result == Secur32Const.SEC_E_OK: handshake_server_bytes = handshake_server_bytes[-extra_amount:] else: self._received_bytes = b'' connection_info_pointer = struct(secur32, 'SecPkgContext_ConnectionInfo') result = secur32.QueryContextAttributesW( temp_context_handle_pointer, Secur32Const.SECPKG_ATTR_CONNECTION_INFO, connection_info_pointer ) handle_error(result, TLSError) connection_info = unwrap(connection_info_pointer) self._protocol = { Secur32Const.SP_PROT_SSL2_CLIENT: 'SSLv2', Secur32Const.SP_PROT_SSL3_CLIENT: 'SSLv3', Secur32Const.SP_PROT_TLS1_CLIENT: 'TLSv1', Secur32Const.SP_PROT_TLS1_1_CLIENT: 'TLSv1.1', Secur32Const.SP_PROT_TLS1_2_CLIENT: 'TLSv1.2', }.get(native(int, connection_info.dwProtocol), str_cls(connection_info.dwProtocol)) if self._protocol in set(['SSLv3', 'TLSv1', 'TLSv1.1', 'TLSv1.2']): session_info = parse_session_info(handshake_server_bytes, handshake_client_bytes) 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'] output_context_flags = deref(output_context_flags_pointer) for flag in requested_flags: if (flag | output_context_flags) == 0: raise OSError(pretty_message( ''' Unable to obtain a credential context with the property %s ''', requested_flags[flag] )) if not renegotiate: self._context_handle_pointer = temp_context_handle_pointer new_context_handle_pointer = None stream_sizes_pointer = struct(secur32, 'SecPkgContext_StreamSizes') result = secur32.QueryContextAttributesW( self._context_handle_pointer, Secur32Const.SECPKG_ATTR_STREAM_SIZES, stream_sizes_pointer ) handle_error(result) stream_sizes = unwrap(stream_sizes_pointer) self._header_size = native(int, stream_sizes.cbHeader) self._message_size = native(int, stream_sizes.cbMaximumMessage) self._trailer_size = native(int, stream_sizes.cbTrailer) self._buffer_size = self._header_size + self._message_size + self._trailer_size if self._session._extra_trust_roots: self._extra_trust_root_validation() except (OSError, socket_.error): self.close() raise finally: if out_buffers: if not is_null(out_buffers[0].pvBuffer): secur32.FreeContextBuffer(out_buffers[0].pvBuffer) if not is_null(out_buffers[1].pvBuffer): secur32.FreeContextBuffer(out_buffers[1].pvBuffer) if new_context_handle_pointer: secur32.DeleteSecurityContext(new_context_handle_pointer) def read(self, max_length): """ Reads data from the TLS-wrapped socket :param max_length: The number of bytes to read :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) )) if self._context_handle_pointer is None: # Allow the user to read any remaining decrypted data if self._decrypted_bytes != b'': output = self._decrypted_bytes[0:max_length] self._decrypted_bytes = self._decrypted_bytes[max_length:] return output self._raise_closed() # The first time read is called, set up a single contiguous buffer that # it used by DecryptMessage() to populate the three output buffers. # Since we are creating the buffer, we do not need to free it other # than allowing Python to GC it once this object is GCed. if not self._decrypt_data_buffer: self._decrypt_data_buffer = buffer_from_bytes(self._buffer_size) self._decrypt_desc, self._decrypt_buffers = self._create_buffers(4) self._decrypt_buffers[0].BufferType = Secur32Const.SECBUFFER_DATA self._decrypt_buffers[0].pvBuffer = cast(secur32, 'BYTE *', self._decrypt_data_buffer) to_recv = max(max_length, self._buffer_size) # These variables are set to reduce dict access and function calls # in the read loop. Also makes the code easier to read. null_value = null() buf0 = self._decrypt_buffers[0] buf1 = self._decrypt_buffers[1] buf2 = self._decrypt_buffers[2] buf3 = self._decrypt_buffers[3] def _reset_buffers(): buf0.BufferType = Secur32Const.SECBUFFER_DATA buf0.pvBuffer = cast(secur32, 'BYTE *', self._decrypt_data_buffer) buf0.cbBuffer = 0 buf1.BufferType = Secur32Const.SECBUFFER_EMPTY buf1.pvBuffer = null_value buf1.cbBuffer = 0 buf2.BufferType = Secur32Const.SECBUFFER_EMPTY buf2.pvBuffer = null_value buf2.cbBuffer = 0 buf3.BufferType = Secur32Const.SECBUFFER_EMPTY buf3.pvBuffer = null_value buf3.cbBuffer = 0 output = self._decrypted_bytes output_len = len(output) self._decrypted_bytes = b'' # Don't block if we have buffered data available if output_len > 0 and not self.select_read(0): self._decrypted_bytes = b'' return output # This read loop will only be run if there wasn't enough # buffered data to fulfill the requested max_length do_read = len(self._received_bytes) == 0 while output_len < max_length: if do_read: self._received_bytes += self._socket.recv(to_recv) if len(self._received_bytes) == 0: raise_disconnection() data_len = min(len(self._received_bytes), self._buffer_size) if data_len == 0: break self._decrypt_buffers[0].cbBuffer = data_len write_to_buffer(self._decrypt_data_buffer, self._received_bytes[0:data_len]) result = secur32.DecryptMessage( self._context_handle_pointer, self._decrypt_desc, 0, null() ) do_read = False if result == Secur32Const.SEC_E_INCOMPLETE_MESSAGE: _reset_buffers() do_read = True continue elif result == Secur32Const.SEC_I_CONTEXT_EXPIRED: self._remote_closed = True self.shutdown() break elif result == Secur32Const.SEC_I_RENEGOTIATE: self._handshake(renegotiate=True) return self.read(max_length) elif result != Secur32Const.SEC_E_OK: handle_error(result, TLSError) valid_buffer_types = set([ Secur32Const.SECBUFFER_EMPTY, Secur32Const.SECBUFFER_STREAM_HEADER, Secur32Const.SECBUFFER_STREAM_TRAILER ]) extra_amount = None for buf in (buf0, buf1, buf2, buf3): buffer_type = buf.BufferType if buffer_type == Secur32Const.SECBUFFER_DATA: output += bytes_from_buffer(buf.pvBuffer, buf.cbBuffer) output_len = len(output) elif buffer_type == Secur32Const.SECBUFFER_EXTRA: extra_amount = native(int, buf.cbBuffer) elif buffer_type not in valid_buffer_types: raise OSError(pretty_message( ''' Unexpected decrypt output buffer of type %s ''', buffer_type )) if extra_amount: self._received_bytes = self._received_bytes[data_len - extra_amount:] else: self._received_bytes = self._received_bytes[data_len:] # Here we reset the structs for the next call to DecryptMessage() _reset_buffers() # If we have read something, but there is nothing left to read, we # break so that we don't block for longer than necessary if self.select_read(0): do_read = True if not do_read and len(self._received_bytes) == 0: break # If the output is more than we requested (because data is decrypted in # blocks), we save the extra in a buffer if len(output) > max_length: self._decrypted_bytes = output[max_length:] output = output[0:max_length] return output 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 may include data beyond 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 """ 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: chunk = self.read(8192) 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 """ if self._context_handle_pointer is None: self._raise_closed() if not self._encrypt_data_buffer: self._encrypt_data_buffer = buffer_from_bytes(self._header_size + self._message_size + self._trailer_size) self._encrypt_desc, self._encrypt_buffers = self._create_buffers(4) self._encrypt_buffers[0].BufferType = Secur32Const.SECBUFFER_STREAM_HEADER self._encrypt_buffers[0].cbBuffer = self._header_size self._encrypt_buffers[0].pvBuffer = cast(secur32, 'BYTE *', self._encrypt_data_buffer) self._encrypt_buffers[1].BufferType = Secur32Const.SECBUFFER_DATA self._encrypt_buffers[1].pvBuffer = ref(self._encrypt_data_buffer, self._header_size) self._encrypt_buffers[2].BufferType = Secur32Const.SECBUFFER_STREAM_TRAILER self._encrypt_buffers[2].cbBuffer = self._trailer_size self._encrypt_buffers[2].pvBuffer = ref(self._encrypt_data_buffer, self._header_size + self._message_size) while len(data) > 0: to_write = min(len(data), self._message_size) write_to_buffer(self._encrypt_data_buffer, data[0:to_write], self._header_size) self._encrypt_buffers[1].cbBuffer = to_write self._encrypt_buffers[2].pvBuffer = ref(self._encrypt_data_buffer, self._header_size + to_write) result = secur32.EncryptMessage( self._context_handle_pointer, 0, self._encrypt_desc, 0 ) if result != Secur32Const.SEC_E_OK: handle_error(result, TLSError) to_send = native(int, self._encrypt_buffers[0].cbBuffer) to_send += native(int, self._encrypt_buffers[1].cbBuffer) to_send += native(int, self._encrypt_buffers[2].cbBuffer) try: self._socket.send(bytes_from_buffer(self._encrypt_data_buffer, to_send)) except (socket_.error) as e: if e.errno == 10053: raise_disconnection() raise data = data[to_send:] 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): """ Shuts down the TLS session and then shuts down the underlying socket :raises: OSError - when an error is returned by the OS crypto library """ if self._context_handle_pointer is None: return out_buffers = None try: # ApplyControlToken fails with SEC_E_UNSUPPORTED_FUNCTION # when called on Windows 7 if _win_version_info >= (6, 2): buffers = new(secur32, 'SecBuffer[1]') # This is a SCHANNEL_SHUTDOWN token (DWORD of 1) buffers[0].cbBuffer = 4 buffers[0].BufferType = Secur32Const.SECBUFFER_TOKEN buffers[0].pvBuffer = cast(secur32, 'BYTE *', buffer_from_bytes(b'\x01\x00\x00\x00')) sec_buffer_desc_pointer = struct(secur32, 'SecBufferDesc') sec_buffer_desc = unwrap(sec_buffer_desc_pointer) sec_buffer_desc.ulVersion = Secur32Const.SECBUFFER_VERSION sec_buffer_desc.cBuffers = 1 sec_buffer_desc.pBuffers = buffers result = secur32.ApplyControlToken(self._context_handle_pointer, sec_buffer_desc_pointer) handle_error(result, TLSError) out_sec_buffer_desc_pointer, out_buffers = self._create_buffers(2) out_buffers[0].BufferType = Secur32Const.SECBUFFER_TOKEN out_buffers[1].BufferType = Secur32Const.SECBUFFER_ALERT output_context_flags_pointer = new(secur32, 'ULONG *') result = secur32.InitializeSecurityContextW( self._session._credentials_handle, self._context_handle_pointer, self._hostname, self._context_flags, 0, 0, null(), 0, null(), out_sec_buffer_desc_pointer, output_context_flags_pointer, null() ) acceptable_results = set([ Secur32Const.SEC_E_OK, Secur32Const.SEC_E_CONTEXT_EXPIRED, Secur32Const.SEC_I_CONTINUE_NEEDED ]) if result not in acceptable_results: handle_error(result, TLSError) token = bytes_from_buffer(out_buffers[0].pvBuffer, out_buffers[0].cbBuffer) try: # If there is an error sending the shutdown, ignore it since the # connection is likely gone at this point self._socket.send(token) except (socket_.error): pass finally: if out_buffers: if not is_null(out_buffers[0].pvBuffer): secur32.FreeContextBuffer(out_buffers[0].pvBuffer) if not is_null(out_buffers[1].pvBuffer): secur32.FreeContextBuffer(out_buffers[1].pvBuffer) secur32.DeleteSecurityContext(self._context_handle_pointer) self._context_handle_pointer = None try: self._socket.shutdown(socket_.SHUT_RDWR) except (socket_.error): pass 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 """ cert_context_pointer_pointer = new(crypt32, 'CERT_CONTEXT **') result = secur32.QueryContextAttributesW( self._context_handle_pointer, Secur32Const.SECPKG_ATTR_REMOTE_CERT_CONTEXT, cert_context_pointer_pointer ) handle_error(result, TLSError) cert_context_pointer = unwrap(cert_context_pointer_pointer) cert_context_pointer = cast(crypt32, 'CERT_CONTEXT *', cert_context_pointer) cert_context = unwrap(cert_context_pointer) cert_data = bytes_from_buffer(cert_context.pbCertEncoded, native(int, cert_context.cbCertEncoded)) self._certificate = Asn1Certificate.load(cert_data) self._intermediates = [] store_handle = None try: store_handle = cert_context.hCertStore context_pointer = crypt32.CertEnumCertificatesInStore(store_handle, null()) while not is_null(context_pointer): context = unwrap(context_pointer) data = bytes_from_buffer(context.pbCertEncoded, native(int, context.cbCertEncoded)) # The cert store seems to include the end-entity certificate as # the last entry, but we already have that from the struct. if data != cert_data: self._intermediates.append(Asn1Certificate.load(data)) context_pointer = crypt32.CertEnumCertificatesInStore(store_handle, context_pointer) finally: if store_handle: crypt32.CertCloseStore(store_handle, 0) def _raise_closed(self): """ Raises an exception describing if the local or remote end closed the connection """ if self._remote_closed: raise TLSGracefulDisconnectError('The remote end closed the connection') else: raise TLSDisconnectError('The connection was already closed') @property def certificate(self): """ An asn1crypto.x509.Certificate object of the end-entity certificate presented by the server """ if self._context_handle_pointer 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._context_handle_pointer 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._context_handle_pointer is None: self._raise_closed() return self._socket def __del__(self): self.close() _win/trust_list.py000064400000017720147205106110010272 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import datetime import hashlib import struct from .._asn1 import Certificate from .._ffi import ( array_from_pointer, buffer_from_bytes, bytes_from_buffer, cast, deref, is_null, new, null, struct_from_buffer, unwrap, ) from ._crypt32 import crypt32, Crypt32Const, get_error, handle_error from .._types import str_cls __all__ = [ 'extract_from_system', 'system_path', ] def system_path(): return None def extract_from_system(cert_callback=None, callback_only_on_failure=False): """ Extracts trusted CA certificates from the Windows certificate store :param cert_callback: A callback that is called once for each certificate in the trust store. It should accept two parameters: an asn1crypto.x509.Certificate object, and a reason. The reason will be None if the certificate is being exported, otherwise it will be a unicode string of the reason it won't. :param callback_only_on_failure: A boolean - if the callback should only be called when a certificate is not exported. :raises: OSError - when an error is returned by the OS crypto library :return: A list of 3-element tuples: - 0: a byte string of a DER-encoded certificate - 1: a set of unicode strings that are OIDs of purposes to trust the certificate for - 2: a set of unicode strings that are OIDs of purposes to reject the certificate for """ certificates = {} processed = {} now = datetime.datetime.utcnow() for store in ["ROOT", "CA"]: store_handle = crypt32.CertOpenSystemStoreW(null(), store) handle_error(store_handle) context_pointer = null() while True: context_pointer = crypt32.CertEnumCertificatesInStore(store_handle, context_pointer) if is_null(context_pointer): break context = unwrap(context_pointer) trust_all = False data = None digest = None if context.dwCertEncodingType != Crypt32Const.X509_ASN_ENCODING: continue data = bytes_from_buffer(context.pbCertEncoded, int(context.cbCertEncoded)) digest = hashlib.sha1(data).digest() if digest in processed: continue processed[digest] = True cert_info = unwrap(context.pCertInfo) not_before_seconds = _convert_filetime_to_timestamp(cert_info.NotBefore) try: not_before = datetime.datetime.fromtimestamp(not_before_seconds) if not_before > now: if cert_callback: cert_callback(Certificate.load(data), 'not yet valid') continue except (ValueError, OSError): # If there is an error converting the not before timestamp, # it is almost certainly because it is from too long ago, # which means the cert is definitely valid by now. pass not_after_seconds = _convert_filetime_to_timestamp(cert_info.NotAfter) try: not_after = datetime.datetime.fromtimestamp(not_after_seconds) if not_after < now: if cert_callback: cert_callback(Certificate.load(data), 'no longer valid') continue except (ValueError, OSError) as e: # The only reason we would get an exception here is if the # expiration time is so far in the future that it can't be # used as a timestamp, or it is before 0. If it is very far # in the future, the cert is still valid, so we only raise # an exception if the timestamp is less than zero. if not_after_seconds < 0: message = e.args[0] + ' - ' + str_cls(not_after_seconds) e.args = (message,) + e.args[1:] raise e trust_oids = set() reject_oids = set() # Here we grab the extended key usage properties that Windows # layers on top of the extended key usage extension that is # part of the certificate itself. For highest security, users # should only use certificates for the intersection of the two # lists of purposes. However, many seen to treat the OS trust # list as an override. to_read = new(crypt32, 'DWORD *', 0) res = crypt32.CertGetEnhancedKeyUsage( context_pointer, Crypt32Const.CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, null(), to_read ) # Per the Microsoft documentation, if CRYPT_E_NOT_FOUND is returned # from get_error(), it means the certificate is valid for all purposes error_code, _ = get_error() if not res and error_code != Crypt32Const.CRYPT_E_NOT_FOUND: handle_error(res) if error_code == Crypt32Const.CRYPT_E_NOT_FOUND: trust_all = True else: usage_buffer = buffer_from_bytes(deref(to_read)) res = crypt32.CertGetEnhancedKeyUsage( context_pointer, Crypt32Const.CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, cast(crypt32, 'CERT_ENHKEY_USAGE *', usage_buffer), to_read ) handle_error(res) key_usage_pointer = struct_from_buffer(crypt32, 'CERT_ENHKEY_USAGE', usage_buffer) key_usage = unwrap(key_usage_pointer) # Having no enhanced usage properties means a cert is distrusted if key_usage.cUsageIdentifier == 0: if cert_callback: cert_callback(Certificate.load(data), 'explicitly distrusted') continue oids = array_from_pointer( crypt32, 'LPCSTR', key_usage.rgpszUsageIdentifier, key_usage.cUsageIdentifier ) for oid in oids: trust_oids.add(oid.decode('ascii')) cert = None # If the certificate is not under blanket trust, we have to # determine what purposes it is rejected for by diffing the # set of OIDs from the certificate with the OIDs that are # trusted. if not trust_all: cert = Certificate.load(data) if cert.extended_key_usage_value: for cert_oid in cert.extended_key_usage_value: oid = cert_oid.dotted if oid not in trust_oids: reject_oids.add(oid) if cert_callback and not callback_only_on_failure: if cert is None: cert = Certificate.load(data) cert_callback(cert, None) certificates[digest] = (data, trust_oids, reject_oids) result = crypt32.CertCloseStore(store_handle, 0) handle_error(result) store_handle = None return certificates.values() def _convert_filetime_to_timestamp(filetime): """ Windows returns times as 64-bit unsigned longs that are the number of hundreds of nanoseconds since Jan 1 1601. This converts it to a datetime object. :param filetime: A FILETIME struct object :return: An integer unix timestamp """ hundreds_nano_seconds = struct.unpack( b'>Q', struct.pack( b'>LL', filetime.dwHighDateTime, filetime.dwLowDateTime ) )[0] seconds_since_1601 = hundreds_nano_seconds / 10000000 return seconds_since_1601 - 11644473600 # Seconds from Jan 1 1601 to Jan 1 1970 _win/util.py000064400000012162147205106110007026 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from .. import backend from .._errors import pretty_message from .._ffi import buffer_from_bytes, bytes_from_buffer from .._pkcs12 import pkcs12_kdf from .._types import type_name, byte_cls, int_types __all__ = [ 'pbkdf2', 'pkcs12_kdf', 'rand_bytes', ] _backend = backend() if _backend == 'win': from ._cng import bcrypt, BcryptConst, handle_error, open_alg_handle, close_alg_handle 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", "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 OSError - when an error is returned by the OS crypto library :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', 'sha256', 'sha384', 'sha512']): raise ValueError(pretty_message( ''' hash_algorithm must be one of "sha1", "sha256", "sha384", "sha512", not %s ''', repr(hash_algorithm) )) alg_constant = { 'sha1': BcryptConst.BCRYPT_SHA1_ALGORITHM, 'sha256': BcryptConst.BCRYPT_SHA256_ALGORITHM, 'sha384': BcryptConst.BCRYPT_SHA384_ALGORITHM, 'sha512': BcryptConst.BCRYPT_SHA512_ALGORITHM }[hash_algorithm] alg_handle = None try: alg_handle = open_alg_handle(alg_constant, BcryptConst.BCRYPT_ALG_HANDLE_HMAC_FLAG) output_buffer = buffer_from_bytes(key_length) res = bcrypt.BCryptDeriveKeyPBKDF2( alg_handle, password, len(password), salt, len(salt), iterations, output_buffer, key_length, 0 ) handle_error(res) return bytes_from_buffer(output_buffer) finally: if alg_handle: close_alg_handle(alg_handle) pbkdf2.pure_python = False def rand_bytes(length): """ Returns a number of random bytes suitable for cryptographic purposes :param length: The desired number of 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 """ if not isinstance(length, int_types): raise TypeError(pretty_message( ''' length must be an integer, not %s ''', type_name(length) )) if length < 1: raise ValueError('length must be greater than 0') if length > 1024: raise ValueError('length must not be greater than 1024') alg_handle = None try: alg_handle = open_alg_handle(BcryptConst.BCRYPT_RNG_ALGORITHM) buffer = buffer_from_bytes(length) res = bcrypt.BCryptGenRandom(alg_handle, buffer, length, 0) handle_error(res) return bytes_from_buffer(buffer) finally: if alg_handle: close_alg_handle(alg_handle) # winlegacy backend else: from .._pkcs5 import pbkdf2 from .._rand import rand_bytes _win/__pycache__/__init__.cpython-38.pyc000064400000000242147205106110014072 0ustar00U af@sdS)NrrrG/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/__init__.py_win/__pycache__/_advapi32.cpython-38.pyc000064400000006721147205106110014113 0ustar00U af@sddlmZmZmZmZddlZddlmZddlm Z ddl m Z ddl m Z mZmZdd lmZed krdd lmZmZndd lmZmZd d dgZeZededfZdddZddZddZGdd d Zedkrde_dS))unicode_literalsdivisionabsolute_importprint_functionN)ffi) _try_decode)SignatureError)newunwrapnull)str_clsZcffi)advapi32 get_errorr Advapi32Const handle_errorTcCs|tjkrtj}n|tjkr$tj}n td||s>|tjkrLt}tj}n tj}tj }t t d}t |||||}|st dtjkrt ||||d}t|t|S)NzInvalid provider specified: %sz HCRYPTPROV *r)rMS_ENH_RSA_AES_PROV PROV_RSA_AESMS_ENH_DSS_DH_PROV PROV_DSS_DH ValueErrorr CRYPT_VERIFYCONTEXTCONTAINER_NAMECRYPT_NEWKEYSETr rZCryptAcquireContextWr NTE_EXISTSrr )providerZ verify_onlyZ provider_typeZcontainer_nameflagsZcontext_handle_pointerresrH/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/_advapi32.pyopen_context_handles8    r!cCst|d}t|dS)Nr)rZCryptReleaseContextr)handlerrrr close_context_handleDs r#cCsB|rdSt\}}|tjkr$tdt|ts6t|}t|dS)z Extracts the last Windows error message into a python unicode string :param result: A function result, 0 or None indicates failure :return: A unicode string error message NzSignature is invalid)rrNTE_BAD_SIGNATUREr isinstancerr OSError)resultcodeZ error_stringrrr rIs    c@seZdZdZdZdZdZdZdZdZ dZ d Z d Z dZ d Zd Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZd Zd Z dZ!dZ"dZ#dZ$d Z%dZ&d Z'd!Z(d"Z)d#Z*d$Z+dZ,d%Z-d&Z.d'Z/d(Z0d)S)*rzoscrypto temporary DSS keyset ,(z@Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Providerz5Microsoft Enhanced RSA and AES Cryptographic Providerrl`iii i iifihifi fififififi"i$ir@i i iRSA1iRSA2iDSS1iDSS2N)1__name__ __module__ __qualname__rrrZX509_PUBLIC_KEY_INFOZPKCS_PRIVATE_KEY_INFOZX509_DSS_SIGNATUREZ CRYPT_NO_SALTrrZCRYPT_EXPORTABLErrZCALG_MD5Z CALG_SHA1Z CALG_SHA_256Z CALG_SHA_384Z CALG_SHA_512ZCALG_RC2ZCALG_RC4ZCALG_DESZ CALG_3DES_112Z CALG_3DESZ CALG_AES_128Z CALG_AES_192Z CALG_AES_256Z CALG_DSS_SIGNZ CALG_RSA_SIGNZ CALG_RSA_KEYXZCRYPT_MODE_CBCZ PKCS5_PADDINGZCUR_BLOB_VERSIONZ PUBLICKEYBLOBZPRIVATEKEYBLOBZPLAINTEXTKEYBLOBZKP_IVZ KP_PADDINGZKP_MODEZKP_EFFECTIVE_KEYLENZ CRYPT_OAEPr$rZ AT_SIGNATUREZRSA1ZRSA2ZDSS1ZDSS2rrrr rbs\)rzAMicrosoft Enhanced RSA and AES Cryptographic Provider (Prototype))T) __future__rrrrsysr_decoder errorsr Z_ffir r r _typesrZ_advapi32_cffirrZ_advapi32_ctypes__all__getwindowsversionZ_gwvZ_win_version_infor!r#rrrrrrr s*      'A_win/__pycache__/_advapi32_cffi.cpython-38.pyc000064400000011400147205106110015070 0ustar00U af @sddlmZmZmZmZddlmZddlmZddl m Z ddl Z ddgZ e Ze jd krhed ed zed ZeeeWn>ek rZz eed dkre dW5dZ[XYnXddZdS))unicode_literalsdivisionabsolute_importprint_function) register_ffi)str_cls)LibraryNotFoundErrorNadvapi32 get_error)r Tao typedef HANDLE HCRYPTPROV; typedef HANDLE HCRYPTKEY; typedef HANDLE HCRYPTHASH; typedef unsigned int ALG_ID; typedef struct _CRYPTOAPI_BLOB { DWORD cbData; BYTE *pbData; } CRYPT_INTEGER_BLOB, CRYPT_OBJID_BLOB, CRYPT_DER_BLOB, CRYPT_ATTR_BLOB; typedef struct _CRYPT_ALGORITHM_IDENTIFIER { LPSTR pszObjId; CRYPT_OBJID_BLOB Parameters; } CRYPT_ALGORITHM_IDENTIFIER; typedef struct _CRYPT_BIT_BLOB { DWORD cbData; BYTE *pbData; DWORD cUnusedBits; } CRYPT_BIT_BLOB; typedef struct _CERT_PUBLIC_KEY_INFO { CRYPT_ALGORITHM_IDENTIFIER Algorithm; CRYPT_BIT_BLOB PublicKey; } CERT_PUBLIC_KEY_INFO; typedef struct _CRYPT_ATTRIBUTE { LPSTR pszObjId; DWORD cValue; CRYPT_ATTR_BLOB *rgValue; } CRYPT_ATTRIBUTE; typedef struct _CRYPT_ATTRIBUTES { DWORD cAttr; CRYPT_ATTRIBUTE *rgAttr; } CRYPT_ATTRIBUTES; typedef struct _CRYPT_PRIVATE_KEY_INFO { DWORD Version; CRYPT_ALGORITHM_IDENTIFIER Algorithm; CRYPT_DER_BLOB PrivateKey; CRYPT_ATTRIBUTES *pAttributes; } CRYPT_PRIVATE_KEY_INFO; typedef struct _PUBLICKEYSTRUC { BYTE bType; BYTE bVersion; WORD reserved; ALG_ID aiKeyAlg; } BLOBHEADER, PUBLICKEYSTRUC; typedef struct _DSSPUBKEY { DWORD magic; DWORD bitlen; } DSSPUBKEY; typedef struct _DSSBLOBHEADER { PUBLICKEYSTRUC publickeystruc; DSSPUBKEY dsspubkey; } DSSBLOBHEADER; typedef struct _RSAPUBKEY { DWORD magic; DWORD bitlen; DWORD pubexp; } RSAPUBKEY; typedef struct _RSABLOBHEADER { PUBLICKEYSTRUC publickeystruc; RSAPUBKEY rsapubkey; } RSABLOBHEADER; typedef struct _PLAINTEXTKEYBLOB { BLOBHEADER hdr; DWORD dwKeySize; // rgbKeyData omitted since it is a flexible array member } PLAINTEXTKEYBLOB; typedef struct _DSSSEED { DWORD counter; BYTE seed[20]; } DSSSEED; BOOL CryptAcquireContextW(HCRYPTPROV *phProv, LPCWSTR pszContainer, LPCWSTR pszProvider, DWORD dwProvType, DWORD dwFlags); BOOL CryptReleaseContext(HCRYPTPROV hProv, DWORD dwFlags); BOOL CryptImportKey(HCRYPTPROV hProv, BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey); BOOL CryptGenKey(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey); BOOL CryptGetKeyParam(HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags); BOOL CryptSetKeyParam(HCRYPTKEY hKey, DWORD dwParam, void *pbData, DWORD dwFlags); BOOL CryptExportKey(HCRYPTKEY hKey, HCRYPTKEY hExpKey, DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen); BOOL CryptDestroyKey(HCRYPTKEY hKey); BOOL CryptCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash); BOOL CryptHashData(HCRYPTHASH hHash, BYTE *pbData, DWORD dwDataLen, DWORD dwFlags); BOOL CryptSetHashParam(HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD dwFlags); BOOL CryptSignHashW(HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription, DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen); BOOL CryptVerifySignatureW(HCRYPTHASH hHash, BYTE *pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags); BOOL CryptDestroyHash(HCRYPTHASH hHash); BOOL CryptEncrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen); BOOL CryptDecrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen); z advapi32.dllzcannot load libraryzadvapi32.dll could not be foundcCstS)N)ffiZ getwinerrorrrM/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/_advapi32_cffi.pyr s) __future__rrrrZ_ffir_typesrerrorsr Zcffi__all__ZFFIr__version_info__Z set_unicodeZcdefdlopenr OSErrorefindr rrrrs&      r _win/__pycache__/_advapi32_ctypes.cpython-38.pyc000064400000012727147205106110015505 0ustar00U af> @sddlmZmZmZmZddlZddlmZmZmZm Z m Z m Z m Z ddl mZmZddlmZddlmZddlmZd d gZz ejZWn>ek rZz eed d kred W5dZ[XYnXejZejZejZe Ze Z zGddde Z!e!Z"e!Z#e!Z$e!Z%Gddde Z&Gddde Z'Gddde Z(Gddde Z)Gddde Z*Gddde Z+Gddde Z,e,Z-Gddde Z.Gd d!d!e Z/Gd"d#d#e Z0Gd$d%d%e Z1Gd&d'd'e Z2Gd(d)d)e Z3eeej4ej4eegej5_6ejej5_7eegej8_6ejej8_7eeeeeeegej9_6eej9_7ee eeegej:_6ejej:_7eeeeeegej;_6ejej;_7eee egej<_6ejej<_7eeeeeeegej=_6eej=_7egej>_6ejej>_7ee eeeegej?_6eej?_7eeeegej@_6eej@_7eeeegejA_6eejA_7eeej4eeeegejB_6eejB_7eeeeej4egejC_6eejC_7egejD_6ejejD_7eeeeeeeegejE_6eejE_7eeeeeeegejF_6eejF_7WneGk red*YnXeHed+eeHed,eeHed-eeHed.e"eHed/e#eHed0e$eHed1e%eHede&eHede'eHede(eHede+eHede)eHede*eHede,eHede.eHed!e/eHed#e0eHed%e1eHed2e-eHed'e2eHed)e3d3d ZIdS)4)unicode_literalsdivisionabsolute_importprint_functionN)windllwintypesPOINTER Structurec_void_pc_char_pc_uint)BOOLDWORD)FFIEngineError)str_cls)LibraryNotFoundErroradvapi32 get_errorz'The specified module could not be foundzadvapi32.dll could not be foundc@s"eZdZdefdeejfgZdS)CRYPTOAPI_BLOBcbDatapbDataN)__name__ __module__ __qualname__rrctypesc_byte_fields_rrO/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/_advapi32_ctypes.pyr!s rc@seZdZdejfdefgZdS)CRYPT_ALGORITHM_IDENTIFIERpszObjIdZ ParametersN)rrrrLPSTRCRYPT_OBJID_BLOB_fieldsrrrr r!+sr!c@s"eZdZdefdefdefgZdS)CRYPT_BIT_BLOBrrZ cUnusedBitsN)rrrrPBYTErrrrr r&1sr&c@seZdZdefdefgZdS)CERT_PUBLIC_KEY_INFO AlgorithmZ PublicKeyN)rrrr!r&rrrrr r(8sr(c@s(eZdZdejfdefdeefgZdS)CRYPT_ATTRIBUTEr"ZcValueZrgValueN) rrrrr#rrCRYPT_ATTR_BLOBrrrrr r*>s r*c@s eZdZdefdeefgZdS)CRYPT_ATTRIBUTESZcAttrZrgAttrN)rrrrrr*rrrrr r,Es r,c@s,eZdZdefdefdefdeefgZdS)CRYPT_PRIVATE_KEY_INFOVersionr)Z PrivateKeyZ pAttributesN) rrrrr!CRYPT_DER_BLOBrr,rrrrr r-Ks  r-c@s.eZdZdejfdejfdejfdefgZdS)PUBLICKEYSTRUCZbTypeZbVersionreservedZaiKeyAlgN)rrrrBYTEZWORDALG_IDrrrrr r0Ss r0c@seZdZdefdefgZdS) DSSPUBKEYmagicbitlenNrrrrrrrrr r4\sr4c@seZdZdefdefgZdS) DSSBLOBHEADERpublickeystrucZ dsspubkeyN)rrrr0r4rrrrr r8bsr8c@s"eZdZdefdefdefgZdS) RSAPUBKEYr5r6ZpubexpNr7rrrr r:hsr:c@seZdZdefdefgZdS) RSABLOBHEADERr9Z rsapubkeyN)rrrr0r:rrrrr r;osr;c@seZdZdefdefgZdS)PLAINTEXTKEYBLOBhdrZ dwKeySizeN)rrr BLOBHEADERrrrrrr r<usr<c@s"eZdZdefdejdfgZdS)DSSSEEDcounterseedN)rrrrrr2rrrrr r?|s r?zError initializing ctypes HCRYPTPROV HCRYPTKEY HCRYPTHASHCRYPT_INTEGER_BLOBr$r/r+r>cCst}|t|fS)N)rZ GetLastError FormatError)errorrrr r%s)J __future__rrrrrrrrr r r r Zctypes.wintypesr rZ_ffir_typesrerrorsr__all__rOSErrorefindZHANDLErCrDrEr'r3rrFr$r/r+r!r&r(r*r,r-r0r>r4r8r:r;r<r?ZLPCWSTRZCryptAcquireContextWargtypesrestypeZCryptReleaseContextZCryptImportKeyZ CryptGenKeyZCryptGetKeyParamZCryptSetKeyParamZCryptExportKeyZCryptDestroyKeyZCryptCreateHashZ CryptHashDataZCryptSetHashParamZCryptSignHashWZCryptVerifySignatureWZCryptDestroyHashZ CryptEncryptZ CryptDecryptAttributeErrorsetattrrrrrr sP$                                  _win/__pycache__/_cng.cpython-38.pyc000064400000010547147205106110013252 0ustar00U af@sddlmZmZmZmZddlmZddlmZm Z m Z edkrPddl m Z n ddl m Z dd d d d gZdd d Zdd Zdd ZGdd d ZdS))unicode_literalsdivisionabsolute_importprint_function)ffi)newnullunwrapZcffi)bcryptr BcryptConstclose_alg_handle handle_erroropen_alg_handlecCs,ttd}t||t|}t|t|S)NzBCRYPT_ALG_HANDLE *)rr ZBCryptOpenAlgorithmProviderr rr )ZconstantflagsZhandle_pointerresrC/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/_cng.pyrs cCst|d}t|dS)Nr)r ZBCryptCloseAlgorithmProviderr)handlerrrrrs cCst|dkr dStjdtjdtjdtjdtjdtjdtjd tjd i}d |}|dk rh||krh|d ||7}t |dS) z Extracts the last Windows error message into a python unicode string :param error_num: The number to get the error string for :return: A unicode string error message rNzThe object was not foundz8An invalid parameter was passed to a service or functionz_Not enough virtual memory or paging file quota is available to complete the specified operationzAn invalid HANDLE was specifiedz&The cryptographic signature is invalidzThe request is not supportedz,The buffer is too small to contain the entryz=The size of the buffer is invalid for the specified operationzNTSTATUS error 0x%0.2Xz: ) r STATUS_NOT_FOUNDSTATUS_INVALID_PARAMETERSTATUS_NO_MEMORYSTATUS_INVALID_HANDLESTATUS_INVALID_SIGNATURESTATUS_NOT_SUPPORTEDSTATUS_BUFFER_TOO_SMALLSTATUS_INVALID_BUFFER_SIZEOSError)Z error_nummessagesoutputrrrr#s.  c@seZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#dZ$d Z%d!Z&d"Z'd#Z(d$Z)dZ*d%Z+dZ,d&Z-dZ.d'Z/d(Z0d)Z1d*Z2d+Z3d,Z4d-Z5d.Z6d/Z7d0Z8d1Z9d2Z:d3Z;d4ZdZ?dZ@d7S)8r ZRNGZ KeyLengthZEffectiveKeyLengthZRSAPRIVATEBLOBZRSAFULLPRIVATEBLOBZ RSAPUBLICBLOBZDSAPRIVATEBLOBZ DSAPUBLICBLOBZECCPRIVATEBLOBZ ECCPUBLICBLOBiRSA1iRSA2iRSA3iDSPBiDSPViDPB2iDPV2rr riECS1iECS2iECS3iECS4iECS5iECS6l%l lll ll#liKDBMZ KeyDataBlobZ3DESZ3DES_112AESZDESZRC2ZRC4ZDSAZ ECDSA_P256Z ECDSA_P384Z ECDSA_P521ZRSAMD5SHA1SHA256SHA384SHA512N)A__name__ __module__ __qualname__ZBCRYPT_RNG_ALGORITHMZBCRYPT_KEY_LENGTHZBCRYPT_EFFECTIVE_KEY_LENGTHZBCRYPT_RSAPRIVATE_BLOBZBCRYPT_RSAFULLPRIVATE_BLOBZBCRYPT_RSAPUBLIC_BLOBZBCRYPT_DSA_PRIVATE_BLOBZBCRYPT_DSA_PUBLIC_BLOBZBCRYPT_ECCPRIVATE_BLOBZBCRYPT_ECCPUBLIC_BLOBZBCRYPT_RSAPUBLIC_MAGICZBCRYPT_RSAPRIVATE_MAGICZBCRYPT_RSAFULLPRIVATE_MAGICZBCRYPT_DSA_PUBLIC_MAGICZBCRYPT_DSA_PRIVATE_MAGICZBCRYPT_DSA_PUBLIC_MAGIC_V2ZBCRYPT_DSA_PRIVATE_MAGIC_V2ZDSA_HASH_ALGORITHM_SHA1ZDSA_HASH_ALGORITHM_SHA256ZDSA_HASH_ALGORITHM_SHA512Z DSA_FIPS186_2Z DSA_FIPS186_3ZBCRYPT_NO_KEY_VALIDATIONZBCRYPT_ECDSA_PUBLIC_P256_MAGICZBCRYPT_ECDSA_PRIVATE_P256_MAGICZBCRYPT_ECDSA_PUBLIC_P384_MAGICZBCRYPT_ECDSA_PRIVATE_P384_MAGICZBCRYPT_ECDSA_PUBLIC_P521_MAGICZBCRYPT_ECDSA_PRIVATE_P521_MAGICZSTATUS_SUCCESSrrrrrrrrZBCRYPT_KEY_DATA_BLOB_MAGICZBCRYPT_KEY_DATA_BLOB_VERSION1ZBCRYPT_KEY_DATA_BLOBZBCRYPT_PAD_PKCS1ZBCRYPT_PAD_OAEPZBCRYPT_PAD_PSSZBCRYPT_3DES_ALGORITHMZBCRYPT_3DES_112_ALGORITHMZBCRYPT_AES_ALGORITHMZBCRYPT_DES_ALGORITHMZBCRYPT_RC2_ALGORITHMZBCRYPT_RC4_ALGORITHMZBCRYPT_DSA_ALGORITHMZBCRYPT_ECDSA_P256_ALGORITHMZBCRYPT_ECDSA_P384_ALGORITHMZBCRYPT_ECDSA_P521_ALGORITHMZBCRYPT_RSA_ALGORITHMZBCRYPT_MD5_ALGORITHMZBCRYPT_SHA1_ALGORITHMZBCRYPT_SHA256_ALGORITHMZBCRYPT_SHA384_ALGORITHMZBCRYPT_SHA512_ALGORITHMZBCRYPT_ALG_HANDLE_HMAC_FLAGZBCRYPT_BLOCK_PADDINGrrrrr Fs|N)r) __future__rrrrrZ_ffirr r Z _cng_cffir Z _cng_ctypes__all__rrrr rrrrs    #_win/__pycache__/_cng_cffi.cpython-38.pyc000064400000011106147205106110014231 0ustar00U af~ @sddlmZmZmZmZddlmZddlmZddl m Z ddl m Z dgZ e Zedzed ZeeeWn>ek rZz eed d kre d W5d Z[XYnXd S))unicode_literalsdivisionabsolute_importprint_function) register_ffi)str_cls)LibraryNotFoundError)FFIbcryptaK typedef HANDLE BCRYPT_ALG_HANDLE; typedef HANDLE BCRYPT_KEY_HANDLE; typedef ULONG NTSTATUS; typedef unsigned char *PUCHAR; typedef unsigned char *PBYTE; typedef struct _BCRYPT_RSAKEY_BLOB { ULONG Magic; ULONG BitLength; ULONG cbPublicExp; ULONG cbModulus; ULONG cbPrime1; ULONG cbPrime2; } BCRYPT_RSAKEY_BLOB; typedef struct _BCRYPT_DSA_KEY_BLOB { ULONG dwMagic; ULONG cbKey; UCHAR Count[4]; UCHAR Seed[20]; UCHAR q[20]; } BCRYPT_DSA_KEY_BLOB; typedef struct _BCRYPT_DSA_KEY_BLOB_V2 { ULONG dwMagic; ULONG cbKey; INT hashAlgorithm; INT standardVersion; ULONG cbSeedLength; ULONG cbGroupSize; UCHAR Count[4]; } BCRYPT_DSA_KEY_BLOB_V2; typedef struct _BCRYPT_ECCKEY_BLOB { ULONG dwMagic; ULONG cbKey; } BCRYPT_ECCKEY_BLOB; typedef struct _BCRYPT_PKCS1_PADDING_INFO { LPCWSTR pszAlgId; } BCRYPT_PKCS1_PADDING_INFO; typedef struct _BCRYPT_PSS_PADDING_INFO { LPCWSTR pszAlgId; ULONG cbSalt; } BCRYPT_PSS_PADDING_INFO; typedef struct _BCRYPT_OAEP_PADDING_INFO { LPCWSTR pszAlgId; PUCHAR pbLabel; ULONG cbLabel; } BCRYPT_OAEP_PADDING_INFO; typedef struct _BCRYPT_KEY_DATA_BLOB_HEADER { ULONG dwMagic; ULONG dwVersion; ULONG cbKeyData; } BCRYPT_KEY_DATA_BLOB_HEADER; NTSTATUS BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE *phAlgorithm, LPCWSTR pszAlgId, LPCWSTR pszImplementation, DWORD dwFlags); NTSTATUS BCryptCloseAlgorithmProvider(BCRYPT_ALG_HANDLE hAlgorithm, DWORD dwFlags); NTSTATUS BCryptSetProperty(HANDLE hObject, LPCWSTR pszProperty, ULONG *pbInput, ULONG cbInput, ULONG dwFlags); NTSTATUS BCryptImportKeyPair(BCRYPT_ALG_HANDLE hAlgorithm, BCRYPT_KEY_HANDLE hImportKey, LPCWSTR pszBlobType, BCRYPT_KEY_HANDLE *phKey, PUCHAR pbInput, ULONG cbInput, ULONG dwFlags); NTSTATUS BCryptImportKey(BCRYPT_ALG_HANDLE hAlgorithm, BCRYPT_KEY_HANDLE hImportKey, LPCWSTR pszBlobType, BCRYPT_KEY_HANDLE *phKey, PUCHAR pbKeyObject, ULONG cbKeyObject, PUCHAR pbInput, ULONG cbInput, ULONG dwFlags); NTSTATUS BCryptDestroyKey(BCRYPT_KEY_HANDLE hKey); NTSTATUS BCryptVerifySignature(BCRYPT_KEY_HANDLE hKey, void *pPaddingInfo, PUCHAR pbHash, ULONG cbHash, PUCHAR pbSignature, ULONG cbSignature, ULONG dwFlags); NTSTATUS BCryptSignHash(BCRYPT_KEY_HANDLE hKey, void * pPaddingInfo, PBYTE pbInput, DWORD cbInput, PBYTE pbOutput, DWORD cbOutput, DWORD *pcbResult, ULONG dwFlags); NTSTATUS BCryptEncrypt(BCRYPT_KEY_HANDLE hKey, PUCHAR pbInput, ULONG cbInput, void *pPaddingInfo, PUCHAR pbIV, ULONG cbIV, PUCHAR pbOutput, ULONG cbOutput, ULONG *pcbResult, ULONG dwFlags); NTSTATUS BCryptDecrypt(BCRYPT_KEY_HANDLE hKey, PUCHAR pbInput, ULONG cbInput, void *pPaddingInfo, PUCHAR pbIV, ULONG cbIV, PUCHAR pbOutput, ULONG cbOutput, ULONG *pcbResult, ULONG dwFlags); NTSTATUS BCryptDeriveKeyPBKDF2(BCRYPT_ALG_HANDLE hPrf, PUCHAR pbPassword, ULONG cbPassword, PUCHAR pbSalt, ULONG cbSalt, ULONGLONG cIterations, PUCHAR pbDerivedKey, ULONG cbDerivedKey, ULONG dwFlags); NTSTATUS BCryptGenRandom(BCRYPT_ALG_HANDLE hAlgorithm, PUCHAR pbBuffer, ULONG cbBuffer, ULONG dwFlags); NTSTATUS BCryptGenerateKeyPair(BCRYPT_ALG_HANDLE hAlgorithm, BCRYPT_KEY_HANDLE *phKey, ULONG dwLength, ULONG dwFlags); NTSTATUS BCryptFinalizeKeyPair(BCRYPT_KEY_HANDLE hKey, ULONG dwFlags); NTSTATUS BCryptExportKey(BCRYPT_KEY_HANDLE hKey, BCRYPT_KEY_HANDLE hExportKey, LPCWSTR pszBlobType, PUCHAR pbOutput, ULONG cbOutput, ULONG *pcbResult, ULONG dwFlags); z bcrypt.dllzcannot load libraryzLbcrypt.dll could not be found - Windows XP and Server 2003 are not supportedN) __future__rrrrZ_ffir_typesrerrorsr Zcffir __all__ffiZcdefdlopenr OSErrorefindrrH/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/_cng_cffi.pys     ` _win/__pycache__/_cng_ctypes.cpython-38.pyc000064400000010062147205106110014631 0ustar00U af  @sddlmZmZmZmZddlmZmZmZm Z m Z m Z m Z m Z ddlmZmZmZddlmZddlmZddlmZdgZz ejZWn>ek rZz eed d kred W5d Z[XYnXejZejZejZ e Z!e Z"zeeeeegej#_$e ej#_%eegej&_$e ej&_%eeeeee!eegej'_$e ej'_%eeeeee!ee!eeg ej(_$e ej(_%egej)_$e ej)_%ee e!ee!eegej*_$e ej*_%ee e"ee"eeeegej+_$e ej+_%eee eegej,_$e ej,_%ee!ee e!ee!eeeeg ej-_$e ej-_%ee!ee e!ee!eeeeg ej._$e ej._%ee!ee!ee e!eeg ej/_$e ej/_%ee!eegej0_$e ej0_%eeeeegej1_$e ej1_%eegej2_$e ej2_%eeee!eeeegej3_$e ej3_%Wne4k red YnXGddde Z5Gddde Z6Gddde Z7Gddde Z8Gddde Z9Gddde Z:Gddde Z;Gddde Z __future__rrrrctypesrrrr r r r r Zctypes.wintypesrrrZ_ffir_typesrerrorsr__all__rOSErrorefindZHANDLEr/r0ZNTSTATUSr-ZPBYTEZBCryptOpenAlgorithmProviderargtypesrestypeZBCryptCloseAlgorithmProviderZBCryptImportKeyPairZBCryptImportKeyZBCryptDestroyKeyZBCryptVerifySignatureZBCryptSignHashZBCryptSetPropertyZ BCryptEncryptZ BCryptDecryptZBCryptDeriveKeyPBKDF2ZBCryptGenRandomZBCryptGenerateKeyPairZBCryptFinalizeKeyPairZBCryptExportKeyAttributeErrorrrr&r(r)r+r,r.setattrrrrrs<(                        _win/__pycache__/_crypt32.cpython-38.pyc000064400000004141147205106110014002 0ustar00U afi@sddlmZmZmZmZddlmZddlmZddl m Z ddl m Z edkrddd l mZmZndd lmZmZd d d gZd d ZGdd d ZdS))unicode_literalsdivisionabsolute_importprint_function)ffi) _try_decode)buffer_from_bytes)str_clsZcffi)crypt32 get_errorr Crypt32Const handle_errorcCs0|rdSt\}}t|ts$t|}t|dS)z Extracts the last Windows error message into a python unicode string :param result: A function result, 0 or None indicates failure :return: A unicode string error message N)r isinstancer r OSError)result_Z error_stringrG/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/_crypt32.pyrs   c@sxeZdZdZdZdZdZdZdZdZ dZ dZ dZ dZ d ZdZd Zd Zd Zd ZdZdZdZdZedZedZedZdS)rrzi sMemoryi rill`llll ll s1.3.6.1.5.5.7.3.1s1.3.6.1.4.1.311.10.3.3s2.16.840.1.113730.4.1N)__name__ __module__ __qualname__ZX509_ASN_ENCODINGZERROR_INSUFFICIENT_BUFFERZ%CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAGZCRYPT_E_NOT_FOUNDZCERT_STORE_PROV_MEMORYZCERT_STORE_CREATE_NEW_FLAGZCERT_STORE_ADD_USE_EXISTINGZUSAGE_MATCH_TYPE_ORZCERT_CHAIN_POLICY_SSLZAUTHTYPE_SERVERZ'CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAGZ.CERT_CHAIN_POLICY_IGNORE_ALL_REV_UNKNOWN_FLAGSZCERT_CHAIN_CACHE_END_CERTZ&CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLYZTRUST_E_CERT_SIGNATUREZCERT_E_EXPIREDZ CERT_E_ROLEZCERT_E_PURPOSEZCERT_E_UNTRUSTEDROOTZCERT_E_CN_NO_MATCHZCRYPT_E_REVOKEDr ZPKIX_KP_SERVER_AUTHZSERVER_GATED_CRYPTOZ SGC_NETSCAPErrrrr,s0N) __future__rrrrr_decoder Z_ffir _typesr Z _crypt32_cffir r Z_crypt32_ctypes__all__rrrrrrs     _win/__pycache__/_crypt32_cffi.cpython-38.pyc000064400000014052147205106110014773 0ustar00U af  @sddlmZmZmZmZddlZddlmZddlm Z ddl m Z ddl Z ddgZ e Ze jd krped ejd kred n ed edzedZeeeWn>ek rZz e eddkre dW5dZ[XYnXddZdS))unicode_literalsdivisionabsolute_importprint_functionN) register_ffi)str_cls)LibraryNotFoundErrorcrypt32 get_error)r Tlztypedef uint64_t ULONG_PTR;z typedef unsigned long ULONG_PTR;a typedef HANDLE HCERTSTORE; typedef unsigned char *PBYTE; typedef struct _CRYPTOAPI_BLOB { DWORD cbData; PBYTE pbData; } CRYPTOAPI_BLOB; typedef CRYPTOAPI_BLOB CRYPT_INTEGER_BLOB; typedef CRYPTOAPI_BLOB CERT_NAME_BLOB; typedef CRYPTOAPI_BLOB CRYPT_BIT_BLOB; typedef CRYPTOAPI_BLOB CRYPT_OBJID_BLOB; typedef struct _CRYPT_ALGORITHM_IDENTIFIER { LPSTR pszObjId; CRYPT_OBJID_BLOB Parameters; } CRYPT_ALGORITHM_IDENTIFIER; typedef struct _FILETIME { DWORD dwLowDateTime; DWORD dwHighDateTime; } FILETIME; typedef struct _CERT_PUBLIC_KEY_INFO { CRYPT_ALGORITHM_IDENTIFIER Algorithm; CRYPT_BIT_BLOB PublicKey; } CERT_PUBLIC_KEY_INFO; typedef struct _CERT_EXTENSION { LPSTR pszObjId; BOOL fCritical; CRYPT_OBJID_BLOB Value; } CERT_EXTENSION, *PCERT_EXTENSION; typedef struct _CERT_INFO { DWORD dwVersion; CRYPT_INTEGER_BLOB SerialNumber; CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm; CERT_NAME_BLOB Issuer; FILETIME NotBefore; FILETIME NotAfter; CERT_NAME_BLOB Subject; CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo; CRYPT_BIT_BLOB IssuerUniqueId; CRYPT_BIT_BLOB SubjectUniqueId; DWORD cExtension; PCERT_EXTENSION *rgExtension; } CERT_INFO, *PCERT_INFO; typedef struct _CERT_CONTEXT { DWORD dwCertEncodingType; PBYTE pbCertEncoded; DWORD cbCertEncoded; PCERT_INFO pCertInfo; HCERTSTORE hCertStore; } CERT_CONTEXT, *PCERT_CONTEXT; typedef struct _CERT_TRUST_STATUS { DWORD dwErrorStatus; DWORD dwInfoStatus; } CERT_TRUST_STATUS, *PCERT_TRUST_STATUS; typedef struct _CERT_ENHKEY_USAGE { DWORD cUsageIdentifier; LPSTR *rgpszUsageIdentifier; } CERT_ENHKEY_USAGE, *PCERT_ENHKEY_USAGE; typedef struct _CERT_CHAIN_ELEMENT { DWORD cbSize; PCERT_CONTEXT pCertContext; CERT_TRUST_STATUS TrustStatus; void *pRevocationInfo; PCERT_ENHKEY_USAGE pIssuanceUsage; PCERT_ENHKEY_USAGE pApplicationUsage; LPCWSTR pwszExtendedErrorInfo; } CERT_CHAIN_ELEMENT, *PCERT_CHAIN_ELEMENT; typedef struct _CERT_SIMPLE_CHAIN { DWORD cbSize; CERT_TRUST_STATUS TrustStatus; DWORD cElement; PCERT_CHAIN_ELEMENT *rgpElement; void *pTrustListInfo; BOOL fHasRevocationFreshnessTime; DWORD dwRevocationFreshnessTime; } CERT_SIMPLE_CHAIN, *PCERT_SIMPLE_CHAIN; typedef struct _CERT_CHAIN_CONTEXT { DWORD cbSize; CERT_TRUST_STATUS TrustStatus; DWORD cChain; PCERT_SIMPLE_CHAIN *rgpChain; DWORD cLowerQualityChainContext; void *rgpLowerQualityChainContext; BOOL fHasRevocationFreshnessTime; DWORD dwRevocationFreshnessTime; } CERT_CHAIN_CONTEXT, *PCERT_CHAIN_CONTEXT; typedef struct _CERT_USAGE_MATCH { DWORD dwType; CERT_ENHKEY_USAGE Usage; } CERT_USAGE_MATCH; typedef struct _CERT_CHAIN_PARA { DWORD cbSize; CERT_USAGE_MATCH RequestedUsage; } CERT_CHAIN_PARA; typedef struct _CERT_CHAIN_POLICY_PARA { DWORD cbSize; DWORD dwFlags; void *pvExtraPolicyPara; } CERT_CHAIN_POLICY_PARA; typedef struct _HTTPSPolicyCallbackData { DWORD cbSize; DWORD dwAuthType; DWORD fdwChecks; WCHAR *pwszServerName; } SSL_EXTRA_CERT_CHAIN_POLICY_PARA; typedef struct _CERT_CHAIN_POLICY_STATUS { DWORD cbSize; DWORD dwError; LONG lChainIndex; LONG lElementIndex; void *pvExtraPolicyStatus; } CERT_CHAIN_POLICY_STATUS; typedef HANDLE HCERTCHAINENGINE; typedef HANDLE HCRYPTPROV; HCERTSTORE CertOpenStore(LPCSTR lpszStoreProvider, DWORD dwMsgAndCertEncodingType, HCRYPTPROV hCryptProv, DWORD dwFlags, void *pvPara); BOOL CertAddEncodedCertificateToStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, BYTE *pbCertEncoded, DWORD cbCertEncoded, DWORD dwAddDisposition, PCERT_CONTEXT *ppCertContext); BOOL CertGetCertificateChain(HCERTCHAINENGINE hChainEngine, CERT_CONTEXT *pCertContext, FILETIME *pTime, HCERTSTORE hAdditionalStore, CERT_CHAIN_PARA *pChainPara, DWORD dwFlags, void *pvReserved, PCERT_CHAIN_CONTEXT *ppChainContext); BOOL CertVerifyCertificateChainPolicy(ULONG_PTR pszPolicyOID, PCERT_CHAIN_CONTEXT pChainContext, CERT_CHAIN_POLICY_PARA *pPolicyPara, CERT_CHAIN_POLICY_STATUS *pPolicyStatus); void CertFreeCertificateChain(PCERT_CHAIN_CONTEXT pChainContext); HCERTSTORE CertOpenSystemStoreW(HANDLE hprov, LPCWSTR szSubsystemProtocol); PCERT_CONTEXT CertEnumCertificatesInStore(HCERTSTORE hCertStore, CERT_CONTEXT *pPrevCertContext); BOOL CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags); BOOL CertGetEnhancedKeyUsage(CERT_CONTEXT *pCertContext, DWORD dwFlags, CERT_ENHKEY_USAGE *pUsage, DWORD *pcbUsage); z crypt32.dllzcannot load libraryzcrypt32.dll could not be foundcCstS)N)ffiZ getwinerrorrrL/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/_crypt32_cffi.pyr s) __future__rrrrsysZ_ffir_typesrerrorsr Zcffi__all__ZFFIr__version_info__Z set_unicodemaxsizeZcdefdlopenr OSErrorefindr rrrrs0          _win/__pycache__/_crypt32_ctypes.cpython-38.pyc000064400000015041147205106110015372 0ustar00U af @sddlmZmZmZmZddlZddlZddlmZmZm Z m Z m Z m Z ddl mZddlmZddlmZddlmZd d lmZd d gZz ejZWn>ek rZz eed dkredW5dZ[XYnXejZejZejZejZ e Z!ej"dkrej#Z$nej%Z$zNGddde Z&e&Z'e&Z(e&Z)e&Z*Gddde Z+Gddde Z,Gddde Z-e e-Z.Gddde Z/e e/Z0Gddde Z1e e1Z2Gddde Z3e e3Z4Gdd d e Z5Gd!d"d"e Z6e e6Z7Gd#d$d$e Z8e e8Z9Gd%d&d&e Z:e e:Z;Gd'd(d(e ZGd-d.d.e Z?Gd/d0d0e Z@ejAeeee gejB_CeejB_Deee!eee e2gejE_CejFejE_Dee2e ejGee e=ee e e;gejH_CejFejH_De$e;e e>e e@gejI_CejFejI_De;gejJ_CdejJ_DejejKgejL_CeejL_Dee2gejM_Ce2ejM_DeegejN_CejFejN_De2ee e egejO_CejFejO_DWnePk rzed1YnXeQed2ejGeQede3eQede1eQed3e2eQed(e<eQed*e=eQed,e>eQed.e?eQed0e@eQed4e;d5d ZRdS)6)unicode_literalsdivisionabsolute_importprint_functionN)windllwintypesPOINTER Structurec_void_pc_char_p)DWORD)FFIEngineError)str_cls)LibraryNotFoundError)kernel32crypt32 get_errorz'The specified module could not be foundzcrypt32.dll could not be foundlc@seZdZdefdefgZdS)CRYPTOAPI_BLOBZcbDataZpbDataN__name__ __module__ __qualname__r r _fields_rrN/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/_crypt32_ctypes.pyr(src@seZdZdejfdefgZdS)CRYPT_ALGORITHM_IDENTIFIERpszObjIdZ ParametersN)rrrrLPSTRCRYPT_OBJID_BLOBrrrrrr2src@seZdZdefdefgZdS)CERT_PUBLIC_KEY_INFOZ AlgorithmZ PublicKeyN)rrrrCRYPT_BIT_BLOBrrrrrr"8sr"c@s&eZdZdejfdejfdefgZdS)CERT_EXTENSIONrZ fCriticalValueN)rrrrr BOOLr!rrrrrr$>sr$c@s`eZdZdefdefdefdefdejfdejfdefde fd e fd e fd efd e e fg Z d S) CERT_INFOZ dwVersionZ SerialNumberZSignatureAlgorithmZIssuerZ NotBeforeZNotAfterSubjectZSubjectPublicKeyInfoZIssuerUniqueIdZSubjectUniqueIdZ cExtensionZ rgExtensionN)rrrr CRYPT_INTEGER_BLOBrCERT_NAME_BLOBrFILETIMEr"r#rPCERT_EXTENSIONrrrrrr'Fs r'c@s.eZdZdefdefdefdefdefgZdS) CERT_CONTEXTZdwCertEncodingTypeZ pbCertEncodedZ cbCertEncodedZ pCertInfoZ hCertStoreN)rrrr r PCERT_INFO HCERTSTORErrrrrr-Ws r-c@s&eZdZdefdeeejfgZdS)CERT_ENHKEY_USAGEZcUsageIdentifierZrgpszUsageIdentifierN)rrrr rrZBYTErrrrrr0bsr0c@seZdZdefdefgZdS)CERT_TRUST_STATUSZ dwErrorStatusZ dwInfoStatusN)rrrr rrrrrr1jsr1c@s<eZdZdefdefdefdefdefdefdej fgZ dS) CERT_CHAIN_ELEMENTcbSizeZ pCertContext TrustStatusZpRevocationInfoZpIssuanceUsageZpApplicationUsageZpwszExtendedErrorInfoN) rrrr PCERT_CONTEXTr1r PCERT_ENHKEY_USAGErLPCWSTRrrrrrr2psr2c@s@eZdZdefdefdefdeefdefdej fdefgZ dS) CERT_SIMPLE_CHAINr3r4ZcElementZ rgpElementZpTrustListInfofHasRevocationFreshnessTimedwRevocationFreshnessTimeN) rrrr r1rPCERT_CHAIN_ELEMENTr rr&rrrrrr8}s r8c @sFeZdZdefdefdefdeefdefdefdej fdefgZ d S) CERT_CHAIN_CONTEXTr3r4ZcChainZrgpChainZcLowerQualityChainContextZrgpLowerQualityChainContextr9r:N) rrrr r1rPCERT_SIMPLE_CHAINr rr&rrrrrr<s r<c@seZdZdefdefgZdS)CERT_USAGE_MATCHZdwTypeUsageN)rrrr r0rrrrrr>sr>c@seZdZdefdefgZdS)CERT_CHAIN_PARAr3ZRequestedUsageN)rrrr r>rrrrrr@sr@c@s"eZdZdefdefdefgZdS)CERT_CHAIN_POLICY_PARAr3ZdwFlagsZpvExtraPolicyParaNrrrrrrAsrAc@s*eZdZdefdefdefdejfgZdS) SSL_EXTRA_CERT_CHAIN_POLICY_PARAr3Z dwAuthTypeZ fdwChecksZpwszServerNameN)rrrr rr7rrrrrrBs rBc@s2eZdZdefdefdejfdejfdefgZdS)CERT_CHAIN_POLICY_STATUSr3ZdwErrorZ lChainIndexZ lElementIndexZpvExtraPolicyStatusN)rrrr rLONGr rrrrrrCs rCzError initializing ctypesr+r5PCERT_CHAIN_CONTEXTcCst}|t|fS)N)ctypesZ GetLastError FormatError)errorrrrrs)S __future__rrrrsysrFrrrr r r Zctypes.wintypesr Z_ffir_typesrerrorsrZ _kernel32r__all__rOSErrorefindZHANDLEr/ZHCERTCHAINENGINEZ HCRYPTPROVZ HCRYPTKEYZPBYTEmaxsizec_uint64Z ULONG_PTRc_ulongrr)r*r#r!rr"r$r,r'r.r-r5r0r6r1r2r;r8r=r<rEr>r@rArBrCZLPCSTRZ CertOpenStoreargtypesrestypeZ CertAddEncodedCertificateToStorer&r+ZCertGetCertificateChainZ CertVerifyCertificateChainPolicyZCertFreeCertificateChainr7ZCertOpenSystemStoreWZCertEnumCertificatesInStoreZCertCloseStoreZCertGetEnhancedKeyUsageAttributeErrorsetattrrrrrrs                          _win/__pycache__/_decode.cpython-38.pyc000064400000001572147205106110013724 0ustar00U af@sHddlmZmZmZmZddlZddlmZeZ ddgZ ddZ dS) )unicode_literalsdivisionabsolute_importprint_functionN)str_clszutf-8cp1252c Csfz t|tWStk rXtD]2}zt||ddWYStk rPYq Xq YnXt|ddS)z Tries decoding a byte string from the OS into a unicode string :param byte_string: A byte string :return: A unicode string strict)errorsreplace)r _encodingUnicodeDecodeError_fallback_encodings)Z byte_stringencodingrF/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/_decode.py _try_decode s  r) __future__rrrrlocale_typesrgetpreferredencodingr rrrrrrs  _win/__pycache__/_kernel32.cpython-38.pyc000064400000001722147205106110014123 0ustar00U af&@s|ddlmZmZmZmZddlmZddlmZddl m Z edkrXddl m Z m Z nddlm Z m Z d d gZd d Zd S) )unicode_literalsdivisionabsolute_importprint_function)ffi) _try_decode)str_clsZcffi)kernel32 get_error handle_errorr cCs0|rdSt\}}t|ts$t|}t|dS)z Extracts the last Windows error message into a python unicode string :param result: A function result, 0 or None indicates failure :return: A unicode string error message N)r isinstancer r OSError)result_Z error_stringrH/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/_kernel32.pyr s   N) __future__rrrrr_decoder _typesr Z_kernel32_cffir r Z_kernel32_ctypes__all__r rrrrs    _win/__pycache__/_kernel32_cffi.cpython-38.pyc000064400000002254147205106110015113 0ustar00U af @sddlmZmZmZmZddlmZddlmZddl m Z ddl Z ddgZ e Ze jd krhed ed zed ZeeeWn>ek rZz eed dkre dW5dZ[XYnXddZdS))unicode_literalsdivisionabsolute_importprint_function) register_ffi)str_cls)LibraryNotFoundErrorN get_errorkernel32)r Ta typedef long long LARGE_INTEGER; BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount); typedef struct _FILETIME { DWORD dwLowDateTime; DWORD dwHighDateTime; } FILETIME; void GetSystemTimeAsFileTime(FILETIME *lpSystemTimeAsFileTime); z kernel32.dllzcannot load libraryzkernel32.dll could not be foundcCstS)N)ffiZ getwinerrorrrM/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/_kernel32_cffi.pyr +s) __future__rrrrZ_ffir_typesrerrorsr Zcffi__all__ZFFIr__version_info__Z set_unicodeZcdefdlopenr OSErrorefindr rrrrs&       _win/__pycache__/_kernel32_ctypes.cpython-38.pyc000064400000002642147205106110015514 0ustar00U af @s<ddlmZmZmZmZddlZddlmZmZmZm Z m Z ddl m Z ddl mZddlmZdd gZz ejZWn>ek rZz eed d kred W5dZ[XYnXe ZzBeegej_ejej_Gd dde Zeegej_dej_Wnek re dYnXeedeeededdZdS))unicode_literalsdivisionabsolute_importprint_functionN)windllwintypesPOINTER c_longlong Structure)FFIEngineError)str_cls)LibraryNotFoundError get_errorkernel32z'The specified module could not be foundzkernel32.dll could not be foundc@s eZdZdejfdejfgZdS)FILETIMEZ dwLowDateTimeZdwHighDateTimeN)__name__ __module__ __qualname__rZDWORD_fields_rrO/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/_kernel32_ctypes.pyrsrzError initializing ctypes LARGE_INTEGERcCst}|t|fS)N)ctypesZ GetLastError FormatError)errorrrrr0s) __future__rrrrrrrrr r Z_ffir _typesr errorsr__all__rOSErrorefindrZQueryPerformanceCounterargtypesZBOOLrestyperZGetSystemTimeAsFileTimeAttributeErrorsetattrrrrrrs4        _win/__pycache__/_secur32.cpython-38.pyc000064400000007333147205106110013770 0ustar00U af@sddlmZmZmZmZddlmZddlmZddl m Z ddl m Z edkrddd l mZmZndd lmZmZd d d gZddd ZGdd d Zd S))unicode_literalsdivisionabsolute_importprint_function)ffi) _try_decode)TLSError)str_clsZcffi)secur32 get_error handle_errorr Secur32ConstNcCs~|dkr dS|tjkrtd|tjkr0td|tjkrBtdt\}}t|ts^t|}|dkrjt }|d||dS)a5 Extracts the last Windows error message into a python unicode string :param result: A function result, 0 or None indicates failure :param exception_class: The exception class to use for the exception if an error occurred :return: A unicode string error message rNz"A packet was received out of orderzA packet was received alteredzThe TLS session expiredzSECURITY_STATUS error 0x%0.2X: ) rSEC_E_OUT_OF_SEQUENCEr SEC_E_MESSAGE_ALTEREDSEC_E_CONTEXT_EXPIREDr isinstancer r OSError)resultZexception_class_Z error_stringrG/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/_secur32.pyrs     c@s,eZdZdZdZdZdZdZdZdZ dZ dZ d Z d Z d Zd Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ*dZ+d Z,dZ-d!Z.dZ/dZ0d"Z1d#Z2d$Z3d%Z4dZ5dZ6dZ7d&Z8d'Z9d(Z:d)Z;d*Zd-Z?d.Z@d/ZAd0ZBd1ZCd2ZDd3ZEd4ZFd5ZGd6ZHd7ZId8ZJd9S):rrz,Microsoft Unified Security Protocol Provider i@ri i i! lli1lll]l"l%l(l&ll!i  iirZSiiifififihififiii i iiiiiii$i"i"N)K__name__ __module__ __qualname__ZSCHANNEL_CRED_VERSIONZSECPKG_CRED_OUTBOUNDZ UNISP_NAMEZSCH_CRED_MANUAL_CRED_VALIDATIONZSCH_CRED_AUTO_CRED_VALIDATIONZSCH_USE_STRONG_CRYPTOZSCH_CRED_NO_DEFAULT_CREDSZSECBUFFER_VERSIONZSEC_E_OKZSEC_I_CONTINUE_NEEDEDZSEC_I_CONTEXT_EXPIREDZSEC_I_RENEGOTIATEZSEC_E_INCOMPLETE_MESSAGEZSEC_E_INVALID_TOKENrrrZSEC_E_INVALID_PARAMETERZSEC_E_WRONG_PRINCIPALZSEC_E_UNTRUSTED_ROOTZSEC_E_CERT_EXPIREDZSEC_E_ILLEGAL_MESSAGEZSEC_E_INTERNAL_ERRORZSEC_E_BUFFER_TOO_SMALLZSEC_I_INCOMPLETE_CREDENTIALSZISC_REQ_REPLAY_DETECTZISC_REQ_SEQUENCE_DETECTZISC_REQ_CONFIDENTIALITYZISC_REQ_ALLOCATE_MEMORYZISC_REQ_INTEGRITYZISC_REQ_STREAMZISC_REQ_USE_SUPPLIED_CREDSZISC_RET_REPLAY_DETECTZISC_RET_SEQUENCE_DETECTZISC_RET_CONFIDENTIALITYZISC_RET_ALLOCATED_MEMORYZISC_RET_INTEGRITYZISC_RET_STREAMZSECBUFFER_ALERTZSECBUFFER_STREAM_HEADERZSECBUFFER_STREAM_TRAILERZSECBUFFER_EXTRAZSECBUFFER_TOKENZSECBUFFER_DATAZSECBUFFER_EMPTYZSECPKG_ATTR_STREAM_SIZESZSECPKG_ATTR_CONNECTION_INFOZSECPKG_ATTR_REMOTE_CERT_CONTEXTZSP_PROT_TLS1_2_CLIENTZSP_PROT_TLS1_1_CLIENTZSP_PROT_TLS1_CLIENTZSP_PROT_SSL3_CLIENTZSP_PROT_SSL2_CLIENTZ CALG_AES_256Z CALG_AES_128Z CALG_3DESZCALG_RC4ZCALG_RC2ZCALG_DESZCALG_MD5Z CALG_SHA1Z CALG_SHA256Z CALG_SHA384Z CALG_SHA512Z CALG_DH_SFZ CALG_DH_EPHEMZ CALG_ECDHZ CALG_ECDHEZ CALG_RSA_KEYXZ CALG_RSA_SIGNZ CALG_ECDSAZ CALG_DSS_SIGNrrrrr;s)N) __future__rrrrr_decoder errorsr _typesr Z _secur32_cffir r Z_secur32_ctypes__all__rrrrrrs      %_win/__pycache__/_secur32_cffi.cpython-38.pyc000064400000010207147205106110014751 0ustar00U af @sddlmZmZmZmZddlZddlmZddlm Z ddl m Z ddl Z ddgZ e Ze jd krped ejd kred n ed edzedZeeeWn>ek rZz e eddkre dW5dZ[XYnXddZdS))unicode_literalsdivisionabsolute_importprint_functionN) register_ffi)str_cls)LibraryNotFoundError get_errorsecur32)r Tlztypedef uint64_t ULONG_PTR;z typedef unsigned long ULONG_PTR;ar typedef HANDLE HCERTSTORE; typedef unsigned int ALG_ID; typedef WCHAR SEC_WCHAR; typedef unsigned long SECURITY_STATUS; typedef void *LUID; typedef void *SEC_GET_KEY_FN; typedef struct _SecHandle { ULONG_PTR dwLower; ULONG_PTR dwUpper; } SecHandle; typedef SecHandle CredHandle; typedef SecHandle CtxtHandle; typedef struct _SCHANNEL_CRED { DWORD dwVersion; DWORD cCreds; void *paCred; HCERTSTORE hRootStore; DWORD cMappers; void **aphMappers; DWORD cSupportedAlgs; ALG_ID *palgSupportedAlgs; DWORD grbitEnabledProtocols; DWORD dwMinimumCipherStrength; DWORD dwMaximumCipherStrength; DWORD dwSessionLifespan; DWORD dwFlags; DWORD dwCredFormat; } SCHANNEL_CRED; typedef struct _TimeStamp { DWORD dwLowDateTime; DWORD dwHighDateTime; } TimeStamp; typedef struct _SecBuffer { ULONG cbBuffer; ULONG BufferType; BYTE *pvBuffer; } SecBuffer; typedef struct _SecBufferDesc { ULONG ulVersion; ULONG cBuffers; SecBuffer *pBuffers; } SecBufferDesc; typedef struct _SecPkgContext_StreamSizes { ULONG cbHeader; ULONG cbTrailer; ULONG cbMaximumMessage; ULONG cBuffers; ULONG cbBlockSize; } SecPkgContext_StreamSizes; typedef struct _CERT_CONTEXT { DWORD dwCertEncodingType; BYTE *pbCertEncoded; DWORD cbCertEncoded; void *pCertInfo; HCERTSTORE hCertStore; } CERT_CONTEXT; typedef struct _SecPkgContext_ConnectionInfo { DWORD dwProtocol; ALG_ID aiCipher; DWORD dwCipherStrength; ALG_ID aiHash; DWORD dwHashStrength; ALG_ID aiExch; DWORD dwExchStrength; } SecPkgContext_ConnectionInfo; SECURITY_STATUS AcquireCredentialsHandleW(SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse, LUID *pvLogonID, void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument, CredHandle *phCredential, TimeStamp *ptsExpiry); SECURITY_STATUS FreeCredentialsHandle(CredHandle *phCredential); SECURITY_STATUS InitializeSecurityContextW(CredHandle *phCredential, CtxtHandle *phContext, SEC_WCHAR *pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, SecBufferDesc *pInput, ULONG Reserved2, CtxtHandle *phNewContext, SecBufferDesc *pOutput, ULONG *pfContextAttr, TimeStamp *ptsExpiry); SECURITY_STATUS FreeContextBuffer(void *pvContextBuffer); SECURITY_STATUS ApplyControlToken(CtxtHandle *phContext, SecBufferDesc *pInput); SECURITY_STATUS DeleteSecurityContext(CtxtHandle *phContext); SECURITY_STATUS QueryContextAttributesW(CtxtHandle *phContext, ULONG ulAttribute, void *pBuffer); SECURITY_STATUS EncryptMessage(CtxtHandle *phContext, ULONG fQOP, SecBufferDesc *pMessage, ULONG MessageSeqNo); SECURITY_STATUS DecryptMessage(CtxtHandle *phContext, SecBufferDesc *pMessage, ULONG MessageSeqNo, ULONG *pfQOP); z secur32.dllzcannot load libraryzsecur32.dll could not be foundcCstS)N)ffiZ getwinerrorrrL/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/_secur32_cffi.pyr s) __future__rrrrsysZ_ffir_typesrerrorsr Zcffi__all__ZFFIr__version_info__Z set_unicodemaxsizeZcdefdlopenr OSErrorefindr rrrrs.         \ _win/__pycache__/_secur32_ctypes.cpython-38.pyc000064400000007766147205106110015371 0ustar00U af @sLddlmZmZmZmZddlZddlZddlmZmZm Z m Z m Z m Z ddl mZmZddlmZddlmZddlmZd d gZz ejZWn>ek rZz eed d kred W5dZ[XYnXejZe ZejdkrejZ nej!Z e Z"e Z#ej!Z$ej%Z&zGddde Z'e'Z(e'Z)Gddde Z*Gddde Z+Gddde Z,e e,Z-Gddde Z.Gddde Z/Gddde Z0e e&e e&ee e#e e"e e e(e e+g ej1_2e$ej1_3e e(gej4_2e$ej4_3e e(e e)e e&eeee e.ee e)e e.e ee e+g ej5_2e$ej5_3e gej6_2e$ej6_3e e)e e.gej7_2e$ej7_3e e)gej8_2e$ej8_3e e)ee gej9_2e$ej9_3e e)ee e.egej:_2e$ej:_3e e)e e.ee egej;_2e$ej;_3WnedS)")unicode_literalsdivisionabsolute_importprint_functionN)windllwintypesPOINTERc_void_pc_uint Structure)DWORDULONG)FFIEngineError)str_cls)LibraryNotFoundError get_errorsecur32z'The specified module could not be foundzsecur32.dll could not be foundlc@seZdZdefdefgZdS) SecHandleZdwLowerZdwUpperN)__name__ __module__ __qualname__ ULONG_PTR_fields_rrN/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/_secur32_ctypes.pyr(src@sleZdZdefdefdefdefdefdeefdefdeefd efd efd efd efd efdefgZdS) SCHANNEL_CREDZ dwVersionZcCredsZpaCredZ hRootStoreZcMappersZ aphMappersZcSupportedAlgsZpalgSupportedAlgsZgrbitEnabledProtocolsZdwMinimumCipherStrengthZdwMaximumCipherStrengthZdwSessionLifespanZdwFlagsZ dwCredFormatN) rrrr r HCERTSTORErALG_IDrrrrrr1s  rc@seZdZdefdefgZdS) TimeStampZ dwLowDateTimeZdwHighDateTimeN)rrrr rrrrrr Csr c@s(eZdZdefdefdeejfgZdS) SecBufferZcbBufferZ BufferTypeZpvBufferN)rrrr rctypesc_byterrrrrr!Is r!c@s"eZdZdefdefdefgZdS) SecBufferDescZ ulVersioncBuffersZpBuffersN)rrrr PSecBufferrrrrrr$Rsr$c@s.eZdZdefdefdefdefdefgZdS)SecPkgContext_StreamSizesZcbHeaderZ cbTrailerZcbMaximumMessager%Z cbBlockSizeN)rrrr rrrrrr'Ys r'c@s:eZdZdefdefdefdefdefdefdefgZdS) SecPkgContext_ConnectionInfoZ dwProtocolZaiCipherZdwCipherStrengthZaiHashZdwHashStrengthZaiExchZdwExchStrengthN)rrrr rrrrrrr(bsr(zError initializing ctypesr CredHandle CtxtHandlecCst}|t|fS)N)r"Z GetLastError FormatError)errorrrrrs)? __future__rrrrsysr"rrrr r r Zctypes.wintypesr r Z_ffir_typesrerrorsr__all__rOSErrorefindZHANDLErrmaxsizec_uint64rc_ulongZSEC_GET_KEY_FNZLUIDZSECURITY_STATUSZWCHARZ SEC_WCHARrr)r*rr r!r&r$r'r(ZAcquireCredentialsHandleWargtypesrestypeZFreeCredentialsHandleZInitializeSecurityContextWZFreeContextBufferZApplyControlTokenZDeleteSecurityContextZQueryContextAttributesWZEncryptMessageZDecryptMessageAttributeErrorsetattrrrrrrs                  _win/__pycache__/asymmetric.cpython-38.pyc000064400000264510147205106110014522 0ustar00U af@s#ddlmZmZmZmZddlZddlZddlZddlZddl m Z m Z m Z mZmZmZmZmZmZmZmZmZmZmZmZddlmZmZmZmZmZm Z m!Z!m"Z"m#Z#ddl$m%Z%ddl&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6ddl7m8Z8dd l9m:Z:dd l;mZ>dd l?m@Z@mAZAmBZBmCZCdd lDmEZEmFZFmGZGmHZHmIZImJZJdd lKmLZLeMZNeNdeNdfZOe8ZPePdkrddlQmRZRmSZSmTZTmUZUmVZVddlWmXZYmZZ[m\Z\m]Z^m_Z`nddlambZbmcZcmTZTmdZdmeZedddddddddddddd d!d"d#d$d%d&d'gZfdd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;dd?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd d d d d ddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddÐdĐdŐdƐdǐdȐdɐdʐdːd̐d͐dΐdϐdАdѐdҐdӐdԐdՐd֐dאdؐdِdڐdېdܐdݐdސdߐdddddddddddddddddddddddddddddddddddddddddd d d d d ddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddÐdĐdŐdƐdǐdȐdɐdʐdːd̐d͐dΐdϐdАdѐdҐdӐdԐdՐd֐dאdؐdِdڐdېdܐdݐdސdߐdddddddddddddddddddddddddddddddddddddddddd d d d d ddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddÐdĐdŐdƐdǐdȐdɐdʐdːd̐d͐dΐdϐdАdѐdҐdӐdԐdՐd֐dאdؐdِdڐdېdܐdݐdސdߐdddddddddddddddddddddddddddddddddddddddddd d d d d ddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddÐdĐdŐdƐdǐdȐdɐdʐdːd̐d͐dΐdϐdАdѐdҐdӐdԐdՐd֐dאdؐdِdڐdېdܐdݐdސdߐdddddddddddddddddddddddddddddddddddddddddd d d d d ddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddÐdĐdŐdƐdǐdȐdɐdʐdːd̐d͐dΐdϐdАdѐdҐdӐdԐdՐd֐dאdؐdِdڐdېdܐdݐdސdߐdddddddddddddddddddddddddddddddddddddddddd d d d d ddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddÐdĐdŐdƐdǐdȐdɐdʐdːd̐d͐dΐdϐdАdѐdҐdӐdԐdՐd֐dאdؐdِdڐdېdܐdݐdސdߐdddddddddddddddddddddddddddddddddddddddddd d d d d ddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddÐdĐdŐdƐdǐdȐdɐdʐdːd̐d͐dΐdϐdАdѐdҐdӐdԐdՐd֐dאdؐdِdڐdېdܐdݐdސdߐdddddddddddddddddddddddddddddddddddddddddd d d d d ddddddddddddddddddd d!d"d#d$d%d&gZgGd'd(d(ZhGd)ddeheZiGd*ddeheZjGd+ddeheZ dvd,dZkd-d.Zldwd/d0Zmd1d2Zndxd3d4Zod5d6Zpd7d8Zqd9d:Zrd;d<Zsd=d>Ztd?d@ZudAdBZvdCdZwdDdEZxdFdGZydydIdJZzdKdLZ{dzdMdZ|dNdZ}d{dOdZ~d|dPdZdQd%ZdRd'ZdSdZdTdZ_d}dVdWZd~dXdYZddZd[Zd\d$Zd]d&Zd^dZd_dZ]dd`daZddbdcZddddeZddfdgZddhdiZddjdkZddldmZddndoZddpdqZdrd#Zdsd"Zdtd!Zdud ZdS()unicode_literalsdivisionabsolute_importprint_functionN) Certificate DHParameters DSAParams DSASignatureECDomainParameters ECPrivateKeyIntegerint_from_bytes int_to_bytesPrivateKeyAlgorithmPrivateKeyInfoPublicKeyAlgorithm PublicKeyInfo RSAPrivateKey RSAPublicKey) _CertificateBase _fingerprint _parse_pkcs12_PrivateKeyBase_PublicKeyBase_unwrap_private_key_infoparse_certificate parse_private parse_public)pretty_message)buffer_from_bytesbuffer_from_unicode byte_arraybytes_from_buffercastderefnativenewnull pointer_setsizeofstruct struct_bytesstruct_from_bufferunwrapwrite_to_buffer)backend) fill_width)AsymmetricKeyErrorIncompleteAsymmetricKeyErrorSignatureError) type_namestr_clsbyte_cls int_types)add_pkcs1v15_signature_paddingadd_pss_paddingraw_rsa_private_cryptraw_rsa_public_crypt!remove_pkcs1v15_signature_paddingverify_pss_padding)constant_compare winlegacy)advapi32 Advapi32Const handle_erroropen_context_handleclose_context_handle)ec_generate_pairec_compute_public_key_pointec_public_key_info ecdsa_sign ecdsa_verify)bcrypt BcryptConstrDopen_alg_handleclose_alg_handlerdsa_sign dsa_verifyrJrK 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_verify %)+/5;=CGIOSYaegkmqiii iiiii%i3i7i9i=iKiQi[i]iaigioiui{iiiiiiiiiiiiiiiiiiiiii i ii#i-i3i9i;iAiKiQiWiYi_ieiiikiwiiiiiiiiiiiiiiiiiiiiiiiii)i+i5i7i;i=iGiUiYi[i_imiqisiwiiiiiiiiiiiiiiiiiiii iiii%i'i-i?iCiEiIiOiUi]iciiiiiiiiiiiiiiiiiiiiii i iiiii'i)i/iQiWi]ieiwiiiiiiiiiiiiiiiiiiiiii iiii#i+i/i=iAiGiIiMiSiUi[ieiyiiiiiiiiiiiiiiiiiii iii'i7iEiKiOiQiUiWiaimisiyiiiiiiiiiiiiiiiiiiii!i#i'i)i3i?iAiQiSiYi]i_iiiqiiiiiiiiiiiiiiiii i i i# i% i+ i/ i5 iC iI iM iO iU iY i_ ik iq iw i i i i i i i i i i i i i i i i i i! i1 i9 i= iI iW ia ic ig io iu i{ i i i i i i i i i i i i i i i i i i i i i i i i i# i) i- i? iG iQ iW i] ie io i{ i i i i i i i i i i i i i i i i i i i% i/ i1 iA i[ i_ ia im is iw i i i i i i i i i i i i i i i i i i i i i i! i+ i- i= i? iO iU ii iy i i i i i i i i i i i i i i i i i i i i i iii!i'i/i5i;iKiWiYi]ikiqiui}iiiiiiiiiiiiiiii i ii%i)i1iCiGiMiOiSiYi[igikiiiiiiiiiiiiiiiiiiii!i%i+i9i=i?iQiiisiyi{iiiiiiiiiiiiiiiiii ii'i-i9iEiGiYi_iciiioiiiiiiiiiiiiiiiii iii#i)i+i1i7iAiGiSi_iqisiyi}iiiiiiiiiiiiii ii'i-i7iCiEiIiOiWi]igiiimi{iiiiiiiiiiiiiiiiiiii!i/i3i;iEiMiYikioiqiuiiiiiiiiiiiii iiii%i)i+i7i=iAiCiIi_ieigiki}iiiiiiiiiiiiiii iiiiii%i3i9i=iEiOiUiiimioiuiiiiiiiiiiiiiiiiiii ii#i'i3iAi]iciwi{iiiiiiiiiiiiiiiiiiii5i7i;iCiIiMiUigiqiwi}iiiiiiiiiiiiiiiiiiiiii1i3iEiIiQi[iyiiiiiiiiiiiiiiiiiii!i#i-i/i5i?iMiQiiiki{i}iiiiiiiiiiiiiiiiii#i%i/i1i7i;iAiGiOiUiYieikisiiiiiiiiiiiii iii'i+i-i3i=iEiKiOiUisiiiiiiiiiiiii ii!i#i5i9i?iAiKiSi]iciiiqiui{i}iiiiiiiiiiiiiiiiii iii%i+i/i=iIiMiOimiqiiiiiiiiiiiiiiiii iii9iIiKiQigiui{iiiiiiiiiiiiiiii i i i' i) i- i3 iG iM iQ i_ ic ie ii iw i} i i i i i i i i i i i i i i !i!i5!iA!iI!iO!iY!i[!i_!is!i}!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i"i "i"i"i!"i%"i+"i1"i9"iK"iO"ic"ig"is"iu"i"i"i"i"i"i"i"i"i"i"i"i"i"i"i#i #i #i'#i)#i/#i3#i5#iE#iQ#iS#iY#ic#ik#i#i#i#i#i#i#i#i#i#i#i#i#i#i#i#i$i $i$i$i)$i=$iA$iC$iM$i_$ig$ik$iy$i}$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i%i%i%i%i'%i1%i=%iC%iK%iO%is%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i&i &i&i&i'&i)&i5&i;&i?&iK&iS&iY&ie&ii&io&i{&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i'i'i5'i7'iM'iS'iU'i_'ik'im'is'iw'i'i'i'i'i'i'i'i'i'i'i'i'i'i(i(i (i(i(i(i!(i1(i=(i?(iI(iQ(i[(i](ia(ig(iu(i(i(i(i(i(i(i(i(i(i(i(i(i)i)i)i!)i#)i?)iG)i])ie)ii)io)iu)i)i)i)i)i)i)i)i)i)i)i)i)i)i)i)i*i*i*i%*i/*iO*iU*i_*ie*ik*im*is*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i+i'+i1+i3+i=+i?+iK+iO+iU+ii+im+io+i{+i+i+i+i+i+i+i+i+i+i+i+i+i+i ,i,i,i#,i/,i5,i9,iA,iW,iY,ii,iw,i,i,i,i,i,i,i,i,i,i,i,i,i,i,i,i-i-i-i;-iC-iI-iM-ia-ie-iq-i-i-i-i-i-i-i-i-i-i-i.i.i.i .i.i.i%.i-.i3.i7.i9.i?.iW.i[.io.iy.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i/i /i /i/i'/i)/iA/iE/iK/iM/iQ/iW/io/iu/i}/i/i/i/i/i/i/i/i/i/i/i/i/i/i/i0i 0i#0i)0i70i;0iU0iY0i[0ig0iq0iy0i}0i0i0i0i0i0i0i0i0i0i0i0i0i0i0i0i0i1i 1i1i!1i'1i-1i91iC1iE1iK1i]1ia1ig1im1is1i1i1i1i1i1i1i1i1i1i1i1i1i1i 2i2i2i2i)2i52iY2i]2ic2ik2io2iu2iw2i{2i2i2i2i2i2i2i2i2i2i2i2i2i2i2i2i3i%3i+3i/3i53iA3iG3i[3i_3ig3ik3is3iy3i3i3i3i3i3i3i3i3i3i3i3i3i4i4i4i4i4i74iE4iU4iW4ic4ii4im4i4i4i4i4i4i4i4i4i4i4i4i4i4i 5i5i5i-5i35i;5iA5iQ5ie5io5iq5iw5i{5i}5i5i5i5i5i5i5i5i5i5i5i5i5i5i5i6i6i6i#6i16i56i76i;6iM6iO6iS6iY6ia6ik6im6i6i6i6i6i6i6i6i6i6i6i6i7i7i7i7i?7iE7iI7iO7i]7ia7iu7i7i7i7i7i7i7i7i7i7i7i7i8i 8i!8i38i58iA8iG8iK8iS8iW8i_8ie8io8iq8i}8i8i8i8i8i8i8i8i8i8i8i8i8i8i9i9i#9i%9i)9i/9i=9iA9iM9i[9ik9iy9i}9i9i9i9i9i9i9i9i9i9i9i9i9i9i9i9i9i9i:i:i:i:i':i+:i1:iK:iQ:i[:ic:ig:im:iy:i:i:i:i:i:i:i:i:i:i:i:i;i;i;i!;i#;i-;i9;iE;iS;iY;i_;iq;i{;i;i;i;i;i;i;i;i;i;i;i;i;i;i;i;i;i;i<i <i<i<i<i)<i5<iC<iO<iS<i[<ie<ik<iq<i<i<i<i<i<i<i<i<i<i<i<i<i=i =i=i=i=i!=i-=i3=i7=i?=iC=io=is=iu=iy=i{=i=i=i=i=i=i=i=i=i=i=i=i=i>i >i>i>i>i#>i)>i/>i3>iA>iW>ic>ie>iw>i>i>i>i>i>i>i>i>i>i>i>i>i>i>i>i ?i ?i7?i;?i=?iA?iY?i_?ie?ig?iy?i}?i?i?i?i?i?i?i?i?i?i?i?i@i!@i%@i+@i1@i?@iC@iE@i]@ia@ig@im@i@i@i@i@i@i@i@i@i@i@i@i@i Ai AiAiAi!Ai3Ai5Ai;Ai?AiYAieAikAiwAi{AiAiAiAiAiAiAiAiAiAiAiBiBiBiBi#Bi)Bi/BiCBiSBiUBi[BiaBisBi}BiBiBiBiBiBiBiBiBiBiBiBiBiBiCiCiCi%Ci'Ci3Ci7Ci9CiOCiWCiiCiCiCiCiCiCiCiCiCiCiCiCiCiCiCiCiCi Di DiDi#Di)Di;Di?DiEDiKDiQDiSDiYDieDioDiDiDiDiDiDiDiDiDiDiDiDiDiDiEiEiEi+Ei1EiAEiIEiSEiUEiaEiwEi}EiEiEiEiEiEiEiEc@s,eZdZdZdZdZdZddZddZdS)_WinKeyNcCs&||_||_tdkrt|_nt|_dS)z :param key_handle: A CNG BCRYPT_KEY_HANDLE value (Vista and newer) or an HCRYPTKEY (XP and 2003) from loading/importing the key :param asn1: An asn1crypto object for the concrete type rAN) key_handleasn1_backendrB_librLselfrrrI/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/asymmetric.py__init__s z_WinKey.__init__cCsb|jr:tdkr|j|j}n|j|j}t|d|_|jrXtdkrXt|jd|_d|_dS)NrA)rrrCryptDestroyKeyBCryptDestroyKeyrDcontext_handlerF)rresrrr__del__s z_WinKey.__del__) __name__ __module__ __qualname__rr ex_key_handlerrrrrrrrvs rc@s4eZdZdZdZddZeddZeddZdS) rXzM Container for the OS crypto library representation of a private key NcCst|||dS)z :param key_handle: A CNG BCRYPT_KEY_HANDLE value (Vista and newer) or an HCRYPTKEY (XP and 2003) from loading/importing the key :param asn1: An asn1crypto.keys.PrivateKeyInfo object Nrrrrrrrs zPrivateKey.__init__cCstdkr|jdkr2t|j}tdt||j|_q|jdkr|jdd}tt d|dt t |dj |jd j j |d j d }t||_q|jd j }tt d d it|d|ddd }t||_n t|j|j|j\}}t||_|jS)z\ :return: A PublicKey object corresponding to this private key. rAecNdsaprivate_key_algorithm parameters algorithmrg private_keypr public_keyrrsamoduluspublic_exponentrr)rr(_pure_python_ec_compute_public_key_pointrrYrIcurve _public_keyrrr powr&parsedrVr_bcrypt_key_handle_to_asn1bit_sizer)rZ pub_pointparamsZpub_asn1r_rrrrsB        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)rrrUrrrr fingerprints zPrivateKey.fingerprint) rrr__doc__rrpropertyrrrrrrrXs  0c@seZdZdZddZdS)rYzL Container for the OS crypto library representation of a public key cCst|||dS)z :param key_handle: A CNG BCRYPT_KEY_HANDLE value (Vista and newer) or an HCRYPTKEY (XP and 2003) from loading/importing the key :param asn1: An asn1crypto.keys.PublicKeyInfo object Nrrrrrrs zPublicKey.__init__N)rrrrrrrrrrYsc@s8eZdZdZdZdZddZeddZeddZ dS) rzM Container for the OS crypto library representation of a certificate NcCst|||dS)z :param key_handle: A CNG BCRYPT_KEY_HANDLE value (Vista and newer) or an HCRYPTKEY (XP and 2003) from loading/importing the certificate :param asn1: An asn1crypto.x509.Certificate object Nrrrrrrs zCertificate.__init__cCs$|jdkrt|jdd|_|jS)zh :return: The PublicKey object for the public key this certificate contains Ntbs_certificatesubject_public_key_info)rrVrrrrrrs zCertificate.public_keycCs|jdkrd|_|jjtddgkr|jdj}|jdj}|dkrJt}n8|dkrXt}n*|dkrft}n|d krtt }nt t d |z*|||jd j |jd  |d |_Wntk rYnX|jS)zT :return: A boolean - if the certificate is self-signed NFyesmaybeZsignature_algorithmZrsassa_pkcs1v15 rsassa_pssrZecdsaz Unable to verify the signature of the certificate since it uses the unsupported algorithm %s Zsignature_valuerT) _self_signedr self_signedsetsignature_algo hash_algor_rarQrKOSErrorrr&dumpr4)rrrZ verify_funcrrrr*s8      zCertificate.self_signed) rrrrrrrrrrrrrrr s  cCs(|tdddgkr$ttdt||dkrT|tddddgkrttd t|n|dkrtd ksltd kr|dkrttd t|q|tdddgkrttd t|n,|dkr|tdddgkrttdt|td kr|dkrt|\}}td|td|fSt ||St |||SdS)aB 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 on Windows 8 or newer. :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(). rrrzM algorithm must be one of "rsa", "dsa", "ec", not %s i zX bit_size must be one of 1024, 2048, 3072, 4096, not %s rrAzG bit_size must be 1024, not %s zZ bit_size must be one of 1024, 2048, 3072, not %s secp256r1 secp384r1 secp521r1zd curve must be one of "secp256r1", "secp384r1", "secp521r1", not %s N) r ValueErrorrrepr_win_version_infor_pure_python_ec_generate_pairrYrX_advapi32_generate_pair_bcrypt_generate_pair)rrrZpub_infoZ priv_inforrrrRWsF    cCs>|dkrd}nd}ttd}t|ttjdt|}t|t|}t|}t|ttjd||}t|t t||}t |} t t| } t ||| d} |dkrt || | \} } n~ttd}t|ttjdt|}t|t|}t|}t|ttjd||}t|t ||| d}t||| \} } | | fS)ao Accepts an key handle and exports it to ASN.1 :param algorithm: The key algorithm - "rsa" or "dsa" :param bit_size: An integer - only used when algorithm is "rsa" :param key_handle: The handle to export :return: A 2-element tuple of asn1crypto.keys.PrivateKeyInfo and asn1crypto.keys.PublicKeyInfo r RSABLOBHEADER DSSBLOBHEADERDWORD *rN)r'rBZCryptExportKeyr(rCPRIVATEKEYBLOBrDr%r r-r.r*r# _advapi32_interpret_rsa_key_blob PUBLICKEYBLOB _advapi32_interpret_dsa_key_blob)rrr struct_typeout_lenr buffer_lengthbuffer_blob_struct_pointer blob_struct struct_size private_blob public_info private_infopublic_out_lenpublic_buffer_length public_buffer public_blobrrr_advapi32_key_handle_to_asn1sl    rc Cs|dkrtj}tj}n tj}tj}d}d}zht|dd}t td}|d>tj B}t ||||}t |t |}t|||\} } t| t| fWS|rt||rt|XdS)a Generates a public/private key pair using CryptoAPI :param algorithm: The key algorithm - "rsa" or "dsa" :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. :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(). rNFZ verify_only HCRYPTKEY *)rCMS_ENH_RSA_AES_PROV CALG_RSA_SIGNMS_ENH_DSS_DH_PROV CALG_DSS_SIGNrFrBrrEr'ZCRYPT_EXPORTABLEZ CryptGenKeyrDr.rrVrU) rrprovider algorithm_idrrkey_handle_pointerflagsrrrrrrrs(  rc Cs |dkrd}tj}tj}n8|dkrB|dkr0d}nd}tj}tj}nd}tj}tj}ttd}t |t |t d |d }t |t |}t |} t |t || ||d }t |tt|| } t| } tt| } t| || d } |dkrtd | | }n@|dkr(|dkrtd d | | }ntd d | | }n td | | }ttd}t |t |t d |d }t |t |}t |}t |t ||||d }t |tt||}t|}tt|} t||| d }|dkrtd||}n@|dkr |dkrtdd ||}ntdd ||}n td||}||fS)au Accepts an key handle and exports it to ASN.1 :param algorithm: The key algorithm - "rsa", "dsa" or "ec" :param bit_size: An integer - only used when algorithm is "dsa" :param key_handle: The handle to export :return: A 2-element tuple of asn1crypto.keys.PrivateKeyInfo and asn1crypto.keys.PublicKeyInfo rBCRYPT_RSAKEY_BLOBrrBCRYPT_DSA_KEY_BLOB_V2BCRYPT_DSA_KEY_BLOBBCRYPT_ECCKEY_BLOBULONG *rNprivaterr@public)rMBCRYPT_RSAFULLPRIVATE_BLOBBCRYPT_RSAPUBLIC_BLOBBCRYPT_DSA_PRIVATE_BLOBBCRYPT_DSA_PUBLIC_BLOBBCRYPT_ECCPRIVATE_BLOBBCRYPT_ECCPUBLIC_BLOBr'rLZBCryptExportKeyr(rDr%r r-r.r*r#_bcrypt_interpret_rsa_key_blob_bcrypt_interpret_dsa_key_blob_bcrypt_interpret_ec_key_blob)rrrrZprivate_blob_typeZpublic_blob_typeZprivate_out_lenrZprivate_buffer_lengthZprivate_bufferZprivate_blob_struct_pointerZprivate_blob_structrrrrrrZpublic_blob_struct_pointerZpublic_blob_structrrrrrr3s               rc Cs|dkrtj}n6|dkr tj}n&tjtjtjd|}dddd|}d}zZt|}t td}t |||d }t |t |}t |d }t |t|||\}} W5|rt|Xt|t| fS) aL Generates a public/private key pair using CNG :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 on Windows 8 or newer. :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(). rrrrrirNBCRYPT_KEY_HANDLE *r)rMBCRYPT_RSA_ALGORITHMBCRYPT_DSA_ALGORITHMBCRYPT_ECDSA_P256_ALGORITHMBCRYPT_ECDSA_P384_ALGORITHMBCRYPT_ECDSA_P521_ALGORITHMrLrrNr'ZBCryptGenerateKeyPairrDr.ZBCryptFinalizeKeyPairrrVrU) rrr alg_constantr alg_handlerrrrrrrrs:   rc Cs|t|tsttdt||dkr,td|dkrr?r@rArBr=public_key_inforsa_private_keyprivate_key_inforrrrjs\  rc Csd}|d}|}||}||}|}t|d|ddd} t|||ddd} t|||ddd} t||||ddd} t||||ddd} ttdt| | | ddt| d }tdtdt| | | ddt| d }||fS) a Takes a CryptoAPI DSS private key blob and converts it into the ASN.1 structures for the public and private keys :param bit_size: The integer bit size of the key :param public_blob: A byte string of the binary data after the public key header :param private_blob: A byte string of the binary data after the private key header :return: A 2-element tuple of (asn1crypto.keys.PublicKeyInfo, asn1crypto.keys.PrivateKeyInfo) rrNr9rrr-rrrrC)rrrr r rr)rrrrGrHq_offsetg_offsetZx_offsetZy_offsetrr-rr8yrOrQrrrrsF  rc Cshtt|j}tt|j}|}t|d|}t||||}|dkrhttddit||ddS|dkrRtt|j}tt|j } ||} | |} | | } | | } | | }||}t|| | }t|| | }t|| | }t|| |}t|||}t||||}t d||||||||d }t dt ddi|d St td t|d S) a Take a CNG BCRYPT_RSAFULLPRIVATE_BLOB and converts it into an ASN.1 structure :param key_type: A unicode string of "private" or "public" :param blob_struct: An instance of BCRYPT_RSAKEY_BLOB :param blob: A byte string of the binary data contained after the struct :return: An asn1crypto.keys.PrivateKeyInfo or asn1crypto.keys.PublicKeyInfo object, based on the key_type param rr rrrrrr:r;rCM key_type must be one of "public", "private", not %s N)r&int cbPublicExp cbModulusrrrrcbPrime1cbPrime2rrrrrr)key_typerrFZpublic_exponent_byte_lengthZmodulus_byte_lengthZmodulus_offsetrrZprime1_byte_lengthZprime2_byte_lengthrIrJrKrLrMrNr>r?r@rArBr=rPrrrrsl       rc Cstt|j}|dkrZttt|j}|}||}||}t|d|} t|||} n|dkrtt|j} tt|j} | } | | }||}||}||}t|| |}t|||} t|||} ntdt ||dkr"t|||}t t dt | || ddt |d S|d krjt||||}tdtdt | || ddt |d Sttd t |d S)an Take a CNG BCRYPT_DSA_KEY_BLOB or BCRYPT_DSA_KEY_BLOB_V2 and converts it into an ASN.1 structure :param key_type: A unicode string of "private" or "public" :param version: An integer - 1 or 2, indicating the blob is BCRYPT_DSA_KEY_BLOB or BCRYPT_DSA_KEY_BLOB_V2 :param blob_struct: An instance of BCRYPT_DSA_KEY_BLOB or BCRYPT_DSA_KEY_BLOB_V2 :param blob: A byte string of the binary data contained after the struct :return: An asn1crypto.keys.PrivateKeyInfo or asn1crypto.keys.PublicKeyInfo object, based on the key_type param r@rrzversion must be 1 or 2, not %sr rrSrrrrCrWN)r&rXcbKeyrr7r- cbSeedLength cbGroupSizerrrrr r rrr)r]r<rrFkey_byte_lengthr-rUZ public_offsetZprivate_offsetrrZseed_byte_lengthZgroup_byte_lengthrTp_offsetr rrrrrCsf     rc Cstt|j}tt|j}tjdtjdtjdtjdtj dtj di|}d|d|d}|dkrt t dt d |d d |d S|d krt||d|d}tdtdt d |d d td||ddSttdt|dS)a Take a CNG BCRYPT_ECCKEY_BLOB and converts it into an ASN.1 structure :param key_type: A unicode string of "private" or "public" :param blob_struct: An instance of BCRYPT_ECCKEY_BLOB :param blob: A byte string of the binary data contained after the struct :return: An asn1crypto.keys.PrivateKeyInfo or asn1crypto.keys.PublicKeyInfo object, based on the key_type param rrrrrr rnamed)namevaluerrrrbZ ecPrivkeyVer1)r<rrrCrWN)r&rXdwMagicr^rMBCRYPT_ECDSA_PRIVATE_P256_MAGICBCRYPT_ECDSA_PRIVATE_P384_MAGICBCRYPT_ECDSA_PRIVATE_P521_MAGICBCRYPT_ECDSA_PUBLIC_P256_MAGICBCRYPT_ECDSA_PUBLIC_P384_MAGICBCRYPT_ECDSA_PUBLIC_P521_MAGICrrr rrrr rrr)r]rrFmagicrarr rrrrrsd    rc Csnt|tr|}nTt|tr$t|}n@t|trRt|d}t|}W5QRXnttdt |t |t S)a Loads an x509 certificate into a Certificate object :param source: A byte string of file contents or a unicode string filename :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 r*z source must be a byte string, unicode string or asn1crypto.x509.Certificate object, not %s ) r"Asn1Certificater7rr6openreadr#rr5 _load_keyr)sourceZ certificatefrrrrSs     cCs|}t|tr|dd}|j}d}|dkrj|j\}}|dkrJttd|tddd gkrttd nt|d kr|jdkrttd nT|j d krt dkst dkrttd|j |j n |j dkr|jdkrttdt dkr|dkr|d|St |||St||||S)a Loads a certificate, public key or private key into a Certificate, PublicKey or PrivateKey object :param key_object: An asn1crypto.x509.Certificate, asn1crypto.keys.PublicKeyInfo or asn1crypto.keys.PrivateKeyInfo object :param container: The class of the object to hold the key_handle :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 key is incompatible with the OS crypto library OSError - when an error is returned by the OS crypto library :return: A PrivateKey, PublicKey or Certificate object, based on container rrNrrdzR Windows only supports EC keys using named curves rrrz Windows only supports EC keys using the named curves secp256r1, secp384r1 and secp521r1 rz The DSA key does not contain the necessary p, q and g parameters and can not be used rrrAz Windows XP, 2003, Vista, 7 and Server 2008 only support DSA keys based on SHA1 (1024 bits or less) - this key is based on %s and is %s bits rsha1a Windows only supports 2048 bit DSA keys based on SHA2 - this key is 2048 bits and based on SHA1, a non-standard combination that is usually generated by old versions of OpenSSL )r"rorrr2rrrr3rrrupper_advapi32_load_key_bcrypt_load_key) key_object containerkey_infoalgo curve_nameZ curve_typerrrrr sF        rrcCsLt|trdnd}|j}|dkr$d}|dks4|dkrr?r@rArBr=Z DSSPUBKEYrrrrRrr-rZDSSSEEDl)rCrrrZ CALG_RSA_KEYXrr+rBr.ZbTypeZCUR_BLOB_VERSIONZbVersionreservedZaiKeyAlgZpublickeystrucrZbitlenrZRSA1rnr&rErZRSA2rDZDSS1ZDSS2Z dsspubkeycounterr,)r{r]r|r~ blob_typerrZblob_header_pointerZ blob_headerrrrrGrHZpubkey_pointerZpubkeyZparsed_key_infoZ blob_datarZkey_dataZdssseed_pointerZdssseedrrrrs|       "  """"""   "     rc+ Csfd}d}t|trdnd}|j}|dkr,d}z"|dkrB|jdn|}tjtjtjtj tj d|} t | }|dkr|dkrtj } tj } |d j} d } d }nztj} tj} |d j} t| d j}t| d j}t| dj}t| dj}t| dj}t| dj}t|} t|}t| dj}t| dj}ttd}t|}| |_|j|_t||_t||_| |_||_t|||}|dkr |||7}|t|| 7}|t||7}|t|| 7}|t|t|7}n2|dkr|dkrtj } |d jj}|dd}n0tj!} t"|d j}t|d jj}|dd}t|}t|dj}t|dj}t|dj} |jdkrt| }!nd}!t#t|t|t|}"t||"}t||"}t||"}t| |!} d}#d|!}$|jdkrx|dkrtj$} ntj%} ttd }t|}| |_&|"|_'tj(|_)tj*|_+|!|_,|!|_-t.|#|_/t|}||$| |||7}|dkr|t||!7}n|dkrtj0} ntj1} ttd!}t|}| |_&|"|_'t.|#|_/t.|$|_2t.| |_3t||||}|dkr |t||!7}n|dkr |dkr(tj4} |d 5\}%}&nDtj6} |d jd }|rP|5\}%}&nd }%d }&t|d jd j}ttd"}t|}tj7tj8tj9tj:tj;tj|t?| |)|t|tj@}*tA|*t|)}|||WS|r`t|XdS))a Loads a certificate, public key or private key into a Certificate, PublicKey or PrivateKey object via CNG :param key_object: An asn1crypto.x509.Certificate, asn1crypto.keys.PublicKeyInfo or asn1crypto.keys.PrivateKeyInfo object :param key_info: An asn1crypto.keys.PublicKeyInfo or asn1crypto.keys.PrivateKeyInfo object :param container: The class of the object to hold the key_handle :param curve_name: None or a unicode string of the curve name for an EC key :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 key is incompatible with the OS crypto library OSError - when an error is returned by the OS crypto library :return: A PrivateKey, PublicKey or Certificate object, based on container Nr rrrrr@)rrrrrrrrr>r?r@rArBr=rrrrrrrrrr-rrRsrrr))r r)r r)r r)rr)rr)rr 0Brr)Br"rrrOrrMrrrrrrNr ZBCRYPT_RSAPUBLIC_MAGICrr ZBCRYPT_RSAFULLPRIVATE_MAGICrr&rr+rLr.ZMagicrZ BitLengthrYrZr[r\r,r1r r rmaxZBCRYPT_DSA_PUBLIC_MAGIC_V2ZBCRYPT_DSA_PRIVATE_MAGIC_V2rgr^ZDSA_HASH_ALGORITHM_SHA256Z hashAlgorithmZ DSA_FIPS186_3ZstandardVersionr_r`r"ZCountZBCRYPT_DSA_PUBLIC_MAGICZBCRYPT_DSA_PRIVATE_MAGICZSeedr-rZ to_coordsrrkrlrmrhrirjr'ZBCryptImportKeyPairr(ZBCRYPT_NO_KEY_VALIDATIONrD)+ryr{rzr}rrr]r|Z alg_selectorrrrnZ parsed_keyZ prime1_sizeZ prime2_sizer>r?r@rArBr=rrrrrFrrZ private_bytesZ public_bytesrrr-Zq_lenZ key_widthcountseedr8rVZx_bytesZy_bytesrrrrrrxs:                                      rxc Cst|tr|}n|dk rHt|tr,|d}t|tsHttdt|t|trrt|d}| }W5QRXnt|tsttdt|t ||}t |t S)a 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 Nutf-8zP password must be a byte string, not %s r*z source must be a byte string, unicode string or asn1crypto.keys.PrivateKeyInfo object, not %s ) r"rr6encoder7r#rr5rprqrrrrX)rspasswordZprivate_objectrtrrrrUs(        c Csnt|tr|}nTt|tr$t|}n@t|trRt|d}t|}W5QRXnttdt |t |t S)a3 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 r*z source must be a byte string, unicode string or asn1crypto.keys.PublicKeyInfo object, not %s ) r"rr7rr6rprqr#rr5rrrY)rsrrtrrrrV9s     cCs 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 )rrU)datarrrrrWasc Cs|dk r8t|tr|d}t|ts8ttdt|t|trbt|d}|}W5QRXnt|ts~ttdt|t ||\}}}d}d}|rt |t }|rt |j t }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 r*zR source must be a byte string or a unicode string, not %s cSsg|]}t|jtqSr)rrrr).0inforrr szload_pkcs12..)r"r6rr7r#rr5rprqrWrrrXrr) rsrrtr{Z cert_infoZextra_certs_infokeycertZ extra_certsrrrrTzs2        cCs |jdkrtdt||||S)a 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", "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 r*The key specified is not an RSA public keyrr_verifycertificate_or_public_key signaturerhash_algorithmrrrr_s cCs0|j}|dkr|dkrtdt||||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", "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 rrrTrsa_pss_paddingr)rrrrcp_algrrrrascCs |jdkrtdt||||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", "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 rz)The key specified is not a DSA public keyrrrrrrQs cCs |jdkrtdt||||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", "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 rz)The key specified is not an EC public keyrrrrrrK s Fc Cs\t|ttfs ttdt|t|tsr4r=r(r?rrBCryptDestroyHashrCCALG_MD5 CALG_SHA1 CALG_SHA_256 CALG_SHA_384 CALG_SHA_512r'CryptCreateHashrr(rDr. CryptHashDatarr loadto_p1363 OverflowErrorr#ZCryptVerifySignatureWr)rrrrrr| algo_is_rsa hash_lengthZdecrypted_signatureZkey_sizeZpadded_plaintext plaintext hash_handlealg_idhash_handle_pointerrhalf_lenZreversed_signaturerrrr s          rc Csz|dkr|}n0tjtjtjtjtjd|}tt||}t }d}|j } | dkp\| dk} | r|rtj }t t d} t| } t|} tt d| | _t|| _n@tj}t t d} t| } |dkrt | _nt|} tt d| | _tt d | }n8zt|}Wn$tttfk r$td YnXt |j||t||t||}|tjk}|p^|tjk}|rntd t |d S) a0 Verifies an RSA, DSA or ECDSA signature via CNG :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", "sha256", "sha384", "sha512" or "raw" :param rsa_pss_padding: If PSS padding should be used for RSA keys :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 rrrrrBCRYPT_PSS_PADDING_INFO wchar_t *BCRYPT_PKCS1_PADDING_INFOvoid *rN)!rMBCRYPT_MD5_ALGORITHMBCRYPT_SHA1_ALGORITHMBCRYPT_SHA256_ALGORITHMBCRYPT_SHA384_ALGORITHMBCRYPT_SHA512_ALGORITHMgetattrhashlibdigestr(rBCRYPT_PAD_PSSr+rLr.r!r$pszAlgIdrcbSaltBCRYPT_PAD_PKCS1r rrrrr#r4ZBCryptVerifySignaturerZSTATUS_INVALID_SIGNATUREZSTATUS_INVALID_PARAMETERrD)rrrrrr hash_constant padding_inforrrpadding_info_struct_pointerpadding_info_struct hash_bufferrZfailurerrrr sb     rcCs|jdkrtdt|||S)aL 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", "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 r+The key specified is not an RSA private keyrr_signrrrrrrr^^ s cCs.|j}|dkr|dkrtdt|||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", "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 rrrTrr)rrrpkey_algrrrr` scCs|jdkrtdt|||S)a7 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", "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 rz*The key specified is not a DSA private keyrrrrrrP s cCs|jdkrtdt|||S)a: 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", "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 rz*The key specified is not an EC private keyrrrrrrJ s cCs8t|tsttdt|t|ts8ttdt||j}|dkpL|dk}tddddd g}|jdkr||s||td gO}||krd }|r|s|d 7}ttd |t ||s|dk rttd| |d krt ||j dkrttd|j t |t dkr*|jdkrt|||St||||St||||S)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", "sha256", "sha384", "sha512" or "raw" :param rsa_pss_padding: If PSS padding should be used for RSA keys :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 rrrrrurrrrrrrFrrez 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 rAr)r"rXr#rr5r7rrrrrvrr(r_pure_python_ecdsa_sign_advapi32_sign _bcrypt_sign)rrrrr pkey_is_rsarrrrrr sR      rc Cs|j}|dkp|dk}|r8|dkr8t|j|}t||S|rr|rrdddddd |d }t|||j|}t||S|jd kr|d krttd d}z&t j t j t jt jt jd|} tt d} t |j| td | } t| t| }t ||t|d } t| tt d} t |t jtd t| } t| t| } t| }t |t jtd || } t| t|t| }|ddd}|d krt|d}||d|d|}t| }|WS|rt |XdS)a Generates an RSA, DSA or ECDSA signature via CryptoAPI :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", "sha256", "sha384", "sha512" or "raw" :param rsa_pss_padding: If PSS padding should be used for RSA keys :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 rrrrRrrrrrrrrzO Windows does not support md5 signatures with DSA keys Nrrrr9r)!rr9r(r;rr:rrrrBrrCrrrrrr'rrr(rDr.rrZCryptSignHashWZ AT_SIGNATUREr%r r#r from_p1363r)rrrrr|rZ padded_datarrrrrrrrrrrrrr0 s        rc Cs|dkr|}n0tjtjtjtjtjd|}tt||}t }d}|j }|dkp\|dk} | r|rdddd d d|} tj }t t d } t| } t|} tt d | | _| | _n@tj}t t d } t| } |dkrt | _nt|} tt d | | _tt d| }|dkr0|jdkr0|tddgkr0ttdtt d}t |j||t|t d||}t|t|}t|}| rtt d| }t |j||t|||||}t|t|t|}| st !|"}|S)a Generates an RSA, DSA or ECDSA signature via CNG :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", "sha256", "sha384", "sha512" or "raw" :param rsa_pss_padding: If PSS padding should be used for RSA keys :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 rrrrrrrRrrrrrrrrrrruz~ Windows does not support sha1 signatures with DSA keys based on sha224, sha256 or sha512 r)#rMrrrrrrrrr(rrr+rLr.r!r$rrrrrrrr'ZBCryptSignHashrrrDr%r r#r rr)rrrrrrrrrrrrrrrr buffer_lenr)rrrrr s    (    rcCsxt|ttfs ttdt|t|tsutilr?getwindowsversionZ_gwvrrZ _advapi32rBrCrDrErFZ_ecdsarGrrHrrIrJrrKrZ_cngrLrMrNrO__all__r&rrXrYrRrrrrr.r'rrrrrrSrrrwrrxrUrVrWrTr_rarQrrrr^r`rPrrrrrrrrrr]r\r[rZrrrrsD, H     ,WLP X4 e@ d . G = U [ G & P Wg i8 (= " "  bnY ! !  Xzy49H3+H   _win/__pycache__/symmetric.cpython-38.pyc000064400000054726147205106110014367 0ustar00U afx @sddlmZmZmZmZddlmZddlmZm Z m Z m Z m Z m Z mZmZmZmZddlmZddlmZddlmZmZeZed krdd lmZmZmZmZmZndd l m!Z!m"Z"mZm#Z#m$Z$d d ddddddddddg Z%dd Z&dd Z'ddZ(ddZ)ddZ*ddZ+ddZ,ddZ-d dZ.d!dZ/d"dZ0d#dZ1d$d%Z2d&d'Z3d(d)Z4d*d+Z5d,d-Z6d.d/Z7d0d1Z8d2d3Z9d4S)5)unicode_literalsdivisionabsolute_importprint_function)pretty_message) buffer_from_bytesbytes_from_bufferderefnewnull pointer_setstruct struct_bytesunwrapwrite_to_buffer) rand_bytes)backend) type_namebyte_cls winlegacy)advapi32 Advapi32Const handle_erroropen_context_handleclose_context_handle)bcrypt BcryptConstropen_alg_handleclose_alg_handleaes_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_encryptcCst|dkrttdt||s,td}nt|dkrJttdt|t|ddkrlttdt||td|||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 the OS crypto library :return: A tuple of two byte strings (iv, ciphertext)  o key must be either 16, 24 or 32 bytes (128, 192 or 256 bits) long - is %s r.: iv must be 16 bytes long - is %s rzJ data must be a multiple of 16 bytes long - is %s aesFlen ValueErrorrr_encryptkeydataivr<H/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/symmetric.pyr"-s$   cCsLt|dkrttdt|t|dkrr8r<r<r=r#s  cCs:t|dkst|dkr*ttdt|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 the OS crypto library :return: A byte string of the ciphertext r.Q key must be 5 to 16 bytes (40 to 128 bits) long - is %s rc4N)r5r6rr7r9r:r<r<r=r*s cCs:t|dkst|dkr*ttdt|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 the OS crypto library :return: A byte string of the plaintext r@r.rArBNr>rCr<r<r=r)s cCsjt|dkst|dkr*ttdt||s8td}nt|dkrVttdt||td|||dfS)ab Encrypts plaintext using RC2 with a 64 bit key :param key: The encryption key - a byte string 8 bytes long :param data: The plaintext - a byte string :param iv: The 8-byte initialization vector to use - a byte string - set as None to generate an appropriate one :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 tuple of two byte strings (iv, ciphertext) r@r.rA9 iv must be 8 bytes long - is %s rc2Tr4r8r<r<r=r(#s  cCsXt|dkst|dkr*ttdt|t|dkrHttdt|td|||dS)a" Decrypts RC2 ciphertext using a 64 bit key :param key: The encryption key - a byte string 8 bytes long :param data: The ciphertext - a byte string :param iv: The initialization vector used for encryption - 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 the OS crypto library :return: A byte string of the plaintext r@r.rArDrErFTr>r8r<r<r=r'Os cCs~t|dkr*t|dkr*ttdt||s8td}nt|dkrVttdt|d}t|dkrjd}|t||||dfS) a Encrypts plaintext using 3DES in either 2 or 3 key mode :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 8-byte initialization vector to use - a byte string - set as None to generate an appropriate one :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 tuple of two byte strings (iv, ciphertext) r.r/W key must be 16 bytes (2 key) or 24 bytes (3 key) long - is %s rDrEtripledes_3keytripledes_2keyTr4r9r:r;cipherr<r<r=r,xs    cCslt|dkr*t|dkr*ttdt|t|dkrHttdt|d}t|dkr\d}t||||dS) aC Decrypts 3DES ciphertext in either 2 or 3 key mode :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 used for encryption - 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 the OS crypto library :return: A byte string of the plaintext r.r/rGrDrErHrITr>rJr<r<r=r+s  cCs^t|dkrttdt||s,td}nt|dkrJttdt||td|||dfS)a Encrypts plaintext using DES with a 56 bit key :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 8-byte initialization vector to use - a byte string - set as None to generate an appropriate one :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 tuple of two byte strings (iv, ciphertext) rDT key must be 8 bytes (56 bits + 8 parity bits) long - is %s rEdesTr4r8r<r<r=r&s   cCsLt|dkrttdt|t|dkrr8r<r<r=r%s  cCsd}|dkr(tjtjtjdt|}ntjtjtjtjtj d|}tj }t |dd}t t d}t|}tj|_tj|_d|_||_t t d }t|} || _t|| _t||} d} |td d gkrt|d krtj} tt d } t || t| t| | } t| t| }|d krFtt dt|d}t |tj|d} t| |d krt |tj |d} t| tt dtj!}t |tj"|d} t| tt dtj#}t |tj$|d} t| ||fS)a Creates an HCRYPTPROV and HCRYPTKEY for symmetric encryption/decryption. The HCRYPTPROV must be released by close_context_handle() and the HCRYPTKEY must be released by advapi32.CryptDestroyKey() when done. :param cipher: A unicode string of "aes", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: A byte string of the symmetric key :param iv: The initialization vector - a byte string - unused for RC4 :return: A tuple of (HCRYPTPROV, HCRYPTKEY) Nr3r-)rMrIrHrFrBF)Z verify_onlyZ BLOBHEADERrPLAINTEXTKEYBLOBrFrBr@z HCRYPTKEY *DWORD *rD)%rZ CALG_AES_128Z CALG_AES_192Z CALG_AES_256r5ZCALG_DESZ CALG_3DES_112Z CALG_3DESZCALG_RC2ZCALG_RC4ZMS_ENH_RSA_AES_PROVrrrrrNZbTypeZCUR_BLOB_VERSIONZbVersionreservedZaiKeyAlghdrZ dwKeySizersetZ CRYPT_NO_SALTr ZCryptImportKeyr rZCryptSetKeyParamZKP_EFFECTIVE_KEYLENZKP_IVZCRYPT_MODE_CBCZKP_MODEZ PKCS5_PADDINGZ KP_PADDING)rKr9r;context_handleZ algorithm_idproviderZblob_header_pointerZ blob_headerblob_struct_pointer blob_structblobflagskey_handle_pointerres key_handlebufr<r<r=_advapi32_create_handles,s        r]c Csd}tjtjtjtjtjtjd|}zt|}tj }t t d}t |}tj |_tj|_t||_t||}|dkrtt dt|d}t |tj|dd} t| tt d } t |t|| td|t|d } t| t | WS|rt|XdS) ao Creates a BCRYPT_KEY_HANDLE for symmetric encryption/decryption. The handle must be released by bcrypt.BCryptDestroyKey() when done. :param cipher: A unicode string of "aes", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: A byte string of the symmetric key :return: A BCRYPT_KEY_HANDLE N)r3rMrIrHrFrBZBCRYPT_KEY_DATA_BLOB_HEADERrFrOrDrzBCRYPT_KEY_HANDLE *)rZBCRYPT_AES_ALGORITHMZBCRYPT_DES_ALGORITHMZBCRYPT_3DES_112_ALGORITHMZBCRYPT_3DES_ALGORITHMZBCRYPT_RC2_ALGORITHMZBCRYPT_RC4_ALGORITHMr rZBCRYPT_KEY_DATA_BLOBrrrZBCRYPT_KEY_DATA_BLOB_MAGICZdwMagicZBCRYPT_KEY_DATA_BLOB_VERSION1Z dwVersionr5Z cbKeyDatarr ZBCryptSetPropertyZBCRYPT_EFFECTIVE_KEY_LENGTHrZBCryptImportKeyr ) rKr9Z alg_handleZ alg_constantZ blob_typerUrVrWr\rZrYr<r<r=_bcrypt_create_key_handlesZ       r_cCst|tsttdt|t|ts8ttdt||dkr\t|ts\ttdt||dkr|s|dkrt|ddkstdtd krt|||||St |||||S) a Encrypts plaintext :param cipher: A unicode string of "aes", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: The encryption key - a byte string 5-16 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 the OS crypto library :return: A byte string of the ciphertext ; key must be a byte string, not %s < data must be a byte string, not %s rB: iv must be a byte string, not %s r3r.rpadding must be specifiedr) isinstancer TypeErrorrrr5r6_backend_advapi32_encrypt_bcrypt_encryptrKr9r:r;paddingr<r<r=r7s*   r7c Csd}d}zt|||\}}ttdt|}t|tddt|d}t|t |} t | } t | |t |t|t|tdd| || }t|t | t |} |dkr|st| t|dkr| dd} | WS|rt||rt|XdS)a Encrypts plaintext via CryptoAPI :param cipher: A unicode string of "aes", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: The encryption key - a byte string 5-16 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 the OS crypto library :return: A byte string of the ciphertext NrOTrr3r.i)rCryptDestroyKeyrr]r r5Z CryptEncryptr rr rrr r ) rKr9r:r;rjrSr[out_lenrZ buffer_lenbufferoutputr<r<r=rg"sJ      rgc Csd}zt||}|dkrd}nt|}d}|dkr8tj}ttd}t||t|ttdtd|| } t | t |} t | } |rt |nt} t||t|t| || | || } t | t | t |WS|rt|XdS)a Encrypts plaintext via CNG :param cipher: A unicode string of "aes", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: The encryption key - a byte string 5-16 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 the OS crypto library :return: A byte string of the ciphertext NrTULONG *) rBCryptDestroyKeyr_r5rBCRYPT_BLOCK_PADDINGr Z BCryptEncryptr rr rr rKr9r:r;rjr[Ziv_lenrXrlrZrmrnZ iv_bufferr<r<r=rhqsT    rhcCst|tsttdt|t|ts8ttdt||dkr\t|ts\ttdt||tddgkrx|sxtdtdkrt|||||St |||||S)a Decrypts AES/RC4/RC2/3DES/DES ciphertext :param cipher: A unicode string of "aes", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: The encryption key - a byte string 5-16 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 the OS crypto library :return: A byte string of the plaintext r`rarBrbr3rcr) rdrrerrrRr6rf_advapi32_decrypt_bcrypt_decryptrir<r<r=r?s(  r?c Csd}d}zt|||\}}|dkr>|s>t|ddkr>tdt|}ttdt|}t|t |dkrp|spdndd||} t | t |t |WS|rt||rt|XdS) a Decrypts AES/RC4/RC2/3DES/DES ciphertext via CryptoAPI :param cipher: A unicode string of "aes", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: The encryption key - a byte string 5-16 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 the OS crypto library :return: A byte string of the plaintext Nr3r.rz9Invalid data - ciphertext length must be a multiple of 16rOFT) rrkrr]r5r6rr Z CryptDecryptr rr r ) rKr9r:r;rjrSr[rnrlrZr<r<r=rts,  rtc Csd}zt||}|dkrd}nt|}d}|dkr8tj}ttd}t||t|ttdtd|| } t | t |} t | } |rt |nt} t||t|t| || | || } t | t | t |WS|rt|XdS)a Decrypts AES/RC4/RC2/3DES/DES ciphertext via CNG :param cipher: A unicode string of "aes", "des", "tripledes_2key", "tripledes_3key", "rc2", "rc4" :param key: The encryption key - a byte string 5-16 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 the OS crypto library :return: A byte string of the plaintext NrTrp) rrqr_r5rrrr Z BCryptDecryptr rr rr rsr<r<r=ru>sT    ruN): __future__rrrr_errorsrZ_ffirr r r r r rrrrutilrr_typesrrrfZ _advapi32rrrrrZ_cngrrrr __all__r"r!r$r#r*r)r(r'r,r+r&r%r]r_r7rgrhr?rtrur<r<r<r=sT 0  7+.*,)0--*oG@OS==_win/__pycache__/tls.cpython-38.pyc000064400000101146147205106110013142 0ustar00U af@sddlmZmZmZmZddlZddlZddlZddl Z ddl Z ddl m Z ddlmZddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZddlm Z m!Z!m"Z"dd l#m$Z$m%Z%m"Z&dd l'm(Z(dd l)m*Z*m+Z+m,Z,m-Z-dd l.m/Z/m0Z0m1Z1m2Z2dd l3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;mZ>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFddlGmHZHm Z ddlImJZJejKdkreLZMejNZOnePZOejKdkrejQZRnejRZRddgZSeTdZUeVZWeWdeWdfZXGddde0ZYGddde/ZZGddde[Z\Gddde[Z]dS))unicode_literalsdivisionabsolute_importprint_functionN) Certificate)pretty_message)buffer_from_bytesbuffer_from_unicodebytes_from_buffercastderefis_nullnativenewnullrefsizeofstructunwrapwrite_to_buffer)secur32 Secur32Const handle_error)crypt32 Crypt32Constr)kernel32) type_namestr_clsbyte_cls int_types)TLSErrorTLSVerificationErrorTLSDisconnectErrorTLSGracefulDisconnectError)detect_client_auth_requestdetect_other_protocol extract_chainget_dh_params_length parse_alertparse_session_inforaise_client_authraise_dh_paramsraise_disconnectionraise_expired_not_yet_validraise_handshakeraise_hostnameraise_no_issuerraise_protocol_errorraise_protocol_version raise_revokedraise_self_signedraise_verificationraise_weak_signature)load_certificater)parse_certificate))r; TLSSession TLSSockets( | | )c@s eZdZdS)_TLSDowngradeErrorN)__name__ __module__ __qualname__rCrCB/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/tls.pyr?Qsr?c@seZdZdZdS)_TLSRetryErrorz TLSv1.2 on Windows 7 and 8 seems to have isuses with some DHE_RSA ServerKeyExchange messages due to variable length integer encoding. This exception is used to trigger a reconnection to attempt the handshake again. N)r@rArB__doc__rCrCrCrDrEVsrEc@s>eZdZdZdZdZdZdZdZd ddZ ddZ dd Z dS) r=zj A TLS session object that multiple TLSSocket objects can share for the sake of session reuse NFc Cs<t|tsttdt|||_|dkr8tdddg}t|trNt|g}nt|tsjttdt||tddddg}|rttdt |||_ g|_ |r0|D]}t|t r|j }nbt|trt|}nNt|trt|d }t|}W5QRXnt|ts"ttd t||j |q|dS) 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 NTLSv1TLSv1.1TLSv1.2zu protocol must be a unicode string or set of unicode strings, not %s SSLv3z 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 ) isinstancebool TypeErrorrr_manual_validationsetr ValueErrorrepr _protocols_extra_trust_rootsrZasn1r r:openreadAsn1Certificateappend_obtain_credentials)selfprotocolZmanual_validationZextra_trust_rootsZunsupported_protocolsZextra_trust_rootfrCrCrD__init__msN          zTLSSession.__init__c Cstjtjtjtjd}d}|D]\}}||jkr"||O}q"tjtjtj tj tj tj tj tjtjtjg }d|jkr|tjtjtjgttdt|}t|D]\}}|||<qtjtjB} |js|js| tjO} n | tjO} ttd} t | } tj!| _"d| _#t$| _%t$| _&d| _'t$| _(t|| _)|| _*|| _+d| _,d| _-d| _.| | _/d| _0ttd} t1t$tj2tj3t$| t$t$| t$ } t4| | |_5dS)zU Obtains a credentials handle from secur32.dll for use with SChannel )rJrGrHrIrrIz ALG_ID[%s]Z SCHANNEL_CREDz CredHandle *N)6rSP_PROT_SSL3_CLIENTSP_PROT_TLS1_CLIENTSP_PROT_TLS1_1_CLIENTSP_PROT_TLS1_2_CLIENTitemsrSZ CALG_AES_128Z CALG_AES_256Z CALG_3DESZ CALG_SHA1Z CALG_ECDHEZ CALG_DH_EPHEMZ CALG_RSA_KEYXZ CALG_RSA_SIGNZ CALG_ECDSAZ CALG_DSS_SIGNextendZ CALG_SHA512Z CALG_SHA384Z CALG_SHA256rrlen enumerateZSCH_USE_STRONG_CRYPTOZSCH_CRED_NO_DEFAULT_CREDSrOrTZSCH_CRED_AUTO_CRED_VALIDATIONZSCH_CRED_MANUAL_CRED_VALIDATIONrrZSCHANNEL_CRED_VERSIONZ dwVersionZcCredsrZpaCredZ hRootStoreZcMappersZ aphMappersZcSupportedAlgsZpalgSupportedAlgsZgrbitEnabledProtocolsZdwMinimumCipherStrengthZdwMaximumCipherStrengthZdwSessionLifespandwFlagsZ dwCredFormatZAcquireCredentialsHandleWZ UNISP_NAMEZSECPKG_CRED_OUTBOUNDr_credentials_handle)rZZprotocol_valuesZprotocol_bit_maskkeyvalueZalgsZ alg_arrayindexalgflagsZschannel_cred_pointerZ schannel_credZcred_handle_pointerresultrCrCrDrYs~            zTLSSession._obtain_credentialscCs$|jr t|j}t|d|_dSN)rgrZFreeCredentialsHandler)rZrmrCrCrD__del__s zTLSSession.__del__)NFN) r@rArBrFrSZ_ciphersrOrTrgr]rYrorCrCrCrDr=as ZQc@seZdZdZdZdZdZdZdZdZ dZ dZ dZ dZ dZdZdZdZdZdZdZdZdZdZdZdZdZdZed=ddZd>ddZd d Zd d Z d?d dZ!ddZ"d@ddZ#ddZ$ddZ%ddZ&ddZ'dAddZ(ddZ)dd Z*d!d"Z+d#d$Z,e-d%d&Z.e-d'd(Z/e-d)d*Z0e-d+d,Z1e-d-d.Z2e-d/d0Z3e-d1d2Z4e-d3d4Z5e-d5d6Z6e-d7d8Z7e-d9d:Z8d;d<Z9dS)Br>z8 A wrapper around a socket.socket that adds TLS NFc Cst|tjsttdt|t|ts:ttdt||dk r^t|ts^ttdt||dd|d}||_||_ z | Wnbt k r}zt |j |j}|W5d}~XYn0tk r}zt|j }|W5d}~XYnX|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)rLsocket_socketrNrrrr=_socket _hostname _handshaker?r#message certificaterEr")clsrshostnamerqZ new_socketeZnew_erCrCrDwrapEs6    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||_z |Wntk r`|t|jtdg|j|j}|d|_||_t ||f||_|j ||YnBtk rd|_t ||f||_|j ||YnXdS)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 rprI)_received_bytes_decrypted_bytesrtrLrrNrrr!numbersNumberrrcreate_connection settimeoutr=_sessionrurvr?closerSrPrOrTrorE)rZaddressporttimeoutrqZ new_sessionrCrCrDr]sf        zTLSSocket.__init__cCsnttd|}td|D]&}d||_tj||_t||_qt td}t |}tj |_ ||_ ||_||fS)z Creates a SecBufferDesc struct and contained SecBuffer structs :param number: The number of contains SecBuffer objects to create :return: A tuple of (SecBufferDesc pointer, SecBuffer array) z SecBuffer[%d]r SecBufferDesc)rrrangecbBufferrSECBUFFER_EMPTY BufferTyperpvBufferrrSECBUFFER_VERSION ulVersioncBufferspBuffers)rZnumberbuffersrjsec_buffer_desc_pointersec_buffer_descrCrCrD_create_bufferss    zTLSSocket._create_buffersc( Csd}d}zttjtjtdt}t|r6t dt }|j j D]B}| }t|tj|t|tjt}|szt d||jqDttd}t|jtj|}t|t|}ttd|}ttd} t| ttd| } ttd} ttdtj| d<ttdtj| d<ttdtj | d <t!td } t| } d | _"ttd | | _#t!td }t|}tj$|_%| |_&t!td}t|}||_'t(t|}||_)ttd}t*t|| ||tj+tj,Bt|}t |tj-}t|}t|}t.t/|j0}|dkrbt|j1}t|}t.t/|j2}|j3|d}t|}t|j4}t5|j6t.t/|j7}t89|}|j|krb|tj:O}t!td}t|} t(t| | _)tj;| _|j?| _@t!td}!t|!}"t(t|"|"_)||"_Attd||"_Bt!td}#t|#}$t(t|$|$_)tCtjD||!|#}t |t|}%t5|%j6t.t/|%j7}t89|}|$jE}&|&r|&tjFkrRtG||&tjHkrtI|}'|'jJrxtK|ntL||&tjMkrtN||j?|&tjOkrtP||&tjQkrtR|tS||jTt ddgkrtP|W5|rt|d|r t|XdS)z Manually invoked windows certificate chain builder and verification step when there are extra trust roots to include in the search process NrzPCERT_CONTEXT *Z PCERT_CONTEXTz FILETIME *z char *[3]zchar *rrZCERT_ENHKEY_USAGEr;zchar **ZCERT_USAGE_MATCHZCERT_CHAIN_PARAzPCERT_CHAIN_CONTEXT *Z SSL_EXTRA_CERT_CHAIN_POLICY_PARAz wchar_t *ZCERT_CHAIN_POLICY_PARAzvoid *ZCERT_CHAIN_POLICY_STATUSmd5Zmd2)UrCertCloseStoreZCertFreeCertificateChainZ CertOpenStorerZCERT_STORE_PROV_MEMORYZX509_ASN_ENCODINGrrhandle_crypt32_errorrPrrTdumpZ CertAddEncodedCertificateToStorerdZCERT_STORE_ADD_USE_EXISTINGaddsha256rrQueryContextAttributesW_context_handle_pointerrSECPKG_ATTR_REMOTE_CERT_CONTEXTrrr rZGetSystemTimeAsFileTimeZPKIX_KP_SERVER_AUTHZSERVER_GATED_CRYPTOZ SGC_NETSCAPErZcUsageIdentifierZrgpszUsageIdentifierZUSAGE_MATCH_TYPE_ORZdwTypeUsageZRequestedUsagerZcbSizeZCertGetCertificateChainZCERT_CHAIN_CACHE_END_CERTZ&CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLYZ.CERT_CHAIN_POLICY_IGNORE_ALL_REV_UNKNOWN_FLAGSrintZcChainZrgpChainZcElementZ rgpElementZ pCertContextr pbCertEncoded cbCertEncodedrWloadZ'CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAGZAUTHTYPE_SERVERZ dwAuthTypeZ fdwChecksr ruZpwszServerNamerfZpvExtraPolicyParaZ CertVerifyCertificateChainPolicyZCERT_CHAIN_POLICY_SSLZdwErrorZCERT_E_EXPIREDr/ZCERT_E_UNTRUSTEDROOTr9 self_signedr6r2ZCERT_E_CN_NO_MATCHr1TRUST_E_CERT_SIGNATUREr8ZCRYPT_E_REVOKEDr5r7Z hash_algo)(rZstoreZcert_chain_context_pointerZ cert_hashescert cert_datarmcert_context_pointer_pointercert_context_pointerZorig_now_pointerZ now_pointerZusage_identifiersZcert_enhkey_usage_pointerZcert_enhkey_usageZcert_usage_match_pointerZcert_usage_matchZcert_chain_para_pointerZcert_chain_paraZcert_chain_para_sizeZ"cert_chain_context_pointer_pointerZcert_chain_policy_para_flagsZcert_chain_contextZ num_chainsZfirst_simple_chain_pointerZfirst_simple_chainZ num_elementsZlast_element_pointerZ last_elementZlast_element_certZlast_element_cert_dataZ last_certZ(ssl_extra_cert_chain_policy_para_pointerZ ssl_extra_cert_chain_policy_paraZcert_chain_policy_para_pointerZcert_chain_policy_paraZ cert_chain_policy_status_pointerZcert_chain_policy_status cert_contexterror oscrypto_certrCrCrD_extra_trust_root_validations                                       z&TLSSocket._extra_trust_root_validationc!Csd}d}d}zzd|r |j}nttd}|}tjdtj dtj dtj dtj d tj d tjd i}d|_|D]}|j|O_qf|d \}}tj|d_|d \} }tj|d_tj|d_ttd } |r|} t} n t} |} t|jj| |j|jddtd| | | t } | ttjtjgkr*t| t|s6| }n| }d}d}|djdkrt|dj|dj}||7}|j !|d|d_t|djt|d_t"d}t#td||d_d}| tjkrz$d}|j $d}|dkrt%Wnt&k r d}YnX||7}|j'|7_'t(|j'|d_t)||j't|jj||j|jdd|dt| | t } | tj*krtj|d_|djtj+krtj+|d_d|d_t|djst|djt|d_|rt%q| tj,kr&t-|rt.t/|}|r |dkr t0t1| tj2krJt3|}t4|d|j| tj5krjt3|}t6|d| tj7krt3|}|d}t8|}|j9st:|t;|| tj| tj?krt.| t@jAkrtB|| tjCkr|djdkr|t|dj|dj}||7}|dd}|dksF|dkr|d|jjDkr|t(|jjDdkr|t3|}tEd|dt-|rt.tF|rtG|t1| tjHks| tjIkrd|jjDkrtJd|rt%| tjKkrt=|dkrt>| ttjtjgkrt| t|djdkr~t|dj|dj}||7}|j !|d|d_t|djt|d_|djtjLkr|dj}|j'| d|_'tj+|d_d|d_t|djt|d_| tjkr|| d}nd|_'qtMtd}tN|tjO|} t| ttP|}tjQdtjRdtjSd tjTd!tjUdiVtWtX|jYtZ|jY|_[|j[tdd d!dgkrt\||}|d"|_]|d#|_^|d$|__|d%|_`ta| }|D]&}||Bdkrtbtcd&||q|sb||_d}tMtd'}tN|jtjd|} t| tP|} tWtX| je|_ftWtX| jg|_htWtX| ji|_j|jf|jh|jj|_k|jjlrt|mWn&tbtnjofk r|pYnXW5|rt|djst|djt|djst|dj|rt|XdS)(z Perform an initial TLS handshake, or a renegotiation :param renegotiate: If the handshake is for a renegotiation Nrrz CtxtHandle *zreplay detectionzsequence detectionZconfidentialityzmemory allocationZ integrityzstream orientationzdisable automatic client authrULONG *r~iBYTE *F T)rFir<(+rIzMServer certificate verification failed - weak certificate signature algorithmzTLS handshake failedZSecPkgContext_ConnectionInfoZSSLv2rJrGrH cipher_suite compression session_idsession_ticketzl Unable to obtain a credential context with the property %s ZSecPkgContext_StreamSizes)qrrrFreeContextBufferDeleteSecurityContextrrrZISC_REQ_REPLAY_DETECTZISC_REQ_SEQUENCE_DETECTZISC_REQ_CONFIDENTIALITYZISC_REQ_ALLOCATE_MEMORYZISC_REQ_INTEGRITYZISC_REQ_STREAMZISC_REQ_USE_SUPPLIED_CREDS_context_flagsrSECBUFFER_TOKENrSECBUFFER_ALERTrInitializeSecurityContextWrrgrurPSEC_E_OKSEC_I_CONTINUE_NEEDEDrr"rr rtsendr r recvr.socket_error_clsrrdrSEC_E_INCOMPLETE_MESSAGErZSEC_E_ILLEGAL_MESSAGEr&r,r*r4r0ZSEC_E_WRONG_PRINCIPALr(r1ZSEC_E_CERT_EXPIREDr/ZSEC_E_UNTRUSTED_ROOTr9rr2r6ZSEC_E_INTERNAL_ERRORr)r-ZSEC_I_INCOMPLETE_CREDENTIALSrrr8ZSEC_E_INVALID_TOKENrSr?r'r3ZSEC_E_BUFFER_TOO_SMALLZSEC_E_MESSAGE_ALTEREDrEZSEC_E_INVALID_PARAMETERSECBUFFER_EXTRArrZSECPKG_ATTR_CONNECTION_INFOrZSP_PROT_SSL2_CLIENTr^r_r`ragetrrZ dwProtocolr _protocolr+ _cipher_suite _compression _session_id_session_ticketr OSErrorrZSECPKG_ATTR_STREAM_SIZESZcbHeader _header_sizeZcbMaximumMessage _message_sizeZ cbTrailer _trailer_size _buffer_sizerTrrrrr)!rZ renegotiateZ in_buffers out_buffersZnew_context_handle_pointerZtemp_context_handle_pointerZrequested_flagsflagZin_sec_buffer_desc_pointerout_sec_buffer_desc_pointeroutput_context_flags_pointerZ first_handleZ second_handlermZhandshake_server_bytesZhandshake_client_bytestokenZin_data_buffer bytes_readZ fail_lateZ alert_infochainrrZ alert_bytesZ alert_number extra_amountZconnection_info_pointerZconnection_infoZ session_infoZoutput_context_flagsZstream_sizes_pointerZ stream_sizesrCrCrDrvs                                                           zTLSSocket._handshakec sXt|tsttdt|jdkrZjdkrRjd|}j|d_|Sjst j _ d\_ _ tjj d_ttdjj d_t|j }tj dj dj dj d fd d }j}t|}d_|dkr&ds&d_|Stjdk}||kr,|rpjj|7_tjdkrptttjj }|dkrq,|j d_tjjd|tjj dt}d }|tj kr|d }q4nX|tj!krd _"#q,n8|tj$kr*j%d d&|S|tj'kr@t(|t)t*tj+tj,tj-g} d} fD]f} | j} | tjkr|t.| j| j7}t|}n2| tj/krt0t1| j} n| | krdt2td| qd| rj|| d_nj|d_|drd }|s4tjdkr4q,q4t||krT||d_|d|}|S)a0 Reads data from the TLS-wrapped socket :param max_length: The number of bytes to read :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 zG max_length must be an integer, not %s Nr~rrrrr;cs^tj_ttdj_d_tj__d_tj__d_tj__d_dS)Nrr) rSECBUFFER_DATArr r_decrypt_data_bufferrrrrCZbuf0Zbuf1buf2Zbuf3Z null_valuerZrCrD_reset_bufferssz&TLSSocket.read.._reset_buffersFT)rz] Unexpected decrypt output buffer of type %s )3rLr!rNrrrr _raise_closedrr rr _decrypt_desc_decrypt_buffersrrrr rrmaxrrd select_readrrtrr.minrrZDecryptMessagerZSEC_I_CONTEXT_EXPIRED_remote_closedshutdownZSEC_I_RENEGOTIATErvrVrrr"rPrSECBUFFER_STREAM_HEADERSECBUFFER_STREAM_TRAILERr rrrr) rZ max_lengthoutputZto_recvrZ output_lenZdo_readdata_lenrmZvalid_buffer_typesrbufZ buffer_typerCrrDrVs                          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)rdrselectrt)rZrZ read_ready_rCrCrDrszTLSSocket.select_readc Cst|ts&t|ts&ttdt|d}t|t}t|jdkrP|j}d|_n |d}t|}||7}|r| |}|dk r| }qq4t d|t|d}| ||}|dkr4|t|}qq4||d|j|_|d|S)a Reads data from the socket until a marker is found. Data read may include data beyond 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 z_ marker must be a byte string or compiled regex object, not %s r~rrNr) rLr PatternrNrrrdrrVsearchendrfind) rZmarkerris_regexchunkoffsetmatchrstartrCrCrD read_untils2     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_regexrZrCrCrD 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)rVrd)rZ num_bytesr remainingrCrCrD read_exactlys zTLSSocket.read_exactlyc Cs|jdkr||jst|j|j|j|_|d\|_|_ t j |j d_ |j|j d_ ttd|j|j d_t j|j d_ t|j|j|j d_t j|j d_ |j|j d_ t|j|j|j|j d_t|dkrtt||j}t|j|d||j||j d_ t|j|j||j d_t|jd|jd}|t jkrVt|ttt|j dj }|tt|j dj 7}|tt|j dj 7}z|jt|j|Wn:t j!k r}z|j"dkrt#W5d}~XYnX||d}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 NrrrrriE')$rr_encrypt_data_bufferr rrrr _encrypt_desc_encrypt_buffersrrrrr rrrrrrdrrZEncryptMessagerrr"rrrtrr rrrerrnor.)rZdataZto_writermto_sendr{rCrCrDwritesH     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)rrtrd)rZrrZ write_readyrCrCrD select_write's zTLSSocket.select_writec Cs|jdkrdSd}zHt dkrt td}d|d_ tj|d_ttdtd|d_ttd }t|}tj|_d|_||_t|j|}t|t|d \}}tj|d_tj|d_t td }t|jj |j|j!|j"ddt#dt#||t# }t$tj%tj&tj'g}||krt|tt(|dj|dj } z|j)| Wntj k rXYnXW5|rt|djst|djt|djst|djt|jd|_z|jtj Wntj k rYnXXdS) z Shuts down the TLS session and then shuts down the underlying socket :raises: OSError - when an error is returned by the OS crypto library Nrr)rrz SecBuffer[1]rrsrrr)*rrrrrrrtrrr SHUT_RDWRr_win_version_inforrrrrr r rrrrrrZApplyControlTokenrr"rrrrrgrurrrPrZSEC_E_CONTEXT_EXPIREDrr r) rZrrrrrmrrZacceptable_resultsrrCrCrDr7sr             zTLSSocket.shutdowncCsFz |W5|jr@z|jWntjk r8YnXd|_XdS)zN Shuts down the TLS session and socket and forcibly closes it N)rtrrrrrrrCrCrDrs zTLSSocket.closec Csttd}t|jtj|}t|tt |}t td|}t |}t |j t t|j}t||_g|_d}zd|j}t|t}t|st |}t |j t t|j} | |kr|jt| t||}qW5|rt|dXdS)zh Reads end-entity and intermediate certificate information from the TLS session zCERT_CONTEXT **zCERT_CONTEXT *Nr)rrrrrrrrr"rr r rrrrrWr _certificate_intermediatesrZ hCertStoreZCertEnumCertificatesInStorerrrX) rZrrmrrrZ store_handleZcontext_pointercontextr rCrCrD_read_certificatess2    zTLSSocket._read_certificatescCs|jrtdntddS)zi Raises an exception describing if the local or remote end closed the connection z$The remote end closed the connectionz!The connection was already closedN)rr%r$rrCrCrDrs zTLSSocket._raise_closedcCs*|jdkr||jdkr$||jS)zu An asn1crypto.x509.Certificate object of the end-entity certificate presented by the server N)rrrrrrCrCrDrxs   zTLSSocket.certificatecCs*|jdkr||jdkr$||jS)zz A list of asn1crypto.x509.Certificate objects that were presented as intermediates by the server N)rrrrrrrCrCrD intermediatess   zTLSSocket.intermediatescCs|jS)zg A unicode string of the IANA cipher suite name of the negotiated cipher suite )rrrCrCrDrszTLSSocket.cipher_suitecCs|jS)zM A unicode string of: "TLSv1.2", "TLSv1.1", "TLSv1", "SSLv3" )rrrCrCrDr[szTLSSocket.protocolcCs|jS)z5 A boolean if compression is enabled )rrrCrCrDrszTLSSocket.compressioncCs|jSzM A unicode string of "new" or "reused" or None for no ticket )rrrCrCrDrszTLSSocket.session_idcCs|jSr)rrrCrCrDr szTLSSocket.session_ticketcCs|jS)zM The oscrypto.tls.TLSSession object used for this connection )rrrCrCrDrqszTLSSocket.sessioncCs|jS)zN A unicode string of the TLS server domain name or IP address )rurrCrCrDrzszTLSSocket.hostnamecCs|jdS)zJ An integer of the port number the socket is connected to r)rs getpeernamerrCrCrDr%szTLSSocket.portcCs|jdkr||jS)z9 The underlying socket.socket connection N)rrrtrrCrCrDrs-s zTLSSocket.socketcCs |dSrn)rrrCrCrDro8szTLSSocket.__del__)N)r}N)F)N)N):r@rArBrFrtrrrrurrrrrrrrrrrrrrrrrrr classmethodr|r]rrrvrVrrrrr r rrrrpropertyrxrrr[rrrrqrzrrsrorCrCrCrDr>s > W3 0+ 7 > T(            )^ __future__rrrrsysrersrrrrZ_asn1rrW_errorsrZ_ffir r r r r rrrrrrrrrZ_secur32rrrZ_crypt32rrrZ _kernel32r_typesrrr r!errorsr"r#r$r%_tlsr&r'r(r)r*r+r,r-r.r/r0r1r2r3r4r5r6r7r8Z asymmetricr9keysr: version_infoxrangerrrZ WindowsErrorZ _pattern_typer__all__compilergetwindowsversionZ_gwvrr?rEobjectr=r>rCrCrCrDsD  @ T     ?_win/__pycache__/trust_list.cpython-38.pyc000064400000011010147205106110014542 0ustar00U af@sddlmZmZmZmZddlZddlZddlZddlm Z ddl m Z m Z m Z mZmZmZmZmZmZmZddlmZmZmZmZddlmZd d gZd d Zdd d ZddZdS))unicode_literalsdivisionabsolute_importprint_functionN) Certificate) array_from_pointerbuffer_from_bytesbytes_from_buffercastderefis_nullnewnullstruct_from_bufferunwrap)crypt32 Crypt32Const get_error handle_error)str_clsextract_from_system system_pathcCsdS)NrrrI/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/trust_list.pyrsFc! Cs:i}i}tj}dD]}tt|}t|t}t||}t|rPqt|}d} d} d} |j t j krrq8t |j t|j} t| } | |krq8d|| <t|j} t| j} z0tj| }||kr|r|t| dWq8Wnttfk rYnXt| j}z4tj|}||kr@|r<|t| dWq8Wnbttfk r}z>|dkr|jddt|}|f|jd d|_|W5d}~XYnXt}t}ttd d}t |t j!t|}t"\}}|s|t j#krt||t j#krd} nt$t%|}t |t j!t&td ||}t|t'td |}t|}|j(dkrl|r8|t| d q8t)td|j*|j(}|D]}|+|,dqd}| st| }|j-r|j-D] }|j.}||kr|+|q|r|s|dkrt| }||d| ||f|| <q8t/|d} t| d}q|0S)a Extracts trusted CA certificates from the Windows certificate store :param cert_callback: A callback that is called once for each certificate in the trust store. It should accept two parameters: an asn1crypto.x509.Certificate object, and a reason. The reason will be None if the certificate is being exported, otherwise it will be a unicode string of the reason it won't. :param callback_only_on_failure: A boolean - if the callback should only be called when a certificate is not exported. :raises: OSError - when an error is returned by the OS crypto library :return: A list of 3-element tuples: - 0: a byte string of a DER-encoded certificate - 1: a set of unicode strings that are OIDs of purposes to trust the certificate for - 2: a set of unicode strings that are OIDs of purposes to reject the certificate for )ROOTCAFNTz not yet validzno longer validrz - rzDWORD *zCERT_ENHKEY_USAGE *ZCERT_ENHKEY_USAGEzexplicitly distrustedZLPCSTRascii)1datetimeutcnowrZCertOpenSystemStoreWrrZCertEnumCertificatesInStorer rZdwCertEncodingTyperZX509_ASN_ENCODINGr Z pbCertEncodedintZ cbCertEncodedhashlibsha1digestZ pCertInfo_convert_filetime_to_timestampZ NotBefore fromtimestamprload ValueErrorOSErrorZNotAfterargsrsetrZCertGetEnhancedKeyUsageZ%CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAGrZCRYPT_E_NOT_FOUNDr r r rZcUsageIdentifierrZrgpszUsageIdentifieradddecodeZextended_key_usage_valueZdottedZCertCloseStorevalues)!Z cert_callbackZcallback_only_on_failureZ certificates processednowstoreZ store_handleZcontext_pointercontextZ trust_alldatar$Z cert_infoZnot_before_secondsZ not_beforeZnot_after_secondsZ not_afteremessageZ trust_oidsZ reject_oidsZto_readresZ error_code_Z usage_bufferZkey_usage_pointerZ key_usageZoidsoidcertZcert_oidresultrrrr#s                          cCs.tdtd|j|jd}|d}|dS)a Windows returns times as 64-bit unsigned longs that are the number of hundreds of nanoseconds since Jan 1 1601. This converts it to a datetime object. :param filetime: A FILETIME struct object :return: An integer unix timestamp s>Qs>LLril!l )structunpackpackZdwHighDateTimeZ dwLowDateTime)ZfiletimeZhundreds_nano_secondsZseconds_since_1601rrrr%s r%)NF) __future__rrrrrr"r;Z_asn1rZ_ffirr r r r r rrrrZ_crypt32rrrr_typesr__all__rrr%rrrrs 0   *_win/__pycache__/util.cpython-38.pyc000064400000007726147205106110013326 0ustar00U afr@sddlmZmZmZmZddlmZddlmZddl m Z m Z ddl m Z ddlmZmZmZdd d gZeZed krd d lmZmZmZmZmZddZde_dd ZnddlmZddlmZdS))unicode_literalsdivisionabsolute_importprint_function)backend)pretty_message)buffer_from_bytesbytes_from_buffer) pkcs12_kdf) type_namebyte_cls int_typespbkdf2r rand_byteswin)bcrypt BcryptConst handle_erroropen_alg_handleclose_alg_handlec Cs4t|tsttdt|t|ts8ttdt|t|tsTttdt||dkrdtdt|tsttdt||dkrtd|tdd d d gkrttd t|t j t j t j t j d |}d}zJt|t j}t|}t||t||t||||d }t|t|WS|r.t|XdS)a% PBKDF2 from PKCS#5 :param hash_algorithm: The string name of the hash algorithm to use: "sha1", "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 OSError - when an error is returned by the OS crypto library :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 rz!iterations must be greater than 0zG key_length must be an integer, not %s z!key_length must be greater than 0sha1sha256sha384sha512z| hash_algorithm must be one of "sha1", "sha256", "sha384", "sha512", not %s )rrrrNr) isinstancer TypeErrorrr r ValueErrorsetreprrZBCRYPT_SHA1_ALGORITHMZBCRYPT_SHA256_ALGORITHMZBCRYPT_SHA384_ALGORITHMZBCRYPT_SHA512_ALGORITHMrrZBCRYPT_ALG_HANDLE_HMAC_FLAGr rZBCryptDeriveKeyPBKDF2lenrr ) Zhash_algorithmpasswordZsaltZ iterationsZ key_lengthZ alg_constant alg_handleZ output_bufferresr%C/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_win/util.pyrsn        FcCst|tsttdt||dkr,td|dkrs"   j / __pycache__/__init__.cpython-38.pyc000064400000017741147205106110013152 0ustar00U af&@sddlmZmZmZmZddlZddlZddlZddlZddl m Z m Z ddl m Z ddlmZmZddd d d d d dgZeZddddZdd ZddZddd ZddZdd Zdd Zdd ZdS))unicode_literalsdivisionabsolute_importprint_functionN)str_cls type_name)LibraryNotFoundError) __version____version_info__r r backendffi load_order use_ctypes use_openssl use_winlegacy)r backend_configr c Cstddk rtdSttddk r:tdW5QRStjdkrhtddkr^dtd<qdtd<ntjdkr|d td<nd td<tdW5QRSQRXdS) zs :return: A unicode string of the backend being used: "openssl", "mac", "win", "winlegacy" r Nwin32r winlegacywindarwinmacopenssl)_module_values _backend_locksysplatformgetwindowsversionrrB/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/__init__.pyr "s       c CsntdkriStddk r"tdSt>tddk rHtdW5QRSitd<tdW5QRSQRXdS)z :return: A dict of config info for the backend. Only currently used by "openssl", it may contains zero or more of the following keys: - "libcrypto_path" - "libssl_path" rrN)r rrrrrr _backend_config>s   r!c Cst|tstdt|t|ts4tdt|tj|sLtd|tj|sdtd||dk rt|tstdt|tj|std|t \|||d}t d d krt d |krW5QRdSt d dk rt d d t d <|t d <W5QRXdS) a Forces using OpenSSL dynamic libraries on OS X (.dylib) or Windows (.dll), or using a specific dynamic library on Linux/BSD (.so). This can also be used to configure oscrypto to use LibreSSL dynamic libraries. This method must be called before any oscrypto submodules are imported. :param libcrypto_path: A unicode string of the file path to the OpenSSL/LibreSSL libcrypto dynamic library. :param libssl_path: A unicode string of the file path to the OpenSSL/LibreSSL libssl dynamic library. :param trust_list_path: An optional unicode string of the path to a file containing OpenSSL-compatible CA certificates in PEM format. If this is not provided and the platform is OS X or Windows, the system trust roots will be exported from the OS and used for all TLS connections. :raises: ValueError - when one of the paths is not a unicode string OSError - when the trust_list_path does not exist on the filesystem oscrypto.errors.LibraryNotFoundError - when one of the path does not exist on the filesystem RuntimeError - when this function is called after another part of oscrypto has been imported z/libcrypto_path must be a unicode string, not %sz,libssl_path must be a unicode string, not %szlibcrypto does not exist at %szlibssl does not exist at %sNz0trust_list_path must be a unicode string, not %sz$trust_list_path does not exist at %s)libcrypto_path libssl_pathtrust_list_pathr rrzRAnother part of oscrypto has already been imported, unable to force use of OpenSSL) isinstancer ValueErrorrospathexistsr OSErrorrr RuntimeError)r"r#r$Z new_configrrr rUs0          c Csztjdkr0tptj}|dkr$d}td|t<tddkrPW5QRdStddk rdtddtd<W5QRXdS) as Forces use of the legacy Windows CryptoAPI. This should only be used on Windows XP or for testing. It is less full-featured than the Cryptography Next Generation (CNG) API, and as a result the elliptic curve and PSS padding features are implemented in pure Python. This isn't ideal, but it a shim for end-user client code. No one is going to run a server on Windows XP anyway, right?! :raises: EnvironmentError - when this function is called on an operating system other than Windows RuntimeError - when this function is called after another part of oscrypto has been imported rDarwinzOS Xz9The winlegacy backend can only be used on Windows, not %sr rNzcAnother part of oscrypto has already been imported, unable to force use of Windows legacy CryptoAPI)rrsystemEnvironmentErrorrrr+)platrrr rs    c CsJt<tddkr W5QRdStddk r4tddtd<W5QRXdS)z Forces use of ctypes instead of cffi for the FFI layer :raises: RuntimeError - when this function is called after another part of oscrypto has been imported r ctypesNr zQAnother part of oscrypto has already been imported, unable to force use of ctypes)rrr+rrrr rs  c Csjtddk rtdStHzddl}dtd<Wntk rJdtd<YnXtdW5QRSQRXdS)zh Returns the FFI module being used :return: A unicode string of "cffi" or "ctypes" r Nrcffir0)rrr1 ImportError)r1rrr r s  cECsddddddddd d d d d ddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;dd?d@dAdBdCdDdEgES)Fa) Returns a list of the module and sub-module names for oscrypto in dependency load order, for the sake of live reloading code :return: A list of unicode strings of module names, as they would appear in sys.modules, ordered by which module should be reloaded first zoscrypto._asn1zoscrypto._cipher_suiteszoscrypto._errorsz oscrypto._intzoscrypto._typeszoscrypto.errorszoscrypto.versionZoscryptoz oscrypto._ffizoscrypto._pkcs12zoscrypto._pkcs5zoscrypto._randz oscrypto._tlszoscrypto._linux_bsd.trust_listz!oscrypto._mac._common_crypto_cffiz#oscrypto._mac._common_crypto_ctypeszoscrypto._mac._common_cryptoz#oscrypto._mac._core_foundation_cffiz%oscrypto._mac._core_foundation_ctypeszoscrypto._mac._core_foundationzoscrypto._mac._security_cffizoscrypto._mac._security_ctypeszoscrypto._mac._securityzoscrypto._mac.trust_listzoscrypto._mac.utilz!oscrypto._openssl._libcrypto_cffiz#oscrypto._openssl._libcrypto_ctypeszoscrypto._openssl._libcryptozoscrypto._openssl._libssl_cffiz oscrypto._openssl._libssl_ctypeszoscrypto._openssl._libsslzoscrypto._openssl.utilzoscrypto._win._cng_cffizoscrypto._win._cng_ctypeszoscrypto._win._cngzoscrypto._win._decodezoscrypto._win._advapi32_cffizoscrypto._win._advapi32_ctypeszoscrypto._win._advapi32zoscrypto._win._kernel32_cffizoscrypto._win._kernel32_ctypeszoscrypto._win._kernel32zoscrypto._win._secur32_cffizoscrypto._win._secur32_ctypeszoscrypto._win._secur32zoscrypto._win._crypt32_cffizoscrypto._win._crypt32_ctypeszoscrypto._win._crypt32zoscrypto._win.trust_listzoscrypto._win.utilzoscrypto.trust_listz oscrypto.utilz oscrypto.kdfzoscrypto._mac.symmetriczoscrypto._openssl.symmetriczoscrypto._win.symmetriczoscrypto.symmetriczoscrypto._asymmetriczoscrypto._ecdsazoscrypto._pkcs1zoscrypto._mac.asymmetriczoscrypto._openssl.asymmetriczoscrypto._win.asymmetriczoscrypto.asymmetricz oscrypto.keyszoscrypto._mac.tlszoscrypto._openssl.tlszoscrypto._win.tlsz oscrypto.tlsrrrrr rs )N) __future__rrrrr'rr threading_typesrrerrorsr versionr r __all__Lockrrr r!rrrr rrrrr s8   B __pycache__/_asn1.cpython-38.pyc000064400000002571147205106110012407 0ustar00U af@s@ddlmZmZmZmZddlmZmZmZm Z m Z m Z m Z m Z ejZejZejZejZejZejZejZejZe jZe jZe jZe jZe jZe jZe jZe jZe jZe jZe j Z e j!Z!e j"Z"e j#Z#e j$Z$e j%Z%e j&Z&e j'Z'e j(Z(e j)Z)e j*Z*e j+Z+e j,Z,ddddddd d d d d ddddddddddddddddddd d!gZ-d"S)#)unicode_literalsdivisionabsolute_importprint_function)algoscmscorekeyspempkcs12utilx509armorCertBag Certificate DHParameters DSAParams DSAPrivateKey DSASignatureECDomainParametersECPointBitString ECPrivateKey EncryptedDataEncryptedPrivateKeyInfoint_from_bytes int_to_bytesIntegerKeyExchangeAlgorithmNull OctetString OrderedDict Pbkdf2SaltPfxPrivateKeyAlgorithmPrivateKeyInfoPublicKeyAlgorithm PublicKeyInfo RSAPrivateKey RSAPublicKey SafeContentstimezoneTrustedCertificateunarmorN). __future__rrrrZ asn1cryptorrrr r r r r rrrr!rrrrrrrrrrr#r$r%r&r'r(rrr r*rr,rr"r)rr+__all__r/r/?/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_asn1.pys(__pycache__/_asymmetric.cpython-38.pyc000064400000050731147205106110013723 0ustar00U afx@sjddlmZmZmZmZddlZddlZddlZddlZddl m Z m Z m Z m Z mZmZmZmZmZmZmZmZmZmZmZddlmZmZmZddlmZmZm Z m!Z!m"Z"ddl#m$Z$ddl%m&Z&dd l'm(Z(m)Z)m*Z*Gd d d Z+Gd d d Z,GdddZ-ddZ.ddZ/e e!ee"edZ0ddZ1ddZ2d%ddZ3d&ddZ4ddZ5dd Z6d!d"Z7d#d$Z8dS)')unicode_literalsdivisionabsolute_importprint_functionN)CertBag Certificate DSAPrivateKey ECPrivateKey EncryptedDataEncryptedPrivateKeyInfoInteger OctetStringPfxPrivateKeyInfo PublicKeyInfo RSAPrivateKey RSAPublicKey SafeContentsunarmor)pbkdf1pbkdf2 pkcs12_kdf)aes_cbc_pkcs7_decryptdes_cbc_pkcs5_decryptrc2_cbc_pkcs5_decrypt rc4_decrypttripledes_cbc_pkcs5_decrypt)constant_compare)pretty_message)byte_clsstr_cls type_namec@sLeZdZdZdZddZeddZeddZedd Z ed d Z dS) _PrivateKeyBaseNcCs|jdkr|jdjS|jdkr^|jdd}td|d|d|d |j|jdjd S|jd kr|jdj}|jdd|d<|j|d <|Sd S)a. Unwraps the private key into an asn1crypto.keys.RSAPrivateKey, asn1crypto.keys.DSAPrivateKey or asn1crypto.keys.ECPrivateKey object :return: An asn1crypto.keys.RSAPrivateKey, asn1crypto.keys.DSAPrivateKey or asn1crypto.keys.ECPrivateKey object rsa private_keydsaprivate_key_algorithm parametersrpqgversionr)r*r+ public_keyr%ecr.N) algorithmasn1parsedr r.unwrap)selfparamsoutputr7E/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_asymmetric.pyr3-s"      z_PrivateKeyBase.unwrapcCs|jjSzO :return: A unicode string of "rsa", "dsa" or "ec" r1r0r4r7r7r8r0Ksz_PrivateKeyBase.algorithmcCs |jjdSH :return: A unicode string of EC curve name rr1curver;r7r7r8r?Tsz_PrivateKeyBase.curvecCs|jjSzS :return: The number of bits in the key, as an integer r1bit_sizer;r7r7r8rB]sz_PrivateKeyBase.bit_sizecCs|jjSzT :return: The number of bytes in the key, as an integer r1 byte_sizer;r7r7r8rEfsz_PrivateKeyBase.byte_size) __name__ __module__ __qualname__r1 _fingerprintr3propertyr0r?rBrEr7r7r7r8r#(s   r#c@sXeZdZdZdZddZeddZeddZedd Z ed d Z ed d Z dS)_PublicKeyBaseNcCs |jdkr|jdS|jdjS)a7 Unwraps a public key into an asn1crypto.keys.RSAPublicKey, asn1crypto.core.Integer (for DSA) or asn1crypto.keys.ECPointBitString object :return: An asn1crypto.keys.RSAPublicKey, asn1crypto.core.Integer or asn1crypto.keys.ECPointBitString object r/r.)r0r1r2r;r7r7r8r3us  z_PublicKeyBase.unwrapcCs|jdkrt|jd|_|jS)aZ Creates a fingerprint that can be compared with a private 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)rIr1r;r7r7r8 fingerprints z_PublicKeyBase.fingerprintcCs|jjSr9r:r;r7r7r8r0sz_PublicKeyBase.algorithmcCs |jjdSr<r>r;r7r7r8r?sz_PublicKeyBase.curvecCs|jjSr@rAr;r7r7r8rBsz_PublicKeyBase.bit_sizecCs|jjSrCrDr;r7r7r8rEsz_PublicKeyBase.byte_size) rFrGrHr1rIr3rJrLr0r?rBrEr7r7r7r8rKps    rKc@s@eZdZdZeddZeddZeddZedd ZdS) _CertificateBaseNcCs|jjSr9)r.r0r;r7r7r8r0sz_CertificateBase.algorithmcCs|jjS)r=)r.r?r;r7r7r8r?sz_CertificateBase.curvecCs|jjS)zZ :return: The number of bits in the public key, as an integer )r.rBr;r7r7r8rBsz_CertificateBase.bit_sizecCs|jjS)z[ :return: The number of bytes in the public key, as an integer )r.rEr;r7r7r8rEsz_CertificateBase.byte_size) rFrGrHr1rJr0r?rBrEr7r7r7r8rMs   rMc Cs|j}|dks|dkr |djS|dkrz|dd}|dj}td|d|d |d tt|d j|j|dj|d S|d kr|dj}|dd|d<|Std |jdS)a Unwraps an asn1crypto.keys.PrivateKeyInfo object into an asn1crypto.keys.RSAPrivateKey, asn1crypto.keys.DSAPrivateKey or asn1crypto.keys.ECPrivateKey. :param key_info: An asn1crypto.keys.PrivateKeyInfo object :return: One of: - asn1crypto.keys.RSAPrivateKey - asn1crypto.keys.DSAPrivateKey - asn1crypto.keys.ECPrivateKey r$Z rsassa_pssr%r&r'r(rr)r*r+r,r/z#Unsupported key_info.algorithm "%s"N)r0r2r r pownative ValueError)key_infoZkey_algr5r2r7r7r8_unwrap_private_key_infos.     rRcCst|tr|dj}|jdkr:d|dj|djf}n|jdkr|dd}tt|d j|djj|d j}d |d j|d j|d j|jf}nT|jd kr|dj}|dkr||j}|jdjj}d|j d}| d}||7}t|t r| d}t |St|tr|jdkrN|dj}d|dj|djf}n~|jdkr|dj}|dd}d |d j|d j|d j|jf}n6|jd kr|dj}d|j d}| d}||7}t|t r| d}t |Sttdt|dS)a5 Returns a fingerprint used for correlating public keys and private keys :param key_object: An asn1crypto.keys.PrivateKeyInfo or asn1crypto.keys.PublicKeyInfo :raises: ValueError - when the key_object is not of the proper type ;return: A byte string fingerprint r%r$z%d:%dmodulusZpublic_exponentr&r'r(r+r)z %d:%d:%d:%dr*r/r.Nz%s:rzutf-8r0z key_object must be an instance of the asn1crypto.keys.PrivateKeyInfo or asn1crypto.keys.PublicKeyInfo classes, not %s ) isinstancerr2r0rOr rNr.r1r?encoder!hashlibsha256digestrrPrr")Z key_objectload_private_keykeyZto_hashr5r.Zpublic_key_objectr7r7r8rIsv                       rI)rc2rc4des tripledesaescCs(t|tsttdt|d}td|dk rft|\}}}|dkrRttd|dkrft |dS|dksv|dkrzt |}|j |WStk rYnXzt |}|j t |dWStk rYnX|dks|dkrzt |}|d d }|WStk rYnXtd dS) a Loads a public key from a DER or PEM-formatted file. Supports RSA, DSA and EC public keys. For RSA keys, both the old RSAPublicKey and SubjectPublicKeyInfo structures are supported. Also allows extracting a public key from an X.509 certificate. :param data: A byte string to load the public key from :raises: ValueError - when the data does not appear to contain a public key :return: An asn1crypto.keys.PublicKeyInfo object < data must be a byte string, not %s N\s*----- private keyz The data specified does not appear to be a public key or certificate, but rather a private key r$ public key certificatetbs_certificatesubject_public_key_infozQThe data specified does not appear to be a known public key or certificate format)rTr TypeErrorrr"rematch _unarmor_pemrPrwraploadrOrr)datakey_typealgopkiZrpkZ parsed_certrQr7r7r8 parse_public~sF       rqcCst|tsttdt|d}td|dk rft|\}}}|dkrRttd|dkrfttd|dksv|dkrz t |WStk rYnXttd dS) a@ Loads a certificate from a DER or PEM-formatted file. Supports X.509 certificates only. :param data: A byte string to load the certificate from :raises: ValueError - when the data does not appear to contain a certificate :return: An asn1crypto.x509.Certificate object r`Nrarbz The data specified does not appear to be a certificate, but rather a private key rcz The data specified does not appear to be a certificate, but rather a public key rdzU The data specified does not appear to be a known certificate format ) rTr rgrr"rhrirjrPrrl)rmrn_r7r7r8parse_certificates0  rsc Cst|tsttdt||dk rBt|tsFttdt|nd}td|dk rt||\}}}|dkrzttd|dkrttd zt |}|j |WStk rYnXz>t |}|d }|d j }t |||}t |}|j |WStk rYnXzt |} | j t | d WStk rDYnXzt |} | j t | d WStk rzYnXzt |} | j t | dWStk rYnXttddS)a% Loads a private key from a DER or PEM-formatted file. Supports RSA, DSA and EC private keys. Works with the follow formats: - RSAPrivateKey (PKCS#1) - ECPrivateKey (SECG SEC1 V2) - DSAPrivateKey (OpenSSL) - PrivateKeyInfo (RSA/DSA/EC - PKCS#8) - EncryptedPrivateKeyInfo (RSA/DSA/EC - PKCS#8) - Encrypted RSAPrivateKey (PEM only, OpenSSL) - Encrypted DSAPrivateKey (PEM only, OpenSSL) - Encrypted ECPrivateKey (PEM only, OpenSSL) :param data: A byte string to load the private key from :param password: The password to unencrypt the private key :raises: ValueError - when the data does not appear to contain a private key, or the password is invalid :return: An asn1crypto.keys.PrivateKeyInfo object r`NH password must be a byte string, not %s rarcz The data specified does not appear to be a private key, but rather a public key rdz The data specified does not appear to be a private key, but rather a certificate encryption_algorithmencrypted_datar$r&r/zU The data specified does not appear to be a known private key format )rTr rgrr"rhrirjrPrrlrOr _decrypt_encrypted_datarrkr r ) rmpasswordrnrrrpZparsed_wrapperencryption_algorithm_inforwZdecrypted_datar2r7r7r8 parse_privatesv          r{c Cst|\}}}d}t||}|s.ttd|d}|}|tdddgkrr|d}d|t |||fS|} d }| d krd} n| d krd } d }| ||fS)a3 Removes PEM-encoding from a public key, private key or certificate. If the private key is encrypted, the password will be used to decrypt it. :param data: A byte string of the PEM-encoded data :param password: A byte string of the encryption password, or None :return: A 3-element tuple in the format: (key_type, algorithm, der_bytes). The key_type will be a unicode string of "public key", "private key" or "certificate". The algorithm will be a unicode string of "rsa", "dsa" or "ec". zc^((DSA|EC|RSA) PRIVATE KEY|ENCRYPTED PRIVATE KEY|PRIVATE KEY|PUBLIC KEY|RSA PUBLIC KEY|CERTIFICATE)zx data does not seem to contain a PEM-encoded certificate, private key or public key rzRSA PRIVATE KEYzDSA PRIVATE KEYzEC PRIVATE KEYrbNzencrypted private keyzrsa public keyrcr$) rrhrirPrgroupstripsetlower_unarmor_pem_openssl_private) rmryZ object_typeheadersZ der_bytesZ type_regexZ armor_typeZ pem_headerrornr7r7r8rjvs(  rjc CsDd}d}d}d|krB|d}|ddkr>|d\}}nd}|sJ|S|r^t|d}|}ddddd d dd d d d ddddddd d d |}t||d d  }|t |kr|t|||d d  7}q|d |}dddddddddddddddddddd |} t | } | dkr8| ||S| |||S)a Parses a PKCS#1 private key, or encrypted private key :param headers: A dict of "Name: Value" lines from right after the PEM header :param data: A byte string of the DER-encoded PKCS#1 private key :param password: A byte string of the password to use if the private key is encrypted :return: A byte string of the DER-encoded private key NzDEK-Info,ZRC4ascii )z aes-128-cbczaes-128z aes-192-cbczaes-192z aes-256-cbczaes-256r\zrc4-64zrc4-40z rc2-64-cbcz rc2-40-cbczrc2-cbcr[z des-ede3-cbczdes-ede3Zdes3z des-ede-cbczdes-cbcr]rr_r\r[r^r]) findr~splitbinascii unhexlifyrUrrVmd5rXlen crypto_funcs) rrmryZenc_algoZ enc_iv_hexenc_ivr5Zenc_key_lengthenc_keyZ enc_algo_name decrypt_funcr7r7r8rs $   rcst|tsttdt||dk rBt|tsFttdt|nd}ii}t|}|d}|djdkrzttd|j }|d }|r|d d d j}d ddddddd|} t |||dj|dj| d} t t |} t | |dj| } |d dj} t| | std|D]~}|d}t|trJt|j|||nPt|tr|d}|d}|dj}t|||}t||||n ttdqt|}t}tt||@}d}d}g}t|dkr|d|}}fdd D}|||fSt|dkr@tt|d}||}tdkrpttd}|}|=tdkrttd!d"d#}|||fS)$aY 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 :param load_private_key: A callable that will accept a byte string and return an oscrypto.asymmetric.PrivateKey object :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 r`Nrtru auth_safe content_typermzV Only password-protected PKCS12 files are currently supported mac_datamacZdigest_algorithmr0r0@)sha1sha224rWsha384sha512Z sha512_224Z sha512_256Zmac_saltZ iterationscontentrXzPassword provided is invalidencrypted_content_infoZcontent_encryption_algorithmencrypted_contentz[ Public-key-based PKCS12 files are not currently supported rrcsg|]}|kr|qSr7r7).0fcertsrLr7r8 |sz!_parse_pkcs12..cSs|jjS)N)subjectZhuman_friendly)cr7r7r8ruz_parse_pkcs12..)rZ)rTr rgrr"rrlrOrPauthenticated_safergetattrrVhmacnewcontentsrXrr_parse_safe_contentsr rxrkeyssortedlistrvalues)rmryrY private_keyspfxrrrZmac_algo key_lengthZmac_keyZhash_modZ computed_hmacZ stored_hmacZ content_inforrrzrZdecrypted_contentZkey_fingerprintsZcert_fingerprintsZcommon_fingerprintsrZcertZ other_certsZ first_keyr7rr8 _parse_pkcs12s              rc Cst|trt|}|D]}|d}t|trh|djdkr|dj}|dd}|dj|t|d<qt|tr||t||<qt|t r|d} |d j} t | | |} t| } | |t| |<qt|trt |||||qqdS) a& Parses a SafeContents PKCS#12 ANS.1 structure and extracts certs and keys :param safe_contents: A byte string of ber-encoded SafeContents, or a asn1crypto.pkcs12.SafeContents parsed object :param certs: A dict to store certificates in :param keys: A dict to store keys in :param password: A byte string of the password to any encrypted data :param load_private_key: A callable that will accept a byte string and return an oscrypto.asymmetric.PrivateKey object bag_valueZcert_idx509Z cert_valuererfNrvrw) rTr rrlrrOr2rIrr rxr) Z safe_contentsrrryrYZsafe_bagrrZpublic_key_inforzZencrypted_key_bytesZdecrypted_key_bytesr%r7r7r8rs(           rcCst|j}|jdkrV|jdkr*ttdt|j||j|j|j }|j }||||}n|jdkrt |j||j|j|j d}|dd}|dd}||||}nb|jdkrt |j||j|j|j d }|jd kr|||}n&t |j||j|j|j d }||||}|S) al Decrypts encrypted ASN.1 data :param encryption_algorithm_info: An instance of asn1crypto.pkcs5.Pkcs5EncryptionAlgorithm :param encrypted_content: A byte string of the encrypted content :param password: A byte string of the encrypted content's password :return: A byte string of the decrypted plaintext rZrc5zc PBES2 encryption scheme utilizing RC5 encryption is not supported rrrrrrr\r|)rZencryption_cipherkdfrPrrZkdf_hmacZkdf_saltZkdf_iterationsrZ encryption_ivrrZencryption_block_size)rzrryrrr plaintextZderived_outputr7r7r8rxs^          rx)N)N)9 __future__rrrrrVrrhrZ_asn1rrr r r r r rrrrrrrrrrrrZ symmetricrrrrrutilr_errorsr_typesr r!r"r#rKrMrRrIrrqrsr{rjrrrrxr7r7r7r8s<D  HK)-e I: u 3[ 4__pycache__/_cipher_suites.cpython-38.pyc000064400000036663147205106110014424 0ustar00U afFG@sLddlmZmZmZmZdgZddddddd d d d d ddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;dd?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd d d d d ddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIFZdJS(K)unicode_literalsdivisionabsolute_importprint_functionCIPHER_SUITE_MAPZTLS_NULL_WITH_NULL_NULLZTLS_RSA_WITH_NULL_MD5ZTLS_RSA_WITH_NULL_SHAZTLS_RSA_EXPORT_WITH_RC4_40_MD5ZTLS_RSA_WITH_RC4_128_MD5ZTLS_RSA_WITH_RC4_128_SHAZ"TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5ZTLS_RSA_WITH_IDEA_CBC_SHAZ!TLS_RSA_EXPORT_WITH_DES40_CBC_SHAZTLS_RSA_WITH_DES_CBC_SHAZTLS_RSA_WITH_3DES_EDE_CBC_SHAZ$TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHAZTLS_DH_DSS_WITH_DES_CBC_SHAZ TLS_DH_DSS_WITH_3DES_EDE_CBC_SHAZ$TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHAZTLS_DH_RSA_WITH_DES_CBC_SHAZ TLS_DH_RSA_WITH_3DES_EDE_CBC_SHAZ%TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHAZTLS_DHE_DSS_WITH_DES_CBC_SHAZ!TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHAZ%TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHAZTLS_DHE_RSA_WITH_DES_CBC_SHAZ!TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHAZ"TLS_DH_anon_EXPORT_WITH_RC4_40_MD5ZTLS_DH_anon_WITH_RC4_128_MD5Z%TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHAZTLS_DH_anon_WITH_DES_CBC_SHAZ!TLS_DH_anon_WITH_3DES_EDE_CBC_SHAZTLS_KRB5_WITH_DES_CBC_SHAZTLS_KRB5_WITH_3DES_EDE_CBC_SHAZTLS_KRB5_WITH_RC4_128_SHAZTLS_KRB5_WITH_IDEA_CBC_SHAZTLS_KRB5_WITH_DES_CBC_MD5ZTLS_KRB5_WITH_3DES_EDE_CBC_MD5ZTLS_KRB5_WITH_RC4_128_MD5ZTLS_KRB5_WITH_IDEA_CBC_MD5Z#TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHAZ#TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHAZTLS_KRB5_EXPORT_WITH_RC4_40_SHAZ#TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5Z#TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5ZTLS_KRB5_EXPORT_WITH_RC4_40_MD5ZTLS_PSK_WITH_NULL_SHAZTLS_DHE_PSK_WITH_NULL_SHAZTLS_RSA_PSK_WITH_NULL_SHAZTLS_RSA_WITH_AES_128_CBC_SHAZTLS_DH_DSS_WITH_AES_128_CBC_SHAZTLS_DH_RSA_WITH_AES_128_CBC_SHAZ TLS_DHE_DSS_WITH_AES_128_CBC_SHAZ TLS_DHE_RSA_WITH_AES_128_CBC_SHAZ TLS_DH_anon_WITH_AES_128_CBC_SHAZTLS_RSA_WITH_AES_256_CBC_SHAZTLS_DH_DSS_WITH_AES_256_CBC_SHAZTLS_DH_RSA_WITH_AES_256_CBC_SHAZ TLS_DHE_DSS_WITH_AES_256_CBC_SHAZ TLS_DHE_RSA_WITH_AES_256_CBC_SHAZ TLS_DH_anon_WITH_AES_256_CBC_SHAZTLS_RSA_WITH_NULL_SHA256ZTLS_RSA_WITH_AES_128_CBC_SHA256ZTLS_RSA_WITH_AES_256_CBC_SHA256Z"TLS_DH_DSS_WITH_AES_128_CBC_SHA256Z"TLS_DH_RSA_WITH_AES_128_CBC_SHA256Z#TLS_DHE_DSS_WITH_AES_128_CBC_SHA256Z!TLS_RSA_WITH_CAMELLIA_128_CBC_SHAZ$TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHAZ$TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHAZ%TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHAZ%TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHAZ%TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHAZ#TLS_DHE_RSA_WITH_AES_128_CBC_SHA256Z"TLS_DH_DSS_WITH_AES_256_CBC_SHA256Z"TLS_DH_RSA_WITH_AES_256_CBC_SHA256Z#TLS_DHE_DSS_WITH_AES_256_CBC_SHA256Z#TLS_DHE_RSA_WITH_AES_256_CBC_SHA256Z#TLS_DH_anon_WITH_AES_128_CBC_SHA256Z#TLS_DH_anon_WITH_AES_256_CBC_SHA256Z!TLS_RSA_WITH_CAMELLIA_256_CBC_SHAZ$TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHAZ$TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHAZ%TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHAZ%TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHAZ%TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHAZTLS_PSK_WITH_RC4_128_SHAZTLS_PSK_WITH_3DES_EDE_CBC_SHAZTLS_PSK_WITH_AES_128_CBC_SHAZTLS_PSK_WITH_AES_256_CBC_SHAZTLS_DHE_PSK_WITH_RC4_128_SHAZ!TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHAZ TLS_DHE_PSK_WITH_AES_128_CBC_SHAZ TLS_DHE_PSK_WITH_AES_256_CBC_SHAZTLS_RSA_PSK_WITH_RC4_128_SHAZ!TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHAZ TLS_RSA_PSK_WITH_AES_128_CBC_SHAZ TLS_RSA_PSK_WITH_AES_256_CBC_SHAZTLS_RSA_WITH_SEED_CBC_SHAZTLS_DH_DSS_WITH_SEED_CBC_SHAZTLS_DH_RSA_WITH_SEED_CBC_SHAZTLS_DHE_DSS_WITH_SEED_CBC_SHAZTLS_DHE_RSA_WITH_SEED_CBC_SHAZTLS_DH_anon_WITH_SEED_CBC_SHAZTLS_RSA_WITH_AES_128_GCM_SHA256ZTLS_RSA_WITH_AES_256_GCM_SHA384Z#TLS_DHE_RSA_WITH_AES_128_GCM_SHA256Z#TLS_DHE_RSA_WITH_AES_256_GCM_SHA384Z"TLS_DH_RSA_WITH_AES_128_GCM_SHA256Z"TLS_DH_RSA_WITH_AES_256_GCM_SHA384Z#TLS_DHE_DSS_WITH_AES_128_GCM_SHA256Z#TLS_DHE_DSS_WITH_AES_256_GCM_SHA384Z"TLS_DH_DSS_WITH_AES_128_GCM_SHA256Z"TLS_DH_DSS_WITH_AES_256_GCM_SHA384Z#TLS_DH_anon_WITH_AES_128_GCM_SHA256Z#TLS_DH_anon_WITH_AES_256_GCM_SHA384ZTLS_PSK_WITH_AES_128_GCM_SHA256ZTLS_PSK_WITH_AES_256_GCM_SHA384Z#TLS_DHE_PSK_WITH_AES_128_GCM_SHA256Z#TLS_DHE_PSK_WITH_AES_256_GCM_SHA384Z#TLS_RSA_PSK_WITH_AES_128_GCM_SHA256Z#TLS_RSA_PSK_WITH_AES_256_GCM_SHA384ZTLS_PSK_WITH_AES_128_CBC_SHA256ZTLS_PSK_WITH_AES_256_CBC_SHA384ZTLS_PSK_WITH_NULL_SHA256ZTLS_PSK_WITH_NULL_SHA384Z#TLS_DHE_PSK_WITH_AES_128_CBC_SHA256Z#TLS_DHE_PSK_WITH_AES_256_CBC_SHA384ZTLS_DHE_PSK_WITH_NULL_SHA256ZTLS_DHE_PSK_WITH_NULL_SHA384Z#TLS_RSA_PSK_WITH_AES_128_CBC_SHA256Z#TLS_RSA_PSK_WITH_AES_256_CBC_SHA384ZTLS_RSA_PSK_WITH_NULL_SHA256ZTLS_RSA_PSK_WITH_NULL_SHA384Z$TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256Z'TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256Z'TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256Z(TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256Z(TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256Z(TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256Z$TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256Z'TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256Z'TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256Z(TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256Z(TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256Z(TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256Z!TLS_EMPTY_RENEGOTIATION_INFO_SCSVZTLS_AES_128_GCM_SHA256ZTLS_AES_256_GCM_SHA384ZTLS_CHACHA20_POLY1305_SHA256ZTLS_AES_128_CCM_SHA256ZTLS_AES_128_CCM_8_SHA256ZTLS_ECDH_ECDSA_WITH_NULL_SHAZTLS_ECDH_ECDSA_WITH_RC4_128_SHAZ$TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHAZ#TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHAZ#TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHAZTLS_ECDHE_ECDSA_WITH_NULL_SHAZ TLS_ECDHE_ECDSA_WITH_RC4_128_SHAZ%TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHAZ$TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHAZ$TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHAZTLS_ECDH_RSA_WITH_NULL_SHAZTLS_ECDH_RSA_WITH_RC4_128_SHAZ"TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHAZ!TLS_ECDH_RSA_WITH_AES_128_CBC_SHAZ!TLS_ECDH_RSA_WITH_AES_256_CBC_SHAZTLS_ECDHE_RSA_WITH_NULL_SHAZTLS_ECDHE_RSA_WITH_RC4_128_SHAZ#TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHAZ"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHAZ"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHAZTLS_ECDH_anon_WITH_NULL_SHAZTLS_ECDH_anon_WITH_RC4_128_SHAZ#TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHAZ"TLS_ECDH_anon_WITH_AES_128_CBC_SHAZ"TLS_ECDH_anon_WITH_AES_256_CBC_SHAZ!TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHAZ%TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHAZ%TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHAZ TLS_SRP_SHA_WITH_AES_128_CBC_SHAZ$TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHAZ$TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHAZ TLS_SRP_SHA_WITH_AES_256_CBC_SHAZ$TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHAZ$TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHAZ'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256Z'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384Z&TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256Z&TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384Z%TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256Z%TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384Z$TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256Z$TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384Z'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256Z'TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384Z&TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256Z&TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384Z%TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256Z%TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384Z$TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256Z$TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384ZTLS_ECDHE_PSK_WITH_RC4_128_SHAZ#TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHAZ"TLS_ECDHE_PSK_WITH_AES_128_CBC_SHAZ"TLS_ECDHE_PSK_WITH_AES_256_CBC_SHAZ%TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256Z%TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384ZTLS_ECDHE_PSK_WITH_NULL_SHAZTLS_ECDHE_PSK_WITH_NULL_SHA256ZTLS_ECDHE_PSK_WITH_NULL_SHA384Z TLS_RSA_WITH_ARIA_128_CBC_SHA256Z TLS_RSA_WITH_ARIA_256_CBC_SHA384Z#TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256Z#TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384Z#TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256Z#TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384Z$TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256Z$TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384Z$TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256Z$TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384Z$TLS_DH_anon_WITH_ARIA_128_CBC_SHA256Z$TLS_DH_anon_WITH_ARIA_256_CBC_SHA384Z(TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256Z(TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384Z'TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256Z'TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384Z&TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256Z&TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384Z%TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256Z%TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384Z TLS_RSA_WITH_ARIA_128_GCM_SHA256Z TLS_RSA_WITH_ARIA_256_GCM_SHA384Z$TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256Z$TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384Z#TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256Z#TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384Z$TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256Z$TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384Z#TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256Z#TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384Z$TLS_DH_anon_WITH_ARIA_128_GCM_SHA256Z$TLS_DH_anon_WITH_ARIA_256_GCM_SHA384Z(TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256Z(TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384Z'TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256Z'TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384Z&TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256Z&TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384Z%TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256Z%TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384Z TLS_PSK_WITH_ARIA_128_CBC_SHA256Z TLS_PSK_WITH_ARIA_256_CBC_SHA384Z$TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256Z$TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384Z$TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256Z$TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384Z TLS_PSK_WITH_ARIA_128_GCM_SHA256Z TLS_PSK_WITH_ARIA_256_GCM_SHA384Z$TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256Z$TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384Z$TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256Z$TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384Z&TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256Z&TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384Z,TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256Z,TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384Z+TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256Z+TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384Z*TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256Z*TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384Z)TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256Z)TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384Z$TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256Z$TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384Z(TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256Z(TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384Z'TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256Z'TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384Z(TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256Z(TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384Z'TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256Z'TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384Z(TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256Z(TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384Z,TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256Z,TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384Z+TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256Z+TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384Z*TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256Z*TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384Z)TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256Z)TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384Z$TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256Z$TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384Z(TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256Z(TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384Z(TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256Z(TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384Z$TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256Z$TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384Z(TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256Z(TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384Z(TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256Z(TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384Z*TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256Z*TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384ZTLS_RSA_WITH_AES_128_CCMZTLS_RSA_WITH_AES_256_CCMZTLS_DHE_RSA_WITH_AES_128_CCMZTLS_DHE_RSA_WITH_AES_256_CCMZTLS_RSA_WITH_AES_128_CCM_8ZTLS_RSA_WITH_AES_256_CCM_8ZTLS_DHE_RSA_WITH_AES_128_CCM_8ZTLS_DHE_RSA_WITH_AES_256_CCM_8ZTLS_PSK_WITH_AES_128_CCMZTLS_PSK_WITH_AES_256_CCMZTLS_DHE_PSK_WITH_AES_128_CCMZTLS_DHE_PSK_WITH_AES_256_CCMZTLS_PSK_WITH_AES_128_CCM_8ZTLS_PSK_WITH_AES_256_CCM_8ZTLS_PSK_DHE_WITH_AES_128_CCM_8ZTLS_PSK_DHE_WITH_AES_256_CCM_8Z+TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256Z-TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256Z)TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256Z%TLS_PSK_WITH_CHACHA20_POLY1305_SHA256Z+TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256Z)TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256Z)TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256(Fssssssssss s s s s sssssssssssssssss s!s"s#s$s%s&s's(s)s*s+s,s-s.s/s0s1s2s3s4s5s6s7s8s9s:s;ss?s@sAsBsCsDsEsFsgshsisjskslsmsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss s s s s sssssssssssssssssss s!s"s#s$s%s&s's(s)s*s+s,s-s.s/s0s1s2s3s4s5s6s7s8s9s:s;ss?s@sAsBsCsDsEsFsGsHsIsJsKsLsMsNsOsPsQsRsSsTsUsVsWsXsYsZs[s\s]s^s_s`sasbscsdsesfsgshsisjskslsmsnsospsqsrssstsusvswsxsyszs{s|s}s~ssssssssssssssssssssssssssssssssssssssssssssss̨s̩s̪s̫s̬s̭s̮N) __future__rrrr__all__rr r H/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_cipher_suites.pys__pycache__/_ecdsa.cpython-38.pyc000064400000035477147205106110012637 0ustar00U af"Y@sddlmZmZmZmZddlZddlZddlZddlm Z ddl m Z m Z m Z mZmZmZmZmZmZmZddlmZddlmZmZddlmZdd lmZejd kreZ e!Z"nd d Z e Z#e#d kre$ddddddgZ%ddddZ&ddddZ'ddZ(ddZ)ddZ*ddZ+ddZ,ddZ-Gd d!d!Z.Gd"d#d#Z/e/dddZ0e.d$d%d&Z1e/e1d'd(d)Z2e.d*d%d+Z3e/e3d,d-d.Z4e.d/d%d0Z5e/e5d1d2d3Z6e.d4d%d5Z7e/e7d6d7d8Z8e.d9d%d:Z9e/e9d;d)unicode_literalsdivisionabsolute_importprint_functionN)backend) Certificate DSASignatureECDomainParametersECPointBitString ECPrivateKeyint_from_bytesPrivateKeyAlgorithmPrivateKeyInfoPublicKeyAlgorithm PublicKeyInfo)pretty_message) type_namebyte_cls) rand_bytes)SignatureError)cCs t|gS)N)bytes)numr@/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_ecdsa.pychr_clssrZ winlegacyz2Pure-python ECDSA code is only for Windows XP/2003ec_generate_pairec_compute_public_key_pointec_public_key_info ecdsa_sign ecdsa_verify 0B secp256r1 secp384r1 secp521r1cCs|tdddgkr$ttdt|t|}tttd|}t|}t |dd}|dkr<||j krrAnativer Z from_coordsxy)r6Z curve_typedetailsZ base_pointZ public_pointrrrrs8  cCsD|tdddgkr$ttdt|ttdtd|dd|d S) a Constructs the PublicKeyInfo for an ECPointBitString :param private_key: An asn1crypto.keys.ECPointBitString object :param curve: A unicode string of the curve name - one of secp256r1, secp384r1 or secp521r1 :raises: ValueError - when any of the parameters contain an invalid value :return: An asn1crypto.keys.PublicKeyInfo object r&r'r(r*r-r.r/r2)r3r7)r8r9rr:rrr )public_key_pointrBrrrrscCs2t|drt|jts(ttdt||j}|tdddgkrLt tdt|t shttdt||tdd d d d gkrt td t |t t |}|jdj}|dj}|dj}t|}tttd|} | j} ||} t| } t| dd| } d| }d| }t||d|| |}t|||}t||d|| |}t|||}d}d}d}t||krt|||}||7}qxt|d|dd}|dkst|| krАqt| |j| }|dkrqtt|| | ||| | }|dkr qtq qtt||dS)aN Generates an ECDSA signature in pure Python (thus slow) :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 "sha1", "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 asn1zy private_key must be an instance of the oscrypto.asymmetric.PrivateKey class, not %s r&r'r(zx private_key does not use one of the named curves secp256r1, secp384r1 or secp521r1 < data must be a byte string, not %s sha1sha224sha256sha384sha512z hash_algorithm must be one of "sha1", "sha224", "sha256", "sha384", "sha512", not %s r6r%Fr+r)rs)hasattrrGrNrrHrrrBr8r9rr:getattrhashlibrAcontentsrIr;r<r=r>r?digestlenr hmacnewrJ inverse_modr dump)r6datahash_algorithm curve_name hash_funcZec_private_keyrErFrCrDnr_Z hash_lengthhVKrYrZTkrrrr st         cCst|d}|rt|jttfs0ttdt||j}|t dddgkrTt tdt|t spttdt|t|t sttdt||t d d d d d gkrt tdt ||j}t|tr|j }tttd|}|d\}} |j} t|j|| | } z"t|}|dj} |dj} Wnt k r@tdYnXd}|| dkO}|| | kO}|| dkO}|| | kO}|rtdtt|}||}t|dd| }t| | }||| }| || }||| |}| |j| krtddS)a Verifies an ECDSA signature in pure Python (thus slow) :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", "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 rNz certificate_or_public_key must be an instance of the oscrypto.asymmetric.PublicKey or oscrypto.asymmetric.Certificate classes, not %s r&r'r(z certificate_or_public_key does not use one of the named curves secp256r1, secp384r1 or secp521r1 zA signature must be a byte string, not %s rOrPrQrRrSrTrUr%r7rYrZzSignature is invalidrrFr+N)r[rGrNrrrHrrrBr8r9rr:r7r<r=r>Z to_coordsr? PrimePointr loadrIrr\r]r_r rcrJ)Zcertificate_or_public_key signaturererfZhas_asn1rgrNrDrJrKrirMrYrZinvalidrhr_zwu1u2Z hash_pointrrrr!`sx                c Cs|dks||kr||}||}}d\}}}}|dkrrt|||f\}}}||||||||f\}}}}q.|dks~t|dkr|S||SdS)z Compute the modular inverse of a (mod p) :param a: An integer :param p: An integer :return: An integer r)rrrrrN)divmodAssertionError) apcdZucvcZudZvdqrrrrcs  & rcc@s eZdZdZddZddZdS) PrimeCurvezc Elliptic curve over a prime field. Characteristic two field curves are not supported. cCs||_||_||_dS)a The curve of points satisfying y^2 = x^3 + a*x + b (mod p) :param p: The prime number as an integer :param a: The component a as an integer :param b: The component b as an integer N)rzryb)selfrzryrrrr__init__-szPrimeCurve.__init__cCsB|j|j}|j|j|j}|||j|j|j|jdkS)z~ :param point: A Point object :return: Boolean if the point is on this curve r)rKrJryrrz)rZpointy2x3rrrcontains?s zPrimeCurve.containsN)__name__ __module__ __qualname____doc__rrrrrrr'src@sBeZdZdZdddZddZddZd d Zd d Zd dZ dS)roz1 A point on a prime-field elliptic curve NcCsR||_||_||_||_|jr2|j|s2td|jrN||jtkrNtddS)a) :param curve: A PrimeCurve object :param x: The x coordinate of the point as an integer :param y: The y coordinate of the point as an integer :param order: The order of the point, as an integer - optional zInvalid EC pointN)rBrJrKr?rr9INFINITY)rrBrJrKr?rrrrRs zPrimePoint.__init__cCs0|j|jkr(|j|jkr(|j|jkr(dSdSdS)zy :param other: A PrimePoint object :return: 0 if identical, 1 otherwise rrN)rBrJrKrotherrrr__cmp__os$zPrimePoint.__cmp__cCs|tkr |S|tkr|S|j|jks(t|j|jkrX|j|j|jjdkrPtS|S|jj}|j|jt|j|j||}|||j|j|}||j||j|}t|j||S)zq :param other: A PrimePoint object :return: A PrimePoint object r) rrBrxrJrKrzdoublercro)rrrzl_ry3rrr__add__|s  "zPrimePoint.__add__cCsdd}|}|jr||j}|dkr(tS|tkr4tS|dks@td|}t|j|j|j |j}||d}|}|dkr|}||@dkr||@dkr||}||@dkr||@dkr||}|d}qp|S) :param other: An integer to multiple the Point by :return: A PrimePoint object cSs*|dks td}||kr"d|}q|dS)Nrr)rx)rJresultrrr leftmost_bits   z(PrimePoint.__mul__..leftmost_bitrrrr)r?rrxrorBrJrKr)rrreZe3Z negative_selfirrrr__mul__s*     zPrimePoint.__mul__cCs||S)rrrrrr__rmul__s zPrimePoint.__rmul__cCst|jj}|jj}d|j|j|td|j||}||d|j|}||j||j|}t|j||S)zS :return: A PrimePoint object that is twice this point rr)rBrzryrJrcrKro)rrzryrrrrrrrs (zPrimePoint.double)N) rrrrrrrrrrrrrrroMs  + rol l 9{uDjSg9g(Bl +'1t:_|v!a:@ml H<^W]dZ{cxW\Iql 1(i&^#a;l?lF eY8 w-X"PVd/%PP!-l!"X!#BXtJ9!'|%VA-l4~ f&Dv@h!fE0m9_ qlM/l=*8%(?l?@lK`Opq^cv 3,e< 1U]>{|R*ZlB11e %:f=K`wrH7gHK8hklQ~o]l+fUg+<)Z?8O?q!OlQ%x +Ohbi+}s@l~l*'#.TEbc+Z'@=D 1 "(?7N2Z_+|S/1fl dxRjoyU8T( :ss"nZL8k&"_Ul_!uR/sX0 @qaNQNB&JxS8KJEY K%lls)e`gwl X_[nlv|l#l#?VQ(zO%b95~cte1oR{V;LH w>l-rZE]"Sr&Ga9}*Fl#f=xK)H-apY$3^Q n%k{;/K!u{4-{?$Od8V1l3s: l#Pf?QE$XN!85aZU WL9YLhz f$Du13otc!% pMxjRr`l# dp"z\}[z3"nZ;PK# `7roCQ); __future__rrrrr]rasysrZ_asn1rr r r r r rrrr_errorsr_typesrrutilrerrorsr version_infochrrxrangerangeZ_backend SystemError__all__r;ZCURVE_EXTRA_BITSrrrr r!rcrrorZSECP192R1_CURVEZSECP192R1_BASE_POINTZSECP224R1_CURVEZSECP224R1_BASE_POINTZSECP256R1_CURVEr<ZSECP384R1_CURVEr=ZSECP521R1_CURVEr>rrrrs 0     <;%%#&     __pycache__/_errors.cpython-38.pyc000064400000002052147205106110013053 0ustar00U af@s>dZddlmZmZmZmZddlZddlZdgZddZ dS)z] Helper for formatting exception messages. Exports the following items: - pretty_message() )unicode_literalsdivisionabsolute_importprint_functionNpretty_messagecGs>t|}|ddkr&tdd|}|r2||}|}|S)a_ Takes a multi-line string and does the following: - dedents - converts newlines with text before and after into a single line - strips leading and trailing whitespace :param string: The string to format :param *params: Params to interpolate into the string :return: The formatted string  z(?<=\S) (?=[^ \d\*\-=]) )textwrapdedentfindresubstrip)stringparamsoutputrA/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_errors.pyrs ) __doc__ __future__rrrrr r __all__rrrrrs __pycache__/_ffi.cpython-38.pyc000064400000026066147205106110012316 0ustar00U afF/@s`dZddlmZmZmZmZddlZddlZddlm Z ddl m Z ddl m Z mZmZmZdd d d d d ddddddddddddddddddd d!d"gZe d#krdd$lmZiZeZ d%dZd&d'Zd(d Zd)d Zdfd*d"Zd+d Zd,dZd-dZdgd.dZd/dZd0d Zd1dZ d2d Z!d3dZ"d4dZ#d5dZ$dhd6dZ%did7dZ&d8dZ'd9dZ(d:d!Z)d;dZ*ddZ-d?dZ.d#Z/nddl0Z0dd@l0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6ee3e07e0j8fZ9dAdAdAdAdBZ:e5e6e3e07e3e2e4e0j;e0jZ>e:?dAdAdAdAdFe=?e0j8e3e6e3e6e>j@e>jAe07e0j8e07e07e0j8dG dHdIZBdJdZdKd ZdLd ZdjdMd"ZdNd ZdOdZdPdZdkdQdZdRdZdSd ZdTdZ dUd Z!dVdZ"dWdZ#dXdZ$dldYdZ%dmdZdZ&d[dZ'd\dZ(d]d!Z)d^dZ*d_dZ+d`d Z,dadZ-dbdZ.dcZ/dddZCGdeddeDZEdS)nzK Exceptions and compatibility shims for consistently using ctypes and cffi )unicode_literalsdivisionabsolute_importprint_functionN) find_library)ffi)str_clsbyte_cls int_types bytes_to_listarray_from_pointer array_setbuffer_from_bytesbuffer_from_unicodebuffer_pointer byte_arraybyte_string_from_bufferbytes_from_buffercallbackcastdereferrnoFFIEngineError get_libraryis_nullnativenewnull pointer_setref register_ffisizeofstruct struct_bytesstruct_from_bufferunwrapwrite_to_buffercffi)FFIcCs |t|<dSN) _ffi_registrylibraryffi_objr/>/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_ffi.pyr!8scCs|tkrt|StSr*)r+r)r-r/r/r0_get_ffi;sr1cCs"tjdkrtd|Std|S)Nwin32zunsigned char[]zchar[])sysplatformrr initializerr/r/r0r@s  cCs td|S)Nz wchar_t []rrr5r/r/r0rEscCs||||t|<dSr*)lenbufferdataoffsetr/r/r0r'HscCstd|gS)Nzchar *[]r7r:r/r/r0rKscCst|}|||Sr*)r1r)r-type_valuer.r/r/r0rNscCst|}||Sr*)r1r")r-r?r.r/r/r0r"RscCs.|dk rt||ddSt|ddSr*rr:r:maxlenr/r/r0rVscCs t|Sr*)rstringr=r/r/r0r[scCs|Sr*r/Z byte_stringr/r/r0r^scCs ||d<dSNrr/Zpointer_r?r/r/r0rascCst|D]\}}|||<qdSr* enumeratearrayr?indexvalr/r/r0rdscCstjSr*)rNULLr/r/r/r0rhscCsH|dkr dS|tjkrdStt|dkr2dS|dtjkrDdSdS)NTvoid *Fr)rrMZgetctypeZtypeofpointr/r/r0rks cCstjSr*)rrr/r/r/r0rvscCsJt|}g}|dk r|||tddgkr:||dS|j|f|S)NZBCRYPT_KEY_HANDLEZBCRYPT_ALG_HANDLEr)r1appendsetrr)r-r>r?r.paramsr/r/r0rys  cCs||Sr*r/r?r<r/r/r0r scCs4|tkrt|S|tkr,t|ddS||Sr*)r rrCr r:r>r?r/r/r0rs  cCs|dSrEr/rOr/r/r0rscCs|dSrEr/rOr/r/r0r&scCst|}|d|S)N%s *)r1r)r-namer.r/r/r0r#scCst|ddSr*r@Zstruct_r/r/r0r$scCsRt|}|d|}|d}t||}||}|||dd|dd<|S)NrVr)r1rr"r:)r-rWr:r.Znew_struct_pointerZ new_structZ struct_sizeZ struct_bufferr/r/r0r%s  c Cst|}|d||f|}||}|dkr2gSg}ddddddd}||k} td|D]$} || } | rt|| } || qZ|S)Nz%s[%s]rT)LPSTRLPCSTRLPWSTRLPCWSTRchar * wchar_t *)r1rr"rangerCrQ) r-rWrPsizer.rJ total_bytesoutput string_typesZ string_typeir?r/r/r0r s(   cCst|}|||Sr*)r1r)r-Zsignature_namefuncr.r/r/r0rs)pointerc_intc_char_pc_uintc_void_p c_wchar_pT)rNr^r]char **)rNr^r]rlintz unsigned intZsize_tZuint32_tr2)wintypes)rYr[rZr\) ZBYTErYr[rZr\ULONGDWORDr]rlcCs|dddk}|r |dd}|dddko6|tk}|rH|dd}|ddk}|r||dd|d}|d krd }nt|}|d |d}|tkrt|}n t||}|rt|}|||fS) Nz **z *[r]Tr)_pointer_typesfindrm _type_mapgetattrctypesPOINTER)r-r>Zis_double_pointer is_pointeris_arrayr/r/r0 _type_infos&     rcCsdSr*r/r,r/r/r0r!scCs t|Sr*)r{create_string_bufferr5r/r/r0r scCs t|Sr*)r{create_unicode_bufferr5r/r/r0rscCsPt|ttjr(t||t|dS|dkr8||_n|jd|||_dSrE) isinstancer{r|c_bytememmover8r?rawr9r/r/r0r's cCstt|tSr*)rfr{rrhr=r/r/r0rscCs8t||\}}}|r t|}n |r,||}t||Sr*)rr{r|r)r-r>r?r}r~r/r/r0rs  cCs t|Sr*)r{r")r-r?r/r/r0r"(scCs2t|trt||S|dk r,|jd|S|jSrE)r_pointer_int_typesr{ string_atrrAr/r/r0r+s   cCs|jSr*)r?r=r/r/r0r2scCstjt|t|Sr*)r{rr8r rDr/r/r0r5scCs ||j_dSr*)contentsr?rFr/r/r0r8scCst|D]\}}|||<qdSr*rGrIr/r/r0r;scCsdSr*r/r/r/r/r0r?scCs t| Sr*)boolrOr/r/r0rBscCstSr*)r{ get_errnor/r/r/r0rEscCs`t||\}}}|r2|dkr*||}d}n||}g}|dk rH||||}|r\t|}|S)NT)rrQrf)r-r>r?r}r~rSrbr/r/r0rHs cCs0|dkrt|Stt||ttjSrE)r{byrefr addressofr|rrTr/r/r0r [s cCsdt||r|Stjdkr.|tkr.t|tr.|St|tjrZ|jtjkrZt t ||j S||j S)N)) rr3 version_informr r{Array_type_rrr_length_r?rUr/r/r0r`s cCs|dSrEr/rOr/r/r0riscCs|jSr*)rrOr/r/r0r&lscCstt||Sr*)rfrz)r-rWr/r/r0r#oscCst|t|jSr*)r{rr"rrXr/r/r0r$rscCs4t||}|}tt||t|t|Sr*)rzr{rrr"rf)r-r>r:class_r?r/r/r0r%us cCsHt||\}}}t|t|}g}td|D]}|||q0|SrE)rr{rr|r_rQ)r-r>rPr`_rJrbrdr/r/r0r {s cCst|||Sr*)rz)r-Zsignature_typerer/r/r0rsr{cCspt|}tjdkrld|}|dd|}ttttdd}|sX|dkrX|}n|dkrl||krl|}|S) a Retrieve the C library path with special handling for Mac :param name: A unicode string of the library to search the system for :param dylib_name: Mac only - a unicode string of the unversioned dylib name :param version: Mac only - a unicode string of the dylib version to use. Used on macOS 10.15+ when the unversioned dylib is found, since unversioned OpenSSL/LibreSSL are just placeholders, and a versioned dylib must be imported. Used on macOS 10.16+ when find_library() doesn't return a result, due to system dylibs not being present on the filesystem any longer. :return: A unicode string of the path to the library darwinz /usr/lib/%sz.dylibz .%s.dylibr.) )r) rr3r4replacetuplemaprmmac_versplit)rWZ dylib_nameversionr-Z unversionedZ versionedrr/r/r0rs  c@seZdZdZdS)rz@ An exception when trying to instantiate ctypes or cffi N)__name__ __module__ __qualname____doc__r/r/r/r0rs)r)N)N)r)r)N)N)r)Fr __future__rrrrr3r4 ctypes.utilrrvr_typesr r r r __all__r(r)r+r!r1rrr'rrr"rrrrrrrrrr rrr&r#r$r%r rZenginer{rfrgrhrirjrkr|rrrwc_size_tc_uint32ryrnupdaterorprr Exceptionrr/r/r/r0s                    &__pycache__/_int.cpython-38.pyc000064400000001535147205106110012336 0ustar00U af@s.dZddlmZmZmZmZdgZddZdS)z Function to fill ensure integers converted to a byte string are a specific width. Exports the following items: - fill_width() )unicode_literalsdivisionabsolute_importprint_function fill_widthcCst||krd|}q|S)a  Ensure a byte string representing a positive integer is a specific width (in bytes) :param bytes_: The integer byte string :param width: The desired width as an integer :return: A byte string of the width specified )len)bytes_widthr >/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_int.pyrs  N)__doc__ __future__rrrr__all__rr r r r s__pycache__/_pkcs1.cpython-38.pyc000064400000033662147205106110012573 0ustar00U af]O@s<ddlmZmZmZmZddlZddlZddlZddlZddl Z ddl Z ddl m Z ddl mZmZddlmZmZmZmZmZddlmZddlmZdd lmZmZmZejd kreZ e!Z"nd d Z e Z#d ddddddgZ$ddZ%dd Z&ddZ'ddZ(ddZ)ddZ*ddZ+ddZ,dd Z-d!dZ.d"dZ/dS)#)unicode_literalsdivisionabsolute_importprint_functionN)backend)constant_compare rand_bytes) Certificateint_from_bytes int_to_bytesPrivateKeyInfo PublicKeyInfo)pretty_message) fill_width) type_namebyte_cls int_types)cCs t|gS)N)bytes)numr@/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_pkcs1.pychr_clssradd_pss_paddingadd_pkcs1v15_signature_paddingraw_rsa_private_cryptraw_rsa_public_crypt"remove_pkcs1v15_encryption_padding!remove_pkcs1v15_signature_paddingverify_pss_paddingcCs:tjdkrdStd}ttt|ddddkS)zM :return: A bool if the current machine is running OS X 10.7 darwinFr.) )sysplatformmac_vertuplemapintsplit)versionrrr _is_osx_107/s  r.cCstdkrtjdkrttdt|ts:ttdt|t|t sVttdt||dkrpt tdt |t|t sttdt||d krt td t ||t d d d ddgkrt tdt |t t|}|d}tt|d}||}t|}|||dkr$t td|dkr:t|} nd} d|| } || } d|||d} | d| } t|| ||d}tt| t|A}t|t|}d||}d|dd|}t|d}|dkrt|t|dd@|dd}|| dS)a5 Pads a byte string using the EMSA-PSS-Encode operation described in PKCS#1 v2.2. :param hash_algorithm: The string name of the hash algorithm to use: "sha1", "sha224", "sha256", "sha384", "sha512" :param salt_length: The length of the salt as an integer - typically the same as the length of the output from the hash_algorithm :param key_length: The length of the RSA key, in bits :param message: A byte string of the message to pad :return: The encoded (passed) message winlegacyr!z~ Pure-python RSA PSS signature padding addition code is only for Windows XP/2003 and OS X ? message must be a byte string, not %s @ salt_length must be an integer, not %s r? salt_length must be 0 or more - is %s ? key_length must be an integer, not %s iz@ key_length must be 512 or more - is %s sha1sha224sha256sha384sha512z hash_algorithm must be one of "sha1", "sha224", "sha256", "sha384", "sha512", not %s rr#zq Key is not long enough to use with specified hash_algorithm and salt_length 01N)_backendr&r' SystemErrorr isinstancer TypeErrorrr ValueErrorreprsetgetattrhashlibr+mathceildigestlenosurandom_mgf1r r rrord)hash_algorithm salt_length key_lengthmessage hash_funcem_bitsem_lenmessage_digest hash_lengthsaltm_primem_prime_digestpaddingdbdb_mask masked_db zero_bits left_bit_mask left_int_maskrrrr;sv             $cCstdkrtjdkrttdt|ts:ttdt|t|tsVttdt|t|t srttdt||dkrt tdt ||t d d d d d gkrt tdt |t t|}|d}tt|d}||}t|} || |dkrdS|dddkrdSd||} || d} |d| } t| dd} | d| ?}|dkrfdS|| | | }t|||| d}d| dd| }t|d}|dkrt|t|dd@|dd}tt| t|A}t|t| krdt| t||}|| |d}d|}t|d||sDdS|||ddkr^dS|d|d}d||}||}t||S)aZ Verifies the PSS padding on an encoded message :param hash_algorithm: The string name of the hash algorithm to use: "sha1", "sha224", "sha256", "sha384", "sha512" :param salt_length: The length of the salt as an integer - typically the same as the length of the output from the hash_algorithm :param key_length: The length of the RSA key, in bits :param message: A byte string of the message to pad :param signature: The signature to verify :return: A boolean indicating if the signature is invalid r/r!z Pure-python RSA PSS signature padding verification code is only for Windows XP/2003 and OS X r0zA signature must be a byte string, not %s r1rr2r4r5r6r7r8r9rr:r#FNrBr?r@rAr=r>r<)rCr&r'rDrrErrFrrrGrHrIrJrKr+rLrMrNrOrSrRrr r r)rTrUrVrW signaturerXrYrZr[r\rdZmasked_db_lengthrcZ first_byteZbits_that_should_be_zeror_rbrerfraZ zero_lengthZ zero_stringr]r^Zh_primerrrr s            $  c Cst|tsttdt|t|ts8ttdt||dkrRttdt||tddddd gkrzttd t|d }d d dddd|}t t ||}t dj}tt|}td|D] }||} |||| 7}q|d|S)a| The PKCS#1 MGF1 mask generation algorithm :param hash_algorithm: The string name of the hash algorithm to use: "sha1", "sha224", "sha256", "sha384", "sha512" :param seed: A byte string to use as the seed for the mask :param mask_length: The desired mask length, as an integer :return: A byte string of the mask z< seed must be a byte string, not %s z@ mask_length must be an integer, not %s rzD mask_length must be greater than 0 - is %s r4r5r6r7r8r9r; 0@)r4r5r6r7r8s>Ir)rErrFrrrrGrHrIr+rLrMstructStructpackrJrKrangerN) rTseedZ mask_lengthoutputr\Z iterationsrprXcounterbrrrrR:sH    rRcCs tdkrttdt||dS)z Adds PKCS#1 v1.5 padding to a message to be signed :param key_length: An integer of the number of bytes in the key :param data: A byte string to pad :return: The padded data as a byte string r/zz Pure-python RSA PKCSv1.5 signature padding addition code is only for Windows XP/2003 Zsigning)rCrDr_add_pkcs1v15_paddingrVdatarrrrs cCs tdkrttdt||dS)a Removes PKCS#1 v1.5 padding from a signed message using constant time operations :param key_length: An integer of the number of bytes in the key :param data: A byte string to unpad :return: The unpadded data as a byte string r/zy Pure-python RSA PKCSv1.5 signature padding removal code is only for Windows XP/2003 Z verifying)rCrDr_remove_pkcs1v15_paddingrwrrrrs cCststtdt||dS)a Removes PKCS#1 v1.5 padding from a decrypted message using constant time operations :param key_length: An integer of the number of bytes in the key :param data: A byte string to unpad :return: The unpadded data as a byte string zt Pure-python RSA PKCSv1.5 encryption padding removal code is only for OS X 10.7 decrypting)r.rDrryrwrrrrs cCs|dkrd}nd}t|ts.ttdt|t|tsJttdt||dkrdttdt|t||dkrttd |dt||d t|}d }|d krt |}d | d }||7}|t|8}qd ||d |S)a1 Adds PKCS#1 v1.5 padding to a message :param key_length: An integer of the number of bytes in the key :param data: A byte string to unpad :param operation: A unicode string of "encrypting" or "signing" :return: The padded data as a byte string Z encryptingr>< data must be a byte string, not %s r3rm? key_length must be 64 or more - is %s zJ data must be between 1 and %s bytes long - is %s rr;rr=) rErrFrrrrGrHrOr joinr,)rVrx operation second_byteZrequired_bytesr`Z temp_paddingrrrrvs@  rvc Csn|dkrd}nd}t|ts.ttdt|t|tsJttdt||dkrdttdt|t||kr|td|d }d }d }t d t|D]}|||d}t |} |d kr|| O}q|dkr|t | |B|kO}q|d kr|t | d Ad kO}q| d B} |d kr.| r$||O}n||O}q| r>||O}q||O}q|d kr^td|||dd S) aY Removes PKCS#1 v1.5 padding from a message using constant time operations :param key_length: An integer of the number of bytes in the key :param data: A byte string to unpad :param operation: A unicode string of "decrypting" or "verifying" :return: The unpadded data as a byte string rzr#rr|r3rmr}zError %srr$N) rErrFrrrrGrHrOrqrSr+) rVrxrrerrorZtrashZ padding_endibyteZbyte_numZnon_zerorrrrysV             rycCstdkrtdt|dr&t|jts8ttdt||jddj }|dkrj|dkrjt td | t|t sttd t||jd j }tt||d j |d j }t||jjdS)aa Performs a raw RSA algorithm in a byte string using a private key. This is a low-level primitive and is prone to disastrous results if used incorrectly. :param private_key: An oscrypto.asymmetric.PrivateKey object :param data: A byte string of the plaintext to be signed or ciphertext to be decrypted. Must be less than or equal to the length of the private key. In the case of signing, padding must already be applied. In the case of decryption, padding must be removed afterward. :return: A byte string of the transformed data r/1Pure-python RSA crypt is only for Windows XP/2003asn1zy private_key must be an instance of the oscrypto.asymmetric.PrivateKey class, not %s Zprivate_key_algorithm algorithmrsa rsassa_pssz@ private_key must be an RSA key, not %s r| private_keyZprivate_exponentmoduluswidth)rCrDhasattrrErr rFrrnativerGupperrparsedpowr r byte_size)rrxalgoZrsa_private_keytransformed_intrrrrns2  cCstdkrtdt|d}ttf}|r2t|j|sDttdt ||jddj }|dkrv|dkrvt td| t|t sttd t ||jd j}tt||d j |d j }t||jjd S)a Performs a raw RSA algorithm in a byte string using a certificate or public key. This is a low-level primitive and is prone to disastrous results if used incorrectly. :param certificate_or_public_key: An oscrypto.asymmetric.PublicKey or oscrypto.asymmetric.Certificate object :param data: A byte string of the signature when verifying, or padded plaintext when encrypting. Must be less than or equal to the length of the public key. When verifying, padding will need to be removed afterwards. When encrypting, padding must be applied before. :return: A byte string of the transformed data r/rrz certificate_or_public_key must be an instance of the oscrypto.asymmetric.PublicKey or oscrypto.asymmetric.Certificate classes, not %s rrrzN certificate_or_public_key must be an RSA key, not %s r|Z public_keyZpublic_exponentrr)rCrDrrr rErrFrrrrGrrrrr r r)Zcertificate_or_public_keyrxZhas_asn1Z valid_typesrZrsa_public_keyrrrrrs<    )0 __future__rrrrr&rKrLr'rnrPrutilrr Z_asn1r r r r r_errorsr_intr_typesrrr version_infochrrxrangerqrC__all__r.rr rRrrrrvryrrrrrrsJ      ~IC[9__pycache__/_pkcs12.cpython-38.pyc000064400000007072147205106110012651 0ustar00U af @sddlmZmZmZmZddlZddlZddlZddlm Z m Z ddl m Z ddl mZmZmZejdkrpeZndd Zd gZd d ZdS) )unicode_literalsdivisionabsolute_importprint_functionN)int_from_bytes int_to_bytes)pretty_message) type_namebyte_cls int_types)cCs t|gS)N)bytes)numrA/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_pkcs12.pychr_clssr pkcs12_kdfcCslt|tsttdt|t|ts8ttdt|t|tsTttdt||dkrnttdt|t|tsttdt||dkrttdt||tdd d d d d gkrttdt||tdddgkrttdt|| d dd}t t |}ddddddd|}|dkr6d} nd} t || } d} |dkr| tttt|| } t| | kr| |7} qr| d| } d} |dkr| tttt|| }t| |kr| |7} q| d|} | | }ttt||}d ||}td|dD]:}|| |}td|dD]}||}qF||krd}t|| kr||7}qht|d| d}tdt|| D]t}|| }|d| }|||}tt||}t|}|| kr||| d!}|d||||d!}q|d|}t||}|d||d||||d!}q"|d|S)"a 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 :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 rzC 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 md5sha1sha224sha256sha384sha512z hash_algorithm must be one of "md5", "sha1", "sha224", "sha256", "sha384", "sha512", not %s r z< id_ must be one of 1, 2, 3, not %s zutf-8zutf-16bes 0@)rrrrrr)rrrN) isinstancer TypeErrorr r r ValueErrorreprsetdecodeencodegetattrhashlibrintmathceilfloatlenrangedigestrrmin)Zhash_algorithmpasswordZsaltZ iterationsZ key_lengthZid_Zutf16_passwordalgouvdsZs_lenpZp_lenicarZa2_bZnum2startendZi_num2Zi_num2_lbeginZto_copyrrrrs                      ,) __future__rrrrsysr,r.Z_asn1rr_errorsr _typesr r r version_infochrr__all__rrrrrs  __pycache__/_pkcs5.cpython-38.pyc000064400000005466147205106110012600 0ustar00U afU @sddlmZmZmZmZddlZddlZddlZddlZddl m Z m Z ddl m Z ddlmZmZmZejdkrxeZndd Zd gZd d Zd e_dS) )unicode_literalsdivisionabsolute_importprint_functionN)int_from_bytes int_to_bytes)pretty_message) type_namebyte_cls int_types)cCs t|gS)N)bytes)numr@/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_pkcs5.pychr_clssrpbkdf2cCst|tsttdt|t|ts8ttdt|t|tsTttdt||dkrnttdt|t|tsttdt||dkrttdt||tdd d d d d gkrttdt|t t |}ddddddd|}t |d|}d}d} t | |kr|} | |td|| } t| } t|dD],} |} | | | } | t| N} qL| t| |d7} |d7}q| d|S)a4 Implements PBKDF2 from PKCS#5 v2.2 in pure Python :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 :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 rzC 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 md5sha1sha224sha256sha384sha512z hash_algorithm must be one of "md5", "sha1", "sha224", "sha256", "sha384", "sha512", not %s  0@)rrrrrrNs>I)widthr) isinstancer TypeErrorr r r ValueErrorreprsetgetattrhashlibhmacnewlencopyupdatestructpackdigestrranger)Zhash_algorithmpasswordZsaltZ iterationsZ key_lengthalgoZ hash_lengthZ original_hmacblockoutputZprflastu_rrrrsz        T) __future__rrrrsysr(r)r.Z_asn1rr_errorsr _typesr r r version_infochrr__all__rZ pure_pythonrrrrs  t__pycache__/_rand.cpython-38.pyc000064400000002257147205106110012472 0ustar00U af@sNddlmZmZmZmZddlZddlmZddlm Z m Z dgZ ddZ dS))unicode_literalsdivisionabsolute_importprint_functionN)pretty_message) type_name int_types rand_bytescCsFt|tsttdt||dkr,td|dkrs  __pycache__/_tls.cpython-38.pyc000064400000033164147205106110012351 0ustar00U afE@sFddlmZmZmZmZddlZddlmZddlmZm Z m Z ddl m Z ddl mZmZmZdd d d d d dddddddddddddgZdd ZddZdd Zdd Zdd Zd dZd!d Zd"d#Zd$dZd%dZd&dZd'dZd(dZd)dZd*dZ d+d,Z!d-dZ"d.dZ#d/dZ$d0dZ%d1d2Z&d3dZ'd4d5Z(dS)6)unicode_literalsdivisionabsolute_importprint_functionN)datetime) Certificateint_from_bytestimezone)CIPHER_SUITE_MAP)TLSVerificationErrorTLSDisconnectErrorTLSErrordetect_client_auth_request extract_chainget_dh_params_length parse_alertparse_handshake_messagesparse_session_infoparse_tls_recordsraise_client_authraise_dh_paramsraise_disconnectionraise_expired_not_yet_validraise_handshakeraise_hostnameraise_no_issuerraise_protocol_error raise_revokedraise_self_signedraise_verificationraise_weak_signaturec Csg}d}t|D]>\}}}|dkr$qt|D]\}}|dkr,|}qFq,|rqPq|rd}|t|krt|||d} |d} | | } | }|| | } |t| qX|S)a Extracts the X.509 certificates from the server handshake bytes for use when debugging :param server_handshake_bytes: A byte string of the handshake data received from the server :return: A list of asn1crypto.x509.Certificate objects N )rrlenr appendrload) server_handshake_bytesoutputZ chain_bytes record_type_ record_data message_type message_datapointerZ cert_lengthZ cert_startZcert_endZ cert_bytesr0>/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_tls.pyr#s*   cCsDt|D]6\}}}|dkrqt|D]\}}|dkr$dSq$qdS)a) Determines if a CertificateRequest message is sent from the server asking the client for a certificate :param server_handshake_bytes: A byte string of the handshake data received from the server :return: A boolean - if a client certificate request was found r" TF)rr)r(r*r+r,r-r.r0r0r1rKs  cCsld}d}t|D]>\}}}|dkr$qt|D]\}}|dkr,|}qFq,|rqPq|rht|ddd}|S)a Determines the length of the DH params from the ServerKeyExchange :param server_handshake_bytes: A byte string of the handshake data received from the server :return: None or an integer of the bit size of the DH parameters Nr" r)rrr )r(r)Zdh_params_bytesr*r+r,r-r.r0r0r1r`s cCsVt|D]H\}}}|dkrqt|dkr.dSt|ddt|ddfSdS)aV Parses the handshake for protocol alerts :param server_handshake_bytes: A byte string of the handshake data received from the server :return: None or an 2-element tuple of integers: 0: 1 (warning) or 2 (fatal) 1: The alert description (see https://tools.ietf.org/html/rfc5246#section-7.2) r4Nrr)rr%r )r(r*r+r,r0r0r1rs  $cCsVd}d}d}d}d}d}d}t|D]\} } } | dkr8q$t| D]\} } | dkrRq@ddddd d | d d }t| d d}|d kr| dd|}d|}| ||d }t|}|d }| ||ddk}|d}| |d}t|D]\}}|dkrd}q qq$q@q$t|D]\} } } | dkr2qt| D]\} } | dkrPq:t| d d}|d krz| dd|}d|}t| ||d }|d |}t| ||d}|dkr |dkr |d|}| |d}t|D]\}}|dkrd}q qqq:q|dk rF|dkr2d}n||krBd}nd}|||||dS)a Parse the TLS handshake from the client to the server to extract information including the cipher suite selected, if compression is enabled, the session id and if a new or reused session ticket exists. :param server_handshake_bytes: A byte string of the handshake data received from the server :param client_handshake_bytes: A byte string of the handshake data sent to the server :return: A dict with the following keys: - "protocol": unicode string - "cipher_suite": unicode string - "compression": boolean - "session_id": "new", "reused" or None - "session_ticket: "new", "reused" or None NFr"SSLv3TLSv1zTLSv1.1zTLSv1.2zTLSv1.3)sssssrr4"#rnewZreused)protocol cipher_suite compression session_idsession_ticket)rrr r _parse_hello_extensions)r(Zclient_handshake_bytesr?r@rArBrCZserver_session_idZclient_session_idr*r+r,r-r.Zsession_id_lengthZcipher_suite_startZcipher_suite_bytesZcompression_startZextensions_length_startZextensions_dataextension_typeZextension_dataZcipher_suite_lengthZcompression_lengthr0r0r1rs             ccsd}t|}||kr|||ddkr*qt||d|d}|||d||d|d||d|d|fV|d|7}q dS)a Creates a generator returning tuples of information about each record in a byte string of data from a TLS client or server. Stops as soon as it find a ChangeCipherSpec message since all data from then on is encrypted. :param data: A byte string of TLS records :return: A generator that yields 3-element tuples: [0] Byte string of record type [1] Byte string of protocol version [2] Byte string of record data rrr$Nr%r datar/data_lenlengthr0r0r1rsccshd}t|}||krdt||d|d}|||d||d|d|fV|d|7}q dS)a` Creates a generator returning tuples of information about each message in a byte string of data from a TLS handshake record :param data: A byte string of a TLS handshake record data :return: A generator that yields 2-element tuples: [0] Byte string of message type [1] Byte string of message data rrNrHrIr0r0r1r#sccs|dkr dSt|dd}d}d|}|}||krt|||d}t||d|d}|||d|d|fV|d|7}q,dS)a Creates a generator returning tuples of information about each extension from a byte string of extension data contained in a ServerHello ores ClientHello message :param data: A byte string of a extension data from a TLS ServerHello or ClientHello message :return: A generator that yields 2-element tuples: [0] Byte string of extension type [1] Byte string of extension data Nrr4rM)r )rJZextentions_lengthZextensions_startZextensions_endr/rEZextension_lengthr0r0r1rD<srDcCstd|p|ddk}|r(d|}nd|}d|}d|j}d|j}|r`|d|7}|rp|rp|d 7}|r|d |7}t||d S) z Raises a TLSVerificationError due to a hostname mismatch :param certificate: An asn1crypto.x509.Certificate object :raises: TLSVerificationError z^\d+\.\d+\.\d+\.\d+$:z IP address %szdomain name %sz:Server certificate verification failed - %s does not matchz, z valid domains: %sz orz valid IP addresses: %sN)rematchfindjoin valid_ips valid_domainsr ) certificatehostnameZis_ipZ hostname_typemessagerUrVr0r0r1r^s      cCsd}t||dS)z Raises a generic TLSVerificationError :param certificate: An asn1crypto.x509.Certificate object :raises: TLSVerificationError z&Server certificate verification failedNr rWrYr0r0r1r zs cCsd}t||dS)z Raises a TLSVerificationError when a certificate uses a weak signature algorithm :param certificate: An asn1crypto.x509.Certificate object :raises: TLSVerificationError zMServer certificate verification failed - weak certificate signature algorithmNrZr[r0r0r1r!s cCsd}t|dS)zg Raises a TLSError indicating client authentication is required :raises: TLSError z5TLS handshake failed - client authentication requiredNr)rYr0r0r1rscCsd}t||dS)z Raises a TLSVerificationError due to the certificate being revoked :param certificate: An asn1crypto.x509.Certificate object :raises: TLSVerificationError zEServer certificate verification failed - certificate has been revokedNrZr[r0r0r1rs cCsd}t||dS)z Raises a TLSVerificationError due to no issuer certificate found in trust roots :param certificate: An asn1crypto.x509.Certificate object :raises: TLSVerificationError zgServer certificate verification failed - certificate issuer not found in trusted root certificate storeNrZr[r0r0r1rs cCsd}t||dS)z Raises a TLSVerificationError due to a self-signed certificate roots :param certificate: An asn1crypto.x509.Certificate object :raises: TLSVerificationError zCServer certificate verification failed - certificate is self-signedNrZr[r0r0r1rs cCsd}t||dS)z Raises a TLSVerificationError due to a certificate lifetime exceeding the CAB forum certificate lifetime limit :param certificate: An asn1crypto.x509.Certificate object :raises: TLSVerificationError zIServer certificate verification failed - certificate lifetime is too longNrZr[r0r0r1raise_lifetime_too_longs r]cCsp|dd}|dj}|dj}ttj}||krH|d}d|}n||krb|d}d|}t||dS) z Raises a TLSVerificationError due to certificate being expired, or not yet being valid :param certificate: An asn1crypto.x509.Certificate object :raises: TLSVerificationError Ztbs_certificatevalidity not_after not_beforez%Y-%m-%d %H:%M:%SZzGServer certificate verification failed - certificate not valid until %sz?Server certificate verification failed - certificate expired %sN)Znativernowr utcstrftimer )rWr^r_r`raZformatted_beforerYZformatted_afterr0r0r1rs       cCs tddS)ze Raises a TLSDisconnectError due to a disconnection :raises: TLSDisconnectError z$The remote end closed the connectionN)r r0r0r0r1rscCs$t|}|rtd|tddS)z Raises a TLSError due to a protocol error :param server_handshake_bytes: A byte string of the handshake data received from the server :raises: TLSError z.TLS protocol error - server responded using %sz@TLS protocol error - server responded using a different protocolN)detect_other_protocolr)r(Zother_protocolr0r0r1r s  cCs tddS)zS Raises a TLSError due to a handshake error :raises: TLSError zTLS handshake failedNr\r0r0r0r1rscCs tddS)z_ Raises a TLSError due to a TLS version incompatibility :raises: TLSError z-TLS handshake failed - protocol version errorNr\r0r0r0r1raise_protocol_version)srecCs tddS)zP Raises a TLSError due to weak DH params :raises: TLSError z)TLS handshake failed - weak DH parametersNr\r0r0r0r1r4scCs|dddkrdS|dddkrs`  (o"     __pycache__/_types.cpython-38.pyc000064400000002240147205106110012702 0ustar00U afh@sjddlmZmZmZmZddlZddlZejdkrLeZ e Z e e fZddZne Z eZ e fZeZddZdS))unicode_literalsdivisionabsolute_importprint_functionN)cCsdd|DS)NcSsg|] }t|qS)ord).0brr@/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/_types.py sz!bytes_to_list..r)Z byte_stringrrr bytes_to_list sr cCs>t|r|}n|j}|jtddgkr.|jSd|j|jfS)z Returns a user-readable name for the type of an object :param value: A value to get the type name of :return: A unicode string of the object's type name builtins __builtin__z%s.%s)inspectisclass __class__ __module__set__name__)valueclsrrr type_names r) __future__rrrrsysr version_infounicodeZstr_clsstrZbyte_clsintlong int_typesr byteslistrrrrr s  __pycache__/asymmetric.cpython-38.pyc000064400000021326147205106110013562 0ustar00U afV3@sXddlmZmZmZmZddlZddlZddlmZddl m Z m Z m Z mZmZmZmZmZmZddlmZddlmZddlmZmZdd lmZmZdd lmZdd l m!Z!eZ"e"d krdd l#m Z m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7ne"dks2e"dkrdd l8m Z m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7n\dd l9m Z m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7ddddddddddddddddd d!d"d#d$d%d&d'd(d)gZ:d1d+dZ;d2d,dZd0dZ?dS)5)unicode_literalsdivisionabsolute_importprint_functionN)backend) armor Certificate DHParametersEncryptedPrivateKeyInfoNull OrderedDict Pbkdf2SaltPrivateKeyInfo PublicKeyInfo)_unwrap_private_key_info)pretty_message) type_namestr_cls)pbkdf2pbkdf2_iteration_calculator)aes_cbc_pkcs7_encrypt) rand_bytesmac)r dsa_sign dsa_verify ecdsa_sign ecdsa_verify generate_pairgenerate_dh_parametersload_certificate load_pkcs12load_private_keyload_public_key PrivateKey PublicKeyrsa_pkcs1v15_signrsa_pkcs1v15_verify rsa_pss_signrsa_pss_verifyrsa_pkcs1v15_encryptrsa_pkcs1v15_decryptrsa_oaep_encryptrsa_oaep_decryptwinZ winlegacyr rrdump_certificatedump_dh_parametersdump_openssl_private_keydump_private_keydump_public_keyrrrrr r!r"r#r$r%r-r,r+r*r&r'r(r)pemcCs\|tddgkr"ttdt|t|ts>ttdt||}|dkrXt d|}|S)a Serializes an asn1crypto.algos.DHParameters object into a byte string :param dh_parameters: An asn1crypto.algos.DHParameters object :param encoding: A unicode string of "pem" or "der" :return: A byte string of the encoded DH parameters r4derF encoding must be one of "pem", "der", not %s zp dh_parameters must be an instance of asn1crypto.algos.DHParameters, not %s z DH PARAMETERS) set ValueErrorrrepr isinstancer TypeErrorrdumpr)Z dh_parametersencodingoutputr?D/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/asymmetric.pyr0s  cCst|tddgkr"ttdt|t|t}t|tsL|sLttdt||rV|j }| }|dkrpt d|}|S)a# Serializes a public key object into a byte string :param public_key: An oscrypto.asymmetric.PublicKey or asn1crypto.keys.PublicKeyInfo object :param encoding: A unicode string of "pem" or "der" :return: A byte string of the encoded public key r4r5r6z public_key must be an instance of oscrypto.asymmetric.PublicKey or asn1crypto.keys.PublicKeyInfo, not %s z PUBLIC KEY) r7r8rr9r:r%rr;rasn1r<r)Z public_keyr= is_oscryptor>r?r?r@r3s"  cCst|tddgkr"ttdt|t|t}t|tsL|sLttdt||rV|j }| }|dkrpt d|}|S)a& Serializes a certificate object into a byte string :param certificate: An oscrypto.asymmetric.Certificate or asn1crypto.x509.Certificate object :param encoding: A unicode string of "pem" or "der" :return: A byte string of the encoded certificate r4r5r6z certificate must be an instance of oscrypto.asymmetric.Certificate or asn1crypto.x509.Certificate, not %s CERTIFICATE) r7r8rr9r:r Asn1Certificater;rrAr<r)Z certificater=rBr>r?r?r@r/s"  cCsh|tddgkr"ttdt||dk rZt|tsFttdt||dkrZttdt|t}t|t s|sttdt||r|j }| }|dk rcipher key_lengthZkdf_hmacZkdf_saltZ iterationspassphrase_byteskeyivZ ciphertext object_typer?r?r@r2sz        c Csl|dk r8t|ts$ttdt||dkr8ttdt|t}t|tsb|sbttdt||rl|j}t | }d}|dk r*t d}t }d|d<d t |d |d <d}|d }t||d d}|t|kr|t|||d d7}q|d |}t|||\}}|jdkrr_rYrVrWrXrZr?r?r@r1usN     $    )r4)r4)r4)r4rE)@ __future__rrrrrcr`rGrZ_asn1rr rDr r r r rrrZ _asymmetricr_errorsr_typesrrZkdfrrZ symmetricrutilrZ_backendZ_mac.asymmetricrrrrrrr r!r"r#r$r%r&r'r(r)r*r+r,r-Z_win.asymmetricZ_openssl.asymmetric__all__r0r3r/r2r1r?r?r?r@s` ,     ^^\ % ) ) v__pycache__/errors.cpython-38.pyc000064400000005671147205106110012726 0ustar00U afx @sddlmZmZmZmZddlZddlZddddddd d d g ZGd ddeZ Gd ddeZ GdddeZ Gddde Z GdddeZ GdddejZGdddeZGdd d eZGdd d eZGdd d eZdS))unicode_literalsdivisionabsolute_importprint_functionNAsymmetricKeyError CACertsErrorLibraryNotFoundErrorSignatureErrorTLSErrorTLSConnectionErrorTLSDisconnectErrorTLSGracefulDisconnectErrorTLSVerificationErrorc@seZdZdZdS)rz; An exception when trying to find a shared library N__name__ __module__ __qualname____doc__rr@/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/errors.pyrsc@seZdZdZdS)r z2 An exception when validating a signature Nrrrrrr sc@seZdZdZdS)rz; An exception when a key is invalid or unsupported Nrrrrrr'sc@seZdZdZdS)IncompleteAsymmetricKeyErrorzB An exception when a key is missing necessary information Nrrrrrr0src@seZdZdZdS)rzF An exception when exporting CA certs from the OS trust store Nrrrrrr9sc@s,eZdZdZdZddZddZddZdS) r z3 An exception related to TLS functionality NcCs|f|_||_dSN)argsmessage)selfrrrr__init__JszTLSError.__init__cCs |}tjdkr|d}|S)N)zutf-8) __unicode__sys version_infoencode)routputrrr__str__Ns  zTLSError.__str__cCs|jSr)r)rrrrrTszTLSError.__unicode__)rrrrrrr"rrrrrr Bs c@s eZdZdS)r Nrrrrrrrr Xsc@s eZdZdS)r Nr#rrrrr \sc@s eZdZdS)r Nr#rrrrr `sc@seZdZdZdZddZdS)rzQ A server certificate verification error happened during a TLS handshake NcCs t||||_||f|_dSr)r r certificater)rrr$rrrrls zTLSVerificationError.__init__)rrrrr$rrrrrrds) __future__rrrrrsocket__all__ Exceptionrr rrrerrorr r r r rrrrrs,      __pycache__/kdf.cpython-38.pyc000064400000013257147205106110012155 0ustar00U af@s.ddlmZmZmZmZddlZddlZddlmZddlm Z ddl m Z ddl m Z mZmZddlmZdd lmZmZe Zed krdd lmZmZnBed ksed krdd lmZmZddlmZmZndd lmZmZddddgZejdkrddZ ddZ!nddZ ddZ!dddZ"ddZ#dS))unicode_literalsdivisionabsolute_importprint_functionN)datetime)backend) rand_bytes) type_namebyte_cls int_types)pretty_message)newderefmac)pbkdf2 pkcs12_kdfwinZ winlegacy)kernel32 handle_errorpbkdf1rpbkdf2_iteration_calculatorrwin32cCs$ttd}t|}t|t|S)NzLARGE_INTEGER *)rrZQueryPerformanceCounterrr)numberresr=/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/kdf.py _get_start$s  rcCst|}t|dS)Ng@@)rint)startlengthrrr _get_elapsed*s r!cCstS)N)rnowrrrrr/scCs:t|}|j|jdd}|jd}t||dS)Nii)rr"secondsdays microsecondsr)rr r$Z millisecondsrrrr!2s  dFcs2tdddddgkr(ttdtttsDttdtdkr^ttd tttszttd tdkrttd ttj rt td d d dt fdd}|}t |d|}|dkrdnd}t t|}|dkr.|dd}|S)a Runs pbkdf2() twice to determine the approximate number of iterations to use to hit a desired time per run. Use this on a production machine to dynamically adjust the number of iterations as high as you can. :param hash_algorithm: The string name of the hash algorithm to use: "md5", "sha1", "sha224", "sha256", "sha384", "sha512" :param key_length: The length of the desired key in bytes :param target_ms: The number of milliseconds the derivation should take :param quiet: If no output should be printed as attempts are made :return: An integer number of iterations of PBKDF2 using the specified hash that will take at least target_ms sha1sha224sha256sha384sha512zz hash_algorithm must be one of "sha1", "sha224", "sha256", "sha384", "sha512", not %s ? key_length must be an integer, not %s rC key_length must be greater than 0 - is %s z> target_ms must be an integer, not %s zB target_ms must be greater than 0 - is %s z Only a very slow, pure-python version of PBKDF2 is available, making this function useless i'zthis is a testzutf-8cs>t}tt|}s2td|fd|S)Nz%s iterations in %smsg?)rrr!print)rZ observed_mshash_algorithm iterations key_lengthpasswordquietsalt target_msrr_measures z-pbkdf2_iteration_calculator.._measureg@ii Ni)set ValueErrorr repr isinstancer TypeErrorr rZ pure_pythonOSErrorencoder rround)r1r3r7r5r8fractionZ round_factorresultrr0rr9sT      cCsdt|tsttdt|t|ts8ttdt|t|tsTttdt||dkrnttdt|t|tsttdt||dkrttdt||tdd d gkrttd t||d kr|tdd gkrttd |t|f|dkr|d krttdt|t t |}||| }t d|dD]}|| }qD|d|S)aF An implementation of PBKDF1 - should only be used for interop with legacy systems, not new architectures :param hash_algorithm: The string name of the hash algorithm to use: "md2", "md5", "sha1" :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 :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 rzC iterations must be greater than 0 - is %s r-r.Zmd2md5r(zT hash_algorithm must be one of "md2", "md5", "sha1", not %s zM key_length can not be longer than 16 for %s - is %s zO key_length can not be longer than 20 for sha1 - is %s N) r>r r?r r r r<r=r;getattrhashlibdigestrange)r1r4r6r2r3algooutput_rrrrsd      )r'F)$ __future__rrrrsysrJrrutilr _typesr r r _errorsr Z_ffirrZ_backendZ _mac.utilrrZ _win.utilZ_win._kernel32rrZ _openssl.util__all__platformrr!rrrrrrs6       g__pycache__/keys.cpython-38.pyc000064400000001213147205106110012351 0ustar00U af@sddlmZmZmZmZddlmZddlmZm Z m Z eZ e dkrTddl m Z n*e dksde dkrrddlm Z n ddlm Z d d d d gZd S))unicode_literalsdivisionabsolute_importprint_function)backend)parse_certificate parse_private parse_publicmac) parse_pkcs12winZ winlegacyrr r r N) __future__rrrrrZ _asymmetricrr r Z_backendZ_mac.asymmetricr Z_win.asymmetricZ_openssl.asymmetric__all__rr>/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/keys.pys  __pycache__/symmetric.cpython-38.pyc000064400000002064147205106110013417 0ustar00U af0 @sddlmZmZmZmZddlmZeZedkrlddlm Z m Z m Z m Z m Z mZmZmZmZmZmZmZnedks|edkrddlm Z m Z m Z m Z m Z mZmZmZmZmZmZmZn8ddlm Z m Z m Z m Z m Z mZmZmZmZmZmZmZdd d d d d ddddddg ZdS))unicode_literalsdivisionabsolute_importprint_function)backendmac) aes_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_encryptwinZ winlegacyr r r r r rrrrrrrN) __future__rrrrrZ_backendZ_mac.symmetricr r r r r rrrrrrrZ_win.symmetricZ_openssl.symmetric__all__rrC/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/symmetric.pys( ::8__pycache__/tls.cpython-38.pyc000064400000001031147205106110012176 0ustar00U af@sddlmZmZmZmZddlmZeZedkrDddlm Z m Z n2edksTedkrfddl m Z m Z nddl m Z m Z dd gZ d S) )unicode_literalsdivisionabsolute_importprint_function)backendmac) TLSSession TLSSocketwinZ winlegacyr r N) __future__rrrrrZ_backendZ_mac.tlsr r Z_win.tlsZ _openssl.tls__all__rr=/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/tls.pys __pycache__/trust_list.cpython-38.pyc000064400000025147147205106110013626 0ustar00U af4 @s`ddlmZmZmZmZddlZddlZddlZddlZddl Z ddl m Z m Z ddl mZddlmZejdkrddlmZmZn,ejd krddlmZmZnddlmZmZd d d gZe Ze Zddd ZedgedgedgedgeddgeddgeddddgdZd'dd Zd(dd Zd)dd Z d*dd Z!d!d"Z"d#d$Z#d%d&Z$dS)+)unicode_literalsdivisionabsolute_importprint_functionN)armor Certificate)pretty_message) CACertsErrorwin32)extract_from_system system_pathdarwin clear_cacheget_listget_path) last_updatecertsz1.3.6.1.5.5.7.3.4z1.3.6.1.5.5.7.3.3z1.3.6.1.5.5.7.3.81.3.6.1.5.5.7.3.1z1.3.6.1.5.5.7.3.2z1.3.6.1.5.5.7.3.13z1.3.6.1.5.5.7.3.14z1.3.6.1.5.5.7.3.5z1.3.6.1.5.5.7.3.6z1.3.6.1.5.5.7.3.7z1.3.6.1.5.5.7.3.17)z1.2.840.113635.100.1.8z1.2.840.113635.100.1.16z1.2.840.113635.100.1.20z1.3.6.1.4.1.311.10.3.21.2.840.113635.100.1.3z1.2.840.113635.100.1.9z1.2.840.113635.100.1.11c Cst|\}}|rt||rt}d}d}d}tDt||rvt|d } t|dD] \} } } tjdkr| |kr|| kr|| kr|r\|t | dq\| |kr|| ks|| kr|r\|t | dq\nttjd krD| |kr|| kr|| kr|r\|t | dq\| |krD|| ks.|| krD|r\|t | dq\|rZ|t | d | t d | q\W5QRXW5QRX|st d |S) a Get the filesystem path to a file that contains OpenSSL-compatible CA certs. On OS X and Windows, there are extracted from the system certificate store and cached in a file on the filesystem. This path should not be writable by other users, otherwise they could inject CA certs into the trust list. :param temp_dir: The temporary directory to cache the CA certs in on OS X and Windows. Needs to have secure permissions so other users can not modify the contents. :param cache_length: The number of hours to cache the CA certs on OS X and Windows :param cert_callback: A callback that is called once for each certificate in the trust store. It should accept two parameters: an asn1crypto.x509.Certificate object, and a reason. The reason will be None if the certificate is being exported, otherwise it will be a unicode string of the reason it won't. This is only called on Windows and OS X when passed to this function. :raises: oscrypto.errors.CACertsError - when an error occurs exporting/locating certs :return: The full filesystem path to a CA certs file z 2.5.29.37.0rrwbTrzimplicitly distrusted for TLSzexplicitly distrusted for TLSr N CERTIFICATEzNo CA certs found) _ca_path_cached_path_needs_updateset path_lockopenr sysplatformrloadwriterr ) temp_dir cache_length cert_callbackca_pathtempZ empty_setZ any_purposeZ apple_sslZwin_server_authfcert trust_oids reject_oidsr+D/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/trust_list.pyrAsT    &Tc Cst|svtdt|slg}t|D]4\}}}|r@t|}t|}|t|||fq"|td<ttd<W5QRXt tdS)af Retrieves (and caches in memory) the list of CA certs from the OS. Includes trust information from the OS - purposes the certificate should be trusted or rejected for. Trust information is encoded via object identifiers (OIDs) that are sourced from various RFCs and vendors (Apple and Microsoft). This trust information augments what is in the certificate itself. Any OID that is in the set of trusted purposes indicates the certificate has been explicitly trusted for a purpose beyond the extended key purpose extension. Any OID in the reject set is a purpose that the certificate should not be trusted for, even if present in the extended key purpose extension. *A list of common trust OIDs can be found as part of the `KeyPurposeId()` class in the `asn1crypto.x509` module of the `asn1crypto` package.* :param cache_length: The number of hours to cache the CA certs in memory before they are refreshed :param map_vendor_oids: A bool indicating if the following mapping of OIDs should happen for trust information from the OS trust list: - 1.2.840.113635.100.1.3 (apple_ssl) -> 1.3.6.1.5.5.7.3.1 (server_auth) - 1.2.840.113635.100.1.3 (apple_ssl) -> 1.3.6.1.5.5.7.3.2 (client_auth) - 1.2.840.113635.100.1.8 (apple_smime) -> 1.3.6.1.5.5.7.3.4 (email_protection) - 1.2.840.113635.100.1.9 (apple_eap) -> 1.3.6.1.5.5.7.3.13 (eap_over_ppp) - 1.2.840.113635.100.1.9 (apple_eap) -> 1.3.6.1.5.5.7.3.14 (eap_over_lan) - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.5 (ipsec_end_system) - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.6 (ipsec_tunnel) - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.7 (ipsec_user) - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.17 (ipsec_ike) - 1.2.840.113635.100.1.16 (apple_code_signing) -> 1.3.6.1.5.5.7.3.3 (code_signing) - 1.2.840.113635.100.1.20 (apple_time_stamping) -> 1.3.6.1.5.5.7.3.8 (time_stamping) - 1.3.6.1.4.1.311.10.3.2 (microsoft_time_stamp_signing) -> 1.3.6.1.5.5.7.3.8 (time_stamping) :param cert_callback: A callback that is called once for each certificate in the trust store. It should accept two parameters: an asn1crypto.x509.Certificate object, and a reason. The reason will be None if the certificate is being exported, otherwise it will be a unicode string of the reason it won't. :raises: oscrypto.errors.CACertsError - when an error occurs exporting/locating certs :return: A (copied) list of 3-element tuples containing CA certs from the OS trust ilst: - 0: an asn1crypto.x509.Certificate object - 1: a set of unicode strings of OIDs of trusted purposes - 2: a set of unicode strings of OIDs of rejected purposes rr) _in_memory_up_to_date memory_lockr _map_oidsappendrr _module_valuestimelist)r#Zmap_vendor_oidsr$rZ cert_bytesr)r*r+r+r,rs6c CsZtdtd<dtd<W5QRXt|\}}|rVttj|rLt|W5QRXdS)a Clears any cached info that was exported from the OS trust store. This will ensure the latest changes are returned from calls to get_list() and get_path(), but at the expense of re-exporting and parsing all certificates. :param temp_dir: The temporary directory to cache the CA certs in on OS X and Windows. Needs to have secure permissions so other users can not modify the contents. Must be the same value passed to get_path(). Nrr)r.r1rrospathexistsremove)r"r%r&r+r+r,rs   cCsVt}|dkrN|dkrt}tj|s8ttd|tj|d}|dfS|dfS)a Returns the file path to the CA certs file :param temp_dir: The temporary directory to cache the CA certs in on OS X and Windows. Needs to have secure permissions so other users can not modify the contents. :return: A 2-element tuple: - 0: A unicode string of the file path - 1: A bool if the file is a temporary file NzR The temp dir specified, "%s", is not a directory zoscrypto-ca-bundle.crtTF) r tempfile gettempdirr4r5isdirr r join)r"r%r+r+r,rs rcCs,t}|D]}|tkr |t|O}q ||BS)a Takes a set of unicode string OIDs and converts vendor-specific OIDs into generics OIDs from RFCs. - 1.2.840.113635.100.1.3 (apple_ssl) -> 1.3.6.1.5.5.7.3.1 (server_auth) - 1.2.840.113635.100.1.3 (apple_ssl) -> 1.3.6.1.5.5.7.3.2 (client_auth) - 1.2.840.113635.100.1.8 (apple_smime) -> 1.3.6.1.5.5.7.3.4 (email_protection) - 1.2.840.113635.100.1.9 (apple_eap) -> 1.3.6.1.5.5.7.3.13 (eap_over_ppp) - 1.2.840.113635.100.1.9 (apple_eap) -> 1.3.6.1.5.5.7.3.14 (eap_over_lan) - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.5 (ipsec_end_system) - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.6 (ipsec_tunnel) - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.7 (ipsec_user) - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.17 (ipsec_ike) - 1.2.840.113635.100.1.16 (apple_code_signing) -> 1.3.6.1.5.5.7.3.3 (code_signing) - 1.2.840.113635.100.1.20 (apple_time_stamping) -> 1.3.6.1.5.5.7.3.8 (time_stamping) - 1.3.6.1.4.1.311.10.3.2 (microsoft_time_stamp_signing) -> 1.3.6.1.5.5.7.3.8 (time_stamping) :param oids: A set of unicode strings :return: The original set of OIDs with any mapped OIDs added )r_oid_map)ZoidsZnew_oidsoidr+r+r,r/ s r/cCsNtj|}|sdSt|}|jt|ddkr)r1r2)r#r+r+r,r-Ks r-)NrN)rTN)N)N)% __future__rrrrr4r2rr8 threadingZ_asn1rr_errorsr errorsr rZ_win.trust_listr r Z_mac.trust_listZ_linux_bsd.trust_list__all__Lockrr.r1rr<rrrrr/rr-r+r+r+r,s`     L E  $ __pycache__/util.cpython-38.pyc000064400000003050147205106110012354 0ustar00U af3@sddlmZmZmZmZddlZddlmZddlm Z m Z ej dkrTddl m Z n$ej dkrlddlm Z n ddlm Z d d gZd d ZdS) )unicode_literalsdivisionabsolute_importprint_functionN)pretty_message) type_namebyte_clsdarwin) rand_byteswin32constant_comparer cCst|tsttdt|t|ts8ttdt|t|t|krLdStjdkrrdd|D}dd|D}d}t||D]\}}|||AO}q|dkS) z Compares two byte strings in constant time to see if they are equal :param a: The first byte string :param b: The second byte string :return: A boolean if the two byte strings are equal z9 a must be a byte string, not %s z9 b must be a byte string, not %s F)cSsg|] }t|qSord.0charrr>/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/util.py 9sz$constant_compare..cSsg|] }t|qSrrrrrrr:sr) isinstancer TypeErrorrrlensys version_infozip)abresultxyrrrr s&   ) __future__rrrrr_errorsr_typesrr platformZ _mac.utilr Z _win.utilZ _openssl.util__all__r rrrrs    __pycache__/version.cpython-38.pyc000064400000000530147205106110013064 0ustar00U af@s$ddlmZmZmZmZdZdZdS))unicode_literalsdivisionabsolute_importprint_functionz1.3.0)rN) __future__rrrr __version____version_info__r r A/opt/nydus/tmp/pip-target-53d1vnqk/lib/python/oscrypto/version.pys