Wine-Devel
Threads by month
- ----- 2026 -----
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 4 participants
- 84544 discussions
March 21, 2022
Currently, apartment OXIDs are generated using the process ID
(and the thread ID for a single threaded-apartment). This means
that if an apartment is destroyed and re-created (using
`CoUninitialize` followed by `CoInitializeEx`), the newly created
apartment will end up with the same OXID as the old apartment.
However, testing shows that Windows will generate a *new* OXID
when an apartment is created in the above manner. Using
RtlGenRandom makes our behavior more consistent with Windows -
however, the actual OXIDs we generate will still differ
from those of Windows.
Additionally, this fixes an issue that caused the .NET 4.8
installer to become stuck during the downloading stage under Wine.
The installer appears to perform the following actions:
1. Call `IBackgroundCopyJob_SetNotify` interface on a BITS
job. This causes us to create a proxy (in the other process
hosting 'qmgr') for the `IBackgroundCopyCallback` pointer
passed as a parameter.
2. Trigger MTA apartment re-creation (in the process running the setup,
*not* the process with the `IBackgroundCopyCallback` proxy)
through `CoUninitialize` followed by `CoInitializeEx`.
3. Call `IBackgroundCopyJob_SetNotify` on a newly created job,
but with the same `IBackgroundCopyCallback` pointer parameter.
When we deserialize the pointer passed to
`IBackgroundCopyJob_SetNotify`, we will end up re-using the same
`proxy_manager` that we created for the previous `IBackgroundCopyCallback`.
This is due to the fact that the OIDs happen to match (due to the fact that
the .NET 4.8 setup appears to perform actions in the same order between
the old and new apartments), and the apartment OXIDs match as explained above.
above. As a result, we will use the old IPID when we send RPC packets
using this `proxy_manager`. However, the new and old IPIDs will *never* match,
since their generation process includes `RtlGenRandom`. This will cause a fault
packet to be generated on the listening side of the RPC connection.
By using RtlGenRandom when we generate the apartment OXID, we ensure that
the proxy side will never incorrectly re-use a stale `proxy_manager`
Signed-off-by: Aaron Hill <aa1ronham(a)gmail.com>
---
dlls/combase/apartment.c | 18 ++++++--------
dlls/ole32/tests/marshal.c | 49 ++++++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+), 11 deletions(-)
diff --git a/dlls/combase/apartment.c b/dlls/combase/apartment.c
index c1b381879d3..d4d78264dea 100644
--- a/dlls/combase/apartment.c
+++ b/dlls/combase/apartment.c
@@ -32,6 +32,7 @@
#include "windef.h"
#include "winbase.h"
#include "servprov.h"
+#include "ntsecapi.h"
#include "combase_private.h"
@@ -382,17 +383,12 @@ static struct apartment *apartment_construct(DWORD model)
apt->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": apartment");
apt->multi_threaded = !(model & COINIT_APARTMENTTHREADED);
-
- if (apt->multi_threaded)
- {
- /* FIXME: should be randomly generated by in an RPC call to rpcss */
- apt->oxid = ((OXID)GetCurrentProcessId() << 32) | 0xcafe;
- }
- else
- {
- /* FIXME: should be randomly generated by in an RPC call to rpcss */
- apt->oxid = ((OXID)GetCurrentProcessId() << 32) | GetCurrentThreadId();
- }
+ /* FIXME: should be generated by in an RPC call to rpcss
+ * Re-creating an apartment (via `CoUninitialize` followed by `CoInitializeEx`)
+ * will result in a *different* oxid. This is consistent with the behavior of
+ * Windows, and ensures that proxies in a different process will create
+ * a new RPC connection, instead of attempting to re-use an old one. */
+ RtlGenRandom(&apt->oxid, sizeof(apt->oxid));
TRACE("Created apartment on OXID %s\n", wine_dbgstr_longlong(apt->oxid));
diff --git a/dlls/ole32/tests/marshal.c b/dlls/ole32/tests/marshal.c
index 6e21ed1889b..0f8a7a643de 100644
--- a/dlls/ole32/tests/marshal.c
+++ b/dlls/ole32/tests/marshal.c
@@ -1239,6 +1239,54 @@ static void test_marshal_proxy_apartment_shutdown(void)
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
}
+static OXID get_apartment_oxid(void)
+{
+ HRESULT hr;
+ OBJREF objref;
+ DWORD size, read;
+ IStream *pStream = NULL;
+
+ hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
+ ok_ole_success(hr, CreateStreamOnHGlobal);
+
+ hr = CoMarshalInterface(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
+ ok_ole_success(hr, CoMarshalInterface);
+
+ hr = IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
+ ok_ole_success(hr, IStream_Seek);
+
+ size = FIELD_OFFSET(OBJREF, u_objref.u_standard.saResAddr);
+ hr = IStream_Read(pStream, &objref, size, &read);
+ ok_ole_success(hr, IStream_Read);
+
+ IStream_Release(pStream);
+
+ return objref.u_objref.u_standard.std.oxid;
+}
+
+/* tests that re-creating an apartment (via `CoUninitialize` followed by `CoInitializeEx`)
+ * results in an apartment with a different OXID than the previous apartment
+ */
+static void test_apartment_oxid(void)
+{
+
+ OXID first_oxid;
+ OXID second_oxid;
+
+ cLocks = 0;
+ external_connections = 0;
+
+ CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ first_oxid = get_apartment_oxid();
+ CoUninitialize();
+
+ CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ second_oxid = get_apartment_oxid();
+ CoUninitialize();
+
+ ok(first_oxid != second_oxid, "Re-created apartment has old OXID: %s\n", wine_dbgstr_longlong(first_oxid));
+}
+
/* tests that proxies are released when the containing mta apartment is destroyed */
static void test_marshal_proxy_mta_apartment_shutdown(void)
{
@@ -4511,6 +4559,7 @@ START_TEST(marshal)
test_cocreateinstance_proxy();
test_implicit_mta();
+ test_apartment_oxid();
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
--
2.35.1
2
1
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52623
Signed-off-by: Austin English <austinenglish(a)gmail.com>
---
dlls/winspool.drv/info.c | 9 +++++++++
dlls/winspool.drv/winspool.drv.spec | 1 +
2 files changed, 10 insertions(+)
diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c
index 52edd362622..7e3b0476735 100644
--- a/dlls/winspool.drv/info.c
+++ b/dlls/winspool.drv/info.c
@@ -8076,3 +8076,12 @@ DWORD WINAPI PerfCollect(LPWSTR query, LPVOID *data, LPDWORD size, LPDWORD obj_c
*obj_count = 0;
return ERROR_SUCCESS;
}
+
+/*****************************************************************************
+ * GetSpoolFileHandle [WINSPOOL.@]
+ */
+HANDLE WINAPI GetSpoolFileHandle(HANDLE printer)
+{
+ FIXME("%p: stub\n", printer);
+ return INVALID_HANDLE_VALUE;
+}
diff --git a/dlls/winspool.drv/winspool.drv.spec b/dlls/winspool.drv/winspool.drv.spec
index 5d8a62d4695..d7bb49bd34b 100644
--- a/dlls/winspool.drv/winspool.drv.spec
+++ b/dlls/winspool.drv/winspool.drv.spec
@@ -144,6 +144,7 @@
@ stdcall GetPrinterDriverDirectoryW(wstr wstr long ptr long ptr)
@ stdcall GetPrinterDriverW(long wstr long ptr long ptr)
@ stdcall GetPrinterW(long long ptr long ptr)
+@ stdcall GetSpoolFileHandle(ptr)
@ stdcall IsValidDevmodeA(ptr long)
@ stdcall IsValidDevmodeW(ptr long)
@ stdcall OpenPrinterA(str ptr ptr)
--
2.35.1
2
1
From: Austin English <austinenglish(a)gmail.com>
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52623
Signed-off-by: Austin English <austinenglish(a)gmail.com>
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/winspool.drv/info.c | 9 +++++++++
dlls/winspool.drv/winspool.drv.spec | 1 +
include/winspool.h | 2 ++
3 files changed, 12 insertions(+)
diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c
index 52edd362622..a89abd0ced9 100644
--- a/dlls/winspool.drv/info.c
+++ b/dlls/winspool.drv/info.c
@@ -8076,3 +8076,12 @@ DWORD WINAPI PerfCollect(LPWSTR query, LPVOID *data, LPDWORD size, LPDWORD obj_c
*obj_count = 0;
return ERROR_SUCCESS;
}
+
+/*****************************************************************************
+ * GetSpoolFileHandle [WINSPOOL.@]
+ */
+HANDLE WINAPI GetSpoolFileHandle( HANDLE printer )
+{
+ FIXME( "%p: stub\n", printer );
+ return INVALID_HANDLE_VALUE;
+}
diff --git a/dlls/winspool.drv/winspool.drv.spec b/dlls/winspool.drv/winspool.drv.spec
index 5d8a62d4695..d7bb49bd34b 100644
--- a/dlls/winspool.drv/winspool.drv.spec
+++ b/dlls/winspool.drv/winspool.drv.spec
@@ -144,6 +144,7 @@
@ stdcall GetPrinterDriverDirectoryW(wstr wstr long ptr long ptr)
@ stdcall GetPrinterDriverW(long wstr long ptr long ptr)
@ stdcall GetPrinterW(long long ptr long ptr)
+@ stdcall GetSpoolFileHandle(ptr)
@ stdcall IsValidDevmodeA(ptr long)
@ stdcall IsValidDevmodeW(ptr long)
@ stdcall OpenPrinterA(str ptr ptr)
diff --git a/include/winspool.h b/include/winspool.h
index 68619741f38..db8773ec418 100644
--- a/include/winspool.h
+++ b/include/winspool.h
@@ -1768,6 +1768,8 @@ BOOL WINAPI XcvDataW(HANDLE hXcv, LPCWSTR pszDataName, PBYTE pInputData,
BOOL WINAPI IsValidDevmodeA(PDEVMODEA pDevMode, SIZE_T size);
BOOL WINAPI IsValidDevmodeW(PDEVMODEW pDevMode, SIZE_T size);
+HANDLE WINAPI GetSpoolFileHandle(HANDLE printer);
+
#ifdef __cplusplus
} /* extern "C" */
#endif
--
2.23.0
1
0
[PATCH 6/6] bcrypt: Stop passing a dummy public key to gnutls_privkey_import_dsa_raw().
by Hans Leidekker March 21, 2022
by Hans Leidekker March 21, 2022
March 21, 2022
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/bcrypt/gnutls.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c
index 6a55c84efef..884f4b1d37e 100644
--- a/dlls/bcrypt/gnutls.c
+++ b/dlls/bcrypt/gnutls.c
@@ -1145,8 +1145,7 @@ static NTSTATUS key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG len )
BLOBHEADER *hdr = (BLOBHEADER *)buf;
DSSPUBKEY *pubkey;
gnutls_privkey_t handle;
- gnutls_datum_t p, q, g, y, x;
- unsigned char dummy[128];
+ gnutls_datum_t p, q, g, x;
unsigned char *data, p_data[128], q_data[20], g_data[128], x_data[20];
int i, ret, size;
@@ -1185,12 +1184,7 @@ static NTSTATUS key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG len )
for (i = 0; i < x.size; i++) x.data[i] = data[x.size - i - 1];
data += x.size;
- WARN( "using dummy public key\n" );
- memset( dummy, 1, sizeof(dummy) );
- y.data = dummy;
- y.size = min( p.size, sizeof(dummy) );
-
- if ((ret = pgnutls_privkey_import_dsa_raw( handle, &p, &q, &g, &y, &x )))
+ if ((ret = pgnutls_privkey_import_dsa_raw( handle, &p, &q, &g, NULL, &x )))
{
pgnutls_perror( ret );
pgnutls_privkey_deinit( handle );
--
2.30.2
1
0
March 21, 2022
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/bcrypt/bcrypt_internal.h | 2 -
dlls/bcrypt/bcrypt_main.c | 68 +----
dlls/bcrypt/gnutls.c | 481 ++++++++--------------------------
3 files changed, 125 insertions(+), 426 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h
index 7342b66479a..d57819f2ec6 100644
--- a/dlls/bcrypt/bcrypt_internal.h
+++ b/dlls/bcrypt/bcrypt_internal.h
@@ -175,8 +175,6 @@ struct key_asymmetric
{
ULONG bitlen; /* ignored for ECC keys */
unsigned flags;
- UCHAR *pubkey;
- unsigned pubkey_len;
DSSSEED dss_seed;
};
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
index 23f30833235..2ffeff66d7b 100644
--- a/dlls/bcrypt/bcrypt_main.c
+++ b/dlls/bcrypt/bcrypt_main.c
@@ -968,8 +968,7 @@ NTSTATUS WINAPI BCryptHash( BCRYPT_ALG_HANDLE algorithm, UCHAR *secret, ULONG se
return status;
}
-static NTSTATUS key_asymmetric_create( struct key **ret_key, enum alg_id alg_id, ULONG bitlen,
- const UCHAR *pubkey, ULONG pubkey_len )
+static NTSTATUS key_asymmetric_create( enum alg_id alg_id, ULONG bitlen, struct key **ret_key )
{
struct key *key;
@@ -983,14 +982,6 @@ static NTSTATUS key_asymmetric_create( struct key **ret_key, enum alg_id alg_id,
key->hdr.magic = MAGIC_KEY;
key->alg_id = alg_id;
key->u.a.bitlen = bitlen;
- key->u.a.pubkey_len = pubkey_len;
-
- if (!(key->u.a.pubkey = malloc( pubkey_len )))
- {
- free( key );
- return STATUS_NO_MEMORY;
- }
- if (pubkey) memcpy( key->u.a.pubkey, pubkey, pubkey_len );
*ret_key = key;
return STATUS_SUCCESS;
@@ -1377,8 +1368,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
if (ecc_blob->cbKey != key_size || input_len < sizeof(*ecc_blob) + ecc_blob->cbKey * 2)
return STATUS_INVALID_PARAMETER;
- size = sizeof(*ecc_blob) + ecc_blob->cbKey * 2;
- if ((status = key_asymmetric_create( &key, alg->id, key_size * 8, (BYTE *)ecc_blob, size ))) return status;
+ if ((status = key_asymmetric_create( alg->id, key_size * 8, &key ))) return status;
params.key = key;
params.flags = KEY_IMPORT_FLAG_PUBLIC;
params.buf = input;
@@ -1419,8 +1409,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
if (ecc_blob->cbKey != key_size || input_len < sizeof(*ecc_blob) + ecc_blob->cbKey * 3)
return STATUS_INVALID_PARAMETER;
- size = sizeof(*ecc_blob) + key_size * 2;
- if ((status = key_asymmetric_create( &key, alg->id, key_size * 8, NULL, size ))) return status;
+ if ((status = key_asymmetric_create( alg->id, key_size * 8, &key ))) return status;
params.key = key;
params.flags = 0;
params.buf = input;
@@ -1445,7 +1434,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
if (size != input_len) return NTE_BAD_DATA;
- if ((status = key_asymmetric_create( &key, alg->id, rsa_blob->BitLength, (BYTE *)rsa_blob, size ))) return status;
+ if ((status = key_asymmetric_create( alg->id, rsa_blob->BitLength, &key ))) return status;
params.key = key;
params.flags = KEY_IMPORT_FLAG_PUBLIC;
params.buf = input;
@@ -1467,8 +1456,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
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->id, rsa_blob->BitLength, (BYTE *)rsa_blob, size ))) return status;
+ if ((status = key_asymmetric_create( alg->id, rsa_blob->BitLength, &key ))) return status;
params.key = key;
params.flags = 0;
params.buf = input;
@@ -1490,8 +1478,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
if ((alg->id != ALG_ID_DSA) || dsa_blob->dwMagic != BCRYPT_DSA_PUBLIC_MAGIC)
return STATUS_NOT_SUPPORTED;
- size = sizeof(*dsa_blob) + dsa_blob->cbKey * 3;
- if ((status = key_asymmetric_create( &key, alg->id, dsa_blob->cbKey * 8, (BYTE *)dsa_blob, size ))) return status;
+ if ((status = key_asymmetric_create( alg->id, dsa_blob->cbKey * 8, &key ))) return status;
params.key = key;
params.flags = KEY_IMPORT_FLAG_PUBLIC;
params.buf = input;
@@ -1530,8 +1517,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
if (input_len < sizeof(*hdr) + sizeof(*pubkey) + (pubkey->bitlen / 8) * 2 + 40 + sizeof(DSSSEED))
return STATUS_INVALID_PARAMETER;
- size = sizeof(*hdr) + sizeof(*pubkey) + (pubkey->bitlen / 8) * 3 + 20 + sizeof(DSSSEED);
- if ((status = key_asymmetric_create( &key, alg->id, pubkey->bitlen, NULL, size ))) return status;
+ if ((status = key_asymmetric_create( alg->id, pubkey->bitlen, &key ))) return status;
key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2;
params.key = key;
params.flags = 0;
@@ -1567,7 +1553,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
size = sizeof(*hdr) + sizeof(*pubkey) + (pubkey->bitlen / 8) * 3 + 20 + sizeof(DSSSEED);
if (input_len < size) return STATUS_INVALID_PARAMETER;
- if ((status = key_asymmetric_create( &key, alg->id, pubkey->bitlen, (BYTE *)hdr, size ))) return status;
+ if ((status = key_asymmetric_create( alg->id, pubkey->bitlen, &key ))) return status;
key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2;
params.key = key;
params.flags = KEY_IMPORT_FLAG_PUBLIC;
@@ -1660,36 +1646,15 @@ NTSTATUS WINAPI BCryptGenerateKeyPair( BCRYPT_ALG_HANDLE algorithm, BCRYPT_KEY_H
struct algorithm *alg = algorithm;
struct key *key;
NTSTATUS status;
- ULONG size;
TRACE( "%p, %p, %lu, %#lx\n", algorithm, handle, key_len, flags );
if (!alg || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE;
if (!handle) return STATUS_INVALID_PARAMETER;
- switch (alg->id)
- {
- case ALG_ID_ECDH_P256:
- case ALG_ID_ECDSA_P256:
- size = sizeof(BCRYPT_ECCKEY_BLOB) + 2 * 256 / 8;
- break;
- case ALG_ID_ECDSA_P384:
- size = sizeof(BCRYPT_ECCKEY_BLOB) + 2 * 384 / 8;
- break;
- case ALG_ID_RSA:
- case ALG_ID_RSA_SIGN:
- size = sizeof(BCRYPT_RSAKEY_BLOB) + 2 * key_len / 8;
- break;
- case ALG_ID_DSA:
- size = sizeof(BCRYPT_DSA_KEY_BLOB) + 3 * key_len / 8;
- break;
- default:
- FIXME( "algorithm %u not supported\n", alg->id );
- return STATUS_NOT_SUPPORTED;
- }
-
- if (!(status = key_asymmetric_create( &key, alg->id, key_len, NULL, size ))) *handle = key;
- return status;
+ if ((status = key_asymmetric_create( alg->id, key_len, &key ))) return status;
+ *handle = key;
+ return STATUS_SUCCESS;
}
NTSTATUS WINAPI BCryptFinalizeKeyPair( BCRYPT_KEY_HANDLE handle, ULONG flags )
@@ -1766,14 +1731,9 @@ static NTSTATUS key_duplicate( struct key *key_orig, struct key *key_copy )
{
struct key_asymmetric_duplicate_params params;
- if (!(buffer = malloc( key_orig->u.a.pubkey_len ))) return STATUS_NO_MEMORY;
- memcpy( buffer, key_orig->u.a.pubkey, key_orig->u.a.pubkey_len );
-
- key_copy->u.a.bitlen = key_orig->u.a.bitlen;
- key_copy->u.a.flags = key_orig->u.a.flags;
- key_copy->u.a.pubkey = buffer;
- key_copy->u.a.pubkey_len = key_orig->u.a.pubkey_len;
- key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
+ key_copy->u.a.bitlen = key_orig->u.a.bitlen;
+ key_copy->u.a.flags = key_orig->u.a.flags;
+ key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
params.key_orig = key_orig;
params.key_copy = key_copy;
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c
index 28119fc9e78..6a55c84efef 100644
--- a/dlls/bcrypt/gnutls.c
+++ b/dlls/bcrypt/gnutls.c
@@ -72,7 +72,11 @@ typedef enum
union key_data
{
gnutls_cipher_hd_t cipher;
- gnutls_privkey_t privkey;
+ struct
+ {
+ gnutls_privkey_t privkey;
+ gnutls_pubkey_t pubkey;
+ } a;
};
C_ASSERT( sizeof(union key_data) <= sizeof(((struct key *)0)->private) );
@@ -98,6 +102,7 @@ static int (*pgnutls_pubkey_import_rsa_raw)(gnutls_pubkey_t, const gnutls_datum_
/* Not present in gnutls version < 2.12.0 */
static int (*pgnutls_pubkey_import_dsa_raw)(gnutls_pubkey_t, const gnutls_datum_t *, const gnutls_datum_t *,
const gnutls_datum_t *, const gnutls_datum_t *);
+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_privkey_export_ecc_raw)(gnutls_privkey_t, gnutls_ecc_curve_t *,
@@ -133,6 +138,7 @@ MAKE_FUNCPTR(gnutls_privkey_import_dsa_raw);
MAKE_FUNCPTR(gnutls_privkey_init);
MAKE_FUNCPTR(gnutls_privkey_sign_hash);
MAKE_FUNCPTR(gnutls_pubkey_deinit);
+MAKE_FUNCPTR(gnutls_pubkey_import_privkey);
MAKE_FUNCPTR(gnutls_pubkey_init);
#undef MAKE_FUNCPTR
@@ -272,6 +278,7 @@ static NTSTATUS gnutls_process_attach( void *args )
LOAD_FUNCPTR(gnutls_privkey_init);
LOAD_FUNCPTR(gnutls_privkey_sign_hash);
LOAD_FUNCPTR(gnutls_pubkey_deinit);
+ LOAD_FUNCPTR(gnutls_pubkey_import_privkey);
LOAD_FUNCPTR(gnutls_pubkey_init);
#undef LOAD_FUNCPTR
@@ -609,234 +616,6 @@ static ULONG export_gnutls_datum( UCHAR *buffer, ULONG buflen, gnutls_datum_t *d
return size;
}
-#define EXPORT_SIZE(d,f,p) export_gnutls_datum( NULL, bitlen / f, &d, p )
-static NTSTATUS export_gnutls_pubkey_rsa( gnutls_privkey_t gnutls_key, ULONG bitlen, void *pubkey, unsigned *pubkey_len )
-{
- BCRYPT_RSAKEY_BLOB *rsa_blob = pubkey;
- gnutls_datum_t m, e;
- UCHAR *dst;
- int ret;
-
- if ((ret = pgnutls_privkey_export_rsa_raw( gnutls_key, &m, &e, NULL, NULL, NULL, NULL, NULL, NULL )))
- {
- pgnutls_perror( ret );
- return STATUS_INTERNAL_ERROR;
- }
-
- if (*pubkey_len < sizeof(*rsa_blob) + EXPORT_SIZE(e,8,0) + EXPORT_SIZE(m,8,1))
- {
- FIXME( "wrong pubkey len %u\n", *pubkey_len );
- pgnutls_perror( ret );
- free( e.data ); free( m.data );
- return STATUS_BUFFER_TOO_SMALL;
- }
-
- 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 );
-
- rsa_blob->Magic = BCRYPT_RSAPUBLIC_MAGIC;
- rsa_blob->BitLength = bitlen;
- rsa_blob->cbPrime1 = 0;
- rsa_blob->cbPrime2 = 0;
-
- *pubkey_len = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
-
- free( e.data ); free( m.data );
- return STATUS_SUCCESS;
-}
-#undef EXPORT_SIZE
-
-static NTSTATUS export_gnutls_pubkey_ecc( gnutls_privkey_t gnutls_key, enum alg_id alg_id, void *pubkey,
- unsigned *pubkey_len )
-{
- BCRYPT_ECCKEY_BLOB *ecc_blob = pubkey;
- gnutls_ecc_curve_t curve;
- gnutls_datum_t x, y;
- DWORD magic, size;
- UCHAR *dst;
- int ret;
-
- switch (alg_id)
- {
- case ALG_ID_ECDH_P256:
- magic = BCRYPT_ECDH_PUBLIC_P256_MAGIC;
- size = 32;
- break;
- case ALG_ID_ECDSA_P256:
- magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
- size = 32;
- break;
- default:
- FIXME( "algorithm %u not supported\n", alg_id );
- return STATUS_NOT_IMPLEMENTED;
- }
-
- if ((ret = pgnutls_privkey_export_ecc_raw( gnutls_key, &curve, &x, &y, NULL )))
- {
- pgnutls_perror( ret );
- return STATUS_INTERNAL_ERROR;
- }
-
- if (curve != GNUTLS_ECC_CURVE_SECP256R1)
- {
- FIXME( "curve %u not supported\n", curve );
- free( x.data ); free( y.data );
- return STATUS_NOT_IMPLEMENTED;
- }
-
- if (*pubkey_len < sizeof(*ecc_blob) + size * 2)
- {
- FIXME( "wrong pubkey len %u / %lu\n", *pubkey_len, sizeof(*ecc_blob) + size * 2 );
- pgnutls_perror( ret );
- free( x.data ); free( y.data );
- return STATUS_BUFFER_TOO_SMALL;
- }
-
- ecc_blob->dwMagic = magic;
- ecc_blob->cbKey = size;
-
- dst = (UCHAR *)(ecc_blob + 1);
- export_gnutls_datum( dst, size, &x, 1 );
-
- dst += size;
- export_gnutls_datum( dst, size, &y, 1 );
-
- *pubkey_len = sizeof(*ecc_blob) + ecc_blob->cbKey * 2;
-
- free( x.data ); free( y.data );
- return STATUS_SUCCESS;
-}
-
-static NTSTATUS export_gnutls_pubkey_dsa( gnutls_privkey_t gnutls_key, ULONG bitlen, void *pubkey, unsigned *pubkey_len )
-{
- BCRYPT_DSA_KEY_BLOB *dsa_blob = pubkey;
- gnutls_datum_t p, q, g, y;
- UCHAR *dst;
- int ret;
-
- if ((ret = pgnutls_privkey_export_dsa_raw( gnutls_key, &p, &q, &g, &y, NULL )))
- {
- pgnutls_perror( ret );
- return STATUS_INTERNAL_ERROR;
- }
-
- if (bitlen > 1024)
- {
- FIXME( "bitlen > 1024 not supported\n" );
- return STATUS_NOT_IMPLEMENTED;
- }
-
- if (*pubkey_len < sizeof(*dsa_blob) + bitlen / 8 * 3)
- {
- FIXME( "wrong pubkey len %u / %lu\n", *pubkey_len, sizeof(*dsa_blob) + bitlen / 8 * 3 );
- pgnutls_perror( ret );
- free( p.data ); free( q.data ); free( g.data ); free( y.data );
- return STATUS_NO_MEMORY;
- }
-
- dst = (UCHAR *)(dsa_blob + 1);
- export_gnutls_datum( dst, bitlen / 8, &p, 1 );
-
- dst += bitlen / 8;
- export_gnutls_datum( dst, bitlen / 8, &g, 1 );
-
- dst += bitlen / 8;
- export_gnutls_datum( dst, bitlen / 8, &y, 1 );
-
- dst = dsa_blob->q;
- export_gnutls_datum( dst, sizeof(dsa_blob->q), &q, 1 );
-
- dsa_blob->dwMagic = BCRYPT_DSA_PUBLIC_MAGIC;
- dsa_blob->cbKey = bitlen / 8;
- memset( dsa_blob->Count, 0, sizeof(dsa_blob->Count) ); /* FIXME */
- memset( dsa_blob->Seed, 0, sizeof(dsa_blob->Seed) ); /* FIXME */
-
- *pubkey_len = sizeof(*dsa_blob) + dsa_blob->cbKey * 3;
-
- free( p.data ); free( q.data ); free( g.data ); free( y.data );
- return STATUS_SUCCESS;
-}
-
-static void reverse_bytes( UCHAR *buf, ULONG len )
-{
- unsigned int i;
- UCHAR tmp;
-
- for (i = 0; i < len / 2; ++i)
- {
- tmp = buf[i];
- buf[i] = buf[len - i - 1];
- buf[len - i - 1] = tmp;
- }
-}
-
-#define Q_SIZE 20
-static NTSTATUS export_gnutls_pubkey_dsa_capi( gnutls_privkey_t gnutls_key, const DSSSEED *seed, unsigned bitlen,
- void *pubkey, unsigned *pubkey_len )
-{
- BLOBHEADER *hdr = pubkey;
- DSSPUBKEY *dsskey;
- gnutls_datum_t p, q, g, y;
- UCHAR *dst;
- int ret, size = sizeof(*hdr) + sizeof(*dsskey) + sizeof(*seed);
-
- if (bitlen > 1024)
- {
- FIXME( "bitlen > 1024 not supported\n" );
- return STATUS_NOT_IMPLEMENTED;
- }
-
- if ((ret = pgnutls_privkey_export_dsa_raw( gnutls_key, &p, &q, &g, &y, NULL )))
- {
- pgnutls_perror( ret );
- return STATUS_INTERNAL_ERROR;
- }
-
- if (*pubkey_len < size + bitlen / 8 * 3 + Q_SIZE)
- {
- FIXME( "wrong pubkey len %u / %u\n", *pubkey_len, size + bitlen / 8 * 3 + Q_SIZE );
- pgnutls_perror( ret );
- free( p.data ); free( q.data ); free( g.data ); free( y.data );
- return STATUS_NO_MEMORY;
- }
-
- hdr->bType = PUBLICKEYBLOB;
- hdr->bVersion = 2;
- hdr->reserved = 0;
- hdr->aiKeyAlg = CALG_DSS_SIGN;
-
- dsskey = (DSSPUBKEY *)(hdr + 1);
- dsskey->magic = MAGIC_DSS1;
- dsskey->bitlen = bitlen;
-
- dst = (UCHAR *)(dsskey + 1);
- export_gnutls_datum( dst, bitlen / 8, &p, 1 );
- reverse_bytes( dst, bitlen / 8 );
- dst += bitlen / 8;
-
- export_gnutls_datum( dst, Q_SIZE, &q, 1 );
- reverse_bytes( dst, Q_SIZE );
- dst += Q_SIZE;
-
- export_gnutls_datum( dst, bitlen / 8, &g, 1 );
- reverse_bytes( dst, bitlen / 8 );
- dst += bitlen / 8;
-
- export_gnutls_datum( dst, bitlen / 8, &y, 1 );
- reverse_bytes( dst, bitlen / 8 );
- dst += bitlen / 8;
-
- memcpy( dst, seed, sizeof(*seed) );
-
- *pubkey_len = size + bitlen / 8 * 3 + Q_SIZE;
-
- free( p.data ); free( q.data ); free( g.data ); free( y.data );
- return STATUS_SUCCESS;
-}
-
#define EXPORT_SIZE(d,f,p) export_gnutls_datum( NULL, key->u.a.bitlen / f, &d, p )
static NTSTATUS key_export_rsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
{
@@ -845,7 +624,7 @@ 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)->privkey, &m, &e, NULL, NULL, NULL, NULL, NULL, NULL )))
+ if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->a.privkey, &m, &e, NULL, NULL, NULL, NULL, NULL, NULL )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
@@ -894,7 +673,7 @@ static NTSTATUS key_export_ecc_public( struct key *key, UCHAR *buf, ULONG len, U
return STATUS_NOT_IMPLEMENTED;
}
- if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key)->privkey, &curve, &x, &y, NULL )))
+ if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key)->a.privkey, &curve, &x, &y, NULL )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
@@ -931,7 +710,7 @@ 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)->privkey, &p, &q, &g, &y, NULL )))
+ if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, NULL )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
@@ -968,6 +747,19 @@ static NTSTATUS key_export_dsa_public( struct key *key, UCHAR *buf, ULONG len, U
return STATUS_SUCCESS;
}
+static void reverse_bytes( UCHAR *buf, ULONG len )
+{
+ unsigned int i;
+ UCHAR tmp;
+
+ for (i = 0; i < len / 2; ++i)
+ {
+ tmp = buf[i];
+ buf[i] = buf[len - i - 1];
+ buf[len - i - 1] = tmp;
+ }
+}
+
#define Q_SIZE 20
static NTSTATUS key_export_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
{
@@ -983,7 +775,7 @@ 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)->privkey, &p, &q, &g, &y, NULL )))
+ if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, NULL )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
@@ -1029,13 +821,13 @@ static NTSTATUS key_asymmetric_generate( void *args )
{
struct key *key = args;
gnutls_pk_algorithm_t pk_alg;
- gnutls_privkey_t handle;
+ gnutls_privkey_t privkey;
+ gnutls_pubkey_t pubkey;
unsigned int bitlen;
- NTSTATUS status;
int ret;
if (!libgnutls_handle) return STATUS_INTERNAL_ERROR;
- if (key_data(key)->privkey) return STATUS_INVALID_HANDLE;
+ if (key_data(key)->a.privkey) return STATUS_INVALID_HANDLE;
switch (key->alg_id)
{
@@ -1061,45 +853,35 @@ static NTSTATUS key_asymmetric_generate( void *args )
return STATUS_NOT_SUPPORTED;
}
- if ((ret = pgnutls_privkey_init( &handle )))
+ if ((ret = pgnutls_privkey_init( &privkey )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
}
-
- if ((ret = pgnutls_privkey_generate( handle, pk_alg, bitlen, 0 )))
+ if ((ret = pgnutls_pubkey_init( &pubkey )))
{
pgnutls_perror( ret );
- pgnutls_privkey_deinit( handle );
+ pgnutls_privkey_deinit( privkey );
return STATUS_INTERNAL_ERROR;
}
- switch (pk_alg)
+ if ((ret = pgnutls_privkey_generate( privkey, pk_alg, bitlen, 0 )))
{
- case GNUTLS_PK_RSA:
- status = export_gnutls_pubkey_rsa( handle, key->u.a.bitlen, key->u.a.pubkey, &key->u.a.pubkey_len );
- break;
-
- case GNUTLS_PK_ECC:
- status = export_gnutls_pubkey_ecc( handle, key->alg_id, key->u.a.pubkey, &key->u.a.pubkey_len );
- break;
-
- case GNUTLS_PK_DSA:
- status = export_gnutls_pubkey_dsa( handle, key->u.a.bitlen, key->u.a.pubkey, &key->u.a.pubkey_len );
- break;
-
- default:
- ERR( "unhandled algorithm %u\n", pk_alg );
+ pgnutls_perror( ret );
+ pgnutls_privkey_deinit( privkey );
+ pgnutls_pubkey_deinit( pubkey );
return STATUS_INTERNAL_ERROR;
}
-
- if (status)
+ if ((ret = pgnutls_pubkey_import_privkey( pubkey, privkey, 0, 0 )))
{
- pgnutls_privkey_deinit( handle );
- return status;
+ pgnutls_perror( ret );
+ pgnutls_privkey_deinit( privkey );
+ pgnutls_pubkey_deinit( pubkey );
+ return STATUS_INTERNAL_ERROR;
}
- key_data(key)->privkey = handle;
+ key_data(key)->a.privkey = privkey;
+ key_data(key)->a.pubkey = pubkey;
return STATUS_SUCCESS;
}
@@ -1128,7 +910,7 @@ static NTSTATUS key_export_ecc( struct key *key, UCHAR *buf, ULONG len, ULONG *r
return STATUS_NOT_IMPLEMENTED;
}
- if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key)->privkey, &curve, &x, &y, &d )))
+ if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key)->a.privkey, &curve, &x, &y, &d )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
@@ -1168,7 +950,6 @@ static NTSTATUS key_import_ecc( struct key *key, UCHAR *buf, ULONG len )
gnutls_ecc_curve_t curve;
gnutls_privkey_t handle;
gnutls_datum_t x, y, k;
- NTSTATUS status;
int ret;
switch (key->alg_id)
@@ -1204,14 +985,8 @@ static NTSTATUS key_import_ecc( struct key *key, UCHAR *buf, ULONG len )
return STATUS_INTERNAL_ERROR;
}
- if ((status = export_gnutls_pubkey_ecc( handle, key->alg_id, key->u.a.pubkey, &key->u.a.pubkey_len )))
- {
- pgnutls_privkey_deinit( handle );
- return status;
- }
-
- if (key_data(key)->privkey) pgnutls_privkey_deinit( key_data(key)->privkey );
- key_data(key)->privkey = handle;
+ if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
+ key_data(key)->a.privkey = handle;
return STATUS_SUCCESS;
}
@@ -1224,7 +999,7 @@ static NTSTATUS key_export_rsa( struct key *key, ULONG flags, UCHAR *buf, ULONG
UCHAR *dst;
int ret;
- if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
+ if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
@@ -1301,8 +1076,8 @@ static NTSTATUS key_import_rsa( struct key *key, UCHAR *buf, ULONG len )
return STATUS_INTERNAL_ERROR;
}
- if (key_data(key)->privkey) pgnutls_privkey_deinit( key_data(key)->privkey );
- key_data(key)->privkey = handle;
+ if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
+ key_data(key)->a.privkey = handle;
return STATUS_SUCCESS;
}
@@ -1314,7 +1089,7 @@ static NTSTATUS key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULO
UCHAR *dst;
int ret, size;
- if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->privkey, &p, &q, &g, &y, &x )))
+ if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, &x )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
@@ -1374,7 +1149,6 @@ static NTSTATUS key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG len )
unsigned char dummy[128];
unsigned char *data, p_data[128], q_data[20], g_data[128], x_data[20];
int i, ret, size;
- NTSTATUS status;
if ((ret = pgnutls_privkey_init( &handle )))
{
@@ -1423,29 +1197,24 @@ static NTSTATUS key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG len )
return STATUS_INTERNAL_ERROR;
}
- if ((status = export_gnutls_pubkey_dsa_capi( handle, &key->u.a.dss_seed, key->u.a.bitlen,
- key->u.a.pubkey, &key->u.a.pubkey_len )))
- {
- pgnutls_privkey_deinit( handle );
- return status;
- }
-
memcpy( &key->u.a.dss_seed, data, sizeof(key->u.a.dss_seed) );
- if (key_data(key)->privkey) pgnutls_privkey_deinit( key_data(key)->privkey );
- key_data(key)->privkey = handle;
+ if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
+ key_data(key)->a.privkey = handle;
return STATUS_SUCCESS;
}
-static NTSTATUS import_gnutls_pubkey_ecc( struct key *key, gnutls_pubkey_t *gnutls_key )
+static NTSTATUS key_import_ecc_public( struct key *key, UCHAR *buf, ULONG len )
{
BCRYPT_ECCKEY_BLOB *ecc_blob;
gnutls_ecc_curve_t curve;
gnutls_datum_t x, y;
+ gnutls_pubkey_t handle;
int ret;
switch (key->alg_id)
{
+ case ALG_ID_ECDH_P256:
case ALG_ID_ECDSA_P256: curve = GNUTLS_ECC_CURVE_SECP256R1; break;
case ALG_ID_ECDSA_P384: curve = GNUTLS_ECC_CURVE_SECP384R1; break;
@@ -1454,103 +1223,112 @@ static NTSTATUS import_gnutls_pubkey_ecc( struct key *key, gnutls_pubkey_t *gnut
return STATUS_NOT_IMPLEMENTED;
}
- if ((ret = pgnutls_pubkey_init( gnutls_key )))
+ if ((ret = pgnutls_pubkey_init( &handle )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
}
- ecc_blob = (BCRYPT_ECCKEY_BLOB *)key->u.a.pubkey;
- x.data = key->u.a.pubkey + sizeof(*ecc_blob);
+ ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
+ x.data = buf + sizeof(*ecc_blob);
x.size = ecc_blob->cbKey;
- y.data = key->u.a.pubkey + sizeof(*ecc_blob) + ecc_blob->cbKey;
+ y.data = buf + sizeof(*ecc_blob) + ecc_blob->cbKey;
y.size = ecc_blob->cbKey;
- if ((ret = pgnutls_pubkey_import_ecc_raw( *gnutls_key, curve, &x, &y )))
+ if ((ret = pgnutls_pubkey_import_ecc_raw( handle, curve, &x, &y )))
{
pgnutls_perror( ret );
- pgnutls_pubkey_deinit( *gnutls_key );
+ pgnutls_pubkey_deinit( handle );
return STATUS_INTERNAL_ERROR;
}
+ if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
+ key_data(key)->a.pubkey = handle;
return STATUS_SUCCESS;
}
-static NTSTATUS import_gnutls_pubkey_rsa( struct key *key, gnutls_pubkey_t *gnutls_key )
+static NTSTATUS key_import_rsa_public( struct key *key, UCHAR *buf, ULONG len )
{
BCRYPT_RSAKEY_BLOB *rsa_blob;
+ gnutls_pubkey_t handle;
gnutls_datum_t m, e;
int ret;
- if ((ret = pgnutls_pubkey_init( gnutls_key )))
+ if ((ret = pgnutls_pubkey_init( &handle )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
}
- rsa_blob = (BCRYPT_RSAKEY_BLOB *)key->u.a.pubkey;
- e.data = key->u.a.pubkey + sizeof(*rsa_blob);
+ rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
+ e.data = buf + sizeof(*rsa_blob);
e.size = rsa_blob->cbPublicExp;
- m.data = key->u.a.pubkey + sizeof(*rsa_blob) + rsa_blob->cbPublicExp;
+ m.data = buf + sizeof(*rsa_blob) + rsa_blob->cbPublicExp;
m.size = rsa_blob->cbModulus;
- if ((ret = pgnutls_pubkey_import_rsa_raw( *gnutls_key, &m, &e )))
+ if ((ret = pgnutls_pubkey_import_rsa_raw( handle, &m, &e )))
{
pgnutls_perror( ret );
- pgnutls_pubkey_deinit( *gnutls_key );
+ pgnutls_pubkey_deinit( handle );
return STATUS_INTERNAL_ERROR;
}
+ if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
+ key_data(key)->a.pubkey = handle;
return STATUS_SUCCESS;
}
-static NTSTATUS import_gnutls_pubkey_dsa( struct key *key, gnutls_pubkey_t *gnutls_key )
+static NTSTATUS key_import_dsa_public( struct key *key, UCHAR *buf, ULONG len )
{
BCRYPT_DSA_KEY_BLOB *dsa_blob;
gnutls_datum_t p, q, g, y;
+ gnutls_pubkey_t handle;
int ret;
- if ((ret = pgnutls_pubkey_init( gnutls_key )))
+ if ((ret = pgnutls_pubkey_init( &handle )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
}
- dsa_blob = (BCRYPT_DSA_KEY_BLOB *)key->u.a.pubkey;
- p.data = key->u.a.pubkey + sizeof(*dsa_blob);
+ dsa_blob = (BCRYPT_DSA_KEY_BLOB *)buf;
+ p.data = buf + sizeof(*dsa_blob);
p.size = dsa_blob->cbKey;
q.data = dsa_blob->q;
q.size = sizeof(dsa_blob->q);
- g.data = key->u.a.pubkey + sizeof(*dsa_blob) + dsa_blob->cbKey;
+ g.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey;
g.size = dsa_blob->cbKey;
- y.data = key->u.a.pubkey + sizeof(*dsa_blob) + dsa_blob->cbKey * 2;
+ y.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey * 2;
y.size = dsa_blob->cbKey;
- if ((ret = pgnutls_pubkey_import_dsa_raw( *gnutls_key, &p, &q, &g, &y )))
+ if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
{
pgnutls_perror( ret );
- pgnutls_pubkey_deinit( *gnutls_key );
+ pgnutls_pubkey_deinit( handle );
return STATUS_INTERNAL_ERROR;
}
+ if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
+ key_data(key)->a.pubkey = handle;
return STATUS_SUCCESS;
}
-static NTSTATUS import_gnutls_pubkey_dsa_capi( struct key *key, gnutls_pubkey_t *gnutls_key )
+static NTSTATUS key_import_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len )
{
BLOBHEADER *hdr;
DSSPUBKEY *pubkey;
gnutls_datum_t p, q, g, y;
+ gnutls_pubkey_t handle;
unsigned char *data, p_data[128], q_data[20], g_data[128], y_data[128];
int i, ret, size;
- if ((ret = pgnutls_pubkey_init( gnutls_key )))
+ if ((ret = pgnutls_pubkey_init( &handle )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
}
- hdr = (BLOBHEADER *)key->u.a.pubkey;
+ hdr = (BLOBHEADER *)buf;
pubkey = (DSSPUBKEY *)(hdr + 1);
size = pubkey->bitlen / 8;
data = (unsigned char *)(pubkey + 1);
@@ -1574,40 +1352,18 @@ static NTSTATUS import_gnutls_pubkey_dsa_capi( struct key *key, gnutls_pubkey_t
y.size = sizeof(y_data);
for (i = 0; i < y.size; i++) y.data[i] = data[y.size - i - 1];
- if ((ret = pgnutls_pubkey_import_dsa_raw( *gnutls_key, &p, &q, &g, &y )))
+ if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
{
pgnutls_perror( ret );
- pgnutls_pubkey_deinit( *gnutls_key );
+ pgnutls_pubkey_deinit( handle );
return STATUS_INTERNAL_ERROR;
}
+ if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
+ key_data(key)->a.pubkey = handle;
return STATUS_SUCCESS;
}
-static NTSTATUS import_gnutls_pubkey( struct key *key, gnutls_pubkey_t *gnutls_key )
-{
- switch (key->alg_id)
- {
- case ALG_ID_ECDSA_P256:
- case ALG_ID_ECDSA_P384:
- return import_gnutls_pubkey_ecc( key, gnutls_key );
-
- case ALG_ID_RSA:
- case ALG_ID_RSA_SIGN:
- return import_gnutls_pubkey_rsa( key, gnutls_key );
-
- case ALG_ID_DSA:
- if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
- return import_gnutls_pubkey_dsa_capi( key, gnutls_key );
- else
- return import_gnutls_pubkey_dsa( key, gnutls_key );
-
- default:
- FIXME("algorithm %u not yet supported\n", key->alg_id );
- return STATUS_NOT_IMPLEMENTED;
- }
-}
-
static NTSTATUS key_asymmetric_export( void *args )
{
const struct key_asymmetric_export_params *params = args;
@@ -1658,26 +1414,21 @@ static NTSTATUS key_asymmetric_import( void *args )
case ALG_ID_ECDSA_P256:
case ALG_ID_ECDSA_P384:
if (flags & KEY_IMPORT_FLAG_PUBLIC)
- {
- FIXME("\n");
- return STATUS_SUCCESS;
- }
+ return key_import_ecc_public( key, params->buf, params->len );
return key_import_ecc( key, params->buf, params->len );
case ALG_ID_RSA:
case ALG_ID_RSA_SIGN:
if (flags & KEY_IMPORT_FLAG_PUBLIC)
- {
- FIXME("\n");
- return STATUS_SUCCESS;
- }
+ return key_import_rsa_public( key, params->buf, params->len );
return key_import_rsa( key, params->buf, params->len );
case ALG_ID_DSA:
if (flags & KEY_IMPORT_FLAG_PUBLIC)
{
- FIXME("\n");
- return STATUS_SUCCESS;
+ if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
+ return key_import_dsa_capi_public( key, params->buf, params->len );
+ 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 );
@@ -1760,7 +1511,6 @@ static NTSTATUS key_asymmetric_verify( void *args )
gnutls_sign_algorithm_t sign_alg;
gnutls_datum_t gnutls_hash, gnutls_signature;
gnutls_pk_algorithm_t pk_alg;
- gnutls_pubkey_t gnutls_key;
NTSTATUS status;
int ret;
@@ -1824,19 +1574,14 @@ static NTSTATUS key_asymmetric_verify( void *args )
return STATUS_NOT_IMPLEMENTED;
}
- if ((status = import_gnutls_pubkey( key, &gnutls_key ))) return status;
if ((status = prepare_gnutls_signature( key, params->signature, params->signature_len, &gnutls_signature )))
- {
- pgnutls_pubkey_deinit( gnutls_key );
return status;
- }
gnutls_hash.data = params->hash;
gnutls_hash.size = params->hash_len;
- ret = pgnutls_pubkey_verify_hash2( gnutls_key, sign_alg, 0, &gnutls_hash, &gnutls_signature );
+ ret = pgnutls_pubkey_verify_hash2( key_data(key)->a.pubkey, sign_alg, 0, &gnutls_hash, &gnutls_signature );
if (gnutls_signature.data != params->signature) free( gnutls_signature.data );
- pgnutls_pubkey_deinit( gnutls_key );
return (ret < 0) ? STATUS_INVALID_SIGNATURE : STATUS_SUCCESS;
}
@@ -1975,7 +1720,7 @@ static NTSTATUS key_asymmetric_sign( void *args )
*params->ret_len = key->u.a.bitlen / 8;
return STATUS_SUCCESS;
}
- if (!key_data(key)->privkey) return STATUS_INVALID_PARAMETER;
+ if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
hash.data = params->input;
hash.size = params->input_len;
@@ -1983,15 +1728,13 @@ static NTSTATUS key_asymmetric_sign( void *args )
signature.data = NULL;
signature.size = 0;
- if ((ret = pgnutls_privkey_sign_hash( key_data(key)->privkey, hash_alg, 0, &hash, &signature )))
+ if ((ret = pgnutls_privkey_sign_hash( key_data(key)->a.privkey, hash_alg, 0, &hash, &signature )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
}
- status = format_gnutls_signature( key->alg_id, signature, params->output,
- params->output_len, params->ret_len );
-
+ status = format_gnutls_signature( key->alg_id, signature, params->output, params->output_len, params->ret_len );
free( signature.data );
return status;
}
@@ -2000,7 +1743,8 @@ static NTSTATUS key_asymmetric_destroy( void *args )
{
struct key *key = args;
- if (key_data(key)->privkey) pgnutls_privkey_deinit( key_data(key)->privkey );
+ if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
+ if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
return STATUS_SUCCESS;
}
@@ -2011,9 +1755,9 @@ static NTSTATUS key_asymmetric_duplicate( void *args )
struct key *key_copy = params->key_copy;
int ret;
- if (!key_data(key_orig)->privkey) return STATUS_SUCCESS;
+ if (!key_data(key_orig)->a.privkey) return STATUS_SUCCESS;
- if ((ret = pgnutls_privkey_init( &key_data(key_copy)->privkey )))
+ if ((ret = pgnutls_privkey_init( &key_data(key_copy)->a.privkey )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
@@ -2025,12 +1769,12 @@ static NTSTATUS key_asymmetric_duplicate( void *args )
case ALG_ID_RSA_SIGN:
{
gnutls_datum_t m, e, d, p, q, u, e1, e2;
- if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key_orig)->privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
+ if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key_orig)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
}
- ret = pgnutls_privkey_import_rsa_raw( key_data(key_copy)->privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 );
+ ret = pgnutls_privkey_import_rsa_raw( key_data(key_copy)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 );
free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
free( e1.data ); free( e2.data );
if (ret)
@@ -2043,12 +1787,12 @@ static NTSTATUS key_asymmetric_duplicate( void *args )
case ALG_ID_DSA:
{
gnutls_datum_t p, q, g, y, x;
- if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key_orig)->privkey, &p, &q, &g, &y, &x )))
+ if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key_orig)->a.privkey, &p, &q, &g, &y, &x )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
}
- ret = pgnutls_privkey_import_dsa_raw( key_data(key_copy)->privkey, &p, &q, &g, &y, &x );
+ ret = pgnutls_privkey_import_dsa_raw( key_data(key_copy)->a.privkey, &p, &q, &g, &y, &x );
free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
if (ret)
{
@@ -2063,12 +1807,12 @@ static NTSTATUS key_asymmetric_duplicate( void *args )
{
gnutls_ecc_curve_t curve;
gnutls_datum_t x, y, k;
- if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key_orig)->privkey, &curve, &x, &y, &k )))
+ if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key_orig)->a.privkey, &curve, &x, &y, &k )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
}
- ret = pgnutls_privkey_import_ecc_raw( key_data(key_copy)->privkey, curve, &x, &y, &k );
+ ret = pgnutls_privkey_import_ecc_raw( key_data(key_copy)->a.privkey, curve, &x, &y, &k );
free( x.data ); free( y.data ); free( k.data );
if (ret)
{
@@ -2094,7 +1838,7 @@ static NTSTATUS key_asymmetric_decrypt( void *args )
e.data = params->input;
e.size = params->input_len;
- if ((ret = pgnutls_privkey_decrypt_data( key_data(params->key)->privkey, 0, &e, &d )))
+ if ((ret = pgnutls_privkey_decrypt_data( key_data(params->key)->a.privkey, 0, &e, &d )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
@@ -2187,8 +1931,6 @@ static struct key *get_asymmetric_key( struct key32 *key32, struct key *key )
key->private[1] = key32->private[1];
key->u.a.bitlen = key32->u.a.bitlen;
key->u.a.flags = key32->u.a.flags;
- key->u.a.pubkey = ULongToPtr(key32->u.a.pubkey);
- key->u.a.pubkey_len = key32->u.a.pubkey_len;
key->u.a.dss_seed = key32->u.a.dss_seed;
return key;
}
@@ -2204,7 +1946,6 @@ static void put_asymmetric_key32( struct key *key, struct key32 *key32 )
key32->private[0] = key->private[0];
key32->private[1] = key->private[1];
key32->u.a.flags = key->u.a.flags;
- key32->u.a.pubkey_len = key->u.a.pubkey_len;
key32->u.a.dss_seed = key->u.a.dss_seed;
}
--
2.30.2
1
0
[PATCH 4/6] bcrypt: Merge the various key import Unix calls into one.
by Hans Leidekker March 21, 2022
by Hans Leidekker March 21, 2022
March 21, 2022
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/bcrypt/bcrypt_internal.h | 8 +--
dlls/bcrypt/bcrypt_main.c | 87 ++++++++++++++++------
dlls/bcrypt/gnutls.c | 132 ++++++++++++++++------------------
3 files changed, 132 insertions(+), 95 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h
index d299def6e11..7342b66479a 100644
--- a/dlls/bcrypt/bcrypt_internal.h
+++ b/dlls/bcrypt/bcrypt_internal.h
@@ -279,9 +279,11 @@ struct key_asymmetric_export_params
ULONG *ret_len;
};
-struct key_import_params
+#define KEY_IMPORT_FLAG_PUBLIC 0x00000001
+struct key_asymmetric_import_params
{
struct key *key;
+ ULONG flags;
UCHAR *buf;
ULONG len;
};
@@ -303,9 +305,7 @@ enum key_funcs
unix_key_asymmetric_verify,
unix_key_asymmetric_destroy,
unix_key_asymmetric_export,
- unix_key_import_dsa_capi,
- unix_key_import_ecc,
- unix_key_import_rsa,
+ unix_key_asymmetric_import,
};
#endif /* __BCRYPT_INTERNAL_H */
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
index 408c477b92f..23f30833235 100644
--- a/dlls/bcrypt/bcrypt_main.c
+++ b/dlls/bcrypt/bcrypt_main.c
@@ -1339,7 +1339,7 @@ static void key_destroy( struct key *key )
static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input,
ULONG input_len )
{
- struct key_import_params params;
+ struct key_asymmetric_import_params params;
struct key *key;
NTSTATUS status;
ULONG size;
@@ -1378,7 +1378,19 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
return STATUS_INVALID_PARAMETER;
size = sizeof(*ecc_blob) + ecc_blob->cbKey * 2;
- return key_asymmetric_create( (struct key **)ret_key, alg->id, key_size * 8, (BYTE *)ecc_blob, size );
+ if ((status = key_asymmetric_create( &key, alg->id, key_size * 8, (BYTE *)ecc_blob, size ))) return status;
+ params.key = key;
+ params.flags = KEY_IMPORT_FLAG_PUBLIC;
+ params.buf = input;
+ params.len = input_len;
+ if ((status = UNIX_CALL( key_asymmetric_import, ¶ms )))
+ {
+ key_destroy( key );
+ return status;
+ }
+
+ *ret_key = key;
+ return STATUS_SUCCESS;
}
else if (!wcscmp( type, BCRYPT_ECCPRIVATE_BLOB ))
{
@@ -1409,11 +1421,11 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
size = sizeof(*ecc_blob) + key_size * 2;
if ((status = key_asymmetric_create( &key, alg->id, key_size * 8, NULL, size ))) return status;
-
- params.key = key;
- params.buf = input;
- params.len = input_len;
- if ((status = UNIX_CALL( key_import_ecc, ¶ms )))
+ params.key = key;
+ params.flags = 0;
+ params.buf = input;
+ params.len = input_len;
+ if ((status = UNIX_CALL( key_asymmetric_import, ¶ms )))
{
key_destroy( key );
return status;
@@ -1432,7 +1444,20 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
if (size != input_len) return NTE_BAD_DATA;
- return key_asymmetric_create( (struct key **)ret_key, alg->id, rsa_blob->BitLength, (BYTE *)rsa_blob, size );
+
+ if ((status = key_asymmetric_create( &key, alg->id, rsa_blob->BitLength, (BYTE *)rsa_blob, size ))) return status;
+ params.key = key;
+ params.flags = KEY_IMPORT_FLAG_PUBLIC;
+ params.buf = input;
+ params.len = input_len;
+ if ((status = UNIX_CALL( key_asymmetric_import, ¶ms )))
+ {
+ key_destroy( key );
+ return status;
+ }
+
+ *ret_key = key;
+ return STATUS_SUCCESS;
}
else if (!wcscmp( type, BCRYPT_RSAPRIVATE_BLOB ) || !wcscmp( type, BCRYPT_RSAFULLPRIVATE_BLOB ))
{
@@ -1443,12 +1468,12 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
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->id, rsa_blob->BitLength, (BYTE *)rsa_blob, size )))
- return status;
- params.key = key;
- params.buf = input;
- params.len = input_len;
- if ((status = UNIX_CALL( key_import_rsa, ¶ms )))
+ if ((status = key_asymmetric_create( &key, alg->id, rsa_blob->BitLength, (BYTE *)rsa_blob, size ))) return status;
+ params.key = key;
+ params.flags = 0;
+ params.buf = input;
+ params.len = input_len;
+ if ((status = UNIX_CALL( key_asymmetric_import, ¶ms )))
{
key_destroy( key );
return status;
@@ -1466,7 +1491,19 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
return STATUS_NOT_SUPPORTED;
size = sizeof(*dsa_blob) + dsa_blob->cbKey * 3;
- return key_asymmetric_create( (struct key **)ret_key, alg->id, dsa_blob->cbKey * 8, (BYTE *)dsa_blob, size );
+ if ((status = key_asymmetric_create( &key, alg->id, dsa_blob->cbKey * 8, (BYTE *)dsa_blob, size ))) return status;
+ params.key = key;
+ params.flags = KEY_IMPORT_FLAG_PUBLIC;
+ params.buf = input;
+ params.len = input_len;
+ if ((status = UNIX_CALL( key_asymmetric_import, ¶ms )))
+ {
+ key_destroy( key );
+ return status;
+ }
+
+ *ret_key = key;
+ return STATUS_SUCCESS;
}
else if (!wcscmp( type, LEGACY_DSA_V2_PRIVATE_BLOB ))
{
@@ -1495,11 +1532,12 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
size = sizeof(*hdr) + sizeof(*pubkey) + (pubkey->bitlen / 8) * 3 + 20 + sizeof(DSSSEED);
if ((status = key_asymmetric_create( &key, alg->id, pubkey->bitlen, NULL, size ))) return status;
-
- params.key = key;
- params.buf = input;
- params.len = input_len;
- if ((status = UNIX_CALL( key_import_dsa_capi, ¶ms )))
+ key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2;
+ params.key = key;
+ params.flags = 0;
+ params.buf = input;
+ params.len = input_len;
+ if ((status = UNIX_CALL( key_asymmetric_import, ¶ms )))
{
key_destroy( key );
return status;
@@ -1531,6 +1569,15 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
if ((status = key_asymmetric_create( &key, alg->id, pubkey->bitlen, (BYTE *)hdr, size ))) return status;
key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2;
+ params.key = key;
+ params.flags = KEY_IMPORT_FLAG_PUBLIC;
+ params.buf = input;
+ params.len = input_len;
+ if ((status = UNIX_CALL( key_asymmetric_import, ¶ms )))
+ {
+ key_destroy( key );
+ return status;
+ }
*ret_key = key;
return STATUS_SUCCESS;
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c
index 01e1fe72092..28119fc9e78 100644
--- a/dlls/bcrypt/gnutls.c
+++ b/dlls/bcrypt/gnutls.c
@@ -1162,10 +1162,8 @@ static NTSTATUS key_export_ecc( struct key *key, UCHAR *buf, ULONG len, ULONG *r
return STATUS_SUCCESS;
}
-static NTSTATUS key_import_ecc( void *args )
+static NTSTATUS key_import_ecc( struct key *key, UCHAR *buf, ULONG len )
{
- const struct key_import_params *params = args;
- struct key *key = params->key;
BCRYPT_ECCKEY_BLOB *ecc_blob;
gnutls_ecc_curve_t curve;
gnutls_privkey_t handle;
@@ -1191,7 +1189,7 @@ static NTSTATUS key_import_ecc( void *args )
return STATUS_INTERNAL_ERROR;
}
- ecc_blob = (BCRYPT_ECCKEY_BLOB *)params->buf;
+ ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
x.data = (unsigned char *)(ecc_blob + 1);
x.size = ecc_blob->cbKey;
y.data = x.data + ecc_blob->cbKey;
@@ -1212,6 +1210,7 @@ static NTSTATUS key_import_ecc( void *args )
return status;
}
+ if (key_data(key)->privkey) pgnutls_privkey_deinit( key_data(key)->privkey );
key_data(key)->privkey = handle;
return STATUS_SUCCESS;
}
@@ -1273,10 +1272,9 @@ static NTSTATUS key_export_rsa( struct key *key, ULONG flags, UCHAR *buf, ULONG
return STATUS_SUCCESS;
}
-static NTSTATUS key_import_rsa( void *args )
+static NTSTATUS key_import_rsa( struct key *key, UCHAR *buf, ULONG len )
{
- const struct key_import_params *params = args;
- BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)params->buf;
+ BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
gnutls_datum_t m, e, p, q;
gnutls_privkey_t handle;
int ret;
@@ -1303,7 +1301,8 @@ static NTSTATUS key_import_rsa( void *args )
return STATUS_INTERNAL_ERROR;
}
- key_data(params->key)->privkey = handle;
+ if (key_data(key)->privkey) pgnutls_privkey_deinit( key_data(key)->privkey );
+ key_data(key)->privkey = handle;
return STATUS_SUCCESS;
}
@@ -1366,11 +1365,9 @@ static NTSTATUS key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULO
return STATUS_SUCCESS;
}
-static NTSTATUS key_import_dsa_capi( void *args )
+static NTSTATUS key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG len )
{
- const struct key_import_params *params = args;
- struct key *key = params->key;
- BLOBHEADER *hdr = (BLOBHEADER *)params->buf;
+ BLOBHEADER *hdr = (BLOBHEADER *)buf;
DSSPUBKEY *pubkey;
gnutls_privkey_t handle;
gnutls_datum_t p, q, g, y, x;
@@ -1435,9 +1432,8 @@ static NTSTATUS key_import_dsa_capi( void *args )
memcpy( &key->u.a.dss_seed, data, sizeof(key->u.a.dss_seed) );
- key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2;
+ if (key_data(key)->privkey) pgnutls_privkey_deinit( key_data(key)->privkey );
key_data(key)->privkey = handle;
-
return STATUS_SUCCESS;
}
@@ -1650,6 +1646,50 @@ static NTSTATUS key_asymmetric_export( void *args )
}
}
+static NTSTATUS key_asymmetric_import( void *args )
+{
+ const struct key_asymmetric_import_params *params = args;
+ struct key *key = params->key;
+ unsigned flags = params->flags;
+
+ switch (key->alg_id)
+ {
+ case ALG_ID_ECDH_P256:
+ case ALG_ID_ECDSA_P256:
+ case ALG_ID_ECDSA_P384:
+ if (flags & KEY_IMPORT_FLAG_PUBLIC)
+ {
+ FIXME("\n");
+ return STATUS_SUCCESS;
+ }
+ return key_import_ecc( key, params->buf, params->len );
+
+ case ALG_ID_RSA:
+ case ALG_ID_RSA_SIGN:
+ if (flags & KEY_IMPORT_FLAG_PUBLIC)
+ {
+ FIXME("\n");
+ return STATUS_SUCCESS;
+ }
+ return key_import_rsa( key, params->buf, params->len );
+
+ case ALG_ID_DSA:
+ if (flags & KEY_IMPORT_FLAG_PUBLIC)
+ {
+ FIXME("\n");
+ return STATUS_SUCCESS;
+ }
+ if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
+ return key_import_dsa_capi( key, params->buf, params->len );
+ FIXME( "DSA private key not supported\n" );
+ return STATUS_NOT_IMPLEMENTED;
+
+ default:
+ FIXME( "algorithm %u not yet supported\n", key->alg_id );
+ return STATUS_NOT_IMPLEMENTED;
+ }
+}
+
static NTSTATUS prepare_gnutls_signature_dsa( struct key *key, UCHAR *signature, ULONG signature_len,
gnutls_datum_t *gnutls_signature )
{
@@ -2085,9 +2125,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
key_asymmetric_verify,
key_asymmetric_destroy,
key_asymmetric_export,
- key_import_dsa_capi,
- key_import_ecc,
- key_import_rsa
+ key_asymmetric_import
};
#ifdef _WIN64
@@ -2477,59 +2515,12 @@ static NTSTATUS wow64_key_asymmetric_export( void *args )
return ret;
}
-static NTSTATUS wow64_key_import_dsa_capi( void *args )
-{
- struct
- {
- PTR32 key;
- PTR32 buf;
- ULONG len;
- } const *params32 = args;
-
- NTSTATUS ret;
- struct key key;
- struct key32 *key32 = ULongToPtr( params32->key );
- struct key_import_params params =
- {
- get_asymmetric_key( key32, &key ),
- ULongToPtr(params32->buf),
- params32->len
- };
-
- ret = key_import_dsa_capi( ¶ms );
- put_asymmetric_key32( &key, key32 );
- return ret;
-}
-
-static NTSTATUS wow64_key_import_ecc( void *args )
-{
- struct
- {
- PTR32 key;
- PTR32 buf;
- ULONG len;
- } const *params32 = args;
-
- NTSTATUS ret;
- struct key key;
- struct key32 *key32 = ULongToPtr( params32->key );
- struct key_import_params params =
- {
- get_asymmetric_key( key32, &key ),
- ULongToPtr(params32->buf),
- params32->len
- };
-
- ret = key_import_ecc( ¶ms );
- put_asymmetric_key32( &key, key32 );
- return ret;
-}
-
-static NTSTATUS wow64_key_import_rsa( void *args )
+static NTSTATUS wow64_key_asymmetric_import( void *args )
{
struct
{
PTR32 key;
+ ULONG flags;
PTR32 buf;
ULONG len;
} const *params32 = args;
@@ -2537,14 +2528,15 @@ static NTSTATUS wow64_key_import_rsa( void *args )
NTSTATUS ret;
struct key key;
struct key32 *key32 = ULongToPtr( params32->key );
- struct key_import_params params =
+ struct key_asymmetric_import_params params =
{
get_asymmetric_key( key32, &key ),
+ params32->flags,
ULongToPtr(params32->buf),
params32->len
};
- ret = key_import_rsa( ¶ms );
+ ret = key_asymmetric_import( ¶ms );
put_asymmetric_key32( &key, key32 );
return ret;
}
@@ -2566,9 +2558,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
wow64_key_asymmetric_verify,
wow64_key_asymmetric_destroy,
wow64_key_asymmetric_export,
- wow64_key_import_dsa_capi,
- wow64_key_import_ecc,
- wow64_key_import_rsa
+ wow64_key_asymmetric_import
};
#endif /* _WIN64 */
--
2.30.2
1
0
[PATCH 3/6] bcrypt: Merge the various key export Unix calls into one.
by Hans Leidekker March 21, 2022
by Hans Leidekker March 21, 2022
March 21, 2022
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/bcrypt/bcrypt_internal.h | 10 +-
dlls/bcrypt/bcrypt_main.c | 46 +++--
dlls/bcrypt/gnutls.c | 336 +++++++++++++++++++++++++---------
3 files changed, 277 insertions(+), 115 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h
index 6d115e10e54..d299def6e11 100644
--- a/dlls/bcrypt/bcrypt_internal.h
+++ b/dlls/bcrypt/bcrypt_internal.h
@@ -268,13 +268,15 @@ struct key_asymmetric_verify_params
unsigned flags;
};
-struct key_export_params
+#define KEY_EXPORT_FLAG_PUBLIC 0x00000001
+#define KEY_EXPORT_FLAG_RSA_FULL 0x00000002
+struct key_asymmetric_export_params
{
struct key *key;
+ ULONG flags;
UCHAR *buf;
ULONG len;
ULONG *ret_len;
- BOOL full;
};
struct key_import_params
@@ -300,9 +302,7 @@ enum key_funcs
unix_key_asymmetric_sign,
unix_key_asymmetric_verify,
unix_key_asymmetric_destroy,
- unix_key_export_dsa_capi,
- unix_key_export_ecc,
- unix_key_export_rsa,
+ unix_key_asymmetric_export,
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 ab9cf67923d..408c477b92f 100644
--- a/dlls/bcrypt/bcrypt_main.c
+++ b/dlls/bcrypt/bcrypt_main.c
@@ -1070,7 +1070,7 @@ static NTSTATUS key_import( BCRYPT_ALG_HANDLE algorithm, const WCHAR *type, BCRY
static NTSTATUS key_export( struct key *key, const WCHAR *type, UCHAR *output, ULONG output_len, ULONG *size )
{
- struct key_export_params params;
+ struct key_asymmetric_export_params params;
if (!wcscmp( type, BCRYPT_KEY_DATA_BLOB ))
{
@@ -1101,38 +1101,34 @@ static NTSTATUS key_export( struct key *key, const WCHAR *type, UCHAR *output, U
}
return STATUS_SUCCESS;
}
- else if (!wcscmp( type, BCRYPT_RSAPUBLIC_BLOB ) || !wcscmp( type, BCRYPT_DSA_PUBLIC_BLOB ) ||
- !wcscmp( type, BCRYPT_ECCPUBLIC_BLOB ) || !wcscmp( type, LEGACY_DSA_V2_PUBLIC_BLOB ))
+ else if (!wcscmp( type, BCRYPT_DSA_PRIVATE_BLOB ) || !wcscmp( type, LEGACY_DSA_V2_PRIVATE_BLOB ) ||
+ !wcscmp( type, BCRYPT_ECCPRIVATE_BLOB ))
{
- *size = key->u.a.pubkey_len;
- if (output_len < key->u.a.pubkey_len) return STATUS_SUCCESS;
- 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.key = key;
+ params.flags = 0;
+ 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 );
+ return UNIX_CALL( key_asymmetric_export, ¶ms );
}
- else if (!wcscmp( type, BCRYPT_ECCPRIVATE_BLOB ))
+ else if (!wcscmp( type, BCRYPT_RSAPRIVATE_BLOB ) || !wcscmp( type, BCRYPT_RSAFULLPRIVATE_BLOB ))
{
- params.key = key;
- params.buf = output;
- params.len = output_len;
+ params.key = key;
+ params.flags = (wcscmp( type, BCRYPT_RSAPRIVATE_BLOB )) ? KEY_EXPORT_FLAG_RSA_FULL : 0;
+ params.buf = output;
+ params.len = output_len;
params.ret_len = size;
- return UNIX_CALL( key_export_ecc, ¶ms );
+ return UNIX_CALL( key_asymmetric_export, ¶ms );
}
- else if (!wcscmp( type, LEGACY_DSA_V2_PRIVATE_BLOB ))
+ else if (!wcscmp( type, BCRYPT_DSA_PUBLIC_BLOB ) || !wcscmp( type, LEGACY_DSA_V2_PUBLIC_BLOB ) ||
+ !wcscmp( type, BCRYPT_ECCPUBLIC_BLOB ) || !wcscmp( type, BCRYPT_RSAPUBLIC_BLOB ))
{
- params.key = key;
- params.buf = output;
- params.len = output_len;
+ params.key = key;
+ params.flags = KEY_EXPORT_FLAG_PUBLIC;
+ params.buf = output;
+ params.len = output_len;
params.ret_len = size;
- return UNIX_CALL( key_export_dsa_capi, ¶ms );
+ return UNIX_CALL( key_asymmetric_export, ¶ms );
}
FIXME( "unsupported key type %s\n", debugstr_w(type) );
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c
index 6862c5cdcf2..01e1fe72092 100644
--- a/dlls/bcrypt/gnutls.c
+++ b/dlls/bcrypt/gnutls.c
@@ -647,6 +647,7 @@ static NTSTATUS export_gnutls_pubkey_rsa( gnutls_privkey_t gnutls_key, ULONG bit
free( e.data ); free( m.data );
return STATUS_SUCCESS;
}
+#undef EXPORT_SIZE
static NTSTATUS export_gnutls_pubkey_ecc( gnutls_privkey_t gnutls_key, enum alg_id alg_id, void *pubkey,
unsigned *pubkey_len )
@@ -836,6 +837,194 @@ static NTSTATUS export_gnutls_pubkey_dsa_capi( gnutls_privkey_t gnutls_key, cons
return STATUS_SUCCESS;
}
+#define EXPORT_SIZE(d,f,p) export_gnutls_datum( NULL, key->u.a.bitlen / f, &d, p )
+static NTSTATUS key_export_rsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
+{
+ BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
+ gnutls_datum_t m, e;
+ UCHAR *dst;
+ int ret;
+
+ if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->privkey, &m, &e, NULL, NULL, NULL, NULL, NULL, NULL )))
+ {
+ pgnutls_perror( ret );
+ return STATUS_INTERNAL_ERROR;
+ }
+
+ *ret_len = sizeof(*rsa_blob) + EXPORT_SIZE(e,8,0) + EXPORT_SIZE(m,8,1);
+ if (len >= *ret_len && buf)
+ {
+ dst = (UCHAR *)(rsa_blob + 1);
+ rsa_blob->cbPublicExp = export_gnutls_datum( dst, key->u.a.bitlen / 8, &e, 0 );
+
+ dst += rsa_blob->cbPublicExp;
+ rsa_blob->cbModulus = export_gnutls_datum( dst, key->u.a.bitlen / 8, &m, 1 );
+
+ rsa_blob->Magic = BCRYPT_RSAPUBLIC_MAGIC;
+ rsa_blob->BitLength = key->u.a.bitlen;
+ rsa_blob->cbPrime1 = 0;
+ rsa_blob->cbPrime2 = 0;
+ }
+
+ free( e.data ); free( m.data );
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS key_export_ecc_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
+{
+ BCRYPT_ECCKEY_BLOB *ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
+ gnutls_ecc_curve_t curve;
+ gnutls_datum_t x, y;
+ DWORD magic, size;
+ UCHAR *dst;
+ int ret;
+
+ switch (key->alg_id)
+ {
+ case ALG_ID_ECDH_P256:
+ magic = BCRYPT_ECDH_PUBLIC_P256_MAGIC;
+ size = 32;
+ break;
+ case ALG_ID_ECDSA_P256:
+ magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
+ size = 32;
+ break;
+ default:
+ FIXME( "algorithm %u not supported\n", key->alg_id );
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key)->privkey, &curve, &x, &y, NULL )))
+ {
+ pgnutls_perror( ret );
+ return STATUS_INTERNAL_ERROR;
+ }
+
+ if (curve != GNUTLS_ECC_CURVE_SECP256R1)
+ {
+ FIXME( "curve %u not supported\n", curve );
+ free( x.data ); free( y.data );
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ *ret_len = sizeof(*ecc_blob) + size * 2;
+ if (len >= *ret_len && buf)
+ {
+ ecc_blob->dwMagic = magic;
+ ecc_blob->cbKey = size;
+
+ dst = (UCHAR *)(ecc_blob + 1);
+ export_gnutls_datum( dst, size, &x, 1 );
+
+ dst += size;
+ export_gnutls_datum( dst, size, &y, 1 );
+ }
+
+ free( x.data ); free( y.data );
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS key_export_dsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
+{
+ BCRYPT_DSA_KEY_BLOB *dsa_blob = (BCRYPT_DSA_KEY_BLOB *)buf;
+ gnutls_datum_t p, q, g, y;
+ UCHAR *dst;
+ int ret;
+
+ if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->privkey, &p, &q, &g, &y, NULL )))
+ {
+ pgnutls_perror( ret );
+ return STATUS_INTERNAL_ERROR;
+ }
+
+ if (key->u.a.bitlen > 1024)
+ {
+ FIXME( "bitlen > 1024 not supported\n" );
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ *ret_len = sizeof(*dsa_blob) + key->u.a.bitlen / 8 * 3;
+ if (len >= *ret_len && buf)
+ {
+ dst = (UCHAR *)(dsa_blob + 1);
+ export_gnutls_datum( dst, key->u.a.bitlen / 8, &p, 1 );
+
+ dst += key->u.a.bitlen / 8;
+ export_gnutls_datum( dst, key->u.a.bitlen / 8, &g, 1 );
+
+ dst += key->u.a.bitlen / 8;
+ export_gnutls_datum( dst, key->u.a.bitlen / 8, &y, 1 );
+
+ dst = dsa_blob->q;
+ export_gnutls_datum( dst, sizeof(dsa_blob->q), &q, 1 );
+
+ dsa_blob->dwMagic = BCRYPT_DSA_PUBLIC_MAGIC;
+ dsa_blob->cbKey = key->u.a.bitlen / 8;
+ memset( dsa_blob->Count, 0, sizeof(dsa_blob->Count) ); /* FIXME */
+ memset( dsa_blob->Seed, 0, sizeof(dsa_blob->Seed) ); /* FIXME */
+ }
+
+ free( p.data ); free( q.data ); free( g.data ); free( y.data );
+ return STATUS_SUCCESS;
+}
+
+#define Q_SIZE 20
+static NTSTATUS key_export_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
+{
+ BLOBHEADER *hdr = (BLOBHEADER *)buf;
+ DSSPUBKEY *dsskey;
+ gnutls_datum_t p, q, g, y;
+ UCHAR *dst;
+ int ret, size = sizeof(*hdr) + sizeof(*dsskey) + sizeof(key->u.a.dss_seed);
+
+ if (key->u.a.bitlen > 1024)
+ {
+ FIXME( "bitlen > 1024 not supported\n" );
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->privkey, &p, &q, &g, &y, NULL )))
+ {
+ pgnutls_perror( ret );
+ return STATUS_INTERNAL_ERROR;
+ }
+
+ *ret_len = size + key->u.a.bitlen / 8 * 3 + Q_SIZE;
+ if (len >= *ret_len && buf)
+ {
+ hdr->bType = PUBLICKEYBLOB;
+ hdr->bVersion = 2;
+ hdr->reserved = 0;
+ hdr->aiKeyAlg = CALG_DSS_SIGN;
+
+ dsskey = (DSSPUBKEY *)(hdr + 1);
+ dsskey->magic = MAGIC_DSS1;
+ dsskey->bitlen = key->u.a.bitlen;
+
+ dst = (UCHAR *)(dsskey + 1);
+ export_gnutls_datum( dst, key->u.a.bitlen / 8, &p, 1 );
+ reverse_bytes( dst, key->u.a.bitlen / 8 );
+ dst += key->u.a.bitlen / 8;
+
+ export_gnutls_datum( dst, Q_SIZE, &q, 1 );
+ reverse_bytes( dst, Q_SIZE );
+ dst += Q_SIZE;
+
+ export_gnutls_datum( dst, key->u.a.bitlen / 8, &g, 1 );
+ reverse_bytes( dst, key->u.a.bitlen / 8 );
+ dst += key->u.a.bitlen / 8;
+
+ export_gnutls_datum( dst, key->u.a.bitlen / 8, &y, 1 );
+ reverse_bytes( dst, key->u.a.bitlen / 8 );
+ dst += key->u.a.bitlen / 8;
+
+ memcpy( dst, &key->u.a.dss_seed, sizeof(key->u.a.dss_seed) );
+ }
+
+ free( p.data ); free( q.data ); free( g.data ); free( y.data );
+ return STATUS_SUCCESS;
+}
+
static NTSTATUS key_asymmetric_generate( void *args )
{
struct key *key = args;
@@ -914,10 +1103,8 @@ static NTSTATUS key_asymmetric_generate( void *args )
return STATUS_SUCCESS;
}
-static NTSTATUS key_export_ecc( void *args )
+static NTSTATUS key_export_ecc( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
{
- const struct key_export_params *params = args;
- struct key *key = params->key;
BCRYPT_ECCKEY_BLOB *ecc_blob;
gnutls_ecc_curve_t curve;
gnutls_datum_t x, y, d;
@@ -954,10 +1141,10 @@ static NTSTATUS key_export_ecc( void *args )
return STATUS_NOT_IMPLEMENTED;
}
- *params->ret_len = sizeof(*ecc_blob) + size * 3;
- if (params->len >= *params->ret_len && params->buf)
+ *ret_len = sizeof(*ecc_blob) + size * 3;
+ if (len >= *ret_len && buf)
{
- ecc_blob = (BCRYPT_ECCKEY_BLOB *)params->buf;
+ ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
ecc_blob->dwMagic = magic;
ecc_blob->cbKey = size;
@@ -1029,13 +1216,12 @@ static NTSTATUS key_import_ecc( void *args )
return STATUS_SUCCESS;
}
-static NTSTATUS key_export_rsa( void *args )
+static NTSTATUS key_export_rsa( struct key *key, ULONG flags, UCHAR *buf, ULONG len, ULONG *ret_len )
{
- 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;
+ BOOL full = (flags & KEY_EXPORT_FLAG_RSA_FULL);
UCHAR *dst;
int ret;
@@ -1045,13 +1231,13 @@ static NTSTATUS key_export_rsa( void *args )
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);
+ *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 (full) *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)
+ if (len >= *ret_len && buf)
{
- rsa_blob = (BCRYPT_RSAKEY_BLOB *)params->buf;
- rsa_blob->Magic = params->full ? BCRYPT_RSAFULLPRIVATE_MAGIC : BCRYPT_RSAPRIVATE_MAGIC;
+ rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
+ rsa_blob->Magic = full ? BCRYPT_RSAFULLPRIVATE_MAGIC : BCRYPT_RSAPRIVATE_MAGIC;
rsa_blob->BitLength = bitlen;
dst = (UCHAR *)(rsa_blob + 1);
@@ -1066,7 +1252,7 @@ static NTSTATUS key_export_rsa( void *args )
dst += rsa_blob->cbPrime1;
rsa_blob->cbPrime2 = export_gnutls_datum( dst, bitlen / 16, &q, 1 );
- if (params->full)
+ if (full)
{
dst += rsa_blob->cbPrime2;
export_gnutls_datum( dst, bitlen / 16, &e1, 1 );
@@ -1121,10 +1307,8 @@ static NTSTATUS key_import_rsa( void *args )
return STATUS_SUCCESS;
}
-static NTSTATUS key_export_dsa_capi( void *args )
+static NTSTATUS key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
{
- const struct key_export_params *params = args;
- struct key *key = params->key;
BLOBHEADER *hdr;
DSSPUBKEY *pubkey;
gnutls_datum_t p, q, g, y, x;
@@ -1145,10 +1329,10 @@ static NTSTATUS key_export_dsa_capi( void *args )
}
size = key->u.a.bitlen / 8;
- *params->ret_len = sizeof(*hdr) + sizeof(*pubkey) + size * 2 + 40 + sizeof(key->u.a.dss_seed);
- if (params->len >= *params->ret_len && params->buf)
+ *ret_len = sizeof(*hdr) + sizeof(*pubkey) + size * 2 + 40 + sizeof(key->u.a.dss_seed);
+ if (len >= *ret_len && buf)
{
- hdr = (BLOBHEADER *)params->buf;
+ hdr = (BLOBHEADER *)buf;
hdr->bType = PRIVATEKEYBLOB;
hdr->bVersion = 2;
hdr->reserved = 0;
@@ -1428,6 +1612,44 @@ static NTSTATUS import_gnutls_pubkey( struct key *key, gnutls_pubkey_t *gnutls_k
}
}
+static NTSTATUS key_asymmetric_export( void *args )
+{
+ const struct key_asymmetric_export_params *params = args;
+ struct key *key = params->key;
+ unsigned flags = params->flags;
+
+ switch (key->alg_id)
+ {
+ case ALG_ID_ECDH_P256:
+ case ALG_ID_ECDSA_P256:
+ case ALG_ID_ECDSA_P384:
+ if (flags & KEY_EXPORT_FLAG_PUBLIC)
+ return key_export_ecc_public( key, params->buf, params->len, params->ret_len );
+ return key_export_ecc( key, params->buf, params->len, params->ret_len );
+
+ case ALG_ID_RSA:
+ case ALG_ID_RSA_SIGN:
+ if (flags & KEY_EXPORT_FLAG_PUBLIC)
+ return key_export_rsa_public( key, params->buf, params->len, params->ret_len );
+ return key_export_rsa( key, flags, params->buf, params->len, params->ret_len );
+
+ case ALG_ID_DSA:
+ if (flags & KEY_EXPORT_FLAG_PUBLIC)
+ {
+ if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
+ return key_export_dsa_capi_public( key, params->buf, params->len, params->ret_len );
+ return key_export_dsa_public( key, params->buf, params->len, params->ret_len );
+ }
+ if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
+ return key_export_dsa_capi( key, params->buf, params->len, params->ret_len );
+ return STATUS_NOT_IMPLEMENTED;
+
+ default:
+ FIXME( "algorithm %u not yet supported\n", key->alg_id );
+ return STATUS_NOT_IMPLEMENTED;
+ }
+}
+
static NTSTATUS prepare_gnutls_signature_dsa( struct key *key, UCHAR *signature, ULONG signature_len,
gnutls_datum_t *gnutls_signature )
{
@@ -1862,9 +2084,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
key_asymmetric_sign,
key_asymmetric_verify,
key_asymmetric_destroy,
- key_export_dsa_capi,
- key_export_ecc,
- key_export_rsa,
+ key_asymmetric_export,
key_import_dsa_capi,
key_import_ecc,
key_import_rsa
@@ -2229,37 +2449,12 @@ static NTSTATUS wow64_key_asymmetric_destroy( void *args )
return key_asymmetric_destroy( get_asymmetric_key( key32, &key ));
}
-static NTSTATUS wow64_key_export_dsa_capi( void *args )
-{
- struct
- {
- PTR32 key;
- PTR32 buf;
- ULONG len;
- PTR32 ret_len;
- } 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)
- };
-
- ret = key_export_dsa_capi( ¶ms );
- put_asymmetric_key32( &key, key32 );
- return ret;
-}
-
-static NTSTATUS wow64_key_export_ecc( void *args )
+static NTSTATUS wow64_key_asymmetric_export( void *args )
{
struct
{
PTR32 key;
+ ULONG flags;
PTR32 buf;
ULONG len;
PTR32 ret_len;
@@ -2268,15 +2463,16 @@ static NTSTATUS wow64_key_export_ecc( void *args )
NTSTATUS ret;
struct key key;
struct key32 *key32 = ULongToPtr( params32->key );
- struct key_export_params params =
+ struct key_asymmetric_export_params params =
{
get_asymmetric_key( key32, &key ),
+ params32->flags,
ULongToPtr(params32->buf),
params32->len,
- ULongToPtr(params32->ret_len)
+ ULongToPtr(params32->ret_len),
};
- ret = key_export_ecc( ¶ms );
+ ret = key_asymmetric_export( ¶ms );
put_asymmetric_key32( &key, key32 );
return ret;
}
@@ -2329,34 +2525,6 @@ 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
@@ -2397,9 +2565,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
wow64_key_asymmetric_sign,
wow64_key_asymmetric_verify,
wow64_key_asymmetric_destroy,
- wow64_key_export_dsa_capi,
- wow64_key_export_ecc,
- wow64_key_export_rsa,
+ wow64_key_asymmetric_export,
wow64_key_import_dsa_capi,
wow64_key_import_ecc,
wow64_key_import_rsa
--
2.30.2
1
0
[PATCH 2/6] bcrypt: Call key_destoy() instead of BCryptDestroyKey().
by Hans Leidekker March 21, 2022
by Hans Leidekker March 21, 2022
March 21, 2022
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/bcrypt/bcrypt_main.c | 40 +++++++++++++++++++--------------------
1 file changed, 19 insertions(+), 21 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
index fe16f9269c9..ab9cf67923d 100644
--- a/dlls/bcrypt/bcrypt_main.c
+++ b/dlls/bcrypt/bcrypt_main.c
@@ -1324,6 +1324,22 @@ static NTSTATUS key_symmetric_decrypt( struct key *key, UCHAR *input, ULONG inpu
return status;
}
+static void key_destroy( struct key *key )
+{
+ if (key_is_symmetric( key ))
+ {
+ UNIX_CALL( key_symmetric_destroy, key );
+ free( key->u.s.vector );
+ free( key->u.s.secret );
+ DeleteCriticalSection( &key->u.s.cs );
+ }
+ else
+ UNIX_CALL( key_asymmetric_destroy, key );
+
+ key->hdr.magic = 0;
+ free( key );
+}
+
static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input,
ULONG input_len )
{
@@ -1403,7 +1419,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
params.len = input_len;
if ((status = UNIX_CALL( key_import_ecc, ¶ms )))
{
- BCryptDestroyKey( key );
+ key_destroy( key );
return status;
}
@@ -1438,7 +1454,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
params.len = input_len;
if ((status = UNIX_CALL( key_import_rsa, ¶ms )))
{
- BCryptDestroyKey( key );
+ key_destroy( key );
return status;
}
@@ -1489,7 +1505,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
params.len = input_len;
if ((status = UNIX_CALL( key_import_dsa_capi, ¶ms )))
{
- BCryptDestroyKey( key );
+ key_destroy( key );
return status;
}
@@ -1724,24 +1740,6 @@ static NTSTATUS key_duplicate( struct key *key_orig, struct key *key_copy )
return STATUS_SUCCESS;
}
-static void key_destroy( struct key *key )
-{
- if (key_is_symmetric( key ))
- {
- UNIX_CALL( key_symmetric_destroy, key );
- free( key->u.s.vector );
- free( key->u.s.secret );
- DeleteCriticalSection( &key->u.s.cs );
- }
- else
- {
- UNIX_CALL( key_asymmetric_destroy, key );
- free( key->u.a.pubkey );
- }
- key->hdr.magic = 0;
- free( key );
-}
-
NTSTATUS WINAPI BCryptDuplicateKey( BCRYPT_KEY_HANDLE handle, BCRYPT_KEY_HANDLE *handle_copy,
UCHAR *object, ULONG object_len, ULONG flags )
{
--
2.30.2
1
0
[PATCH 1/6] bcrypt: Pass the algorithm ID to key_asymmetric_create().
by Hans Leidekker March 21, 2022
by Hans Leidekker March 21, 2022
March 21, 2022
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/bcrypt/bcrypt_main.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
index 5df4da009a4..fe16f9269c9 100644
--- a/dlls/bcrypt/bcrypt_main.c
+++ b/dlls/bcrypt/bcrypt_main.c
@@ -968,7 +968,7 @@ NTSTATUS WINAPI BCryptHash( BCRYPT_ALG_HANDLE algorithm, UCHAR *secret, ULONG se
return status;
}
-static NTSTATUS key_asymmetric_create( struct key **ret_key, struct algorithm *alg, ULONG bitlen,
+static NTSTATUS key_asymmetric_create( struct key **ret_key, enum alg_id alg_id, ULONG bitlen,
const UCHAR *pubkey, ULONG pubkey_len )
{
struct key *key;
@@ -981,7 +981,7 @@ static NTSTATUS key_asymmetric_create( struct key **ret_key, struct algorithm *a
if (!(key = calloc( 1, sizeof(*key) ))) return STATUS_NO_MEMORY;
key->hdr.magic = MAGIC_KEY;
- key->alg_id = alg->id;
+ key->alg_id = alg_id;
key->u.a.bitlen = bitlen;
key->u.a.pubkey_len = pubkey_len;
@@ -1366,7 +1366,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
return STATUS_INVALID_PARAMETER;
size = sizeof(*ecc_blob) + ecc_blob->cbKey * 2;
- return key_asymmetric_create( (struct key **)ret_key, alg, key_size * 8, (BYTE *)ecc_blob, size );
+ return key_asymmetric_create( (struct key **)ret_key, alg->id, key_size * 8, (BYTE *)ecc_blob, size );
}
else if (!wcscmp( type, BCRYPT_ECCPRIVATE_BLOB ))
{
@@ -1396,7 +1396,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
return STATUS_INVALID_PARAMETER;
size = sizeof(*ecc_blob) + key_size * 2;
- if ((status = key_asymmetric_create( &key, alg, key_size * 8, NULL, size ))) return status;
+ if ((status = key_asymmetric_create( &key, alg->id, key_size * 8, NULL, size ))) return status;
params.key = key;
params.buf = input;
@@ -1420,7 +1420,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
if (size != input_len) return NTE_BAD_DATA;
- return key_asymmetric_create( (struct key **)ret_key, alg, rsa_blob->BitLength, (BYTE *)rsa_blob, size );
+ return key_asymmetric_create( (struct key **)ret_key, alg->id, rsa_blob->BitLength, (BYTE *)rsa_blob, size );
}
else if (!wcscmp( type, BCRYPT_RSAPRIVATE_BLOB ) || !wcscmp( type, BCRYPT_RSAFULLPRIVATE_BLOB ))
{
@@ -1431,7 +1431,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
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 )))
+ if ((status = key_asymmetric_create( &key, alg->id, rsa_blob->BitLength, (BYTE *)rsa_blob, size )))
return status;
params.key = key;
params.buf = input;
@@ -1454,7 +1454,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
return STATUS_NOT_SUPPORTED;
size = sizeof(*dsa_blob) + dsa_blob->cbKey * 3;
- return key_asymmetric_create( (struct key **)ret_key, alg, dsa_blob->cbKey * 8, (BYTE *)dsa_blob, size );
+ return key_asymmetric_create( (struct key **)ret_key, alg->id, dsa_blob->cbKey * 8, (BYTE *)dsa_blob, size );
}
else if (!wcscmp( type, LEGACY_DSA_V2_PRIVATE_BLOB ))
{
@@ -1482,7 +1482,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
return STATUS_INVALID_PARAMETER;
size = sizeof(*hdr) + sizeof(*pubkey) + (pubkey->bitlen / 8) * 3 + 20 + sizeof(DSSSEED);
- if ((status = key_asymmetric_create( &key, alg, pubkey->bitlen, NULL, size ))) return status;
+ if ((status = key_asymmetric_create( &key, alg->id, pubkey->bitlen, NULL, size ))) return status;
params.key = key;
params.buf = input;
@@ -1517,7 +1517,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
size = sizeof(*hdr) + sizeof(*pubkey) + (pubkey->bitlen / 8) * 3 + 20 + sizeof(DSSSEED);
if (input_len < size) return STATUS_INVALID_PARAMETER;
- if ((status = key_asymmetric_create( &key, alg, pubkey->bitlen, (BYTE *)hdr, size ))) return status;
+ if ((status = key_asymmetric_create( &key, alg->id, pubkey->bitlen, (BYTE *)hdr, size ))) return status;
key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2;
*ret_key = key;
@@ -1629,7 +1629,7 @@ NTSTATUS WINAPI BCryptGenerateKeyPair( BCRYPT_ALG_HANDLE algorithm, BCRYPT_KEY_H
return STATUS_NOT_SUPPORTED;
}
- if (!(status = key_asymmetric_create( &key, alg, key_len, NULL, size ))) *handle = key;
+ if (!(status = key_asymmetric_create( &key, alg->id, key_len, NULL, size ))) *handle = key;
return status;
}
--
2.30.2
1
0
March 20, 2022
There is no flushing after X11DRV_XIMLookupChars on wine11xdrv. for
this reason, the characters of the GUI are not updated.
In addition, in IME_SetResultString on wine11xdrv, the bInComposition
flag is not deactivated after generating WM_IME_ENDCOMPOSITION, so that
the WM_IME_STARTCOMPOSITION message is not generated in the next
composition.
Also, when WM_IME_COMPOSITION is processed in editor_handle_message on
riched20, the existing selection is removed and the characters being
entered disappear.
WM_IME_STARTCOMPOSITION occurs when attempting to input after full
selection, and ME_DeleteSelection is called, which causes the exact
location of the cursor to be lost.
Signed-off-by: Alex Kwak <take-me-home(a)kakao.com>
---
v2: Fix comment style
---
dlls/riched20/editor.c | 3 +--
dlls/winex11.drv/ime.c | 5 ++---
dlls/winex11.drv/xim.c | 10 ++++++++++
3 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index a8cf3175591..33437a6d6e3 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -4097,8 +4097,8 @@ LRESULT editor_handle_message( ME_TextEditor *editor, UINT msg, WPARAM wParam,
return 0;
case WM_IME_STARTCOMPOSITION:
{
- editor->imeStartIndex=ME_GetCursorOfs(&editor->pCursors[0]);
ME_DeleteSelection(editor);
+ editor->imeStartIndex=ME_GetCursorOfs(&editor->pCursors[0]);
ME_CommitUndo(editor);
ME_UpdateRepaint(editor, FALSE);
return 0;
@@ -4109,7 +4109,6 @@ LRESULT editor_handle_message( ME_TextEditor *editor, UINT msg, WPARAM wParam,
ME_Style *style = style_get_insert_style( editor, editor->pCursors );
hIMC = ITextHost_TxImmGetContext(editor->texthost);
- ME_DeleteSelection(editor);
ME_SaveTempStyle(editor, style);
if (lParam & (GCS_RESULTSTR|GCS_COMPSTR))
{
diff --git a/dlls/winex11.drv/ime.c b/dlls/winex11.drv/ime.c
index c1584930861..db2ff5d85cc 100644
--- a/dlls/winex11.drv/ime.c
+++ b/dlls/winex11.drv/ime.c
@@ -1049,10 +1049,9 @@ void IME_SetResultString(LPWSTR lpResult, DWORD dwResultLen)
GenerateIMEMessage(imc, WM_IME_COMPOSITION, 0, GCS_COMPSTR);
GenerateIMEMessage(imc, WM_IME_COMPOSITION, lpResult[0], GCS_RESULTSTR|GCS_RESULTCLAUSE);
GenerateIMEMessage(imc, WM_IME_ENDCOMPOSITION, 0, 0);
+ myPrivate->bInComposition = FALSE;
- if (!inComp)
- ImmSetOpenStatus(imc, FALSE);
-
+ ImmSetOpenStatus(imc, FALSE);
ImmUnlockIMC(imc);
}
diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c
index 3994c2106cc..66c56c177ac 100644
--- a/dlls/winex11.drv/xim.c
+++ b/dlls/winex11.drv/xim.c
@@ -117,6 +117,16 @@ void X11DRV_XIMLookupChars( const char *str, DWORD count )
IME_SetResultString(wcOutput, dwOutput);
HeapFree(GetProcessHeap(), 0, wcOutput);
+
+ /*
+ * After then if `CompositionString` is remaining, flushing it.
+ * i.e., Korean
+ */
+ if (CompositionString)
+ {
+ IME_SetCompositionString(SCS_SETSTR, CompositionString,
+ dwCompStringLength, NULL, 0);
+ }
}
static BOOL XIMPreEditStateNotifyCallback(XIC xic, XPointer p, XPointer data)
--
2.32.0
3
4