diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c index eea84cf3aa9..0d2661f9a83 100644 --- a/dlls/bcrypt/gnutls.c +++ b/dlls/bcrypt/gnutls.c @@ -107,6 +107,8 @@ 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_dsa_raw)(gnutls_pubkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *, + gnutls_datum_t *); 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 *); @@ -167,6 +169,12 @@ 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_dsa_raw(gnutls_pubkey_t key, gnutls_datum_t *p, gnutls_datum_t *q, + gnutls_datum_t *g, gnutls_datum_t *y) +{ + 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; @@ -305,6 +313,7 @@ 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_export_dsa_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) @@ -740,7 +749,14 @@ static NTSTATUS key_export_dsa_public( struct key *key, UCHAR *buf, ULONG len, U UCHAR *dst; int ret; - if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, NULL ))) + if (key_data(key)->a.pubkey) + ret = pgnutls_pubkey_export_dsa_raw( key_data(key)->a.pubkey, &p, &q, &g, &y ); + else if (key_data(key)->a.privkey) + ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, NULL ); + else + return STATUS_INVALID_PARAMETER; + + if (ret) { pgnutls_perror( ret ); return STATUS_INTERNAL_ERROR; @@ -805,7 +821,14 @@ static NTSTATUS key_export_dsa_capi_public( struct key *key, UCHAR *buf, ULONG l return STATUS_NOT_IMPLEMENTED; } - if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, NULL ))) + if (key_data(key)->a.pubkey) + ret = pgnutls_pubkey_export_dsa_raw( key_data(key)->a.pubkey, &p, &q, &g, &y ); + else if (key_data(key)->a.privkey) + ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, NULL ); + else + return STATUS_INVALID_PARAMETER; + + if (ret) { pgnutls_perror( ret ); return STATUS_INTERNAL_ERROR; @@ -1123,6 +1146,8 @@ static NTSTATUS key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULO UCHAR *dst; int ret, size; + if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER; + if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, &x ))) { pgnutls_perror( ret ); diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index 03a37f31d31..df650379cfb 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -2902,7 +2902,7 @@ static void test_DSA(void) UCHAR sig[40], schemes; ULONG len, size; NTSTATUS ret; - BYTE *buf; + BYTE *buf, buf2[sizeof(BCRYPT_DSA_KEY_BLOB) + sizeof(dsaPublicBlob)]; ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_DSA_ALGORITHM, NULL, 0); ok(!ret, "got %#lx\n", ret); @@ -2917,6 +2917,17 @@ static void test_DSA(void) ret = BCryptImportKeyPair(alg, NULL, BCRYPT_DSA_PUBLIC_BLOB, &key, dsaPublicBlob, sizeof(dsaPublicBlob), 0); ok(!ret, "got %#lx\n", ret); + memset(buf2, 0xcc, sizeof(buf2)); + ret = BCryptExportKey(key, NULL, BCRYPT_DSA_PUBLIC_BLOB, buf2, sizeof(buf2), &size, 0); + ok(!ret, "got %#lx\n", ret); + dsablob = (BCRYPT_DSA_KEY_BLOB *)buf2; + ok(dsablob->dwMagic == BCRYPT_DSA_PUBLIC_MAGIC, "got %#lx\n", dsablob->dwMagic); + ok(dsablob->cbKey == 64, "got %lu\n", dsablob->cbKey); + ok(size == sizeof(*dsablob) + dsablob->cbKey * 3, "got %lu\n", size); + + ret = BCryptExportKey(key, NULL, BCRYPT_DSA_PRIVATE_BLOB, buf2, sizeof(buf2), &size, 0); + todo_wine ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret); + ret = BCryptVerifySignature(key, NULL, dsaHash, sizeof(dsaHash), dsaSignature, sizeof(dsaSignature), 0); ok(!ret, "got %#lx\n", ret);