bcrypt: Add support for exporting RSA private keys.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52060
Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Hans Leidekker 2021-12-03 15:49:29 +01:00 committed by Alexandre Julliard
parent a226331851
commit 2795c7f995
5 changed files with 258 additions and 6 deletions

View File

@ -274,6 +274,7 @@ struct key_export_params
UCHAR *buf;
ULONG len;
ULONG *ret_len;
BOOL full;
};
struct key_import_params
@ -301,6 +302,7 @@ enum key_funcs
unix_key_asymmetric_destroy,
unix_key_export_dsa_capi,
unix_key_export_ecc,
unix_key_export_rsa,
unix_key_import_dsa_capi,
unix_key_import_ecc,
unix_key_import_rsa,

View File

@ -1101,6 +1101,15 @@ static NTSTATUS key_export( struct key *key, const WCHAR *type, UCHAR *output, U
if (output) memcpy( output, key->u.a.pubkey, key->u.a.pubkey_len );
return STATUS_SUCCESS;
}
else if (!wcscmp( type, BCRYPT_RSAPRIVATE_BLOB ) || !wcscmp( type, BCRYPT_RSAFULLPRIVATE_BLOB ))
{
params.key = key;
params.buf = output;
params.len = output_len;
params.ret_len = size;
params.full = wcscmp( type, BCRYPT_RSAPRIVATE_BLOB );
return UNIX_CALL( key_export_rsa, &params );
}
else if (!wcscmp( type, BCRYPT_ECCPRIVATE_BLOB ))
{
params.key = key;
@ -1404,13 +1413,13 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
return key_asymmetric_create( (struct key **)ret_key, alg, rsa_blob->BitLength, (BYTE *)rsa_blob, size );
}
else if (!wcscmp( type, BCRYPT_RSAPRIVATE_BLOB ))
else if (!wcscmp( type, BCRYPT_RSAPRIVATE_BLOB ) || !wcscmp( type, BCRYPT_RSAFULLPRIVATE_BLOB ))
{
BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)input;
if (input_len < sizeof(*rsa_blob)) return STATUS_INVALID_PARAMETER;
if (alg->id != ALG_ID_RSA || rsa_blob->Magic != BCRYPT_RSAPRIVATE_MAGIC)
return STATUS_NOT_SUPPORTED;
if (alg->id != ALG_ID_RSA || (rsa_blob->Magic != BCRYPT_RSAPRIVATE_MAGIC &&
rsa_blob->Magic != BCRYPT_RSAFULLPRIVATE_MAGIC)) return STATUS_NOT_SUPPORTED;
size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
if ((status = key_asymmetric_create( &key, alg, rsa_blob->BitLength, (BYTE *)rsa_blob, size )))

View File

@ -1028,6 +1028,64 @@ static NTSTATUS key_import_ecc( void *args )
return STATUS_SUCCESS;
}
static NTSTATUS key_export_rsa( void *args )
{
const struct key_export_params *params = args;
struct key *key = params->key;
BCRYPT_RSAKEY_BLOB *rsa_blob;
gnutls_datum_t m, e, d, p, q, u, e1, e2;
ULONG bitlen = key->u.a.bitlen;
UCHAR *dst;
int ret;
if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
}
*params->ret_len = sizeof(*rsa_blob) + EXPORT_SIZE(e,8,0) + EXPORT_SIZE(m,8,1) + EXPORT_SIZE(p,16,1) + EXPORT_SIZE(q,16,1);
if (params->full) *params->ret_len += EXPORT_SIZE(e1,16,1) + EXPORT_SIZE(e2,16,1) + EXPORT_SIZE(u,16,1) + EXPORT_SIZE(d,8,1);
if (params->len >= *params->ret_len && params->buf)
{
rsa_blob = (BCRYPT_RSAKEY_BLOB *)params->buf;
rsa_blob->Magic = params->full ? BCRYPT_RSAFULLPRIVATE_MAGIC : BCRYPT_RSAPRIVATE_MAGIC;
rsa_blob->BitLength = bitlen;
dst = (UCHAR *)(rsa_blob + 1);
rsa_blob->cbPublicExp = export_gnutls_datum( dst, bitlen / 8, &e, 0 );
dst += rsa_blob->cbPublicExp;
rsa_blob->cbModulus = export_gnutls_datum( dst, bitlen / 8, &m, 1 );
dst += rsa_blob->cbModulus;
rsa_blob->cbPrime1 = export_gnutls_datum( dst, bitlen / 16, &p, 1 );
dst += rsa_blob->cbPrime1;
rsa_blob->cbPrime2 = export_gnutls_datum( dst, bitlen / 16, &q, 1 );
if (params->full)
{
dst += rsa_blob->cbPrime2;
export_gnutls_datum( dst, bitlen / 16, &e1, 1 );
dst += rsa_blob->cbPrime1;
export_gnutls_datum( dst, bitlen / 16, &e2, 1 );
dst += rsa_blob->cbPrime2;
export_gnutls_datum( dst, bitlen / 16, &u, 1 );
dst += rsa_blob->cbPrime1;
export_gnutls_datum( dst, bitlen / 8, &d, 1 );
}
}
free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
free( e1.data ); free( e2.data );
return STATUS_SUCCESS;
}
static NTSTATUS key_import_rsa( void *args )
{
const struct key_import_params *params = args;
@ -1805,6 +1863,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
key_asymmetric_destroy,
key_export_dsa_capi,
key_export_ecc,
key_export_rsa,
key_import_dsa_capi,
key_import_ecc,
key_import_rsa
@ -2269,6 +2328,34 @@ static NTSTATUS wow64_key_import_ecc( void *args )
return ret;
}
static NTSTATUS wow64_key_export_rsa( void *args )
{
struct
{
PTR32 key;
PTR32 buf;
ULONG len;
PTR32 ret_len;
BOOL full;
} const *params32 = args;
NTSTATUS ret;
struct key key;
struct key32 *key32 = ULongToPtr( params32->key );
struct key_export_params params =
{
get_asymmetric_key( key32, &key ),
ULongToPtr(params32->buf),
params32->len,
ULongToPtr(params32->ret_len),
params32->full
};
ret = key_export_rsa( &params );
put_asymmetric_key32( &key, key32 );
return ret;
}
static NTSTATUS wow64_key_import_rsa( void *args )
{
struct
@ -2311,6 +2398,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
wow64_key_asymmetric_destroy,
wow64_key_export_dsa_capi,
wow64_key_export_ecc,
wow64_key_export_rsa,
wow64_key_import_dsa_capi,
wow64_key_import_ecc,
wow64_key_import_rsa

View File

@ -1977,6 +1977,44 @@ static UCHAR rsaSignature[] =
0xc1, 0x74, 0xe6, 0x7c, 0x18, 0x0f, 0x2b, 0x3b, 0xaa, 0xd1, 0x9d, 0x40, 0x71, 0x1d, 0x19, 0x53
};
static UCHAR rsaPrivateBlob[] =
{
0x52, 0x53, 0x41, 0x32, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0xa6, 0x8b, 0x46, 0x26, 0xb5,
0xa9, 0x69, 0x83, 0x94, 0x66, 0xa7, 0xf3, 0x33, 0x95, 0x74, 0xe9, 0xeb, 0xc8, 0xcd, 0xd7, 0x81,
0x9e, 0x45, 0x66, 0xb2, 0x48, 0x8b, 0x1f, 0xfe, 0xb3, 0x62, 0xc4, 0x0d, 0xa2, 0xf9, 0xf3, 0xe2,
0xa6, 0x86, 0xd1, 0x1e, 0x8a, 0xbb, 0x1d, 0xa5, 0xc5, 0xe8, 0xa7, 0x50, 0x37, 0xfd, 0x69, 0x1f,
0x6f, 0x99, 0x99, 0xca, 0x39, 0x13, 0xea, 0x5b, 0x6b, 0xe3, 0x91, 0xc0, 0xd2, 0x2c, 0x0b, 0x21,
0xb1, 0xac, 0xa9, 0xe8, 0xa0, 0x6d, 0xa4, 0x1f, 0x1b, 0x34, 0xcb, 0x88, 0x7f, 0x2e, 0xeb, 0x7d,
0x91, 0x38, 0x48, 0xce, 0x05, 0x73, 0x05, 0xdd, 0x22, 0x94, 0xc3, 0xdd, 0x1c, 0xfd, 0xc5, 0x41,
0x2e, 0x94, 0xf9, 0xed, 0xe5, 0x92, 0x5f, 0x3f, 0x06, 0xf8, 0x49, 0x60, 0xb8, 0x92, 0x52, 0x6a,
0x56, 0x6e, 0xd7, 0x04, 0x1a, 0xb5, 0xb5, 0x1c, 0x31, 0xd1, 0x1b,
};
static UCHAR rsaFullPrivateBlob[] =
{
0x52, 0x53, 0x41, 0x33, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0xa6, 0x8b, 0x46, 0x26, 0xb5,
0xa9, 0x69, 0x83, 0x94, 0x66, 0xa7, 0xf3, 0x33, 0x95, 0x74, 0xe9, 0xeb, 0xc8, 0xcd, 0xd7, 0x81,
0x9e, 0x45, 0x66, 0xb2, 0x48, 0x8b, 0x1f, 0xfe, 0xb3, 0x62, 0xc4, 0x0d, 0xa2, 0xf9, 0xf3, 0xe2,
0xa6, 0x86, 0xd1, 0x1e, 0x8a, 0xbb, 0x1d, 0xa5, 0xc5, 0xe8, 0xa7, 0x50, 0x37, 0xfd, 0x69, 0x1f,
0x6f, 0x99, 0x99, 0xca, 0x39, 0x13, 0xea, 0x5b, 0x6b, 0xe3, 0x91, 0xc0, 0xd2, 0x2c, 0x0b, 0x21,
0xb1, 0xac, 0xa9, 0xe8, 0xa0, 0x6d, 0xa4, 0x1f, 0x1b, 0x34, 0xcb, 0x88, 0x7f, 0x2e, 0xeb, 0x7d,
0x91, 0x38, 0x48, 0xce, 0x05, 0x73, 0x05, 0xdd, 0x22, 0x94, 0xc3, 0xdd, 0x1c, 0xfd, 0xc5, 0x41,
0x2e, 0x94, 0xf9, 0xed, 0xe5, 0x92, 0x5f, 0x3f, 0x06, 0xf8, 0x49, 0x60, 0xb8, 0x92, 0x52, 0x6a,
0x56, 0x6e, 0xd7, 0x04, 0x1a, 0xb5, 0xb5, 0x1c, 0x31, 0xd1, 0x1b, 0xa3, 0xf3, 0xd1, 0x69, 0x61,
0xab, 0xfe, 0xc1, 0xb6, 0x40, 0x7b, 0x19, 0xbb, 0x2d, 0x59, 0xf5, 0xda, 0x49, 0x32, 0x6f, 0x20,
0x24, 0xd3, 0xb3, 0xec, 0x21, 0xec, 0x0c, 0xc7, 0x5b, 0xf9, 0x1b, 0xba, 0x6e, 0xe9, 0x61, 0xda,
0x55, 0xc6, 0x72, 0xfd, 0x2d, 0x66, 0x3f, 0x3c, 0xcb, 0x49, 0xa9, 0xc5, 0x0d, 0x9b, 0x02, 0x36,
0x7a, 0xee, 0x36, 0x09, 0x55, 0xe4, 0x03, 0xf2, 0xe3, 0xe6, 0x25, 0x14, 0x89, 0x7f, 0x2b, 0xfb,
0x27, 0x0e, 0x8d, 0x37, 0x84, 0xfd, 0xad, 0x10, 0x79, 0x43, 0x4e, 0x38, 0x4a, 0xd4, 0x5e, 0xfa,
0xda, 0x9f, 0x88, 0x21, 0x7c, 0xb4, 0x98, 0xb6, 0x6e, 0x1c, 0x24, 0x09, 0xe5, 0xe7, 0x22, 0x6f,
0xd3, 0x84, 0xc0, 0xdc, 0x36, 0x09, 0xaf, 0x4b, 0x96, 0x8b, 0x5f, 0x47, 0xb3, 0x24, 0x80, 0xb5,
0x64, 0x69, 0xad, 0x83, 0xd5, 0x09, 0xe7, 0xb9, 0xe4, 0x81, 0x6f, 0x1a, 0xe2, 0x6d, 0xf1, 0x5e,
0x2b, 0xb3, 0x7a, 0xd0, 0x77, 0xef, 0x82, 0xcd, 0x55, 0x2e, 0xd5, 0xb1, 0xa7, 0x72, 0xec, 0x02,
0x9d, 0xe2, 0xcc, 0x5a, 0xf1, 0x68, 0x30, 0xe5, 0xbc, 0x8d, 0xad,
};
static void test_RSA(void)
{
static UCHAR hash[] =
@ -1986,7 +2024,7 @@ static void test_RSA(void)
BCRYPT_KEY_HANDLE key;
BCRYPT_RSAKEY_BLOB *rsablob;
UCHAR sig[64];
ULONG len, size, schemes;
ULONG len, size, size2, schemes;
NTSTATUS ret;
BYTE *buf;
@ -2043,6 +2081,46 @@ static void test_RSA(void)
ret = pBCryptSignHash(key, &pad, hash, sizeof(hash), sig, sizeof(sig), &len, BCRYPT_PAD_PKCS1);
ok(!ret, "got %08x\n", ret);
/* export private key */
size = 0;
ret = pBCryptExportKey(key, NULL, BCRYPT_RSAPRIVATE_BLOB, NULL, 0, &size, 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
ok(size, "size not set\n");
buf = HeapAlloc(GetProcessHeap(), 0, size);
ret = pBCryptExportKey(key, NULL, BCRYPT_RSAPRIVATE_BLOB, buf, size, &size, 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
rsablob = (BCRYPT_RSAKEY_BLOB *)buf;
ok(rsablob->Magic == BCRYPT_RSAPRIVATE_MAGIC, "got %08x\n", rsablob->Magic);
ok(rsablob->BitLength == 512, "got %u\n", rsablob->BitLength);
ok(rsablob->cbPublicExp == 3, "got %u\n", rsablob->cbPublicExp);
ok(rsablob->cbModulus == 64, "got %u\n", rsablob->cbModulus);
ok(rsablob->cbPrime1 == 32, "got %u\n", rsablob->cbPrime1);
ok(rsablob->cbPrime2 == 32, "got %u\n", rsablob->cbPrime2);
size2 = sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus + rsablob->cbPrime1 + rsablob->cbPrime2;
ok(size == size2, "got %u expected %u\n", size2, size);
HeapFree(GetProcessHeap(), 0, buf);
size = 0;
ret = pBCryptExportKey(key, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, NULL, 0, &size, 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
ok(size, "size not set\n");
buf = HeapAlloc(GetProcessHeap(), 0, size);
ret = pBCryptExportKey(key, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, buf, size, &size, 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
rsablob = (BCRYPT_RSAKEY_BLOB *)buf;
ok(rsablob->Magic == BCRYPT_RSAFULLPRIVATE_MAGIC, "got %08x\n", rsablob->Magic);
ok(rsablob->BitLength == 512, "got %u\n", rsablob->BitLength);
ok(rsablob->cbPublicExp == 3, "got %u\n", rsablob->cbPublicExp);
ok(rsablob->cbModulus == 64, "got %u\n", rsablob->cbModulus);
ok(rsablob->cbPrime1 == 32, "got %u\n", rsablob->cbPrime1);
ok(rsablob->cbPrime2 == 32, "got %u\n", rsablob->cbPrime2);
size2 = sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus * 2 + rsablob->cbPrime1 * 3 + rsablob->cbPrime2 * 2;
ok(size == size2, "got %u expected %u\n", size2, size);
HeapFree(GetProcessHeap(), 0, buf);
/* export public key */
size = 0;
ret = pBCryptExportKey(key, NULL, BCRYPT_RSAPUBLIC_BLOB, NULL, 0, &size, 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
@ -2071,6 +2149,32 @@ static void test_RSA(void)
ret = pBCryptDestroyKey(key);
ok(!ret, "got %08x\n", ret);
/* import/export private key */
ret = pBCryptImportKeyPair(alg, NULL, BCRYPT_RSAPRIVATE_BLOB, &key, rsaPrivateBlob, sizeof(rsaPrivateBlob), 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
size = 0;
buf = HeapAlloc(GetProcessHeap(), 0, sizeof(rsaPrivateBlob));
ret = pBCryptExportKey(key, NULL, BCRYPT_RSAPRIVATE_BLOB, buf, sizeof(rsaPrivateBlob), &size, 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
ok(size == sizeof(rsaPrivateBlob), "got %u\n", size);
ok(!memcmp(buf, rsaPrivateBlob, size), "wrong data\n");
HeapFree(GetProcessHeap(), 0, buf);
pBCryptDestroyKey(key);
/* import/export full private key */
ret = pBCryptImportKeyPair(alg, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, &key, rsaFullPrivateBlob, sizeof(rsaFullPrivateBlob), 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
size = 0;
buf = HeapAlloc(GetProcessHeap(), 0, sizeof(rsaFullPrivateBlob));
ret = pBCryptExportKey(key, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, buf, sizeof(rsaFullPrivateBlob), &size, 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
ok(size == sizeof(rsaFullPrivateBlob), "got %u\n", size);
ok(!memcmp(buf, rsaFullPrivateBlob, size), "wrong data\n");
HeapFree(GetProcessHeap(), 0, buf);
pBCryptDestroyKey(key);
ret = pBCryptCloseAlgorithmProvider(alg, 0);
ok(!ret, "got %08x\n", ret);
}
@ -2080,7 +2184,10 @@ static void test_RSA_SIGN(void)
BCRYPT_PKCS1_PADDING_INFO pad;
BCRYPT_ALG_HANDLE alg = NULL;
BCRYPT_KEY_HANDLE key = NULL;
BCRYPT_RSAKEY_BLOB *rsablob;
NTSTATUS ret;
ULONG size, size2;
BYTE *buf;
ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_RSA_SIGN_ALGORITHM, NULL, 0);
if (ret)
@ -2117,6 +2224,52 @@ static void test_RSA_SIGN(void)
ret = pBCryptDestroyKey(key);
ok(!ret, "pBCryptDestroyKey failed: %08x\n", ret);
/* export private key */
ret = pBCryptGenerateKeyPair(alg, &key, 512, 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
ret = pBCryptFinalizeKeyPair(key, 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
size = 0;
ret = pBCryptExportKey(key, NULL, BCRYPT_RSAPRIVATE_BLOB, NULL, 0, &size, 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
ok(size, "size not set\n");
buf = HeapAlloc(GetProcessHeap(), 0, size);
ret = pBCryptExportKey(key, NULL, BCRYPT_RSAPRIVATE_BLOB, buf, size, &size, 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
rsablob = (BCRYPT_RSAKEY_BLOB *)buf;
ok(rsablob->Magic == BCRYPT_RSAPRIVATE_MAGIC, "got %08x\n", rsablob->Magic);
ok(rsablob->BitLength == 512, "got %u\n", rsablob->BitLength);
ok(rsablob->cbPublicExp == 3, "got %u\n", rsablob->cbPublicExp);
ok(rsablob->cbModulus == 64, "got %u\n", rsablob->cbModulus);
ok(rsablob->cbPrime1 == 32, "got %u\n", rsablob->cbPrime1);
ok(rsablob->cbPrime2 == 32, "got %u\n", rsablob->cbPrime2);
size2 = sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus + rsablob->cbPrime1 + rsablob->cbPrime2;
ok(size == size2, "got %u expected %u\n", size2, size);
HeapFree(GetProcessHeap(), 0, buf);
size = 0;
ret = pBCryptExportKey(key, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, NULL, 0, &size, 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
ok(size, "size not set\n");
buf = HeapAlloc(GetProcessHeap(), 0, size);
ret = pBCryptExportKey(key, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, buf, size, &size, 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
rsablob = (BCRYPT_RSAKEY_BLOB *)buf;
ok(rsablob->Magic == BCRYPT_RSAFULLPRIVATE_MAGIC, "got %08x\n", rsablob->Magic);
ok(rsablob->BitLength == 512, "got %u\n", rsablob->BitLength);
ok(rsablob->cbPublicExp == 3, "got %u\n", rsablob->cbPublicExp);
ok(rsablob->cbModulus == 64, "got %u\n", rsablob->cbModulus);
ok(rsablob->cbPrime1 == 32, "got %u\n", rsablob->cbPrime1);
ok(rsablob->cbPrime2 == 32, "got %u\n", rsablob->cbPrime2);
size2 = sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus * 2 + rsablob->cbPrime1 * 3 + rsablob->cbPrime2 * 2;
ok(size == size2, "got %u expected %u\n", size2, size);
HeapFree(GetProcessHeap(), 0, buf);
pBCryptDestroyKey(key);
ret = pBCryptCloseAlgorithmProvider(alg, 0);
ok(!ret, "pBCryptCloseAlgorithmProvider failed: %08x\n", ret);
}
@ -2370,7 +2523,6 @@ static void test_BCryptSignHash(void)
ULONG len;
/* RSA */
ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_RSA_ALGORITHM, NULL, 0);
if (ret)
{
@ -2424,7 +2576,6 @@ static void test_BCryptSignHash(void)
ok(!ret, "got %08x\n", ret);
/* ECDSA */
ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_ECDSA_P256_ALGORITHM, NULL, 0);
if (ret)
{

View File

@ -66,6 +66,7 @@ typedef LONG NTSTATUS;
#define BCRYPT_ECCPRIVATE_BLOB L"ECCPRIVATEBLOB"
#define BCRYPT_RSAPUBLIC_BLOB L"RSAPUBLICBLOB"
#define BCRYPT_RSAPRIVATE_BLOB L"RSAPRIVATEBLOB"
#define BCRYPT_RSAFULLPRIVATE_BLOB L"RSAFULLPRIVATEBLOB"
#define BCRYPT_DSA_PUBLIC_BLOB L"DSAPUBLICBLOB"
#define BCRYPT_DSA_PRIVATE_BLOB L"DSAPRIVATEBLOB"
#define BCRYPT_PUBLIC_KEY_BLOB L"PUBLICBLOB"
@ -137,6 +138,7 @@ static const WCHAR BCRYPT_ECCPUBLIC_BLOB[] = {'E','C','C','P','U','B','L','I','C
static const WCHAR BCRYPT_ECCPRIVATE_BLOB[] = {'E','C','C','P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR BCRYPT_RSAPUBLIC_BLOB[] = {'R','S','A','P','U','B','L','I','C','B','L','O','B',0};
static const WCHAR BCRYPT_RSAPRIVATE_BLOB[] = {'R','S','A','P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR BCRYPT_RSAFULLPRIVATE_BLOB[] = {'R','S','A','F','U','L','L','P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR BCRYPT_DSA_PUBLIC_BLOB[] = {'D','S','A','P','U','B','L','I','C','B','L','O','B',0};
static const WCHAR BCRYPT_DSA_PRIVATE_BLOB[] = {'D','S','A','P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR BCRYPT_PUBLIC_KEY_BLOB[] = {'P','U','B','L','I','C','B','L','O','B',0};