-- v4: bcrypt/tests: Test BCRYPT_PAD_NONE encryption result in test_rsa_encrypt(). bcrypt: Set pubkey from privkey in key_asymmetric_import().
From: Paul Gofman pgofman@codeweavers.com
--- dlls/bcrypt/gnutls.c | 2 ++ dlls/bcrypt/tests/bcrypt.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c index bb79e885652..a67030a3ae0 100644 --- a/dlls/bcrypt/gnutls.c +++ b/dlls/bcrypt/gnutls.c @@ -2205,6 +2205,8 @@ static NTSTATUS key_asymmetric_encrypt( void *args ) NTSTATUS status = STATUS_SUCCESS; int ret;
+ if (!key_data(params->key)->a.pubkey) return STATUS_INVALID_HANDLE; + d.data = params->input; d.size = params->input_len; if ((ret = pgnutls_pubkey_encrypt_data(key_data(params->key)->a.pubkey, 0, &d, &e))) diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index 39cdd015c90..3bcdda0cf47 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -2284,12 +2284,12 @@ static void test_rsa_encrypt(void) ret = BCryptGenerateKeyPair(rsa, &key, 512, 0); ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
- todo_wine { /* Not finalized key */ ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, NULL, 0, &encrypted_size, 0); ok(ret == STATUS_INVALID_HANDLE, "got %lx\n", ret); BCryptFinalizeKeyPair(key, 0);
+ todo_wine { /* No padding */ memset(input_no_padding, 0, sizeof(input_no_padding)); strcpy((char *)input_no_padding, "Hello World");
From: Paul Gofman pgofman@codeweavers.com
--- dlls/bcrypt/gnutls.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-)
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c index a67030a3ae0..009f6d2a6b5 100644 --- a/dlls/bcrypt/gnutls.c +++ b/dlls/bcrypt/gnutls.c @@ -1574,6 +1574,8 @@ static NTSTATUS key_asymmetric_import( void *args ) const struct key_asymmetric_import_params *params = args; struct key *key = params->key; unsigned flags = params->flags; + gnutls_pubkey_t pubkey; + NTSTATUS ret;
switch (key->alg_id) { @@ -1583,13 +1585,15 @@ static NTSTATUS key_asymmetric_import( void *args ) case ALG_ID_ECDSA_P384: if (flags & KEY_IMPORT_FLAG_PUBLIC) return key_import_ecc_public( key, params->buf, params->len ); - return key_import_ecc( key, params->buf, params->len ); + ret = key_import_ecc( key, params->buf, params->len ); + break;
case ALG_ID_RSA: case ALG_ID_RSA_SIGN: if (flags & KEY_IMPORT_FLAG_PUBLIC) return key_import_rsa_public( key, params->buf, params->len ); - return key_import_rsa( key, params->buf, params->len ); + ret = key_import_rsa( key, params->buf, params->len ); + break;
case ALG_ID_DSA: if (flags & KEY_IMPORT_FLAG_PUBLIC) @@ -1599,7 +1603,10 @@ static NTSTATUS key_asymmetric_import( void *args ) return key_import_dsa_public( key, params->buf, params->len ); } if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2) - return key_import_dsa_capi( key, params->buf, params->len ); + { + ret = key_import_dsa_capi( key, params->buf, params->len ); + break; + } FIXME( "DSA private key not supported\n" ); return STATUS_NOT_IMPLEMENTED;
@@ -1607,6 +1614,26 @@ static NTSTATUS key_asymmetric_import( void *args ) FIXME( "algorithm %u not yet supported\n", key->alg_id ); return STATUS_NOT_IMPLEMENTED; } + + if (ret) return ret; + + if ((ret = pgnutls_pubkey_init( &pubkey ))) + { + pgnutls_perror( ret ); + return STATUS_INTERNAL_ERROR; + } + + if (pgnutls_pubkey_import_privkey( pubkey, key_data(params->key)->a.privkey, 0, 0 )) + { + /* Imported private key may be legitimately missing public key, so ignore the failure here. */ + pgnutls_pubkey_deinit( pubkey ); + } + else + { + if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey ); + key_data(key)->a.pubkey = pubkey; + } + return STATUS_SUCCESS; }
static NTSTATUS prepare_gnutls_signature_dsa( struct key *key, UCHAR *signature, ULONG signature_len,
From: Paul Gofman pgofman@codeweavers.com
--- dlls/bcrypt/tests/bcrypt.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index 3bcdda0cf47..5d1a80f330b 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -2262,6 +2262,14 @@ static UCHAR rsaPublicBlobWithInvalidPublicExpSize[] = 0x87, 0x75, 0x33, 0x15, 0xb8, 0xde, 0x32, 0x30, 0xb4, 0x5e, 0xfd };
+static const UCHAR rsa_encrypted_no_padding[] = +{ + 0x4a, 0xc1, 0xfa, 0x4f, 0xe0, 0x3f, 0x36, 0x9a, 0x64, 0xbf, 0x2e, 0x00, 0xb4, 0xb5, 0x40, 0xbe, + 0x2d, 0x9a, 0x14, 0xf6, 0x8f, 0xa5, 0xc2, 0xe2, 0x20, 0xaf, 0x21, 0x79, 0xc6, 0x32, 0x7e, 0xea, + 0x73, 0x00, 0x01, 0xbb, 0x9a, 0x19, 0x73, 0x41, 0x96, 0xae, 0x88, 0x6e, 0x36, 0x56, 0xe9, 0x9c, + 0xac, 0x04, 0x82, 0xa8, 0x00, 0xdb, 0x4e, 0x29, 0x61, 0x7e, 0xaf, 0x64, 0xdb, 0xa2, 0x70, 0x0f, +}; + static void test_rsa_encrypt(void) { static UCHAR input[] = "Hello World!"; @@ -2287,7 +2295,15 @@ static void test_rsa_encrypt(void) /* Not finalized key */ ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, NULL, 0, &encrypted_size, 0); ok(ret == STATUS_INVALID_HANDLE, "got %lx\n", ret); - BCryptFinalizeKeyPair(key, 0); + BCryptDestroyKey(key); + + /* Import a different public key first to make sure a public key from private key improted next + * overrides it. */ + ret = BCryptImportKeyPair(rsa, NULL, BCRYPT_RSAPUBLIC_BLOB, &key, rsaPublicBlob, sizeof(rsaPublicBlob), 0); + ok(ret == STATUS_SUCCESS, "got %#lx\n", ret); + + ret = BCryptImportKeyPair(rsa, NULL, BCRYPT_RSAPRIVATE_BLOB, &key, rsaPrivateBlob, sizeof(rsaPrivateBlob), 0); + ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
todo_wine { /* No padding */ @@ -2313,6 +2329,7 @@ static void test_rsa_encrypt(void) ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, encrypted_b, encrypted_size, &encrypted_size, BCRYPT_PAD_NONE); ok(ret == STATUS_SUCCESS, "got %lx\n", ret); ok(!memcmp(encrypted_a, encrypted_b, encrypted_size), "Both outputs should be the same\n"); + ok(!memcmp(encrypted_b, rsa_encrypted_no_padding, encrypted_size), "Data mismatch.\n");
BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_NONE); decrypted = malloc(decrypted_size);