Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52060 Signed-off-by: Hans Leidekker hans@codeweavers.com --- dlls/bcrypt/bcrypt_internal.h | 2 + dlls/bcrypt/bcrypt_main.c | 15 +++- dlls/bcrypt/gnutls.c | 88 +++++++++++++++++++ dlls/bcrypt/tests/bcrypt.c | 157 +++++++++++++++++++++++++++++++++- include/bcrypt.h | 2 + 5 files changed, 258 insertions(+), 6 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h index e015cc1fa42..c0a53f9068b 100644 --- a/dlls/bcrypt/bcrypt_internal.h +++ b/dlls/bcrypt/bcrypt_internal.h @@ -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, diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index 542bd0756a0..a1c6ef2c66c 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -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, ¶ms ); + } 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 ))) diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c index 3a1eff1e7bd..c880c9c1d46 100644 --- a/dlls/bcrypt/gnutls.c +++ b/dlls/bcrypt/gnutls.c @@ -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( ¶ms ); + 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 diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index 4dd0f4195aa..a688d43657b 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -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) { diff --git a/include/bcrypt.h b/include/bcrypt.h index a099f2f4b0e..15c26c1fb0a 100644 --- a/include/bcrypt.h +++ b/include/bcrypt.h @@ -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};