def _bcrypt_load_key(key_object, key_info, container, curve_name):
    """
    Loads a certificate, public key or private key into a Certificate,
    PublicKey or PrivateKey object via CNG

    :param key_object:
        An asn1crypto.x509.Certificate, asn1crypto.keys.PublicKeyInfo or
        asn1crypto.keys.PrivateKeyInfo object

    :param key_info:
        An asn1crypto.keys.PublicKeyInfo or asn1crypto.keys.PrivateKeyInfo
        object

    :param container:
        The class of the object to hold the key_handle

    :param curve_name:
        None or a unicode string of the curve name for an EC key

    :raises:
        ValueError - when any of the parameters contain an invalid value
        TypeError - when any of the parameters are of the wrong type
        oscrypto.errors.AsymmetricKeyError - when the key is incompatible with the OS crypto library
        OSError - when an error is returned by the OS crypto library

    :return:
        A PrivateKey, PublicKey or Certificate object, based on container
    """

    alg_handle = None
    key_handle = None

    key_type = 'public' if isinstance(key_info, keys.PublicKeyInfo) else 'private'
    algo = key_info.algorithm

    try:
        alg_selector = key_info.curve[1] if algo == 'ec' else algo
        alg_constant = {
            'rsa': BcryptConst.BCRYPT_RSA_ALGORITHM,
            'dsa': BcryptConst.BCRYPT_DSA_ALGORITHM,
            'secp256r1': BcryptConst.BCRYPT_ECDSA_P256_ALGORITHM,
            'secp384r1': BcryptConst.BCRYPT_ECDSA_P384_ALGORITHM,
            'secp521r1': BcryptConst.BCRYPT_ECDSA_P521_ALGORITHM,
        }[alg_selector]
        alg_handle = open_alg_handle(alg_constant)

        if algo == 'rsa':
            if key_type == 'public':
                blob_type = BcryptConst.BCRYPT_RSAPUBLIC_BLOB
                magic = BcryptConst.BCRYPT_RSAPUBLIC_MAGIC
                parsed_key = key_info['public_key'].parsed
                prime1_size = 0
                prime2_size = 0
            else:
                blob_type = BcryptConst.BCRYPT_RSAFULLPRIVATE_BLOB
                magic = BcryptConst.BCRYPT_RSAFULLPRIVATE_MAGIC
                parsed_key = key_info['private_key'].parsed
                prime1 = int_to_bytes(parsed_key['prime1'].native)
                prime2 = int_to_bytes(parsed_key['prime2'].native)
                exponent1 = int_to_bytes(parsed_key['exponent1'].native)
                exponent2 = int_to_bytes(parsed_key['exponent2'].native)
                coefficient = int_to_bytes(parsed_key['coefficient'].native)
                private_exponent = int_to_bytes(parsed_key['private_exponent'].native)
                prime1_size = len(prime1)
                prime2_size = len(prime2)

            public_exponent = int_to_bytes(parsed_key['public_exponent'].native)
            modulus = int_to_bytes(parsed_key['modulus'].native)

            blob_struct_pointer = struct(bcrypt, 'BCRYPT_RSAKEY_BLOB')
            blob_struct = unwrap(blob_struct_pointer)
            blob_struct.Magic = magic
            blob_struct.BitLength = key_info.bit_size
            blob_struct.cbPublicExp = len(public_exponent)
            blob_struct.cbModulus = len(modulus)
            blob_struct.cbPrime1 = prime1_size
            blob_struct.cbPrime2 = prime2_size

            blob = struct_bytes(blob_struct_pointer) + public_exponent + modulus
            if key_type == 'private':
                blob += prime1 + prime2
                blob += fill_width(exponent1, prime1_size)
                blob += fill_width(exponent2, prime2_size)
                blob += fill_width(coefficient, prime1_size)
                blob += fill_width(private_exponent, len(modulus))

        elif algo == 'dsa':
            if key_type == 'public':
                blob_type = BcryptConst.BCRYPT_DSA_PUBLIC_BLOB
                public_key = key_info['public_key'].parsed.native
                params = key_info['algorithm']['parameters']
            else:
                blob_type = BcryptConst.BCRYPT_DSA_PRIVATE_BLOB
                public_key = key_info.public_key.native
                private_bytes = int_to_bytes(key_info['private_key'].parsed.native)
                params = key_info['private_key_algorithm']['parameters']

            public_bytes = int_to_bytes(public_key)
            p = int_to_bytes(params['p'].native)
            g = int_to_bytes(params['g'].native)
            q = int_to_bytes(params['q'].native)

            if key_info.bit_size > 1024:
                q_len = len(q)
            else:
                q_len = 20

            key_width = max(len(public_bytes), len(g), len(p))

            public_bytes = fill_width(public_bytes, key_width)
            p = fill_width(p, key_width)
            g = fill_width(g, key_width)
            q = fill_width(q, q_len)
            # We don't know the count or seed, so we set them to the max value
            # since setting them to 0 results in a parameter error
            count = b'\xff' * 4
            seed = b'\xff' * q_len

            if key_info.bit_size > 1024:
                if key_type == 'public':
                    magic = BcryptConst.BCRYPT_DSA_PUBLIC_MAGIC_V2
                else:
                    magic = BcryptConst.BCRYPT_DSA_PRIVATE_MAGIC_V2

                blob_struct_pointer = struct(bcrypt, 'BCRYPT_DSA_KEY_BLOB_V2')
                blob_struct = unwrap(blob_struct_pointer)
                blob_struct.dwMagic = magic
                blob_struct.cbKey = key_width
                # We don't know if SHA256 was used here, but the output is long
                # enough for the generation of q for the supported 2048/224,
                # 2048/256 and 3072/256 FIPS approved pairs
                blob_struct.hashAlgorithm = BcryptConst.DSA_HASH_ALGORITHM_SHA256
                blob_struct.standardVersion = BcryptConst.DSA_FIPS186_3
                blob_struct.cbSeedLength = q_len
                blob_struct.cbGroupSize = q_len
                blob_struct.Count = byte_array(count)

                blob = struct_bytes(blob_struct_pointer)
                blob += seed + q + p + g + public_bytes
                if key_type == 'private':
                    blob += fill_width(private_bytes, q_len)

            else:
                if key_type == 'public':
                    magic = BcryptConst.BCRYPT_DSA_PUBLIC_MAGIC
                else:
                    magic = BcryptConst.BCRYPT_DSA_PRIVATE_MAGIC

                blob_struct_pointer = struct(bcrypt, 'BCRYPT_DSA_KEY_BLOB')
                blob_struct = unwrap(blob_struct_pointer)
                blob_struct.dwMagic = magic
                blob_struct.cbKey = key_width
                blob_struct.Count = byte_array(count)
                blob_struct.Seed = byte_array(seed)
                blob_struct.q = byte_array(q)

                blob = struct_bytes(blob_struct_pointer) + p + g + public_bytes
                if key_type == 'private':
                    blob += fill_width(private_bytes, q_len)

        elif algo == 'ec':
            if key_type == 'public':
                blob_type = BcryptConst.BCRYPT_ECCPUBLIC_BLOB
                public_key = key_info['public_key']
            else:
                blob_type = BcryptConst.BCRYPT_ECCPRIVATE_BLOB
                public_key = key_info.public_key
                private_bytes = int_to_bytes(key_info['private_key'].parsed['private_key'].native)

            blob_struct_pointer = struct(bcrypt, 'BCRYPT_ECCKEY_BLOB')
            blob_struct = unwrap(blob_struct_pointer)

            magic = {
                ('public', 'secp256r1'): BcryptConst.BCRYPT_ECDSA_PUBLIC_P256_MAGIC,
                ('public', 'secp384r1'): BcryptConst.BCRYPT_ECDSA_PUBLIC_P384_MAGIC,
                ('public', 'secp521r1'): BcryptConst.BCRYPT_ECDSA_PUBLIC_P521_MAGIC,
                ('private', 'secp256r1'): BcryptConst.BCRYPT_ECDSA_PRIVATE_P256_MAGIC,
                ('private', 'secp384r1'): BcryptConst.BCRYPT_ECDSA_PRIVATE_P384_MAGIC,
                ('private', 'secp521r1'): BcryptConst.BCRYPT_ECDSA_PRIVATE_P521_MAGIC,
            }[(key_type, curve_name)]

            key_width = {
                'secp256r1': 32,
                'secp384r1': 48,
                'secp521r1': 66
            }[curve_name]

            x, y = public_key.to_coords()

            x_bytes = int_to_bytes(x)
            y_bytes = int_to_bytes(y)

            x_bytes = fill_width(x_bytes, key_width)
            y_bytes = fill_width(y_bytes, key_width)

            blob_struct.dwMagic = magic
            blob_struct.cbKey = key_width

            blob = struct_bytes(blob_struct_pointer) + x_bytes + y_bytes
            if key_type == 'private':
                blob += fill_width(private_bytes, key_width)

        key_handle_pointer = new(bcrypt, 'BCRYPT_KEY_HANDLE *')
        res = bcrypt.BCryptImportKeyPair(
            alg_handle,
            null(),
            blob_type,
            key_handle_pointer,
            blob,
            len(blob),
            BcryptConst.BCRYPT_NO_KEY_VALIDATION
        )
        handle_error(res)

        key_handle = unwrap(key_handle_pointer)
        return container(key_handle, key_object)

    finally:
        if alg_handle:
            close_alg_handle(alg_handle)
def _bcrypt_load_key(key_object, key_info, container, curve_name):
    """
    Loads a certificate, public key or private key into a Certificate,
    PublicKey or PrivateKey object via CNG

    :param key_object:
        An asn1crypto.x509.Certificate, asn1crypto.keys.PublicKeyInfo or
        asn1crypto.keys.PrivateKeyInfo object

    :param key_info:
        An asn1crypto.keys.PublicKeyInfo or asn1crypto.keys.PrivateKeyInfo
        object

    :param container:
        The class of the object to hold the key_handle

    :param curve_name:
        None or a unicode string of the curve name for an EC key

    :raises:
        ValueError - when any of the parameters contain an invalid value
        TypeError - when any of the parameters are of the wrong type
        oscrypto.errors.AsymmetricKeyError - when the key is incompatible with the OS crypto library
        OSError - when an error is returned by the OS crypto library

    :return:
        A PrivateKey, PublicKey or Certificate object, based on container
    """

    alg_handle = None
    key_handle = None

    key_type = 'public' if isinstance(key_info, keys.PublicKeyInfo) else 'private'
    algo = key_info.algorithm

    try:
        alg_selector = key_info.curve[1] if algo == 'ec' else algo
        alg_constant = {
            'rsa': BcryptConst.BCRYPT_RSA_ALGORITHM,
            'dsa': BcryptConst.BCRYPT_DSA_ALGORITHM,
            'secp256r1': BcryptConst.BCRYPT_ECDSA_P256_ALGORITHM,
            'secp384r1': BcryptConst.BCRYPT_ECDSA_P384_ALGORITHM,
            'secp521r1': BcryptConst.BCRYPT_ECDSA_P521_ALGORITHM,
        }[alg_selector]
        alg_handle = open_alg_handle(alg_constant)

        if algo == 'rsa':
            if key_type == 'public':
                blob_type = BcryptConst.BCRYPT_RSAPUBLIC_BLOB
                magic = BcryptConst.BCRYPT_RSAPUBLIC_MAGIC
                parsed_key = key_info['public_key'].parsed
                prime1_size = 0
                prime2_size = 0
            else:
                blob_type = BcryptConst.BCRYPT_RSAFULLPRIVATE_BLOB
                magic = BcryptConst.BCRYPT_RSAFULLPRIVATE_MAGIC
                parsed_key = key_info['private_key'].parsed
                prime1 = int_to_bytes(parsed_key['prime1'].native)
                prime2 = int_to_bytes(parsed_key['prime2'].native)
                exponent1 = int_to_bytes(parsed_key['exponent1'].native)
                exponent2 = int_to_bytes(parsed_key['exponent2'].native)
                coefficient = int_to_bytes(parsed_key['coefficient'].native)
                private_exponent = int_to_bytes(parsed_key['private_exponent'].native)
                prime1_size = len(prime1)
                prime2_size = len(prime2)

            public_exponent = int_to_bytes(parsed_key['public_exponent'].native)
            modulus = int_to_bytes(parsed_key['modulus'].native)

            blob_struct_pointer = struct(bcrypt, 'BCRYPT_RSAKEY_BLOB')
            blob_struct = unwrap(blob_struct_pointer)
            blob_struct.Magic = magic
            blob_struct.BitLength = key_info.bit_size
            blob_struct.cbPublicExp = len(public_exponent)
            blob_struct.cbModulus = len(modulus)
            blob_struct.cbPrime1 = prime1_size
            blob_struct.cbPrime2 = prime2_size

            blob = struct_bytes(blob_struct_pointer) + public_exponent + modulus
            if key_type == 'private':
                blob += prime1 + prime2
                blob += fill_width(exponent1, prime1_size)
                blob += fill_width(exponent2, prime2_size)
                blob += fill_width(coefficient, prime1_size)
                blob += fill_width(private_exponent, len(modulus))

        elif algo == 'dsa':
            if key_type == 'public':
                blob_type = BcryptConst.BCRYPT_DSA_PUBLIC_BLOB
                public_key = key_info['public_key'].parsed.native
                params = key_info['algorithm']['parameters']
            else:
                blob_type = BcryptConst.BCRYPT_DSA_PRIVATE_BLOB
                public_key = key_info.public_key.native
                private_bytes = int_to_bytes(key_info['private_key'].parsed.native)
                params = key_info['private_key_algorithm']['parameters']

            public_bytes = int_to_bytes(public_key)
            p = int_to_bytes(params['p'].native)
            g = int_to_bytes(params['g'].native)
            q = int_to_bytes(params['q'].native)

            if key_info.bit_size > 1024:
                q_len = len(q)
            else:
                q_len = 20

            key_width = max(len(public_bytes), len(g), len(p))

            public_bytes = fill_width(public_bytes, key_width)
            p = fill_width(p, key_width)
            g = fill_width(g, key_width)
            q = fill_width(q, q_len)
            # We don't know the count or seed, so we set them to the max value
            # since setting them to 0 results in a parameter error
            count = b'\xff' * 4
            seed = b'\xff' * q_len

            if key_info.bit_size > 1024:
                if key_type == 'public':
                    magic = BcryptConst.BCRYPT_DSA_PUBLIC_MAGIC_V2
                else:
                    magic = BcryptConst.BCRYPT_DSA_PRIVATE_MAGIC_V2

                blob_struct_pointer = struct(bcrypt, 'BCRYPT_DSA_KEY_BLOB_V2')
                blob_struct = unwrap(blob_struct_pointer)
                blob_struct.dwMagic = magic
                blob_struct.cbKey = key_width
                # We don't know if SHA256 was used here, but the output is long
                # enough for the generation of q for the supported 2048/224,
                # 2048/256 and 3072/256 FIPS approved pairs
                blob_struct.hashAlgorithm = BcryptConst.DSA_HASH_ALGORITHM_SHA256
                blob_struct.standardVersion = BcryptConst.DSA_FIPS186_3
                blob_struct.cbSeedLength = q_len
                blob_struct.cbGroupSize = q_len
                blob_struct.Count = byte_array(count)

                blob = struct_bytes(blob_struct_pointer)
                blob += seed + q + p + g + public_bytes
                if key_type == 'private':
                    blob += fill_width(private_bytes, q_len)

            else:
                if key_type == 'public':
                    magic = BcryptConst.BCRYPT_DSA_PUBLIC_MAGIC
                else:
                    magic = BcryptConst.BCRYPT_DSA_PRIVATE_MAGIC

                blob_struct_pointer = struct(bcrypt, 'BCRYPT_DSA_KEY_BLOB')
                blob_struct = unwrap(blob_struct_pointer)
                blob_struct.dwMagic = magic
                blob_struct.cbKey = key_width
                blob_struct.Count = byte_array(count)
                blob_struct.Seed = byte_array(seed)
                blob_struct.q = byte_array(q)

                blob = struct_bytes(blob_struct_pointer) + p + g + public_bytes
                if key_type == 'private':
                    blob += fill_width(private_bytes, q_len)

        elif algo == 'ec':
            if key_type == 'public':
                blob_type = BcryptConst.BCRYPT_ECCPUBLIC_BLOB
                public_key = key_info['public_key']
            else:
                blob_type = BcryptConst.BCRYPT_ECCPRIVATE_BLOB
                public_key = key_info.public_key
                private_bytes = int_to_bytes(key_info['private_key'].parsed['private_key'].native)

            blob_struct_pointer = struct(bcrypt, 'BCRYPT_ECCKEY_BLOB')
            blob_struct = unwrap(blob_struct_pointer)

            magic = {
                ('public', 'secp256r1'): BcryptConst.BCRYPT_ECDSA_PUBLIC_P256_MAGIC,
                ('public', 'secp384r1'): BcryptConst.BCRYPT_ECDSA_PUBLIC_P384_MAGIC,
                ('public', 'secp521r1'): BcryptConst.BCRYPT_ECDSA_PUBLIC_P521_MAGIC,
                ('private', 'secp256r1'): BcryptConst.BCRYPT_ECDSA_PRIVATE_P256_MAGIC,
                ('private', 'secp384r1'): BcryptConst.BCRYPT_ECDSA_PRIVATE_P384_MAGIC,
                ('private', 'secp521r1'): BcryptConst.BCRYPT_ECDSA_PRIVATE_P521_MAGIC,
            }[(key_type, curve_name)]

            key_width = {
                'secp256r1': 32,
                'secp384r1': 48,
                'secp521r1': 66
            }[curve_name]

            x, y = public_key.to_coords()

            x_bytes = int_to_bytes(x)
            y_bytes = int_to_bytes(y)

            x_bytes = fill_width(x_bytes, key_width)
            y_bytes = fill_width(y_bytes, key_width)

            blob_struct.dwMagic = magic
            blob_struct.cbKey = key_width

            blob = struct_bytes(blob_struct_pointer) + x_bytes + y_bytes
            if key_type == 'private':
                blob += fill_width(private_bytes, key_width)

        key_handle_pointer = new(bcrypt, 'BCRYPT_KEY_HANDLE *')
        res = bcrypt.BCryptImportKeyPair(
            alg_handle,
            null(),
            blob_type,
            key_handle_pointer,
            blob,
            len(blob),
            BcryptConst.BCRYPT_NO_KEY_VALIDATION
        )
        handle_error(res)

        key_handle = unwrap(key_handle_pointer)
        return container(key_handle, key_object)

    finally:
        if alg_handle:
            close_alg_handle(alg_handle)
def _bcrypt_load_key ( key_object , key_info , container , curve_name ) : alg_handle = None key_handle = None key_type = 'public' if isinstance ( key_info , keys . PublicKeyInfo ) else 'private' algo = key_info . algorithm try : alg_selector = key_info . curve [ 1 ] if algo == 'ec' else algo alg_constant = { 'rsa' : BcryptConst . BCRYPT_RSA_ALGORITHM , 'dsa' : BcryptConst . BCRYPT_DSA_ALGORITHM , 'secp256r1' : BcryptConst . BCRYPT_ECDSA_P256_ALGORITHM , 'secp384r1' : BcryptConst . BCRYPT_ECDSA_P384_ALGORITHM , 'secp521r1' : BcryptConst . BCRYPT_ECDSA_P521_ALGORITHM , } [ alg_selector ] alg_handle = open_alg_handle ( alg_constant ) if algo == 'rsa' : if key_type == 'public' : blob_type = BcryptConst . BCRYPT_RSAPUBLIC_BLOB magic = BcryptConst . BCRYPT_RSAPUBLIC_MAGIC parsed_key = key_info [ 'public_key' ] . parsed prime1_size = 0 prime2_size = 0 else : blob_type = BcryptConst . BCRYPT_RSAFULLPRIVATE_BLOB magic = BcryptConst . BCRYPT_RSAFULLPRIVATE_MAGIC parsed_key = key_info [ 'private_key' ] . parsed prime1 = int_to_bytes ( parsed_key [ 'prime1' ] . native ) prime2 = int_to_bytes ( parsed_key [ 'prime2' ] . native ) exponent1 = int_to_bytes ( parsed_key [ 'exponent1' ] . native ) exponent2 = int_to_bytes ( parsed_key [ 'exponent2' ] . native ) coefficient = int_to_bytes ( parsed_key [ 'coefficient' ] . native ) private_exponent = int_to_bytes ( parsed_key [ 'private_exponent' ] . native ) prime1_size = len ( prime1 ) prime2_size = len ( prime2 ) public_exponent = int_to_bytes ( parsed_key [ 'public_exponent' ] . native ) modulus = int_to_bytes ( parsed_key [ 'modulus' ] . native ) blob_struct_pointer = struct ( bcrypt , 'BCRYPT_RSAKEY_BLOB' ) blob_struct = unwrap ( blob_struct_pointer ) blob_struct . Magic = magic blob_struct . BitLength = key_info . bit_size blob_struct . cbPublicExp = len ( public_exponent ) blob_struct . cbModulus = len ( modulus ) blob_struct . cbPrime1 = prime1_size blob_struct . cbPrime2 = prime2_size blob = struct_bytes ( blob_struct_pointer ) + public_exponent + modulus if key_type == 'private' : blob += prime1 + prime2 blob += fill_width ( exponent1 , prime1_size ) blob += fill_width ( exponent2 , prime2_size ) blob += fill_width ( coefficient , prime1_size ) blob += fill_width ( private_exponent , len ( modulus ) ) elif algo == 'dsa' : if key_type == 'public' : blob_type = BcryptConst . BCRYPT_DSA_PUBLIC_BLOB public_key = key_info [ 'public_key' ] . parsed . native params = key_info [ 'algorithm' ] [ 'parameters' ] else : blob_type = BcryptConst . BCRYPT_DSA_PRIVATE_BLOB public_key = key_info . public_key . native private_bytes = int_to_bytes ( key_info [ 'private_key' ] . parsed . native ) params = key_info [ 'private_key_algorithm' ] [ 'parameters' ] public_bytes = int_to_bytes ( public_key ) p = int_to_bytes ( params [ 'p' ] . native ) g = int_to_bytes ( params [ 'g' ] . native ) q = int_to_bytes ( params [ 'q' ] . native ) if key_info . bit_size > 1024 : q_len = len ( q ) else : q_len = 20 key_width = max ( len ( public_bytes ) , len ( g ) , len ( p ) ) public_bytes = fill_width ( public_bytes , key_width ) p = fill_width ( p , key_width ) g = fill_width ( g , key_width ) q = fill_width ( q , q_len ) # We don't know the count or seed, so we set them to the max value # since setting them to 0 results in a parameter error count = b'\xff' * 4 seed = b'\xff' * q_len if key_info . bit_size > 1024 : if key_type == 'public' : magic = BcryptConst . BCRYPT_DSA_PUBLIC_MAGIC_V2 else : magic = BcryptConst . BCRYPT_DSA_PRIVATE_MAGIC_V2 blob_struct_pointer = struct ( bcrypt , 'BCRYPT_DSA_KEY_BLOB_V2' ) blob_struct = unwrap ( blob_struct_pointer ) blob_struct . dwMagic = magic blob_struct . cbKey = key_width # We don't know if SHA256 was used here, but the output is long # enough for the generation of q for the supported 2048/224, # 2048/256 and 3072/256 FIPS approved pairs blob_struct . hashAlgorithm = BcryptConst . DSA_HASH_ALGORITHM_SHA256 blob_struct . standardVersion = BcryptConst . DSA_FIPS186_3 blob_struct . cbSeedLength = q_len blob_struct . cbGroupSize = q_len blob_struct . Count = byte_array ( count ) blob = struct_bytes ( blob_struct_pointer ) blob += seed + q + p + g + public_bytes if key_type == 'private' : blob += fill_width ( private_bytes , q_len ) else : if key_type == 'public' : magic = BcryptConst . BCRYPT_DSA_PUBLIC_MAGIC else : magic = BcryptConst . BCRYPT_DSA_PRIVATE_MAGIC blob_struct_pointer = struct ( bcrypt , 'BCRYPT_DSA_KEY_BLOB' ) blob_struct = unwrap ( blob_struct_pointer ) blob_struct . dwMagic = magic blob_struct . cbKey = key_width blob_struct . Count = byte_array ( count ) blob_struct . Seed = byte_array ( seed ) blob_struct . q = byte_array ( q ) blob = struct_bytes ( blob_struct_pointer ) + p + g + public_bytes if key_type == 'private' : blob += fill_width ( private_bytes , q_len ) elif algo == 'ec' : if key_type == 'public' : blob_type = BcryptConst . BCRYPT_ECCPUBLIC_BLOB public_key = key_info [ 'public_key' ] else : blob_type = BcryptConst . BCRYPT_ECCPRIVATE_BLOB public_key = key_info . public_key private_bytes = int_to_bytes ( key_info [ 'private_key' ] . parsed [ 'private_key' ] . native ) blob_struct_pointer = struct ( bcrypt , 'BCRYPT_ECCKEY_BLOB' ) blob_struct = unwrap ( blob_struct_pointer ) magic = { ( 'public' , 'secp256r1' ) : BcryptConst . BCRYPT_ECDSA_PUBLIC_P256_MAGIC , ( 'public' , 'secp384r1' ) : BcryptConst . BCRYPT_ECDSA_PUBLIC_P384_MAGIC , ( 'public' , 'secp521r1' ) : BcryptConst . BCRYPT_ECDSA_PUBLIC_P521_MAGIC , ( 'private' , 'secp256r1' ) : BcryptConst . BCRYPT_ECDSA_PRIVATE_P256_MAGIC , ( 'private' , 'secp384r1' ) : BcryptConst . BCRYPT_ECDSA_PRIVATE_P384_MAGIC , ( 'private' , 'secp521r1' ) : BcryptConst . BCRYPT_ECDSA_PRIVATE_P521_MAGIC , } [ ( key_type , curve_name ) ] key_width = { 'secp256r1' : 32 , 'secp384r1' : 48 , 'secp521r1' : 66 } [ curve_name ] x , y = public_key . to_coords ( ) x_bytes = int_to_bytes ( x ) y_bytes = int_to_bytes ( y ) x_bytes = fill_width ( x_bytes , key_width ) y_bytes = fill_width ( y_bytes , key_width ) blob_struct . dwMagic = magic blob_struct . cbKey = key_width blob = struct_bytes ( blob_struct_pointer ) + x_bytes + y_bytes if key_type == 'private' : blob += fill_width ( private_bytes , key_width ) key_handle_pointer = new ( bcrypt , 'BCRYPT_KEY_HANDLE *' ) res = bcrypt . BCryptImportKeyPair ( alg_handle , null ( ) , blob_type , key_handle_pointer , blob , len ( blob ) , BcryptConst . BCRYPT_NO_KEY_VALIDATION ) handle_error ( res ) key_handle = unwrap ( key_handle_pointer ) return container ( key_handle , key_object ) finally : if alg_handle : close_alg_handle ( alg_handle )
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
Loads a certificate public key or private key into a Certificate PublicKey or PrivateKey object via CNG