python_version = '<STR_LIT:.>'.join(map(str_cls, sys.version_info[<NUM_LIT:0>:<NUM_LIT:2>]))<EOL>sys_platform = sys.platform<EOL>packages = []<EOL>with open(path, '<STR_LIT:rb>') as f:<EOL><INDENT>contents = f.read().decode('<STR_LIT:utf-8>')<EOL><DEDENT>for line in re.split(r'<STR_LIT>', contents):<EOL><INDENT>line = line.strip()<EOL>if not len(line):<EOL><INDENT>continue<EOL><DEDENT>if re.match(r'<STR_LIT>', line):<EOL><INDENT>continue<EOL><DEDENT>if '<STR_LIT:;>' in line:<EOL><INDENT>package, cond = line.split('<STR_LIT:;>', <NUM_LIT:1>)<EOL>package = package.strip()<EOL>cond = cond.strip()<EOL>cond = cond.replace('<STR_LIT>', repr(sys_platform))<EOL>cond = cond.replace('<STR_LIT>', repr(python_version))<EOL>if not eval(cond):<EOL><INDENT>continue<EOL><DEDENT><DEDENT>else:<EOL><INDENT>package = line.strip()<EOL><DEDENT>if re.match(r'<STR_LIT>', package):<EOL><INDENT>sub_req_file = re.sub(r'<STR_LIT>', '<STR_LIT>', package)<EOL>sub_req_file = os.path.abspath(os.path.join(os.path.dirname(path), sub_req_file))<EOL>packages.extend(_parse_requires(sub_req_file))<EOL>continue<EOL><DEDENT>if re.match(r'<STR_LIT>', package):<EOL><INDENT>packages.append({'<STR_LIT:type>': '<STR_LIT:url>', '<STR_LIT>': package})<EOL>continue<EOL><DEDENT>if '<STR_LIT>' in package:<EOL><INDENT>parts = package.split('<STR_LIT>')<EOL>package = parts[<NUM_LIT:0>].strip()<EOL>ver = parts[<NUM_LIT:1>].strip()<EOL>packages.append({'<STR_LIT:type>': '<STR_LIT>', '<STR_LIT>': package, '<STR_LIT>': ver})<EOL>continue<EOL><DEDENT>if '<STR_LIT>' in package:<EOL><INDENT>parts = package.split('<STR_LIT>')<EOL>package = parts[<NUM_LIT:0>].strip()<EOL>ver = parts[<NUM_LIT:1>].strip()<EOL>packages.append({'<STR_LIT:type>': '<STR_LIT>', '<STR_LIT>': package, '<STR_LIT>': ver})<EOL>continue<EOL><DEDENT>if re.search(r'<STR_LIT>', package):<EOL><INDENT>raise Exception('<STR_LIT>' % package)<EOL><DEDENT>packages.append({'<STR_LIT:type>': '<STR_LIT>', '<STR_LIT>': package})<EOL><DEDENT>return packages<EOL>

Does basic parsing of pip requirements files, to allow for
using something other than Python to do actual TLS requests

:param path:
    A path to a requirements file

:return:
    A list of dict objects containing the keys:
     - 'type' ('any', 'url', '==', '>=')
     - 'pkg'
     - 'ver' (if 'type' == '==' or 'type' == '>=')


proc = subprocess.Popen(<EOL>params,<EOL>stdout=subprocess.PIPE,<EOL>stderr=subprocess.PIPE,<EOL>cwd=cwd<EOL>)<EOL>stdout, stderr = proc.communicate()<EOL>code = proc.wait()<EOL>if code != <NUM_LIT:0>:<EOL><INDENT>e = OSError('<STR_LIT>' % (params, code, stderr))<EOL>e.stdout = stdout<EOL>e.stderr = stderr<EOL>raise e<EOL><DEDENT>return (stdout, stderr)<EOL>

Executes a subprocess

:param params:
    A list of the executable and arguments to pass to it

:param cwd:
    The working directory to execute the command in

:return:
    A 2-element tuple of (stdout, stderr)


loader = unittest.TestLoader()<EOL>test_list = []<EOL>for test_class in test_classes():<EOL><INDENT>if matcher:<EOL><INDENT>names = loader.getTestCaseNames(test_class)<EOL>for name in names:<EOL><INDENT>if re.search(matcher, name):<EOL><INDENT>test_list.append(test_class(name))<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>test_list.append(loader.loadTestsFromTestCase(test_class))<EOL><DEDENT><DEDENT>stream = sys.stdout<EOL>verbosity = <NUM_LIT:1><EOL>if matcher and repeat == <NUM_LIT:1>:<EOL><INDENT>verbosity = <NUM_LIT:2><EOL><DEDENT>elif repeat > <NUM_LIT:1>:<EOL><INDENT>stream = StringIO()<EOL><DEDENT>for _ in range(<NUM_LIT:0>, repeat):<EOL><INDENT>suite = unittest.TestSuite()<EOL>for test in test_list:<EOL><INDENT>suite.addTest(test)<EOL><DEDENT>result = unittest.TextTestRunner(stream=stream, verbosity=verbosity).run(suite)<EOL>if len(result.errors) > <NUM_LIT:0> or len(result.failures) > <NUM_LIT:0>:<EOL><INDENT>if repeat > <NUM_LIT:1>:<EOL><INDENT>print(stream.getvalue())<EOL><DEDENT>return False<EOL><DEDENT>if repeat > <NUM_LIT:1>:<EOL><INDENT>stream.truncate(<NUM_LIT:0>)<EOL><DEDENT><DEDENT>return True<EOL>

Runs the tests

:param matcher:
    A unicode string containing a regular expression to use to filter test
    names by. A value of None will cause no filtering.

:param repeat:
    An integer - the number of times to run the tests

:return:
    A bool - if the tests succeeded


if result:<EOL><INDENT>return<EOL><DEDENT>_, error_string = get_error()<EOL>if not isinstance(error_string, str_cls):<EOL><INDENT>error_string = _try_decode(error_string)<EOL><DEDENT>raise OSError(error_string)<EOL>

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


try:<EOL><INDENT>return str_cls(byte_string, _encoding)<EOL><DEDENT>except (UnicodeDecodeError):<EOL><INDENT>for encoding in _fallback_encodings:<EOL><INDENT>try:<EOL><INDENT>return str_cls(byte_string, encoding, errors='<STR_LIT:strict>')<EOL><DEDENT>except (UnicodeDecodeError):<EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>return str_cls(byte_string, errors='<STR_LIT:replace>')<EOL>

Tries decoding a byte string from the OS into a unicode string

:param byte_string:
    A byte string

:return:
    A unicode string


if error_num == <NUM_LIT:0>:<EOL><INDENT>return<EOL><DEDENT>messages = {<EOL>BcryptConst.STATUS_NOT_FOUND: '<STR_LIT>',<EOL>BcryptConst.STATUS_INVALID_PARAMETER: '<STR_LIT>',<EOL>BcryptConst.STATUS_NO_MEMORY: (<EOL>'<STR_LIT>'<EOL>),<EOL>BcryptConst.STATUS_INVALID_HANDLE: '<STR_LIT>',<EOL>BcryptConst.STATUS_INVALID_SIGNATURE: '<STR_LIT>',<EOL>BcryptConst.STATUS_NOT_SUPPORTED: '<STR_LIT>',<EOL>BcryptConst.STATUS_BUFFER_TOO_SMALL: '<STR_LIT>',<EOL>BcryptConst.STATUS_INVALID_BUFFER_SIZE: '<STR_LIT>',<EOL>}<EOL>output = '<STR_LIT>' % error_num<EOL>if error_num is not None and error_num in messages:<EOL><INDENT>output += '<STR_LIT>' + messages[error_num]<EOL><DEDENT>raise OSError(output)<EOL>

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


certificates = {}<EOL>processed = {}<EOL>now = datetime.datetime.utcnow()<EOL>for store in ["<STR_LIT>", "<STR_LIT>"]:<EOL><INDENT>store_handle = crypt32.CertOpenSystemStoreW(null(), store)<EOL>handle_error(store_handle)<EOL>context_pointer = null()<EOL>while True:<EOL><INDENT>context_pointer = crypt32.CertEnumCertificatesInStore(store_handle, context_pointer)<EOL>if is_null(context_pointer):<EOL><INDENT>break<EOL><DEDENT>context = unwrap(context_pointer)<EOL>trust_all = False<EOL>data = None<EOL>digest = None<EOL>if context.dwCertEncodingType != Crypt32Const.X509_ASN_ENCODING:<EOL><INDENT>continue<EOL><DEDENT>data = bytes_from_buffer(context.pbCertEncoded, int(context.cbCertEncoded))<EOL>digest = hashlib.sha1(data).digest()<EOL>if digest in processed:<EOL><INDENT>continue<EOL><DEDENT>processed[digest] = True<EOL>cert_info = unwrap(context.pCertInfo)<EOL>not_before_seconds = _convert_filetime_to_timestamp(cert_info.NotBefore)<EOL>try:<EOL><INDENT>not_before = datetime.datetime.fromtimestamp(not_before_seconds)<EOL>if not_before > now:<EOL><INDENT>if cert_callback:<EOL><INDENT>cert_callback(Certificate.load(data), '<STR_LIT>')<EOL><DEDENT>continue<EOL><DEDENT><DEDENT>except (ValueError, OSError):<EOL><INDENT>pass<EOL><DEDENT>not_after_seconds = _convert_filetime_to_timestamp(cert_info.NotAfter)<EOL>try:<EOL><INDENT>not_after = datetime.datetime.fromtimestamp(not_after_seconds)<EOL>if not_after < now:<EOL><INDENT>if cert_callback:<EOL><INDENT>cert_callback(Certificate.load(data), '<STR_LIT>')<EOL><DEDENT>continue<EOL><DEDENT><DEDENT>except (ValueError, OSError) as e:<EOL><INDENT>if not_after_seconds < <NUM_LIT:0>:<EOL><INDENT>message = e.args[<NUM_LIT:0>] + '<STR_LIT>' + str_cls(not_after_seconds)<EOL>e.args = (message,) + e.args[<NUM_LIT:1>:]<EOL>raise e<EOL><DEDENT><DEDENT>trust_oids = set()<EOL>reject_oids = set()<EOL>to_read = new(crypt32, '<STR_LIT>', <NUM_LIT:0>)<EOL>res = crypt32.CertGetEnhancedKeyUsage(<EOL>context_pointer,<EOL>Crypt32Const.CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG,<EOL>null(),<EOL>to_read<EOL>)<EOL>error_code, _ = get_error()<EOL>if not res and error_code != Crypt32Const.CRYPT_E_NOT_FOUND:<EOL><INDENT>handle_error(res)<EOL><DEDENT>if error_code == Crypt32Const.CRYPT_E_NOT_FOUND:<EOL><INDENT>trust_all = True<EOL><DEDENT>else:<EOL><INDENT>usage_buffer = buffer_from_bytes(deref(to_read))<EOL>res = crypt32.CertGetEnhancedKeyUsage(<EOL>context_pointer,<EOL>Crypt32Const.CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG,<EOL>cast(crypt32, '<STR_LIT>', usage_buffer),<EOL>to_read<EOL>)<EOL>handle_error(res)<EOL>key_usage_pointer = struct_from_buffer(crypt32, '<STR_LIT>', usage_buffer)<EOL>key_usage = unwrap(key_usage_pointer)<EOL>if key_usage.cUsageIdentifier == <NUM_LIT:0>:<EOL><INDENT>if cert_callback:<EOL><INDENT>cert_callback(Certificate.load(data), '<STR_LIT>')<EOL><DEDENT>continue<EOL><DEDENT>oids = array_from_pointer(<EOL>crypt32,<EOL>'<STR_LIT>',<EOL>key_usage.rgpszUsageIdentifier,<EOL>key_usage.cUsageIdentifier<EOL>)<EOL>for oid in oids:<EOL><INDENT>trust_oids.add(oid.decode('<STR_LIT:ascii>'))<EOL><DEDENT><DEDENT>cert = None<EOL>if not trust_all:<EOL><INDENT>cert = Certificate.load(data)<EOL>if cert.extended_key_usage_value:<EOL><INDENT>for cert_oid in cert.extended_key_usage_value:<EOL><INDENT>oid = cert_oid.dotted<EOL>if oid not in trust_oids:<EOL><INDENT>reject_oids.add(oid)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>if cert_callback and not callback_only_on_failure:<EOL><INDENT>if cert is None:<EOL><INDENT>cert = Certificate.load(data)<EOL><DEDENT>cert_callback(cert, None)<EOL><DEDENT>certificates[digest] = (data, trust_oids, reject_oids)<EOL><DEDENT>result = crypt32.CertCloseStore(store_handle, <NUM_LIT:0>)<EOL>handle_error(result)<EOL>store_handle = None<EOL><DEDENT>return certificates.values()<EOL>

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


hundreds_nano_seconds = struct.unpack(<EOL>b'<STR_LIT>',<EOL>struct.pack(<EOL>b'<STR_LIT>',<EOL>filetime.dwHighDateTime,<EOL>filetime.dwLowDateTime<EOL>)<EOL>)[<NUM_LIT:0>]<EOL>seconds_since_1601 = hundreds_nano_seconds / <NUM_LIT><EOL>return seconds_since_1601 - <NUM_LIT><EOL>

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


def __init__(self, protocol=None, manual_validation=False, extra_trust_roots=None):

if not isinstance(manual_validation, bool):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(manual_validation)<EOL>))<EOL><DEDENT>self._manual_validation = manual_validation<EOL>if protocol is None:<EOL><INDENT>protocol = set(['<STR_LIT>', '<STR_LIT>', '<STR_LIT>'])<EOL><DEDENT>if isinstance(protocol, str_cls):<EOL><INDENT>protocol = set([protocol])<EOL><DEDENT>elif not isinstance(protocol, set):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(protocol)<EOL>))<EOL><DEDENT>unsupported_protocols = protocol - set(['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>'])<EOL>if unsupported_protocols:<EOL><INDENT>raise ValueError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>repr(unsupported_protocols)<EOL>))<EOL><DEDENT>self._protocols = protocol<EOL>self._extra_trust_roots = []<EOL>if extra_trust_roots:<EOL><INDENT>for extra_trust_root in extra_trust_roots:<EOL><INDENT>if isinstance(extra_trust_root, Certificate):<EOL><INDENT>extra_trust_root = extra_trust_root.asn1<EOL><DEDENT>elif isinstance(extra_trust_root, byte_cls):<EOL><INDENT>extra_trust_root = parse_certificate(extra_trust_root)<EOL><DEDENT>elif isinstance(extra_trust_root, str_cls):<EOL><INDENT>with open(extra_trust_root, '<STR_LIT:rb>') as f:<EOL><INDENT>extra_trust_root = parse_certificate(f.read())<EOL><DEDENT><DEDENT>elif not isinstance(extra_trust_root, x509.Certificate):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(extra_trust_root)<EOL>))<EOL><DEDENT>self._extra_trust_roots.append(extra_trust_root)<EOL><DEDENT><DEDENT>self._obtain_credentials()<EOL>

: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


protocol_values = {<EOL>'<STR_LIT>': Secur32Const.SP_PROT_SSL3_CLIENT,<EOL>'<STR_LIT>': Secur32Const.SP_PROT_TLS1_CLIENT,<EOL>'<STR_LIT>': Secur32Const.SP_PROT_TLS1_1_CLIENT,<EOL>'<STR_LIT>': Secur32Const.SP_PROT_TLS1_2_CLIENT,<EOL>}<EOL>protocol_bit_mask = <NUM_LIT:0><EOL>for key, value in protocol_values.items():<EOL><INDENT>if key in self._protocols:<EOL><INDENT>protocol_bit_mask |= value<EOL><DEDENT><DEDENT>algs = [<EOL>Secur32Const.CALG_AES_128,<EOL>Secur32Const.CALG_AES_256,<EOL>Secur32Const.CALG_3DES,<EOL>Secur32Const.CALG_SHA1,<EOL>Secur32Const.CALG_ECDHE,<EOL>Secur32Const.CALG_DH_EPHEM,<EOL>Secur32Const.CALG_RSA_KEYX,<EOL>Secur32Const.CALG_RSA_SIGN,<EOL>Secur32Const.CALG_ECDSA,<EOL>Secur32Const.CALG_DSS_SIGN,<EOL>]<EOL>if '<STR_LIT>' in self._protocols:<EOL><INDENT>algs.extend([<EOL>Secur32Const.CALG_SHA512,<EOL>Secur32Const.CALG_SHA384,<EOL>Secur32Const.CALG_SHA256,<EOL>])<EOL><DEDENT>alg_array = new(secur32, '<STR_LIT>' % len(algs))<EOL>for index, alg in enumerate(algs):<EOL><INDENT>alg_array[index] = alg<EOL><DEDENT>flags = Secur32Const.SCH_USE_STRONG_CRYPTO | Secur32Const.SCH_CRED_NO_DEFAULT_CREDS<EOL>if not self._manual_validation and not self._extra_trust_roots:<EOL><INDENT>flags |= Secur32Const.SCH_CRED_AUTO_CRED_VALIDATION<EOL><DEDENT>else:<EOL><INDENT>flags |= Secur32Const.SCH_CRED_MANUAL_CRED_VALIDATION<EOL><DEDENT>schannel_cred_pointer = struct(secur32, '<STR_LIT>')<EOL>schannel_cred = unwrap(schannel_cred_pointer)<EOL>schannel_cred.dwVersion = Secur32Const.SCHANNEL_CRED_VERSION<EOL>schannel_cred.cCreds = <NUM_LIT:0><EOL>schannel_cred.paCred = null()<EOL>schannel_cred.hRootStore = null()<EOL>schannel_cred.cMappers = <NUM_LIT:0><EOL>schannel_cred.aphMappers = null()<EOL>schannel_cred.cSupportedAlgs = len(alg_array)<EOL>schannel_cred.palgSupportedAlgs = alg_array<EOL>schannel_cred.grbitEnabledProtocols = protocol_bit_mask<EOL>schannel_cred.dwMinimumCipherStrength = <NUM_LIT:0><EOL>schannel_cred.dwMaximumCipherStrength = <NUM_LIT:0><EOL>schannel_cred.dwSessionLifespan = <NUM_LIT:0><EOL>schannel_cred.dwFlags = flags<EOL>schannel_cred.dwCredFormat = <NUM_LIT:0><EOL>cred_handle_pointer = new(secur32, '<STR_LIT>')<EOL>result = secur32.AcquireCredentialsHandleW(<EOL>null(),<EOL>Secur32Const.UNISP_NAME,<EOL>Secur32Const.SECPKG_CRED_OUTBOUND,<EOL>null(),<EOL>schannel_cred_pointer,<EOL>null(),<EOL>null(),<EOL>cred_handle_pointer,<EOL>null()<EOL>)<EOL>handle_error(result)<EOL>self._credentials_handle = cred_handle_pointer<EOL>

Obtains a credentials handle from secur32.dll for use with SChannel


@classmethod<EOL><INDENT>def wrap(cls, socket, hostname, session=None):<DEDENT>

if not isinstance(socket, socket_.socket):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(socket)<EOL>))<EOL><DEDENT>if not isinstance(hostname, str_cls):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(hostname)<EOL>))<EOL><DEDENT>if session is not None and not isinstance(session, TLSSession):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(session)<EOL>))<EOL><DEDENT>new_socket = cls(None, None, session=session)<EOL>new_socket._socket = socket<EOL>new_socket._hostname = hostname<EOL>try:<EOL><INDENT>new_socket._handshake()<EOL><DEDENT>except (_TLSDowngradeError) as e:<EOL><INDENT>new_e = TLSVerificationError(e.message, e.certificate)<EOL>raise new_e<EOL><DEDENT>except (_TLSRetryError) as e:<EOL><INDENT>new_e = TLSError(e.message)<EOL>raise new_e<EOL><DEDENT>return new_socket<EOL>

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


def __init__(self, address, port, timeout=<NUM_LIT:10>, session=None):

self._received_bytes = b'<STR_LIT>'<EOL>self._decrypted_bytes = b'<STR_LIT>'<EOL>if address is None and port is None:<EOL><INDENT>self._socket = None<EOL><DEDENT>else:<EOL><INDENT>if not isinstance(address, str_cls):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(address)<EOL>))<EOL><DEDENT>if not isinstance(port, int_types):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(port)<EOL>))<EOL><DEDENT>if timeout is not None and not isinstance(timeout, numbers.Number):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(timeout)<EOL>))<EOL><DEDENT>self._socket = socket_.create_connection((address, port), timeout)<EOL>self._socket.settimeout(timeout)<EOL><DEDENT>if session is None:<EOL><INDENT>session = TLSSession()<EOL><DEDENT>elif not isinstance(session, TLSSession):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(session)<EOL>))<EOL><DEDENT>self._session = session<EOL>if self._socket:<EOL><INDENT>self._hostname = address<EOL>try:<EOL><INDENT>self._handshake()<EOL><DEDENT>except (_TLSDowngradeError):<EOL><INDENT>self.close()<EOL>new_session = TLSSession(<EOL>session._protocols - set(['<STR_LIT>']),<EOL>session._manual_validation,<EOL>session._extra_trust_roots<EOL>)<EOL>session.__del__()<EOL>self._received_bytes = b'<STR_LIT>'<EOL>self._session = new_session<EOL>self._socket = socket_.create_connection((address, port), timeout)<EOL>self._socket.settimeout(timeout)<EOL>self._handshake()<EOL><DEDENT>except (_TLSRetryError):<EOL><INDENT>self._received_bytes = b'<STR_LIT>'<EOL>self._socket = socket_.create_connection((address, port), timeout)<EOL>self._socket.settimeout(timeout)<EOL>self._handshake()<EOL><DEDENT><DEDENT>

:param address:
    A unicode string of the domain name or IP address to conenct 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


buffers = new(secur32, '<STR_LIT>' % number)<EOL>for index in range(<NUM_LIT:0>, number):<EOL><INDENT>buffers[index].cbBuffer = <NUM_LIT:0><EOL>buffers[index].BufferType = Secur32Const.SECBUFFER_EMPTY<EOL>buffers[index].pvBuffer = null()<EOL><DEDENT>sec_buffer_desc_pointer = struct(secur32, '<STR_LIT>')<EOL>sec_buffer_desc = unwrap(sec_buffer_desc_pointer)<EOL>sec_buffer_desc.ulVersion = Secur32Const.SECBUFFER_VERSION<EOL>sec_buffer_desc.cBuffers = number<EOL>sec_buffer_desc.pBuffers = buffers<EOL>return (sec_buffer_desc_pointer, buffers)<EOL>

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)


store = None<EOL>cert_chain_context_pointer = None<EOL>try:<EOL><INDENT>store = crypt32.CertOpenStore(<EOL>Crypt32Const.CERT_STORE_PROV_MEMORY,<EOL>Crypt32Const.X509_ASN_ENCODING,<EOL>null(),<EOL><NUM_LIT:0>,<EOL>null()<EOL>)<EOL>if is_null(store):<EOL><INDENT>handle_crypt32_error(<NUM_LIT:0>)<EOL><DEDENT>cert_hashes = set()<EOL>for cert in self._session._extra_trust_roots:<EOL><INDENT>cert_data = cert.dump()<EOL>result = crypt32.CertAddEncodedCertificateToStore(<EOL>store,<EOL>Crypt32Const.X509_ASN_ENCODING,<EOL>cert_data,<EOL>len(cert_data),<EOL>Crypt32Const.CERT_STORE_ADD_USE_EXISTING,<EOL>null()<EOL>)<EOL>if not result:<EOL><INDENT>handle_crypt32_error(<NUM_LIT:0>)<EOL><DEDENT>cert_hashes.add(cert.sha256)<EOL><DEDENT>cert_context_pointer_pointer = new(crypt32, '<STR_LIT>')<EOL>result = secur32.QueryContextAttributesW(<EOL>self._context_handle_pointer,<EOL>Secur32Const.SECPKG_ATTR_REMOTE_CERT_CONTEXT,<EOL>cert_context_pointer_pointer<EOL>)<EOL>handle_error(result)<EOL>cert_context_pointer = unwrap(cert_context_pointer_pointer)<EOL>cert_context_pointer = cast(crypt32, '<STR_LIT>', cert_context_pointer)<EOL>orig_now_pointer = new(kernel32, '<STR_LIT>')<EOL>kernel32.GetSystemTimeAsFileTime(orig_now_pointer)<EOL>now_pointer = cast(crypt32, '<STR_LIT>', orig_now_pointer)<EOL>usage_identifiers = new(crypt32, '<STR_LIT>')<EOL>usage_identifiers[<NUM_LIT:0>] = cast(crypt32, '<STR_LIT>', Crypt32Const.PKIX_KP_SERVER_AUTH)<EOL>usage_identifiers[<NUM_LIT:1>] = cast(crypt32, '<STR_LIT>', Crypt32Const.SERVER_GATED_CRYPTO)<EOL>usage_identifiers[<NUM_LIT:2>] = cast(crypt32, '<STR_LIT>', Crypt32Const.SGC_NETSCAPE)<EOL>cert_enhkey_usage_pointer = struct(crypt32, '<STR_LIT>')<EOL>cert_enhkey_usage = unwrap(cert_enhkey_usage_pointer)<EOL>cert_enhkey_usage.cUsageIdentifier = <NUM_LIT:3><EOL>cert_enhkey_usage.rgpszUsageIdentifier = cast(crypt32, '<STR_LIT>', usage_identifiers)<EOL>cert_usage_match_pointer = struct(crypt32, '<STR_LIT>')<EOL>cert_usage_match = unwrap(cert_usage_match_pointer)<EOL>cert_usage_match.dwType = Crypt32Const.USAGE_MATCH_TYPE_OR<EOL>cert_usage_match.Usage = cert_enhkey_usage<EOL>cert_chain_para_pointer = struct(crypt32, '<STR_LIT>')<EOL>cert_chain_para = unwrap(cert_chain_para_pointer)<EOL>cert_chain_para.RequestedUsage = cert_usage_match<EOL>cert_chain_para_size = sizeof(crypt32, cert_chain_para)<EOL>cert_chain_para.cbSize = cert_chain_para_size<EOL>cert_chain_context_pointer_pointer = new(crypt32, '<STR_LIT>')<EOL>result = crypt32.CertGetCertificateChain(<EOL>null(),<EOL>cert_context_pointer,<EOL>now_pointer,<EOL>store,<EOL>cert_chain_para_pointer,<EOL>Crypt32Const.CERT_CHAIN_CACHE_END_CERT | Crypt32Const.CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY,<EOL>null(),<EOL>cert_chain_context_pointer_pointer<EOL>)<EOL>handle_crypt32_error(result)<EOL>cert_chain_policy_para_flags = Crypt32Const.CERT_CHAIN_POLICY_IGNORE_ALL_REV_UNKNOWN_FLAGS<EOL>cert_chain_context_pointer = unwrap(cert_chain_context_pointer_pointer)<EOL>cert_chain_context = unwrap(cert_chain_context_pointer)<EOL>num_chains = native(int, cert_chain_context.cChain)<EOL>if num_chains == <NUM_LIT:1>:<EOL><INDENT>first_simple_chain_pointer = unwrap(cert_chain_context.rgpChain)<EOL>first_simple_chain = unwrap(first_simple_chain_pointer)<EOL>num_elements = native(int, first_simple_chain.cElement)<EOL>last_element_pointer = first_simple_chain.rgpElement[num_elements - <NUM_LIT:1>]<EOL>last_element = unwrap(last_element_pointer)<EOL>last_element_cert = unwrap(last_element.pCertContext)<EOL>last_element_cert_data = bytes_from_buffer(<EOL>last_element_cert.pbCertEncoded,<EOL>native(int, last_element_cert.cbCertEncoded)<EOL>)<EOL>last_cert = x509.Certificate.load(last_element_cert_data)<EOL>if last_cert.sha256 in cert_hashes:<EOL><INDENT>cert_chain_policy_para_flags |= Crypt32Const.CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG<EOL><DEDENT><DEDENT>ssl_extra_cert_chain_policy_para_pointer = struct(crypt32, '<STR_LIT>')<EOL>ssl_extra_cert_chain_policy_para = unwrap(ssl_extra_cert_chain_policy_para_pointer)<EOL>ssl_extra_cert_chain_policy_para.cbSize = sizeof(crypt32, ssl_extra_cert_chain_policy_para)<EOL>ssl_extra_cert_chain_policy_para.dwAuthType = Crypt32Const.AUTHTYPE_SERVER<EOL>ssl_extra_cert_chain_policy_para.fdwChecks = <NUM_LIT:0><EOL>ssl_extra_cert_chain_policy_para.pwszServerName = cast(<EOL>crypt32,<EOL>'<STR_LIT>',<EOL>buffer_from_unicode(self._hostname)<EOL>)<EOL>cert_chain_policy_para_pointer = struct(crypt32, '<STR_LIT>')<EOL>cert_chain_policy_para = unwrap(cert_chain_policy_para_pointer)<EOL>cert_chain_policy_para.cbSize = sizeof(crypt32, cert_chain_policy_para)<EOL>cert_chain_policy_para.dwFlags = cert_chain_policy_para_flags<EOL>cert_chain_policy_para.pvExtraPolicyPara = cast(crypt32, '<STR_LIT>', ssl_extra_cert_chain_policy_para_pointer)<EOL>cert_chain_policy_status_pointer = struct(crypt32, '<STR_LIT>')<EOL>cert_chain_policy_status = unwrap(cert_chain_policy_status_pointer)<EOL>cert_chain_policy_status.cbSize = sizeof(crypt32, cert_chain_policy_status)<EOL>result = crypt32.CertVerifyCertificateChainPolicy(<EOL>Crypt32Const.CERT_CHAIN_POLICY_SSL,<EOL>cert_chain_context_pointer,<EOL>cert_chain_policy_para_pointer,<EOL>cert_chain_policy_status_pointer<EOL>)<EOL>handle_crypt32_error(result)<EOL>cert_context = unwrap(cert_context_pointer)<EOL>cert_data = bytes_from_buffer(cert_context.pbCertEncoded, native(int, cert_context.cbCertEncoded))<EOL>cert = x509.Certificate.load(cert_data)<EOL>error = cert_chain_policy_status.dwError<EOL>if error:<EOL><INDENT>if error == Crypt32Const.CERT_E_EXPIRED:<EOL><INDENT>raise_expired_not_yet_valid(cert)<EOL><DEDENT>if error == Crypt32Const.CERT_E_UNTRUSTEDROOT:<EOL><INDENT>oscrypto_cert = load_certificate(cert)<EOL>if oscrypto_cert.self_signed:<EOL><INDENT>raise_self_signed(cert)<EOL><DEDENT>else:<EOL><INDENT>raise_no_issuer(cert)<EOL><DEDENT><DEDENT>if error == Crypt32Const.CERT_E_CN_NO_MATCH:<EOL><INDENT>raise_hostname(cert, self._hostname)<EOL><DEDENT>if error == Crypt32Const.TRUST_E_CERT_SIGNATURE:<EOL><INDENT>raise_weak_signature(cert)<EOL><DEDENT>if error == Crypt32Const.CRYPT_E_REVOKED:<EOL><INDENT>raise_revoked(cert)<EOL><DEDENT>raise_verification(cert)<EOL><DEDENT>if cert.hash_algo in set(['<STR_LIT>', '<STR_LIT>']):<EOL><INDENT>raise_weak_signature(cert)<EOL><DEDENT><DEDENT>finally:<EOL><INDENT>if store:<EOL><INDENT>crypt32.CertCloseStore(store, <NUM_LIT:0>)<EOL><DEDENT>if cert_chain_context_pointer:<EOL><INDENT>crypt32.CertFreeCertificateChain(cert_chain_context_pointer)<EOL><DEDENT><DEDENT>

Manually invoked windows certificate chain builder and verification
step when there are extra trust roots to include in the search process


in_buffers = None<EOL>out_buffers = None<EOL>new_context_handle_pointer = None<EOL>try:<EOL><INDENT>if renegotiate:<EOL><INDENT>temp_context_handle_pointer = self._context_handle_pointer<EOL><DEDENT>else:<EOL><INDENT>new_context_handle_pointer = new(secur32, '<STR_LIT>')<EOL>temp_context_handle_pointer = new_context_handle_pointer<EOL><DEDENT>requested_flags = {<EOL>Secur32Const.ISC_REQ_REPLAY_DETECT: '<STR_LIT>',<EOL>Secur32Const.ISC_REQ_SEQUENCE_DETECT: '<STR_LIT>',<EOL>Secur32Const.ISC_REQ_CONFIDENTIALITY: '<STR_LIT>',<EOL>Secur32Const.ISC_REQ_ALLOCATE_MEMORY: '<STR_LIT>',<EOL>Secur32Const.ISC_REQ_INTEGRITY: '<STR_LIT>',<EOL>Secur32Const.ISC_REQ_STREAM: '<STR_LIT>',<EOL>Secur32Const.ISC_REQ_USE_SUPPLIED_CREDS: '<STR_LIT>',<EOL>}<EOL>self._context_flags = <NUM_LIT:0><EOL>for flag in requested_flags:<EOL><INDENT>self._context_flags |= flag<EOL><DEDENT>in_sec_buffer_desc_pointer, in_buffers = self._create_buffers(<NUM_LIT:2>)<EOL>in_buffers[<NUM_LIT:0>].BufferType = Secur32Const.SECBUFFER_TOKEN<EOL>out_sec_buffer_desc_pointer, out_buffers = self._create_buffers(<NUM_LIT:2>)<EOL>out_buffers[<NUM_LIT:0>].BufferType = Secur32Const.SECBUFFER_TOKEN<EOL>out_buffers[<NUM_LIT:1>].BufferType = Secur32Const.SECBUFFER_ALERT<EOL>output_context_flags_pointer = new(secur32, '<STR_LIT>')<EOL>if renegotiate:<EOL><INDENT>first_handle = temp_context_handle_pointer<EOL>second_handle = null()<EOL><DEDENT>else:<EOL><INDENT>first_handle = null()<EOL>second_handle = temp_context_handle_pointer<EOL><DEDENT>result = secur32.InitializeSecurityContextW(<EOL>self._session._credentials_handle,<EOL>first_handle,<EOL>self._hostname,<EOL>self._context_flags,<EOL><NUM_LIT:0>,<EOL><NUM_LIT:0>,<EOL>null(),<EOL><NUM_LIT:0>,<EOL>second_handle,<EOL>out_sec_buffer_desc_pointer,<EOL>output_context_flags_pointer,<EOL>null()<EOL>)<EOL>if result not in set([Secur32Const.SEC_E_OK, Secur32Const.SEC_I_CONTINUE_NEEDED]):<EOL><INDENT>handle_error(result, TLSError)<EOL><DEDENT>if not renegotiate:<EOL><INDENT>temp_context_handle_pointer = second_handle<EOL><DEDENT>else:<EOL><INDENT>temp_context_handle_pointer = first_handle<EOL><DEDENT>handshake_server_bytes = b'<STR_LIT>'<EOL>handshake_client_bytes = b'<STR_LIT>'<EOL>if out_buffers[<NUM_LIT:0>].cbBuffer > <NUM_LIT:0>:<EOL><INDENT>token = bytes_from_buffer(out_buffers[<NUM_LIT:0>].pvBuffer, out_buffers[<NUM_LIT:0>].cbBuffer)<EOL>handshake_client_bytes += token<EOL>self._socket.send(token)<EOL>out_buffers[<NUM_LIT:0>].cbBuffer = <NUM_LIT:0><EOL>secur32.FreeContextBuffer(out_buffers[<NUM_LIT:0>].pvBuffer)<EOL>out_buffers[<NUM_LIT:0>].pvBuffer = null()<EOL><DEDENT>in_data_buffer = buffer_from_bytes(<NUM_LIT>)<EOL>in_buffers[<NUM_LIT:0>].pvBuffer = cast(secur32, '<STR_LIT>', in_data_buffer)<EOL>bytes_read = b'<STR_LIT>'<EOL>while result != Secur32Const.SEC_E_OK:<EOL><INDENT>try:<EOL><INDENT>fail_late = False<EOL>bytes_read = self._socket.recv(<NUM_LIT>)<EOL>if bytes_read == b'<STR_LIT>':<EOL><INDENT>raise_disconnection()<EOL><DEDENT><DEDENT>except (socket_error_cls):<EOL><INDENT>fail_late = True<EOL><DEDENT>handshake_server_bytes += bytes_read<EOL>self._received_bytes += bytes_read<EOL>in_buffers[<NUM_LIT:0>].cbBuffer = len(self._received_bytes)<EOL>write_to_buffer(in_data_buffer, self._received_bytes)<EOL>result = secur32.InitializeSecurityContextW(<EOL>self._session._credentials_handle,<EOL>temp_context_handle_pointer,<EOL>self._hostname,<EOL>self._context_flags,<EOL><NUM_LIT:0>,<EOL><NUM_LIT:0>,<EOL>in_sec_buffer_desc_pointer,<EOL><NUM_LIT:0>,<EOL>null(),<EOL>out_sec_buffer_desc_pointer,<EOL>output_context_flags_pointer,<EOL>null()<EOL>)<EOL>if result == Secur32Const.SEC_E_INCOMPLETE_MESSAGE:<EOL><INDENT>in_buffers[<NUM_LIT:0>].BufferType = Secur32Const.SECBUFFER_TOKEN<EOL>if in_buffers[<NUM_LIT:1>].BufferType != Secur32Const.SECBUFFER_EMPTY:<EOL><INDENT>in_buffers[<NUM_LIT:1>].BufferType = Secur32Const.SECBUFFER_EMPTY<EOL>in_buffers[<NUM_LIT:1>].cbBuffer = <NUM_LIT:0><EOL>if not is_null(in_buffers[<NUM_LIT:1>].pvBuffer):<EOL><INDENT>secur32.FreeContextBuffer(in_buffers[<NUM_LIT:1>].pvBuffer)<EOL>in_buffers[<NUM_LIT:1>].pvBuffer = null()<EOL><DEDENT><DEDENT>if fail_late:<EOL><INDENT>raise_disconnection()<EOL><DEDENT>continue<EOL><DEDENT>if result == Secur32Const.SEC_E_ILLEGAL_MESSAGE:<EOL><INDENT>if detect_client_auth_request(handshake_server_bytes):<EOL><INDENT>raise_client_auth()<EOL><DEDENT>alert_info = parse_alert(handshake_server_bytes)<EOL>if alert_info and alert_info == (<NUM_LIT:2>, <NUM_LIT>):<EOL><INDENT>raise_protocol_version()<EOL><DEDENT>raise_handshake()<EOL><DEDENT>if result == Secur32Const.SEC_E_WRONG_PRINCIPAL:<EOL><INDENT>chain = extract_chain(handshake_server_bytes)<EOL>raise_hostname(chain[<NUM_LIT:0>], self._hostname)<EOL><DEDENT>if result == Secur32Const.SEC_E_CERT_EXPIRED:<EOL><INDENT>chain = extract_chain(handshake_server_bytes)<EOL>raise_expired_not_yet_valid(chain[<NUM_LIT:0>])<EOL><DEDENT>if result == Secur32Const.SEC_E_UNTRUSTED_ROOT:<EOL><INDENT>chain = extract_chain(handshake_server_bytes)<EOL>cert = chain[<NUM_LIT:0>]<EOL>oscrypto_cert = load_certificate(cert)<EOL>if not oscrypto_cert.self_signed:<EOL><INDENT>raise_no_issuer(cert)<EOL><DEDENT>raise_self_signed(cert)<EOL><DEDENT>if result == Secur32Const.SEC_E_INTERNAL_ERROR:<EOL><INDENT>if get_dh_params_length(handshake_server_bytes) < <NUM_LIT>:<EOL><INDENT>raise_dh_params()<EOL><DEDENT><DEDENT>if result == Secur32Const.SEC_I_INCOMPLETE_CREDENTIALS:<EOL><INDENT>raise_client_auth()<EOL><DEDENT>if result == Crypt32Const.TRUST_E_CERT_SIGNATURE:<EOL><INDENT>raise_weak_signature(cert)<EOL><DEDENT>if result == Secur32Const.SEC_E_INVALID_TOKEN:<EOL><INDENT>if out_buffers[<NUM_LIT:1>].cbBuffer > <NUM_LIT:0>:<EOL><INDENT>alert_bytes = bytes_from_buffer(out_buffers[<NUM_LIT:1>].pvBuffer, out_buffers[<NUM_LIT:1>].cbBuffer)<EOL>handshake_client_bytes += alert_bytes<EOL>alert_number = alert_bytes[<NUM_LIT:6>:<NUM_LIT:7>]<EOL>if alert_number == b'<STR_LIT>' or alert_number == b'<STR_LIT>':<EOL><INDENT>if '<STR_LIT>' in self._session._protocols and len(self._session._protocols) > <NUM_LIT:1>:<EOL><INDENT>chain = extract_chain(handshake_server_bytes)<EOL>raise _TLSDowngradeError(<EOL>'<STR_LIT>',<EOL>chain[<NUM_LIT:0>]<EOL>)<EOL><DEDENT><DEDENT><DEDENT>if detect_client_auth_request(handshake_server_bytes):<EOL><INDENT>raise_client_auth()<EOL><DEDENT>if detect_other_protocol(handshake_server_bytes):<EOL><INDENT>raise_protocol_error(handshake_server_bytes)<EOL><DEDENT>raise_handshake()<EOL><DEDENT>if result == Secur32Const.SEC_E_BUFFER_TOO_SMALL or result == Secur32Const.SEC_E_MESSAGE_ALTERED:<EOL><INDENT>if '<STR_LIT>' in self._session._protocols:<EOL><INDENT>raise _TLSRetryError('<STR_LIT>')<EOL><DEDENT><DEDENT>if fail_late:<EOL><INDENT>raise_disconnection()<EOL><DEDENT>if result == Secur32Const.SEC_E_INVALID_PARAMETER:<EOL><INDENT>if get_dh_params_length(handshake_server_bytes) < <NUM_LIT>:<EOL><INDENT>raise_dh_params()<EOL><DEDENT><DEDENT>if result not in set([Secur32Const.SEC_E_OK, Secur32Const.SEC_I_CONTINUE_NEEDED]):<EOL><INDENT>handle_error(result, TLSError)<EOL><DEDENT>if out_buffers[<NUM_LIT:0>].cbBuffer > <NUM_LIT:0>:<EOL><INDENT>token = bytes_from_buffer(out_buffers[<NUM_LIT:0>].pvBuffer, out_buffers[<NUM_LIT:0>].cbBuffer)<EOL>handshake_client_bytes += token<EOL>self._socket.send(token)<EOL>out_buffers[<NUM_LIT:0>].cbBuffer = <NUM_LIT:0><EOL>secur32.FreeContextBuffer(out_buffers[<NUM_LIT:0>].pvBuffer)<EOL>out_buffers[<NUM_LIT:0>].pvBuffer = null()<EOL><DEDENT>if in_buffers[<NUM_LIT:1>].BufferType == Secur32Const.SECBUFFER_EXTRA:<EOL><INDENT>extra_amount = in_buffers[<NUM_LIT:1>].cbBuffer<EOL>self._received_bytes = self._received_bytes[-extra_amount:]<EOL>in_buffers[<NUM_LIT:1>].BufferType = Secur32Const.SECBUFFER_EMPTY<EOL>in_buffers[<NUM_LIT:1>].cbBuffer = <NUM_LIT:0><EOL>secur32.FreeContextBuffer(in_buffers[<NUM_LIT:1>].pvBuffer)<EOL>in_buffers[<NUM_LIT:1>].pvBuffer = null()<EOL>if result == Secur32Const.SEC_E_OK:<EOL><INDENT>handshake_server_bytes = handshake_server_bytes[-extra_amount:]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>self._received_bytes = b'<STR_LIT>'<EOL><DEDENT><DEDENT>connection_info_pointer = struct(secur32, '<STR_LIT>')<EOL>result = secur32.QueryContextAttributesW(<EOL>temp_context_handle_pointer,<EOL>Secur32Const.SECPKG_ATTR_CONNECTION_INFO,<EOL>connection_info_pointer<EOL>)<EOL>handle_error(result, TLSError)<EOL>connection_info = unwrap(connection_info_pointer)<EOL>self._protocol = {<EOL>Secur32Const.SP_PROT_SSL2_CLIENT: '<STR_LIT>',<EOL>Secur32Const.SP_PROT_SSL3_CLIENT: '<STR_LIT>',<EOL>Secur32Const.SP_PROT_TLS1_CLIENT: '<STR_LIT>',<EOL>Secur32Const.SP_PROT_TLS1_1_CLIENT: '<STR_LIT>',<EOL>Secur32Const.SP_PROT_TLS1_2_CLIENT: '<STR_LIT>',<EOL>}.get(native(int, connection_info.dwProtocol), str_cls(connection_info.dwProtocol))<EOL>if self._protocol in set(['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']):<EOL><INDENT>session_info = parse_session_info(handshake_server_bytes, handshake_client_bytes)<EOL>self._cipher_suite = session_info['<STR_LIT>']<EOL>self._compression = session_info['<STR_LIT>']<EOL>self._session_id = session_info['<STR_LIT>']<EOL>self._session_ticket = session_info['<STR_LIT>']<EOL><DEDENT>output_context_flags = deref(output_context_flags_pointer)<EOL>for flag in requested_flags:<EOL><INDENT>if (flag | output_context_flags) == <NUM_LIT:0>:<EOL><INDENT>raise OSError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>requested_flags[flag]<EOL>))<EOL><DEDENT><DEDENT>if not renegotiate:<EOL><INDENT>self._context_handle_pointer = temp_context_handle_pointer<EOL>new_context_handle_pointer = None<EOL>stream_sizes_pointer = struct(secur32, '<STR_LIT>')<EOL>result = secur32.QueryContextAttributesW(<EOL>self._context_handle_pointer,<EOL>Secur32Const.SECPKG_ATTR_STREAM_SIZES,<EOL>stream_sizes_pointer<EOL>)<EOL>handle_error(result)<EOL>stream_sizes = unwrap(stream_sizes_pointer)<EOL>self._header_size = native(int, stream_sizes.cbHeader)<EOL>self._message_size = native(int, stream_sizes.cbMaximumMessage)<EOL>self._trailer_size = native(int, stream_sizes.cbTrailer)<EOL>self._buffer_size = self._header_size + self._message_size + self._trailer_size<EOL><DEDENT>if self._session._extra_trust_roots:<EOL><INDENT>self._extra_trust_root_validation()<EOL><DEDENT><DEDENT>except (OSError, socket_.error):<EOL><INDENT>self.close()<EOL>raise<EOL><DEDENT>finally:<EOL><INDENT>if out_buffers:<EOL><INDENT>if not is_null(out_buffers[<NUM_LIT:0>].pvBuffer):<EOL><INDENT>secur32.FreeContextBuffer(out_buffers[<NUM_LIT:0>].pvBuffer)<EOL><DEDENT>if not is_null(out_buffers[<NUM_LIT:1>].pvBuffer):<EOL><INDENT>secur32.FreeContextBuffer(out_buffers[<NUM_LIT:1>].pvBuffer)<EOL><DEDENT><DEDENT>if new_context_handle_pointer:<EOL><INDENT>secur32.DeleteSecurityContext(new_context_handle_pointer)<EOL><DEDENT><DEDENT>

Perform an initial TLS handshake, or a renegotiation

:param renegotiate:
    If the handshake is for a renegotiation


if not isinstance(max_length, int_types):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(max_length)<EOL>))<EOL><DEDENT>if self._context_handle_pointer is None:<EOL><INDENT>if self._decrypted_bytes != b'<STR_LIT>':<EOL><INDENT>output = self._decrypted_bytes[<NUM_LIT:0>:max_length]<EOL>self._decrypted_bytes = self._decrypted_bytes[max_length:]<EOL>return output<EOL><DEDENT>self._raise_closed()<EOL><DEDENT>if not self._decrypt_data_buffer:<EOL><INDENT>self._decrypt_data_buffer = buffer_from_bytes(self._buffer_size)<EOL>self._decrypt_desc, self._decrypt_buffers = self._create_buffers(<NUM_LIT:4>)<EOL>self._decrypt_buffers[<NUM_LIT:0>].BufferType = Secur32Const.SECBUFFER_DATA<EOL>self._decrypt_buffers[<NUM_LIT:0>].pvBuffer = cast(secur32, '<STR_LIT>', self._decrypt_data_buffer)<EOL><DEDENT>to_recv = max(max_length, self._buffer_size)<EOL>null_value = null()<EOL>buf0 = self._decrypt_buffers[<NUM_LIT:0>]<EOL>buf1 = self._decrypt_buffers[<NUM_LIT:1>]<EOL>buf2 = self._decrypt_buffers[<NUM_LIT:2>]<EOL>buf3 = self._decrypt_buffers[<NUM_LIT:3>]<EOL>def _reset_buffers():<EOL><INDENT>buf0.BufferType = Secur32Const.SECBUFFER_DATA<EOL>buf0.pvBuffer = cast(secur32, '<STR_LIT>', self._decrypt_data_buffer)<EOL>buf0.cbBuffer = <NUM_LIT:0><EOL>buf1.BufferType = Secur32Const.SECBUFFER_EMPTY<EOL>buf1.pvBuffer = null_value<EOL>buf1.cbBuffer = <NUM_LIT:0><EOL>buf2.BufferType = Secur32Const.SECBUFFER_EMPTY<EOL>buf2.pvBuffer = null_value<EOL>buf2.cbBuffer = <NUM_LIT:0><EOL>buf3.BufferType = Secur32Const.SECBUFFER_EMPTY<EOL>buf3.pvBuffer = null_value<EOL>buf3.cbBuffer = <NUM_LIT:0><EOL><DEDENT>output = self._decrypted_bytes<EOL>output_len = len(output)<EOL>self._decrypted_bytes = b'<STR_LIT>'<EOL>if output_len > <NUM_LIT:0> and not self.select_read(<NUM_LIT:0>):<EOL><INDENT>self._decrypted_bytes = b'<STR_LIT>'<EOL>return output<EOL><DEDENT>do_read = len(self._received_bytes) == <NUM_LIT:0><EOL>while output_len < max_length:<EOL><INDENT>if do_read:<EOL><INDENT>self._received_bytes += self._socket.recv(to_recv)<EOL>if len(self._received_bytes) == <NUM_LIT:0>:<EOL><INDENT>raise_disconnection()<EOL><DEDENT><DEDENT>data_len = min(len(self._received_bytes), self._buffer_size)<EOL>if data_len == <NUM_LIT:0>:<EOL><INDENT>break<EOL><DEDENT>self._decrypt_buffers[<NUM_LIT:0>].cbBuffer = data_len<EOL>write_to_buffer(self._decrypt_data_buffer, self._received_bytes[<NUM_LIT:0>:data_len])<EOL>result = secur32.DecryptMessage(<EOL>self._context_handle_pointer,<EOL>self._decrypt_desc,<EOL><NUM_LIT:0>,<EOL>null()<EOL>)<EOL>do_read = False<EOL>if result == Secur32Const.SEC_E_INCOMPLETE_MESSAGE:<EOL><INDENT>_reset_buffers()<EOL>do_read = True<EOL>continue<EOL><DEDENT>elif result == Secur32Const.SEC_I_CONTEXT_EXPIRED:<EOL><INDENT>self._remote_closed = True<EOL>self.shutdown()<EOL>break<EOL><DEDENT>elif result == Secur32Const.SEC_I_RENEGOTIATE:<EOL><INDENT>self._handshake(renegotiate=True)<EOL>return self.read(max_length)<EOL><DEDENT>elif result != Secur32Const.SEC_E_OK:<EOL><INDENT>handle_error(result, TLSError)<EOL><DEDENT>valid_buffer_types = set([<EOL>Secur32Const.SECBUFFER_EMPTY,<EOL>Secur32Const.SECBUFFER_STREAM_HEADER,<EOL>Secur32Const.SECBUFFER_STREAM_TRAILER<EOL>])<EOL>extra_amount = None<EOL>for buf in (buf0, buf1, buf2, buf3):<EOL><INDENT>buffer_type = buf.BufferType<EOL>if buffer_type == Secur32Const.SECBUFFER_DATA:<EOL><INDENT>output += bytes_from_buffer(buf.pvBuffer, buf.cbBuffer)<EOL>output_len = len(output)<EOL><DEDENT>elif buffer_type == Secur32Const.SECBUFFER_EXTRA:<EOL><INDENT>extra_amount = native(int, buf.cbBuffer)<EOL><DEDENT>elif buffer_type not in valid_buffer_types:<EOL><INDENT>raise OSError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>buffer_type<EOL>))<EOL><DEDENT><DEDENT>if extra_amount:<EOL><INDENT>self._received_bytes = self._received_bytes[data_len - extra_amount:]<EOL><DEDENT>else:<EOL><INDENT>self._received_bytes = self._received_bytes[data_len:]<EOL><DEDENT>_reset_buffers()<EOL>if self.select_read(<NUM_LIT:0>):<EOL><INDENT>do_read = True<EOL><DEDENT>if not do_read and len(self._received_bytes) == <NUM_LIT:0>:<EOL><INDENT>break<EOL><DEDENT><DEDENT>if len(output) > max_length:<EOL><INDENT>self._decrypted_bytes = output[max_length:]<EOL>output = output[<NUM_LIT:0>:max_length]<EOL><DEDENT>return output<EOL>

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


<EOL>if len(self._decrypted_bytes) > <NUM_LIT:0>:<EOL><INDENT>return True<EOL><DEDENT>read_ready, _, _ = select.select([self._socket], [], [], timeout)<EOL>return len(read_ready) > <NUM_LIT:0><EOL>

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 not isinstance(marker, byte_cls) and not isinstance(marker, Pattern):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(marker)<EOL>))<EOL><DEDENT>output = b'<STR_LIT>'<EOL>is_regex = isinstance(marker, Pattern)<EOL>while True:<EOL><INDENT>if len(self._decrypted_bytes) > <NUM_LIT:0>:<EOL><INDENT>chunk = self._decrypted_bytes<EOL>self._decrypted_bytes = b'<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>chunk = self.read(<NUM_LIT>)<EOL><DEDENT>offset = len(output)<EOL>output += chunk<EOL>if is_regex:<EOL><INDENT>match = marker.search(output)<EOL>if match is not None:<EOL><INDENT>end = match.end()<EOL>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>start = max(<NUM_LIT:0>, offset - len(marker) - <NUM_LIT:1>)<EOL>match = output.find(marker, start)<EOL>if match != -<NUM_LIT:1>:<EOL><INDENT>end = match + len(marker)<EOL>break<EOL><DEDENT><DEDENT><DEDENT>self._decrypted_bytes = output[end:] + self._decrypted_bytes<EOL>return output[<NUM_LIT:0>:end]<EOL>

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


return self.read_until(_line_regex)<EOL>

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


output = b'<STR_LIT>'<EOL>remaining = num_bytes<EOL>while remaining > <NUM_LIT:0>:<EOL><INDENT>output += self.read(remaining)<EOL>remaining = num_bytes - len(output)<EOL><DEDENT>return output<EOL>

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


if self._context_handle_pointer is None:<EOL><INDENT>self._raise_closed()<EOL><DEDENT>if not self._encrypt_data_buffer:<EOL><INDENT>self._encrypt_data_buffer = buffer_from_bytes(self._header_size + self._message_size + self._trailer_size)<EOL>self._encrypt_desc, self._encrypt_buffers = self._create_buffers(<NUM_LIT:4>)<EOL>self._encrypt_buffers[<NUM_LIT:0>].BufferType = Secur32Const.SECBUFFER_STREAM_HEADER<EOL>self._encrypt_buffers[<NUM_LIT:0>].cbBuffer = self._header_size<EOL>self._encrypt_buffers[<NUM_LIT:0>].pvBuffer = cast(secur32, '<STR_LIT>', self._encrypt_data_buffer)<EOL>self._encrypt_buffers[<NUM_LIT:1>].BufferType = Secur32Const.SECBUFFER_DATA<EOL>self._encrypt_buffers[<NUM_LIT:1>].pvBuffer = ref(self._encrypt_data_buffer, self._header_size)<EOL>self._encrypt_buffers[<NUM_LIT:2>].BufferType = Secur32Const.SECBUFFER_STREAM_TRAILER<EOL>self._encrypt_buffers[<NUM_LIT:2>].cbBuffer = self._trailer_size<EOL>self._encrypt_buffers[<NUM_LIT:2>].pvBuffer = ref(self._encrypt_data_buffer, self._header_size + self._message_size)<EOL><DEDENT>while len(data) > <NUM_LIT:0>:<EOL><INDENT>to_write = min(len(data), self._message_size)<EOL>write_to_buffer(self._encrypt_data_buffer, data[<NUM_LIT:0>:to_write], self._header_size)<EOL>self._encrypt_buffers[<NUM_LIT:1>].cbBuffer = to_write<EOL>self._encrypt_buffers[<NUM_LIT:2>].pvBuffer = ref(self._encrypt_data_buffer, self._header_size + to_write)<EOL>result = secur32.EncryptMessage(<EOL>self._context_handle_pointer,<EOL><NUM_LIT:0>,<EOL>self._encrypt_desc,<EOL><NUM_LIT:0><EOL>)<EOL>if result != Secur32Const.SEC_E_OK:<EOL><INDENT>handle_error(result, TLSError)<EOL><DEDENT>to_send = native(int, self._encrypt_buffers[<NUM_LIT:0>].cbBuffer)<EOL>to_send += native(int, self._encrypt_buffers[<NUM_LIT:1>].cbBuffer)<EOL>to_send += native(int, self._encrypt_buffers[<NUM_LIT:2>].cbBuffer)<EOL>try:<EOL><INDENT>self._socket.send(bytes_from_buffer(self._encrypt_data_buffer, to_send))<EOL><DEDENT>except (socket_.error) as e:<EOL><INDENT>if e.errno == <NUM_LIT>:<EOL><INDENT>raise_disconnection()<EOL><DEDENT>raise<EOL><DEDENT>data = data[to_send:]<EOL><DEDENT>

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


_, write_ready, _ = select.select([], [self._socket], [], timeout)<EOL>return len(write_ready) > <NUM_LIT:0><EOL>

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.


if self._context_handle_pointer is None:<EOL><INDENT>return<EOL><DEDENT>out_buffers = None<EOL>try:<EOL><INDENT>if _win_version_info >= (<NUM_LIT:6>, <NUM_LIT:2>):<EOL><INDENT>buffers = new(secur32, '<STR_LIT>')<EOL>buffers[<NUM_LIT:0>].cbBuffer = <NUM_LIT:4><EOL>buffers[<NUM_LIT:0>].BufferType = Secur32Const.SECBUFFER_TOKEN<EOL>buffers[<NUM_LIT:0>].pvBuffer = cast(secur32, '<STR_LIT>', buffer_from_bytes(b'<STR_LIT>'))<EOL>sec_buffer_desc_pointer = struct(secur32, '<STR_LIT>')<EOL>sec_buffer_desc = unwrap(sec_buffer_desc_pointer)<EOL>sec_buffer_desc.ulVersion = Secur32Const.SECBUFFER_VERSION<EOL>sec_buffer_desc.cBuffers = <NUM_LIT:1><EOL>sec_buffer_desc.pBuffers = buffers<EOL>result = secur32.ApplyControlToken(self._context_handle_pointer, sec_buffer_desc_pointer)<EOL>handle_error(result, TLSError)<EOL><DEDENT>out_sec_buffer_desc_pointer, out_buffers = self._create_buffers(<NUM_LIT:2>)<EOL>out_buffers[<NUM_LIT:0>].BufferType = Secur32Const.SECBUFFER_TOKEN<EOL>out_buffers[<NUM_LIT:1>].BufferType = Secur32Const.SECBUFFER_ALERT<EOL>output_context_flags_pointer = new(secur32, '<STR_LIT>')<EOL>result = secur32.InitializeSecurityContextW(<EOL>self._session._credentials_handle,<EOL>self._context_handle_pointer,<EOL>self._hostname,<EOL>self._context_flags,<EOL><NUM_LIT:0>,<EOL><NUM_LIT:0>,<EOL>null(),<EOL><NUM_LIT:0>,<EOL>null(),<EOL>out_sec_buffer_desc_pointer,<EOL>output_context_flags_pointer,<EOL>null()<EOL>)<EOL>acceptable_results = set([<EOL>Secur32Const.SEC_E_OK,<EOL>Secur32Const.SEC_E_CONTEXT_EXPIRED,<EOL>Secur32Const.SEC_I_CONTINUE_NEEDED<EOL>])<EOL>if result not in acceptable_results:<EOL><INDENT>handle_error(result, TLSError)<EOL><DEDENT>token = bytes_from_buffer(out_buffers[<NUM_LIT:0>].pvBuffer, out_buffers[<NUM_LIT:0>].cbBuffer)<EOL>try:<EOL><INDENT>self._socket.send(token)<EOL><DEDENT>except (socket_.error):<EOL><INDENT>pass<EOL><DEDENT><DEDENT>finally:<EOL><INDENT>if out_buffers:<EOL><INDENT>if not is_null(out_buffers[<NUM_LIT:0>].pvBuffer):<EOL><INDENT>secur32.FreeContextBuffer(out_buffers[<NUM_LIT:0>].pvBuffer)<EOL><DEDENT>if not is_null(out_buffers[<NUM_LIT:1>].pvBuffer):<EOL><INDENT>secur32.FreeContextBuffer(out_buffers[<NUM_LIT:1>].pvBuffer)<EOL><DEDENT><DEDENT>secur32.DeleteSecurityContext(self._context_handle_pointer)<EOL>self._context_handle_pointer = None<EOL>try:<EOL><INDENT>self._socket.shutdown(socket_.SHUT_RDWR)<EOL><DEDENT>except (socket_.error):<EOL><INDENT>pass<EOL><DEDENT><DEDENT>

Shuts down the TLS session and then shuts down the underlying socket

:raises:
    OSError - when an error is returned by the OS crypto library


try:<EOL><INDENT>self.shutdown()<EOL><DEDENT>finally:<EOL><INDENT>if self._socket:<EOL><INDENT>try:<EOL><INDENT>self._socket.close()<EOL><DEDENT>except (socket_.error):<EOL><INDENT>pass<EOL><DEDENT>self._socket = None<EOL><DEDENT><DEDENT>

Shuts down the TLS session and socket and forcibly closes it


cert_context_pointer_pointer = new(crypt32, '<STR_LIT>')<EOL>result = secur32.QueryContextAttributesW(<EOL>self._context_handle_pointer,<EOL>Secur32Const.SECPKG_ATTR_REMOTE_CERT_CONTEXT,<EOL>cert_context_pointer_pointer<EOL>)<EOL>handle_error(result, TLSError)<EOL>cert_context_pointer = unwrap(cert_context_pointer_pointer)<EOL>cert_context_pointer = cast(crypt32, '<STR_LIT>', cert_context_pointer)<EOL>cert_context = unwrap(cert_context_pointer)<EOL>cert_data = bytes_from_buffer(cert_context.pbCertEncoded, native(int, cert_context.cbCertEncoded))<EOL>self._certificate = x509.Certificate.load(cert_data)<EOL>self._intermediates = []<EOL>store_handle = None<EOL>try:<EOL><INDENT>store_handle = cert_context.hCertStore<EOL>context_pointer = crypt32.CertEnumCertificatesInStore(store_handle, null())<EOL>while not is_null(context_pointer):<EOL><INDENT>context = unwrap(context_pointer)<EOL>data = bytes_from_buffer(context.pbCertEncoded, native(int, context.cbCertEncoded))<EOL>if data != cert_data:<EOL><INDENT>self._intermediates.append(x509.Certificate.load(data))<EOL><DEDENT>context_pointer = crypt32.CertEnumCertificatesInStore(store_handle, context_pointer)<EOL><DEDENT><DEDENT>finally:<EOL><INDENT>if store_handle:<EOL><INDENT>crypt32.CertCloseStore(store_handle, <NUM_LIT:0>)<EOL><DEDENT><DEDENT>

Reads end-entity and intermediate certificate information from the
TLS session


if self._remote_closed:<EOL><INDENT>raise TLSGracefulDisconnectError('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>raise TLSDisconnectError('<STR_LIT>')<EOL><DEDENT>

Raises an exception describing if the local or remote end closed the
connection


if self._context_handle_pointer is None:<EOL><INDENT>self._raise_closed()<EOL><DEDENT>if self._certificate is None:<EOL><INDENT>self._read_certificates()<EOL><DEDENT>return self._certificate<EOL>

An asn1crypto.x509.Certificate object of the end-entity certificate
presented by the server


if self._context_handle_pointer is None:<EOL><INDENT>self._raise_closed()<EOL><DEDENT>if self._certificate is None:<EOL><INDENT>self._read_certificates()<EOL><DEDENT>return self._intermediates<EOL>

A list of asn1crypto.x509.Certificate objects that were presented as
intermediates by the server


return self._cipher_suite<EOL>

A unicode string of the IANA cipher suite name of the negotiated
cipher suite


return self._protocol<EOL>

A unicode string of: "TLSv1.2", "TLSv1.1", "TLSv1", "SSLv3"


return self._compression<EOL>


return self._session_id<EOL>

A unicode string of "new" or "reused" or None for no ticket


return self._session_ticket<EOL>


return self._session<EOL>

The oscrypto.tls.TLSSession object used for this connection


return self._hostname<EOL>

A unicode string of the TLS server domain name or IP address


return self.socket.getpeername()[<NUM_LIT:1>]<EOL>

An integer of the port number the socket is connected to


if self._context_handle_pointer is None:<EOL><INDENT>self._raise_closed()<EOL><DEDENT>return self._socket<EOL>


if result:<EOL><INDENT>return<EOL><DEDENT>code, error_string = get_error()<EOL>if code == Advapi32Const.NTE_BAD_SIGNATURE:<EOL><INDENT>raise SignatureError('<STR_LIT>')<EOL><DEDENT>if not isinstance(error_string, str_cls):<EOL><INDENT>error_string = _try_decode(error_string)<EOL><DEDENT>raise OSError(error_string)<EOL>

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 == <NUM_LIT:0>:<EOL><INDENT>return<EOL><DEDENT>if result == Secur32Const.SEC_E_OUT_OF_SEQUENCE:<EOL><INDENT>raise TLSError('<STR_LIT>')<EOL><DEDENT>if result == Secur32Const.SEC_E_MESSAGE_ALTERED:<EOL><INDENT>raise TLSError('<STR_LIT>')<EOL><DEDENT>if result == Secur32Const.SEC_E_CONTEXT_EXPIRED:<EOL><INDENT>raise TLSError('<STR_LIT>')<EOL><DEDENT>_, error_string = get_error()<EOL>if not isinstance(error_string, str_cls):<EOL><INDENT>error_string = _try_decode(error_string)<EOL><DEDENT>if exception_class is None:<EOL><INDENT>exception_class = OSError<EOL><DEDENT>raise exception_class(('<STR_LIT>' % result) + error_string)<EOL>

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


def generate_pair(algorithm, bit_size=None, curve=None):

if algorithm not in set(['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']):<EOL><INDENT>raise ValueError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>repr(algorithm)<EOL>))<EOL><DEDENT>if algorithm == '<STR_LIT>':<EOL><INDENT>if bit_size not in set([<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>]):<EOL><INDENT>raise ValueError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>repr(bit_size)<EOL>))<EOL><DEDENT><DEDENT>elif algorithm == '<STR_LIT>':<EOL><INDENT>if _win_version_info < (<NUM_LIT:6>, <NUM_LIT:2>) or _backend == '<STR_LIT>':<EOL><INDENT>if bit_size != <NUM_LIT>:<EOL><INDENT>raise ValueError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>repr(bit_size)<EOL>))<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if bit_size not in set([<NUM_LIT>, <NUM_LIT>, <NUM_LIT>]):<EOL><INDENT>raise ValueError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>repr(bit_size)<EOL>))<EOL><DEDENT><DEDENT><DEDENT>elif algorithm == '<STR_LIT>':<EOL><INDENT>if curve not in set(['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']):<EOL><INDENT>raise ValueError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>repr(curve)<EOL>))<EOL><DEDENT><DEDENT>if _backend == '<STR_LIT>':<EOL><INDENT>if algorithm == '<STR_LIT>':<EOL><INDENT>pub_info, priv_info = _pure_python_ec_generate_pair(curve)<EOL>return (PublicKey(None, pub_info), PrivateKey(None, priv_info))<EOL><DEDENT>return _advapi32_generate_pair(algorithm, bit_size)<EOL><DEDENT>else:<EOL><INDENT>return _bcrypt_generate_pair(algorithm, bit_size, curve)<EOL><DEDENT>

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 == '<STR_LIT>':<EOL><INDENT>provider = Advapi32Const.MS_ENH_RSA_AES_PROV<EOL>algorithm_id = Advapi32Const.CALG_RSA_SIGN<EOL>struct_type = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>provider = Advapi32Const.MS_ENH_DSS_DH_PROV<EOL>algorithm_id = Advapi32Const.CALG_DSS_SIGN<EOL>struct_type = '<STR_LIT>'<EOL><DEDENT>context_handle = None<EOL>key_handle = None<EOL>try:<EOL><INDENT>context_handle = open_context_handle(provider, verify_only=False)<EOL>key_handle_pointer = new(advapi32, '<STR_LIT>')<EOL>flags = (bit_size << <NUM_LIT:16>) | Advapi32Const.CRYPT_EXPORTABLE<EOL>res = advapi32.CryptGenKey(context_handle, algorithm_id, flags, key_handle_pointer)<EOL>handle_error(res)<EOL>key_handle = unwrap(key_handle_pointer)<EOL>out_len = new(advapi32, '<STR_LIT>')<EOL>res = advapi32.CryptExportKey(<EOL>key_handle,<EOL>null(),<EOL>Advapi32Const.PRIVATEKEYBLOB,<EOL><NUM_LIT:0>,<EOL>null(),<EOL>out_len<EOL>)<EOL>handle_error(res)<EOL>buffer_length = deref(out_len)<EOL>buffer_ = buffer_from_bytes(buffer_length)<EOL>res = advapi32.CryptExportKey(<EOL>key_handle,<EOL>null(),<EOL>Advapi32Const.PRIVATEKEYBLOB,<EOL><NUM_LIT:0>,<EOL>buffer_,<EOL>out_len<EOL>)<EOL>handle_error(res)<EOL>blob_struct_pointer = struct_from_buffer(advapi32, struct_type, buffer_)<EOL>blob_struct = unwrap(blob_struct_pointer)<EOL>struct_size = sizeof(advapi32, blob_struct)<EOL>private_blob = bytes_from_buffer(buffer_, buffer_length)[struct_size:]<EOL>if algorithm == '<STR_LIT>':<EOL><INDENT>public_info, private_info = _advapi32_interpret_rsa_key_blob(bit_size, blob_struct, private_blob)<EOL><DEDENT>else:<EOL><INDENT>public_out_len = new(advapi32, '<STR_LIT>')<EOL>res = advapi32.CryptExportKey(<EOL>key_handle,<EOL>null(),<EOL>Advapi32Const.PUBLICKEYBLOB,<EOL><NUM_LIT:0>,<EOL>null(),<EOL>public_out_len<EOL>)<EOL>handle_error(res)<EOL>public_buffer_length = deref(public_out_len)<EOL>public_buffer = buffer_from_bytes(public_buffer_length)<EOL>res = advapi32.CryptExportKey(<EOL>key_handle,<EOL>null(),<EOL>Advapi32Const.PUBLICKEYBLOB,<EOL><NUM_LIT:0>,<EOL>public_buffer,<EOL>public_out_len<EOL>)<EOL>handle_error(res)<EOL>public_blob = bytes_from_buffer(public_buffer, public_buffer_length)[struct_size:]<EOL>public_info, private_info = _advapi32_interpret_dsa_key_blob(bit_size, public_blob, private_blob)<EOL><DEDENT>return (load_public_key(public_info), load_private_key(private_info))<EOL><DEDENT>finally:<EOL><INDENT>if context_handle:<EOL><INDENT>close_context_handle(context_handle)<EOL><DEDENT>if key_handle:<EOL><INDENT>advapi32.CryptDestroyKey(key_handle)<EOL><DEDENT><DEDENT>

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().


def _bcrypt_generate_pair(algorithm, bit_size=None, curve=None):

if algorithm == '<STR_LIT>':<EOL><INDENT>alg_constant = BcryptConst.BCRYPT_RSA_ALGORITHM<EOL>struct_type = '<STR_LIT>'<EOL>private_blob_type = BcryptConst.BCRYPT_RSAFULLPRIVATE_BLOB<EOL>public_blob_type = BcryptConst.BCRYPT_RSAPUBLIC_BLOB<EOL><DEDENT>elif algorithm == '<STR_LIT>':<EOL><INDENT>alg_constant = BcryptConst.BCRYPT_DSA_ALGORITHM<EOL>if bit_size > <NUM_LIT>:<EOL><INDENT>struct_type = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>struct_type = '<STR_LIT>'<EOL><DEDENT>private_blob_type = BcryptConst.BCRYPT_DSA_PRIVATE_BLOB<EOL>public_blob_type = BcryptConst.BCRYPT_DSA_PUBLIC_BLOB<EOL><DEDENT>else:<EOL><INDENT>alg_constant = {<EOL>'<STR_LIT>': BcryptConst.BCRYPT_ECDSA_P256_ALGORITHM,<EOL>'<STR_LIT>': BcryptConst.BCRYPT_ECDSA_P384_ALGORITHM,<EOL>'<STR_LIT>': BcryptConst.BCRYPT_ECDSA_P521_ALGORITHM,<EOL>}[curve]<EOL>bit_size = {<EOL>'<STR_LIT>': <NUM_LIT>,<EOL>'<STR_LIT>': <NUM_LIT>,<EOL>'<STR_LIT>': <NUM_LIT>,<EOL>}[curve]<EOL>struct_type = '<STR_LIT>'<EOL>private_blob_type = BcryptConst.BCRYPT_ECCPRIVATE_BLOB<EOL>public_blob_type = BcryptConst.BCRYPT_ECCPUBLIC_BLOB<EOL><DEDENT>alg_handle = open_alg_handle(alg_constant)<EOL>key_handle_pointer = new(bcrypt, '<STR_LIT>')<EOL>res = bcrypt.BCryptGenerateKeyPair(alg_handle, key_handle_pointer, bit_size, <NUM_LIT:0>)<EOL>handle_error(res)<EOL>key_handle = unwrap(key_handle_pointer)<EOL>res = bcrypt.BCryptFinalizeKeyPair(key_handle, <NUM_LIT:0>)<EOL>handle_error(res)<EOL>private_out_len = new(bcrypt, '<STR_LIT>')<EOL>res = bcrypt.BCryptExportKey(key_handle, null(), private_blob_type, null(), <NUM_LIT:0>, private_out_len, <NUM_LIT:0>)<EOL>handle_error(res)<EOL>private_buffer_length = deref(private_out_len)<EOL>private_buffer = buffer_from_bytes(private_buffer_length)<EOL>res = bcrypt.BCryptExportKey(<EOL>key_handle,<EOL>null(),<EOL>private_blob_type,<EOL>private_buffer,<EOL>private_buffer_length,<EOL>private_out_len,<EOL><NUM_LIT:0><EOL>)<EOL>handle_error(res)<EOL>private_blob_struct_pointer = struct_from_buffer(bcrypt, struct_type, private_buffer)<EOL>private_blob_struct = unwrap(private_blob_struct_pointer)<EOL>struct_size = sizeof(bcrypt, private_blob_struct)<EOL>private_blob = bytes_from_buffer(private_buffer, private_buffer_length)[struct_size:]<EOL>if algorithm == '<STR_LIT>':<EOL><INDENT>private_key = _bcrypt_interpret_rsa_key_blob('<STR_LIT>', private_blob_struct, private_blob)<EOL><DEDENT>elif algorithm == '<STR_LIT>':<EOL><INDENT>if bit_size > <NUM_LIT>:<EOL><INDENT>private_key = _bcrypt_interpret_dsa_key_blob('<STR_LIT>', <NUM_LIT:2>, private_blob_struct, private_blob)<EOL><DEDENT>else:<EOL><INDENT>private_key = _bcrypt_interpret_dsa_key_blob('<STR_LIT>', <NUM_LIT:1>, private_blob_struct, private_blob)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>private_key = _bcrypt_interpret_ec_key_blob('<STR_LIT>', private_blob_struct, private_blob)<EOL><DEDENT>public_out_len = new(bcrypt, '<STR_LIT>')<EOL>res = bcrypt.BCryptExportKey(key_handle, null(), public_blob_type, null(), <NUM_LIT:0>, public_out_len, <NUM_LIT:0>)<EOL>handle_error(res)<EOL>public_buffer_length = deref(public_out_len)<EOL>public_buffer = buffer_from_bytes(public_buffer_length)<EOL>res = bcrypt.BCryptExportKey(<EOL>key_handle,<EOL>null(),<EOL>public_blob_type,<EOL>public_buffer,<EOL>public_buffer_length,<EOL>public_out_len,<EOL><NUM_LIT:0><EOL>)<EOL>handle_error(res)<EOL>public_blob_struct_pointer = struct_from_buffer(bcrypt, struct_type, public_buffer)<EOL>public_blob_struct = unwrap(public_blob_struct_pointer)<EOL>struct_size = sizeof(bcrypt, public_blob_struct)<EOL>public_blob = bytes_from_buffer(public_buffer, public_buffer_length)[struct_size:]<EOL>if algorithm == '<STR_LIT>':<EOL><INDENT>public_key = _bcrypt_interpret_rsa_key_blob('<STR_LIT>', public_blob_struct, public_blob)<EOL><DEDENT>elif algorithm == '<STR_LIT>':<EOL><INDENT>if bit_size > <NUM_LIT>:<EOL><INDENT>public_key = _bcrypt_interpret_dsa_key_blob('<STR_LIT>', <NUM_LIT:2>, public_blob_struct, public_blob)<EOL><DEDENT>else:<EOL><INDENT>public_key = _bcrypt_interpret_dsa_key_blob('<STR_LIT>', <NUM_LIT:1>, public_blob_struct, public_blob)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>public_key = _bcrypt_interpret_ec_key_blob('<STR_LIT>', public_blob_struct, public_blob)<EOL><DEDENT>return (load_public_key(public_key), load_private_key(private_key))<EOL>

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 not isinstance(bit_size, int_types):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(bit_size)<EOL>))<EOL><DEDENT>if bit_size < <NUM_LIT>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if bit_size > <NUM_LIT>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if bit_size % <NUM_LIT:64> != <NUM_LIT:0>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>alg_handle = None<EOL>g = <NUM_LIT:2><EOL>try:<EOL><INDENT>byte_size = bit_size // <NUM_LIT:8><EOL>if _backend == '<STR_LIT>':<EOL><INDENT>alg_handle = open_alg_handle(BcryptConst.BCRYPT_RNG_ALGORITHM)<EOL>buffer = buffer_from_bytes(byte_size)<EOL><DEDENT>while True:<EOL><INDENT>if _backend == '<STR_LIT>':<EOL><INDENT>rb = os.urandom(byte_size)<EOL><DEDENT>else:<EOL><INDENT>res = bcrypt.BCryptGenRandom(alg_handle, buffer, byte_size, <NUM_LIT:0>)<EOL>handle_error(res)<EOL>rb = bytes_from_buffer(buffer)<EOL><DEDENT>p = int_from_bytes(rb)<EOL>if p % <NUM_LIT:2> == <NUM_LIT:0>:<EOL><INDENT>continue<EOL><DEDENT>if g == <NUM_LIT:2>:<EOL><INDENT>if p % <NUM_LIT> != <NUM_LIT:11>:<EOL><INDENT>continue<EOL><DEDENT><DEDENT>elif g == <NUM_LIT:5>:<EOL><INDENT>rem = p % <NUM_LIT:10><EOL>if rem != <NUM_LIT:3> and rem != <NUM_LIT:7>:<EOL><INDENT>continue<EOL><DEDENT><DEDENT>divisible = False<EOL>for prime in _SMALL_PRIMES:<EOL><INDENT>if p % prime == <NUM_LIT:0>:<EOL><INDENT>divisible = True<EOL>break<EOL><DEDENT><DEDENT>if not divisible and _is_prime(bit_size, p):<EOL><INDENT>q = p // <NUM_LIT:2><EOL>if _is_prime(bit_size, q):<EOL><INDENT>return algos.DHParameters({'<STR_LIT:p>': p, '<STR_LIT:g>': g})<EOL><DEDENT><DEDENT><DEDENT><DEDENT>finally:<EOL><INDENT>if alg_handle:<EOL><INDENT>close_alg_handle(alg_handle)<EOL><DEDENT><DEDENT>

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.


r = <NUM_LIT:0><EOL>s = n - <NUM_LIT:1><EOL>while s % <NUM_LIT:2> == <NUM_LIT:0>:<EOL><INDENT>r += <NUM_LIT:1><EOL>s //= <NUM_LIT:2><EOL><DEDENT>if bit_size >= <NUM_LIT>:<EOL><INDENT>k = <NUM_LIT:2><EOL><DEDENT>elif bit_size >= <NUM_LIT>:<EOL><INDENT>k = <NUM_LIT:3><EOL><DEDENT>elif bit_size >= <NUM_LIT>:<EOL><INDENT>k = <NUM_LIT:4><EOL><DEDENT>elif bit_size >= <NUM_LIT>:<EOL><INDENT>k = <NUM_LIT:5><EOL><DEDENT>elif bit_size >= <NUM_LIT>:<EOL><INDENT>k = <NUM_LIT:6><EOL><DEDENT>for _ in range(k):<EOL><INDENT>a = random.randrange(<NUM_LIT:2>, n - <NUM_LIT:1>)<EOL>x = pow(a, s, n)<EOL>if x == <NUM_LIT:1> or x == n - <NUM_LIT:1>:<EOL><INDENT>continue<EOL><DEDENT>for _ in range(r - <NUM_LIT:1>):<EOL><INDENT>x = pow(x, <NUM_LIT:2>, n)<EOL>if x == n - <NUM_LIT:1>:<EOL><INDENT>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>return False<EOL><DEDENT><DEDENT>return True<EOL>

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


def _advapi32_interpret_rsa_key_blob(bit_size, blob_struct, blob):

len1 = bit_size // <NUM_LIT:8><EOL>len2 = bit_size // <NUM_LIT:16><EOL>prime1_offset = len1<EOL>prime2_offset = prime1_offset + len2<EOL>exponent1_offset = prime2_offset + len2<EOL>exponent2_offset = exponent1_offset + len2<EOL>coefficient_offset = exponent2_offset + len2<EOL>private_exponent_offset = coefficient_offset + len2<EOL>public_exponent = blob_struct.rsapubkey.pubexp<EOL>modulus = int_from_bytes(blob[<NUM_LIT:0>:prime1_offset][::-<NUM_LIT:1>])<EOL>prime1 = int_from_bytes(blob[prime1_offset:prime2_offset][::-<NUM_LIT:1>])<EOL>prime2 = int_from_bytes(blob[prime2_offset:exponent1_offset][::-<NUM_LIT:1>])<EOL>exponent1 = int_from_bytes(blob[exponent1_offset:exponent2_offset][::-<NUM_LIT:1>])<EOL>exponent2 = int_from_bytes(blob[exponent2_offset:coefficient_offset][::-<NUM_LIT:1>])<EOL>coefficient = int_from_bytes(blob[coefficient_offset:private_exponent_offset][::-<NUM_LIT:1>])<EOL>private_exponent = int_from_bytes(blob[private_exponent_offset:private_exponent_offset + len1][::-<NUM_LIT:1>])<EOL>public_key_info = keys.PublicKeyInfo({<EOL>'<STR_LIT>': keys.PublicKeyAlgorithm({<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>}),<EOL>'<STR_LIT>': keys.RSAPublicKey({<EOL>'<STR_LIT>': modulus,<EOL>'<STR_LIT>': public_exponent,<EOL>}),<EOL>})<EOL>rsa_private_key = keys.RSAPrivateKey({<EOL>'<STR_LIT:version>': '<STR_LIT>',<EOL>'<STR_LIT>': modulus,<EOL>'<STR_LIT>': public_exponent,<EOL>'<STR_LIT>': private_exponent,<EOL>'<STR_LIT>': prime1,<EOL>'<STR_LIT>': prime2,<EOL>'<STR_LIT>': exponent1,<EOL>'<STR_LIT>': exponent2,<EOL>'<STR_LIT>': coefficient,<EOL>})<EOL>private_key_info = keys.PrivateKeyInfo({<EOL>'<STR_LIT:version>': <NUM_LIT:0>,<EOL>'<STR_LIT>': keys.PrivateKeyAlgorithm({<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>}),<EOL>'<STR_LIT>': rsa_private_key,<EOL>})<EOL>return (public_key_info, private_key_info)<EOL>

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)


def _advapi32_interpret_dsa_key_blob(bit_size, public_blob, private_blob):

len1 = <NUM_LIT:20><EOL>len2 = bit_size // <NUM_LIT:8><EOL>q_offset = len2<EOL>g_offset = q_offset + len1<EOL>x_offset = g_offset + len2<EOL>y_offset = x_offset<EOL>p = int_from_bytes(private_blob[<NUM_LIT:0>:q_offset][::-<NUM_LIT:1>])<EOL>q = int_from_bytes(private_blob[q_offset:g_offset][::-<NUM_LIT:1>])<EOL>g = int_from_bytes(private_blob[g_offset:x_offset][::-<NUM_LIT:1>])<EOL>x = int_from_bytes(private_blob[x_offset:x_offset + len1][::-<NUM_LIT:1>])<EOL>y = int_from_bytes(public_blob[y_offset:y_offset + len2][::-<NUM_LIT:1>])<EOL>public_key_info = keys.PublicKeyInfo({<EOL>'<STR_LIT>': keys.PublicKeyAlgorithm({<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': keys.DSAParams({<EOL>'<STR_LIT:p>': p,<EOL>'<STR_LIT:q>': q,<EOL>'<STR_LIT:g>': g,<EOL>})<EOL>}),<EOL>'<STR_LIT>': core.Integer(y),<EOL>})<EOL>private_key_info = keys.PrivateKeyInfo({<EOL>'<STR_LIT:version>': <NUM_LIT:0>,<EOL>'<STR_LIT>': keys.PrivateKeyAlgorithm({<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': keys.DSAParams({<EOL>'<STR_LIT:p>': p,<EOL>'<STR_LIT:q>': q,<EOL>'<STR_LIT:g>': g,<EOL>})<EOL>}),<EOL>'<STR_LIT>': core.Integer(x),<EOL>})<EOL>return (public_key_info, private_key_info)<EOL>

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)


def _bcrypt_interpret_rsa_key_blob(key_type, blob_struct, blob):

public_exponent_byte_length = native(int, blob_struct.cbPublicExp)<EOL>modulus_byte_length = native(int, blob_struct.cbModulus)<EOL>modulus_offset = public_exponent_byte_length<EOL>public_exponent = int_from_bytes(blob[<NUM_LIT:0>:modulus_offset])<EOL>modulus = int_from_bytes(blob[modulus_offset:modulus_offset + modulus_byte_length])<EOL>if key_type == '<STR_LIT>':<EOL><INDENT>return keys.PublicKeyInfo({<EOL>'<STR_LIT>': keys.PublicKeyAlgorithm({<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>}),<EOL>'<STR_LIT>': keys.RSAPublicKey({<EOL>'<STR_LIT>': modulus,<EOL>'<STR_LIT>': public_exponent,<EOL>}),<EOL>})<EOL><DEDENT>elif key_type == '<STR_LIT>':<EOL><INDENT>prime1_byte_length = native(int, blob_struct.cbPrime1)<EOL>prime2_byte_length = native(int, blob_struct.cbPrime2)<EOL>prime1_offset = modulus_offset + modulus_byte_length<EOL>prime2_offset = prime1_offset + prime1_byte_length<EOL>exponent1_offset = prime2_offset + prime2_byte_length<EOL>exponent2_offset = exponent1_offset + prime2_byte_length<EOL>coefficient_offset = exponent2_offset + prime2_byte_length<EOL>private_exponent_offset = coefficient_offset + prime1_byte_length<EOL>prime1 = int_from_bytes(blob[prime1_offset:prime2_offset])<EOL>prime2 = int_from_bytes(blob[prime2_offset:exponent1_offset])<EOL>exponent1 = int_from_bytes(blob[exponent1_offset:exponent2_offset])<EOL>exponent2 = int_from_bytes(blob[exponent2_offset:coefficient_offset])<EOL>coefficient = int_from_bytes(blob[coefficient_offset:private_exponent_offset])<EOL>private_exponent = int_from_bytes(blob[private_exponent_offset:private_exponent_offset + modulus_byte_length])<EOL>rsa_private_key = keys.RSAPrivateKey({<EOL>'<STR_LIT:version>': '<STR_LIT>',<EOL>'<STR_LIT>': modulus,<EOL>'<STR_LIT>': public_exponent,<EOL>'<STR_LIT>': private_exponent,<EOL>'<STR_LIT>': prime1,<EOL>'<STR_LIT>': prime2,<EOL>'<STR_LIT>': exponent1,<EOL>'<STR_LIT>': exponent2,<EOL>'<STR_LIT>': coefficient,<EOL>})<EOL>return keys.PrivateKeyInfo({<EOL>'<STR_LIT:version>': <NUM_LIT:0>,<EOL>'<STR_LIT>': keys.PrivateKeyAlgorithm({<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>}),<EOL>'<STR_LIT>': rsa_private_key,<EOL>})<EOL><DEDENT>else:<EOL><INDENT>raise ValueError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>repr(key_type)<EOL>))<EOL><DEDENT>

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


def _bcrypt_interpret_dsa_key_blob(key_type, version, blob_struct, blob):

key_byte_length = native(int, blob_struct.cbKey)<EOL>if version == <NUM_LIT:1>:<EOL><INDENT>q = int_from_bytes(native(byte_cls, blob_struct.q))<EOL>g_offset = key_byte_length<EOL>public_offset = g_offset + key_byte_length<EOL>private_offset = public_offset + key_byte_length<EOL>p = int_from_bytes(blob[<NUM_LIT:0>:g_offset])<EOL>g = int_from_bytes(blob[g_offset:public_offset])<EOL><DEDENT>elif version == <NUM_LIT:2>:<EOL><INDENT>seed_byte_length = native(int, blob_struct.cbSeedLength)<EOL>group_byte_length = native(int, blob_struct.cbGroupSize)<EOL>q_offset = seed_byte_length<EOL>p_offset = q_offset + group_byte_length<EOL>g_offset = p_offset + key_byte_length<EOL>public_offset = g_offset + key_byte_length<EOL>private_offset = public_offset + key_byte_length<EOL>q = int_from_bytes(blob[q_offset:p_offset])<EOL>p = int_from_bytes(blob[p_offset:g_offset])<EOL>g = int_from_bytes(blob[g_offset:public_offset])<EOL><DEDENT>else:<EOL><INDENT>raise ValueError('<STR_LIT>' % repr(version))<EOL><DEDENT>if key_type == '<STR_LIT>':<EOL><INDENT>public = int_from_bytes(blob[public_offset:private_offset])<EOL>return keys.PublicKeyInfo({<EOL>'<STR_LIT>': keys.PublicKeyAlgorithm({<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': keys.DSAParams({<EOL>'<STR_LIT:p>': p,<EOL>'<STR_LIT:q>': q,<EOL>'<STR_LIT:g>': g,<EOL>})<EOL>}),<EOL>'<STR_LIT>': core.Integer(public),<EOL>})<EOL><DEDENT>elif key_type == '<STR_LIT>':<EOL><INDENT>private = int_from_bytes(blob[private_offset:private_offset + key_byte_length])<EOL>return keys.PrivateKeyInfo({<EOL>'<STR_LIT:version>': <NUM_LIT:0>,<EOL>'<STR_LIT>': keys.PrivateKeyAlgorithm({<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': keys.DSAParams({<EOL>'<STR_LIT:p>': p,<EOL>'<STR_LIT:q>': q,<EOL>'<STR_LIT:g>': g,<EOL>})<EOL>}),<EOL>'<STR_LIT>': core.Integer(private),<EOL>})<EOL><DEDENT>else:<EOL><INDENT>raise ValueError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>repr(key_type)<EOL>))<EOL><DEDENT>

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


def _bcrypt_interpret_ec_key_blob(key_type, blob_struct, blob):

magic = native(int, blob_struct.dwMagic)<EOL>key_byte_length = native(int, blob_struct.cbKey)<EOL>curve = {<EOL>BcryptConst.BCRYPT_ECDSA_PRIVATE_P256_MAGIC: '<STR_LIT>',<EOL>BcryptConst.BCRYPT_ECDSA_PRIVATE_P384_MAGIC: '<STR_LIT>',<EOL>BcryptConst.BCRYPT_ECDSA_PRIVATE_P521_MAGIC: '<STR_LIT>',<EOL>BcryptConst.BCRYPT_ECDSA_PUBLIC_P256_MAGIC: '<STR_LIT>',<EOL>BcryptConst.BCRYPT_ECDSA_PUBLIC_P384_MAGIC: '<STR_LIT>',<EOL>BcryptConst.BCRYPT_ECDSA_PUBLIC_P521_MAGIC: '<STR_LIT>',<EOL>}[magic]<EOL>public = b'<STR_LIT>' + blob[<NUM_LIT:0>:key_byte_length * <NUM_LIT:2>]<EOL>if key_type == '<STR_LIT>':<EOL><INDENT>return keys.PublicKeyInfo({<EOL>'<STR_LIT>': keys.PublicKeyAlgorithm({<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': keys.ECDomainParameters(<EOL>name='<STR_LIT>',<EOL>value=curve<EOL>)<EOL>}),<EOL>'<STR_LIT>': public,<EOL>})<EOL><DEDENT>elif key_type == '<STR_LIT>':<EOL><INDENT>private = int_from_bytes(blob[key_byte_length * <NUM_LIT:2>:key_byte_length * <NUM_LIT:3>])<EOL>return keys.PrivateKeyInfo({<EOL>'<STR_LIT:version>': <NUM_LIT:0>,<EOL>'<STR_LIT>': keys.PrivateKeyAlgorithm({<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': keys.ECDomainParameters(<EOL>name='<STR_LIT>',<EOL>value=curve<EOL>)<EOL>}),<EOL>'<STR_LIT>': keys.ECPrivateKey({<EOL>'<STR_LIT:version>': '<STR_LIT>',<EOL>'<STR_LIT>': private,<EOL>'<STR_LIT>': public,<EOL>}),<EOL>})<EOL><DEDENT>else:<EOL><INDENT>raise ValueError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>repr(key_type)<EOL>))<EOL><DEDENT>

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


if isinstance(source, x509.Certificate):<EOL><INDENT>certificate = source<EOL><DEDENT>elif isinstance(source, byte_cls):<EOL><INDENT>certificate = parse_certificate(source)<EOL><DEDENT>elif isinstance(source, str_cls):<EOL><INDENT>with open(source, '<STR_LIT:rb>') as f:<EOL><INDENT>certificate = parse_certificate(f.read())<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(source)<EOL>))<EOL><DEDENT>return _load_key(certificate, Certificate)<EOL>

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


key_info = key_object<EOL>if isinstance(key_object, x509.Certificate):<EOL><INDENT>key_info = key_object['<STR_LIT>']['<STR_LIT>']<EOL><DEDENT>algo = key_info.algorithm<EOL>curve_name = None<EOL>if algo == '<STR_LIT>':<EOL><INDENT>curve_type, curve_name = key_info.curve<EOL>if curve_type != '<STR_LIT>':<EOL><INDENT>raise AsymmetricKeyError(pretty_message(<EOL>'''<STR_LIT>'''<EOL>))<EOL><DEDENT>if curve_name not in set(['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']):<EOL><INDENT>raise AsymmetricKeyError(pretty_message(<EOL>'''<STR_LIT>'''<EOL>))<EOL><DEDENT><DEDENT>elif algo == '<STR_LIT>':<EOL><INDENT>if key_info.hash_algo is None:<EOL><INDENT>raise IncompleteAsymmetricKeyError(pretty_message(<EOL>'''<STR_LIT>'''<EOL>))<EOL><DEDENT>elif key_info.bit_size > <NUM_LIT> and (_win_version_info < (<NUM_LIT:6>, <NUM_LIT:2>) or _backend == '<STR_LIT>'):<EOL><INDENT>raise AsymmetricKeyError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>key_info.hash_algo.upper(),<EOL>key_info.bit_size<EOL>))<EOL><DEDENT>elif key_info.bit_size == <NUM_LIT> and key_info.hash_algo == '<STR_LIT>':<EOL><INDENT>raise AsymmetricKeyError(pretty_message(<EOL>'''<STR_LIT>'''<EOL>))<EOL><DEDENT><DEDENT>if _backend == '<STR_LIT>':<EOL><INDENT>if algo == '<STR_LIT>':<EOL><INDENT>return container(None, key_object)<EOL><DEDENT>return _advapi32_load_key(key_object, key_info, container)<EOL><DEDENT>return _bcrypt_load_key(key_object, key_info, container, curve_name)<EOL>

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


def _advapi32_load_key(key_object, key_info, container):

key_type = '<STR_LIT>' if isinstance(key_info, keys.PublicKeyInfo) else '<STR_LIT>'<EOL>algo = key_info.algorithm<EOL>if algo == '<STR_LIT>':<EOL><INDENT>provider = Advapi32Const.MS_ENH_RSA_AES_PROV<EOL><DEDENT>else:<EOL><INDENT>provider = Advapi32Const.MS_ENH_DSS_DH_PROV<EOL><DEDENT>context_handle = None<EOL>key_handle = None<EOL>try:<EOL><INDENT>context_handle = open_context_handle(provider, verify_only=key_type == '<STR_LIT>')<EOL>blob = _advapi32_create_blob(key_info, key_type, algo)<EOL>buffer_ = buffer_from_bytes(blob)<EOL>key_handle_pointer = new(advapi32, '<STR_LIT>')<EOL>res = advapi32.CryptImportKey(<EOL>context_handle,<EOL>buffer_,<EOL>len(blob),<EOL>null(),<EOL><NUM_LIT:0>,<EOL>key_handle_pointer<EOL>)<EOL>handle_error(res)<EOL>key_handle = unwrap(key_handle_pointer)<EOL>output = container(key_handle, key_object)<EOL>output.context_handle = context_handle<EOL>if algo == '<STR_LIT>':<EOL><INDENT>ex_blob = _advapi32_create_blob(key_info, key_type, algo, signing=False)<EOL>ex_buffer = buffer_from_bytes(ex_blob)<EOL>ex_key_handle_pointer = new(advapi32, '<STR_LIT>')<EOL>res = advapi32.CryptImportKey(<EOL>context_handle,<EOL>ex_buffer,<EOL>len(ex_blob),<EOL>null(),<EOL><NUM_LIT:0>,<EOL>ex_key_handle_pointer<EOL>)<EOL>handle_error(res)<EOL>output.ex_key_handle = unwrap(ex_key_handle_pointer)<EOL><DEDENT>return output<EOL><DEDENT>except (Exception):<EOL><INDENT>if key_handle:<EOL><INDENT>advapi32.CryptDestroyKey(key_handle)<EOL><DEDENT>if context_handle:<EOL><INDENT>close_context_handle(context_handle)<EOL><DEDENT>raise<EOL><DEDENT>

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


def _advapi32_create_blob(key_info, key_type, algo, signing=True):

if key_type == '<STR_LIT>':<EOL><INDENT>blob_type = Advapi32Const.PUBLICKEYBLOB<EOL><DEDENT>else:<EOL><INDENT>blob_type = Advapi32Const.PRIVATEKEYBLOB<EOL><DEDENT>if algo == '<STR_LIT>':<EOL><INDENT>struct_type = '<STR_LIT>'<EOL>if signing:<EOL><INDENT>algorithm_id = Advapi32Const.CALG_RSA_SIGN<EOL><DEDENT>else:<EOL><INDENT>algorithm_id = Advapi32Const.CALG_RSA_KEYX<EOL><DEDENT><DEDENT>else:<EOL><INDENT>struct_type = '<STR_LIT>'<EOL>algorithm_id = Advapi32Const.CALG_DSS_SIGN<EOL><DEDENT>blob_header_pointer = struct(advapi32, '<STR_LIT>')<EOL>blob_header = unwrap(blob_header_pointer)<EOL>blob_header.bType = blob_type<EOL>blob_header.bVersion = Advapi32Const.CUR_BLOB_VERSION<EOL>blob_header.reserved = <NUM_LIT:0><EOL>blob_header.aiKeyAlg = algorithm_id<EOL>blob_struct_pointer = struct(advapi32, struct_type)<EOL>blob_struct = unwrap(blob_struct_pointer)<EOL>blob_struct.publickeystruc = blob_header<EOL>bit_size = key_info.bit_size<EOL>len1 = bit_size // <NUM_LIT:8><EOL>len2 = bit_size // <NUM_LIT:16><EOL>if algo == '<STR_LIT>':<EOL><INDENT>pubkey_pointer = struct(advapi32, '<STR_LIT>')<EOL>pubkey = unwrap(pubkey_pointer)<EOL>pubkey.bitlen = bit_size<EOL>if key_type == '<STR_LIT>':<EOL><INDENT>parsed_key_info = key_info['<STR_LIT>'].parsed<EOL>pubkey.magic = Advapi32Const.RSA1<EOL>pubkey.pubexp = parsed_key_info['<STR_LIT>'].native<EOL>blob_data = int_to_bytes(parsed_key_info['<STR_LIT>'].native, signed=False, width=len1)[::-<NUM_LIT:1>]<EOL><DEDENT>else:<EOL><INDENT>parsed_key_info = key_info['<STR_LIT>'].parsed<EOL>pubkey.magic = Advapi32Const.RSA2<EOL>pubkey.pubexp = parsed_key_info['<STR_LIT>'].native<EOL>blob_data = int_to_bytes(parsed_key_info['<STR_LIT>'].native, signed=False, width=len1)[::-<NUM_LIT:1>]<EOL>blob_data += int_to_bytes(parsed_key_info['<STR_LIT>'].native, signed=False, width=len2)[::-<NUM_LIT:1>]<EOL>blob_data += int_to_bytes(parsed_key_info['<STR_LIT>'].native, signed=False, width=len2)[::-<NUM_LIT:1>]<EOL>blob_data += int_to_bytes(parsed_key_info['<STR_LIT>'].native, signed=False, width=len2)[::-<NUM_LIT:1>]<EOL>blob_data += int_to_bytes(parsed_key_info['<STR_LIT>'].native, signed=False, width=len2)[::-<NUM_LIT:1>]<EOL>blob_data += int_to_bytes(parsed_key_info['<STR_LIT>'].native, signed=False, width=len2)[::-<NUM_LIT:1>]<EOL>blob_data += int_to_bytes(parsed_key_info['<STR_LIT>'].native, signed=False, width=len1)[::-<NUM_LIT:1>]<EOL><DEDENT>blob_struct.rsapubkey = pubkey<EOL><DEDENT>else:<EOL><INDENT>pubkey_pointer = struct(advapi32, '<STR_LIT>')<EOL>pubkey = unwrap(pubkey_pointer)<EOL>pubkey.bitlen = bit_size<EOL>if key_type == '<STR_LIT>':<EOL><INDENT>pubkey.magic = Advapi32Const.DSS1<EOL>params = key_info['<STR_LIT>']['<STR_LIT>'].native<EOL>key_data = int_to_bytes(key_info['<STR_LIT>'].parsed.native, signed=False, width=len1)[::-<NUM_LIT:1>]<EOL><DEDENT>else:<EOL><INDENT>pubkey.magic = Advapi32Const.DSS2<EOL>params = key_info['<STR_LIT>']['<STR_LIT>'].native<EOL>key_data = int_to_bytes(key_info['<STR_LIT>'].parsed.native, signed=False, width=<NUM_LIT:20>)[::-<NUM_LIT:1>]<EOL><DEDENT>blob_struct.dsspubkey = pubkey<EOL>blob_data = int_to_bytes(params['<STR_LIT:p>'], signed=False, width=len1)[::-<NUM_LIT:1>]<EOL>blob_data += int_to_bytes(params['<STR_LIT:q>'], signed=False, width=<NUM_LIT:20>)[::-<NUM_LIT:1>]<EOL>blob_data += int_to_bytes(params['<STR_LIT:g>'], signed=False, width=len1)[::-<NUM_LIT:1>]<EOL>blob_data += key_data<EOL>dssseed_pointer = struct(advapi32, '<STR_LIT>')<EOL>dssseed = unwrap(dssseed_pointer)<EOL>dssseed.counter = <NUM_LIT><EOL>blob_data += struct_bytes(dssseed_pointer)<EOL><DEDENT>return struct_bytes(blob_struct_pointer) + blob_data<EOL>

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()


def _bcrypt_load_key(key_object, key_info, container, curve_name):

alg_handle = None<EOL>key_handle = None<EOL>key_type = '<STR_LIT>' if isinstance(key_info, keys.PublicKeyInfo) else '<STR_LIT>'<EOL>algo = key_info.algorithm<EOL>try:<EOL><INDENT>alg_selector = key_info.curve[<NUM_LIT:1>] if algo == '<STR_LIT>' else algo<EOL>alg_constant = {<EOL>'<STR_LIT>': BcryptConst.BCRYPT_RSA_ALGORITHM,<EOL>'<STR_LIT>': BcryptConst.BCRYPT_DSA_ALGORITHM,<EOL>'<STR_LIT>': BcryptConst.BCRYPT_ECDSA_P256_ALGORITHM,<EOL>'<STR_LIT>': BcryptConst.BCRYPT_ECDSA_P384_ALGORITHM,<EOL>'<STR_LIT>': BcryptConst.BCRYPT_ECDSA_P521_ALGORITHM,<EOL>}[alg_selector]<EOL>alg_handle = open_alg_handle(alg_constant)<EOL>if algo == '<STR_LIT>':<EOL><INDENT>if key_type == '<STR_LIT>':<EOL><INDENT>blob_type = BcryptConst.BCRYPT_RSAPUBLIC_BLOB<EOL>magic = BcryptConst.BCRYPT_RSAPUBLIC_MAGIC<EOL>parsed_key = key_info['<STR_LIT>'].parsed<EOL>prime1_size = <NUM_LIT:0><EOL>prime2_size = <NUM_LIT:0><EOL><DEDENT>else:<EOL><INDENT>blob_type = BcryptConst.BCRYPT_RSAFULLPRIVATE_BLOB<EOL>magic = BcryptConst.BCRYPT_RSAFULLPRIVATE_MAGIC<EOL>parsed_key = key_info['<STR_LIT>'].parsed<EOL>prime1 = int_to_bytes(parsed_key['<STR_LIT>'].native)<EOL>prime2 = int_to_bytes(parsed_key['<STR_LIT>'].native)<EOL>exponent1 = int_to_bytes(parsed_key['<STR_LIT>'].native)<EOL>exponent2 = int_to_bytes(parsed_key['<STR_LIT>'].native)<EOL>coefficient = int_to_bytes(parsed_key['<STR_LIT>'].native)<EOL>private_exponent = int_to_bytes(parsed_key['<STR_LIT>'].native)<EOL>prime1_size = len(prime1)<EOL>prime2_size = len(prime2)<EOL><DEDENT>public_exponent = int_to_bytes(parsed_key['<STR_LIT>'].native)<EOL>modulus = int_to_bytes(parsed_key['<STR_LIT>'].native)<EOL>blob_struct_pointer = struct(bcrypt, '<STR_LIT>')<EOL>blob_struct = unwrap(blob_struct_pointer)<EOL>blob_struct.Magic = magic<EOL>blob_struct.BitLength = key_info.bit_size<EOL>blob_struct.cbPublicExp = len(public_exponent)<EOL>blob_struct.cbModulus = len(modulus)<EOL>blob_struct.cbPrime1 = prime1_size<EOL>blob_struct.cbPrime2 = prime2_size<EOL>blob = struct_bytes(blob_struct_pointer) + public_exponent + modulus<EOL>if key_type == '<STR_LIT>':<EOL><INDENT>blob += prime1 + prime2<EOL>blob += fill_width(exponent1, prime1_size)<EOL>blob += fill_width(exponent2, prime2_size)<EOL>blob += fill_width(coefficient, prime1_size)<EOL>blob += fill_width(private_exponent, len(modulus))<EOL><DEDENT><DEDENT>elif algo == '<STR_LIT>':<EOL><INDENT>if key_type == '<STR_LIT>':<EOL><INDENT>blob_type = BcryptConst.BCRYPT_DSA_PUBLIC_BLOB<EOL>public_key = key_info['<STR_LIT>'].parsed.native<EOL>params = key_info['<STR_LIT>']['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>blob_type = BcryptConst.BCRYPT_DSA_PRIVATE_BLOB<EOL>public_key = key_info.public_key.native<EOL>private_bytes = int_to_bytes(key_info['<STR_LIT>'].parsed.native)<EOL>params = key_info['<STR_LIT>']['<STR_LIT>']<EOL><DEDENT>public_bytes = int_to_bytes(public_key)<EOL>p = int_to_bytes(params['<STR_LIT:p>'].native)<EOL>g = int_to_bytes(params['<STR_LIT:g>'].native)<EOL>q = int_to_bytes(params['<STR_LIT:q>'].native)<EOL>if key_info.bit_size > <NUM_LIT>:<EOL><INDENT>q_len = len(q)<EOL><DEDENT>else:<EOL><INDENT>q_len = <NUM_LIT:20><EOL><DEDENT>key_width = max(len(public_bytes), len(g), len(p))<EOL>public_bytes = fill_width(public_bytes, key_width)<EOL>p = fill_width(p, key_width)<EOL>g = fill_width(g, key_width)<EOL>q = fill_width(q, q_len)<EOL>count = b'<STR_LIT>' * <NUM_LIT:4><EOL>seed = b'<STR_LIT>' * q_len<EOL>if key_info.bit_size > <NUM_LIT>:<EOL><INDENT>if key_type == '<STR_LIT>':<EOL><INDENT>magic = BcryptConst.BCRYPT_DSA_PUBLIC_MAGIC_V2<EOL><DEDENT>else:<EOL><INDENT>magic = BcryptConst.BCRYPT_DSA_PRIVATE_MAGIC_V2<EOL><DEDENT>blob_struct_pointer = struct(bcrypt, '<STR_LIT>')<EOL>blob_struct = unwrap(blob_struct_pointer)<EOL>blob_struct.dwMagic = magic<EOL>blob_struct.cbKey = key_width<EOL>blob_struct.hashAlgorithm = BcryptConst.DSA_HASH_ALGORITHM_SHA256<EOL>blob_struct.standardVersion = BcryptConst.DSA_FIPS186_3<EOL>blob_struct.cbSeedLength = q_len<EOL>blob_struct.cbGroupSize = q_len<EOL>blob_struct.Count = byte_array(count)<EOL>blob = struct_bytes(blob_struct_pointer)<EOL>blob += seed + q + p + g + public_bytes<EOL>if key_type == '<STR_LIT>':<EOL><INDENT>blob += fill_width(private_bytes, q_len)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if key_type == '<STR_LIT>':<EOL><INDENT>magic = BcryptConst.BCRYPT_DSA_PUBLIC_MAGIC<EOL><DEDENT>else:<EOL><INDENT>magic = BcryptConst.BCRYPT_DSA_PRIVATE_MAGIC<EOL><DEDENT>blob_struct_pointer = struct(bcrypt, '<STR_LIT>')<EOL>blob_struct = unwrap(blob_struct_pointer)<EOL>blob_struct.dwMagic = magic<EOL>blob_struct.cbKey = key_width<EOL>blob_struct.Count = byte_array(count)<EOL>blob_struct.Seed = byte_array(seed)<EOL>blob_struct.q = byte_array(q)<EOL>blob = struct_bytes(blob_struct_pointer) + p + g + public_bytes<EOL>if key_type == '<STR_LIT>':<EOL><INDENT>blob += fill_width(private_bytes, q_len)<EOL><DEDENT><DEDENT><DEDENT>elif algo == '<STR_LIT>':<EOL><INDENT>if key_type == '<STR_LIT>':<EOL><INDENT>blob_type = BcryptConst.BCRYPT_ECCPUBLIC_BLOB<EOL>public_key = key_info['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>blob_type = BcryptConst.BCRYPT_ECCPRIVATE_BLOB<EOL>public_key = key_info.public_key<EOL>private_bytes = int_to_bytes(key_info['<STR_LIT>'].parsed['<STR_LIT>'].native)<EOL><DEDENT>blob_struct_pointer = struct(bcrypt, '<STR_LIT>')<EOL>blob_struct = unwrap(blob_struct_pointer)<EOL>magic = {<EOL>('<STR_LIT>', '<STR_LIT>'): BcryptConst.BCRYPT_ECDSA_PUBLIC_P256_MAGIC,<EOL>('<STR_LIT>', '<STR_LIT>'): BcryptConst.BCRYPT_ECDSA_PUBLIC_P384_MAGIC,<EOL>('<STR_LIT>', '<STR_LIT>'): BcryptConst.BCRYPT_ECDSA_PUBLIC_P521_MAGIC,<EOL>('<STR_LIT>', '<STR_LIT>'): BcryptConst.BCRYPT_ECDSA_PRIVATE_P256_MAGIC,<EOL>('<STR_LIT>', '<STR_LIT>'): BcryptConst.BCRYPT_ECDSA_PRIVATE_P384_MAGIC,<EOL>('<STR_LIT>', '<STR_LIT>'): BcryptConst.BCRYPT_ECDSA_PRIVATE_P521_MAGIC,<EOL>}[(key_type, curve_name)]<EOL>key_width = {<EOL>'<STR_LIT>': <NUM_LIT:32>,<EOL>'<STR_LIT>': <NUM_LIT>,<EOL>'<STR_LIT>': <NUM_LIT><EOL>}[curve_name]<EOL>x, y = public_key.to_coords()<EOL>x_bytes = int_to_bytes(x)<EOL>y_bytes = int_to_bytes(y)<EOL>x_bytes = fill_width(x_bytes, key_width)<EOL>y_bytes = fill_width(y_bytes, key_width)<EOL>blob_struct.dwMagic = magic<EOL>blob_struct.cbKey = key_width<EOL>blob = struct_bytes(blob_struct_pointer) + x_bytes + y_bytes<EOL>if key_type == '<STR_LIT>':<EOL><INDENT>blob += fill_width(private_bytes, key_width)<EOL><DEDENT><DEDENT>key_handle_pointer = new(bcrypt, '<STR_LIT>')<EOL>res = bcrypt.BCryptImportKeyPair(<EOL>alg_handle,<EOL>null(),<EOL>blob_type,<EOL>key_handle_pointer,<EOL>blob,<EOL>len(blob),<EOL>BcryptConst.BCRYPT_NO_KEY_VALIDATION<EOL>)<EOL>handle_error(res)<EOL>key_handle = unwrap(key_handle_pointer)<EOL>return container(key_handle, key_object)<EOL><DEDENT>finally:<EOL><INDENT>if alg_handle:<EOL><INDENT>close_alg_handle(alg_handle)<EOL><DEDENT><DEDENT>

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