Signed-off-by: Hans Leidekker hans@codeweavers.com --- dlls/bcrypt/gnutls.c | 20 ++++++++++++++++++-- dlls/bcrypt/tests/bcrypt.c | 18 +++++++++++++++++- 2 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c index 9de126c2bfe..eea84cf3aa9 100644 --- a/dlls/bcrypt/gnutls.c +++ b/dlls/bcrypt/gnutls.c @@ -107,6 +107,7 @@ static int (*pgnutls_pubkey_import_dsa_raw)(gnutls_pubkey_t, const gnutls_datum_ static int (*pgnutls_pubkey_import_privkey)(gnutls_pubkey_t, gnutls_privkey_t, unsigned int, unsigned int);
/* Not present in gnutls version < 3.3.0 */ +static int (*pgnutls_pubkey_export_rsa_raw)(gnutls_pubkey_t, gnutls_datum_t *, gnutls_datum_t *); static int (*pgnutls_privkey_export_ecc_raw)(gnutls_privkey_t, gnutls_ecc_curve_t *, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *); static int (*pgnutls_privkey_export_rsa_raw)(gnutls_privkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *, @@ -166,6 +167,11 @@ static int compat_gnutls_pubkey_export_ecc_raw(gnutls_pubkey_t key, gnutls_ecc_c return GNUTLS_E_UNKNOWN_PK_ALGORITHM; }
+static int compat_gnutls_pubkey_export_rsa_raw(gnutls_pubkey_t key, gnutls_datum_t *m, gnutls_datum_t *e) +{ + return GNUTLS_E_UNKNOWN_PK_ALGORITHM; +} + static int compat_gnutls_privkey_export_rsa_raw(gnutls_privkey_t key, gnutls_datum_t *m, gnutls_datum_t *e, gnutls_datum_t *d, gnutls_datum_t *p, gnutls_datum_t *q, gnutls_datum_t *u, gnutls_datum_t *e1, gnutls_datum_t *e2) @@ -299,8 +305,9 @@ static NTSTATUS gnutls_process_attach( void *args )
LOAD_FUNCPTR_OPT(gnutls_cipher_tag) LOAD_FUNCPTR_OPT(gnutls_cipher_add_auth) - LOAD_FUNCPTR_OPT(gnutls_pubkey_import_ecc_raw) LOAD_FUNCPTR_OPT(gnutls_pubkey_export_ecc_raw) + LOAD_FUNCPTR_OPT(gnutls_pubkey_export_rsa_raw) + LOAD_FUNCPTR_OPT(gnutls_pubkey_import_ecc_raw) LOAD_FUNCPTR_OPT(gnutls_privkey_export_rsa_raw) LOAD_FUNCPTR_OPT(gnutls_privkey_export_ecc_raw) LOAD_FUNCPTR_OPT(gnutls_privkey_import_ecc_raw) @@ -633,7 +640,14 @@ static NTSTATUS key_export_rsa_public( struct key *key, UCHAR *buf, ULONG len, U UCHAR *dst; int ret;
- if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->a.privkey, &m, &e, NULL, NULL, NULL, NULL, NULL, NULL ))) + if (key_data(key)->a.pubkey) + ret = pgnutls_pubkey_export_rsa_raw( key_data(key)->a.pubkey, &m, &e ); + else if (key_data(key)->a.privkey) + ret = pgnutls_privkey_export_rsa_raw( key_data(key)->a.privkey, &m, &e, NULL, NULL, NULL, NULL, NULL, NULL ); + else + return STATUS_INVALID_PARAMETER; + + if (ret) { pgnutls_perror( ret ); return STATUS_INTERNAL_ERROR; @@ -1017,6 +1031,8 @@ static NTSTATUS key_export_rsa( struct key *key, ULONG flags, UCHAR *buf, ULONG UCHAR *dst; int ret;
+ if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER; + if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 ))) { pgnutls_perror( ret ); diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index 5d8e81cc522..03a37f31d31 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -2212,7 +2212,7 @@ static void test_RSA_SIGN(void) BCRYPT_RSAKEY_BLOB *rsablob; NTSTATUS ret; ULONG size, size2; - BYTE *buf; + BYTE *buf, buf2[sizeof(BCRYPT_RSAKEY_BLOB) + sizeof(rsaPublicBlob)];
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_RSA_SIGN_ALGORITHM, NULL, 0); if (ret) @@ -2224,6 +2224,22 @@ static void test_RSA_SIGN(void) ret = BCryptImportKeyPair(alg, NULL, BCRYPT_RSAPUBLIC_BLOB, &key, rsaPublicBlob, sizeof(rsaPublicBlob), 0); ok(!ret, "BCryptImportKeyPair failed: %#lx\n", ret);
+ memset(buf2, 0xcc, sizeof(buf2)); + ret = BCryptExportKey(key, NULL, BCRYPT_RSAPUBLIC_BLOB, buf2, sizeof(buf2), &size, 0); + ok(!ret, "got %#lx\n", ret); + rsablob = (BCRYPT_RSAKEY_BLOB *)buf2; + ok(rsablob->Magic == BCRYPT_RSAPUBLIC_MAGIC, "got %#lx\n", rsablob->Magic); + ok(rsablob->BitLength == 2048, "got %lu\n", rsablob->BitLength); + ok(rsablob->cbPublicExp == 3, "got %lu\n", rsablob->cbPublicExp); + ok(rsablob->cbModulus == 256, "got %lu\n", rsablob->cbModulus); + ok(rsablob->cbPrime1 == 0, "got %lu\n", rsablob->cbPrime1); + ok(rsablob->cbPrime2 == 0, "got %lu\n", rsablob->cbPrime2); + size2 = sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus + rsablob->cbPrime1 + rsablob->cbPrime2; + ok(size == size2, "got %lu expected %lu\n", size2, size); + + ret = BCryptExportKey(key, NULL, BCRYPT_RSAPRIVATE_BLOB, buf2, sizeof(buf2), &size, 0); + ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret); + pad.pszAlgId = BCRYPT_SHA1_ALGORITHM; ret = BCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1); ok(!ret, "BCryptVerifySignature failed: %#lx\n", ret);