This reverts commit a19c8712917042361208b8a4a0a503e06815d20a.
It turns out commit a19c8712917042361208b8a4a0a503e06815d20a is wrong and causing regressions. Crypt provider info is actually stored in certificate and that is the only place where, e. g., secur32 can get private key from.
It turns out that Street Fightet 6 which is creating a great amount of temporary certificates and growing cert storage does the same on Windows, with the only difference that on Windows those certificates are stored on disk and not in registry.
-- v2: crypt32/tests: Test CertCreateSelfSignCertificate() without provider info.
From: Paul Gofman pgofman@codeweavers.com
This reverts commit a19c8712917042361208b8a4a0a503e06815d20a. --- dlls/crypt32/cert.c | 53 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 10 deletions(-)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c index ec3cf5b15ec..b9645770ce1 100644 --- a/dlls/crypt32/cert.c +++ b/dlls/crypt32/cert.c @@ -3682,21 +3682,54 @@ static void CRYPT_MakeCertInfo(PCERT_INFO info, const CRYPT_DATA_BLOB *pSerialNu } }
+typedef RPC_STATUS (RPC_ENTRY *UuidCreateFunc)(UUID *); +typedef RPC_STATUS (RPC_ENTRY *UuidToStringFunc)(UUID *, unsigned char **); +typedef RPC_STATUS (RPC_ENTRY *RpcStringFreeFunc)(unsigned char **); + static HCRYPTPROV CRYPT_CreateKeyProv(void) { - HCRYPTPROV prov; - HCRYPTKEY key; + HCRYPTPROV hProv = 0; + HMODULE rpcrt = LoadLibraryW(L"rpcrt4");
- if (!CryptAcquireContextA(&prov, NULL, MS_DEF_PROV_A, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_NEWKEYSET)) - return 0; - - if (!CryptGenKey(prov, AT_SIGNATURE, 0, &key)) + if (rpcrt) { - CryptReleaseContext(prov, 0); - return 0; + UuidCreateFunc uuidCreate = (UuidCreateFunc)GetProcAddress(rpcrt, + "UuidCreate"); + UuidToStringFunc uuidToString = (UuidToStringFunc)GetProcAddress(rpcrt, + "UuidToStringA"); + RpcStringFreeFunc rpcStringFree = (RpcStringFreeFunc)GetProcAddress( + rpcrt, "RpcStringFreeA"); + + if (uuidCreate && uuidToString && rpcStringFree) + { + UUID uuid; + RPC_STATUS status = uuidCreate(&uuid); + + if (status == RPC_S_OK || status == RPC_S_UUID_LOCAL_ONLY) + { + unsigned char *uuidStr; + + status = uuidToString(&uuid, &uuidStr); + if (status == RPC_S_OK) + { + BOOL ret = CryptAcquireContextA(&hProv, (LPCSTR)uuidStr, + MS_DEF_PROV_A, PROV_RSA_FULL, CRYPT_NEWKEYSET); + + if (ret) + { + HCRYPTKEY key; + + ret = CryptGenKey(hProv, AT_SIGNATURE, 0, &key); + if (ret) + CryptDestroyKey(key); + } + rpcStringFree(&uuidStr); + } + } + } + FreeLibrary(rpcrt); } - CryptDestroyKey(key); - return prov; + return hProv; }
PCCERT_CONTEXT WINAPI CertCreateSelfSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hProv,
From: Paul Gofman pgofman@codeweavers.com
--- dlls/crypt32/tests/cert.c | 45 +++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 9 deletions(-)
diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c index 83594560efa..ac0987e76bd 100644 --- a/dlls/crypt32/tests/cert.c +++ b/dlls/crypt32/tests/cert.c @@ -2167,17 +2167,44 @@ static void testCreateSelfSignCert(void) HCRYPTPROV csp; BOOL ret; HCRYPTKEY key; - CRYPT_KEY_PROV_INFO info; + CRYPT_KEY_PROV_INFO info, *ret_info; + DWORD size;
/* This crashes: - context = CertCreateSelfSignCertificate(0, NULL, 0, NULL, NULL, NULL, NULL, - NULL); - * Calling this with no first parameter creates a new key container, which - * lasts beyond the test, so I don't test that. Nb: the generated key - * name is a GUID. - context = CertCreateSelfSignCertificate(0, &name, 0, NULL, NULL, NULL, NULL, - NULL); - */ + context = CertCreateSelfSignCertificate(0, NULL, 0, NULL, NULL, NULL, NULL, NULL); */ + + /* Test CSP created by implementation without CSP or CSP parameters provided. */ + context = CertCreateSelfSignCertificate(0, &name, 0, NULL, NULL, NULL, NULL, NULL); + ok(!!context, "failed, error %#lx.\n", GetLastError()); + size = 0; + ret = CertGetCertificateContextProperty(context, CERT_KEY_PROV_INFO_PROP_ID, NULL, &size); + ok(ret, "failed, error %#lx.\n", GetLastError()); + ret_info = malloc(size); + ok(!!ret_info, "memory allocation failed.\n"); + ret = CertGetCertificateContextProperty(context, CERT_KEY_PROV_INFO_PROP_ID, ret_info, &size); + ok(ret, "failed, error %#lx.\n", GetLastError()); + CertFreeCertificateContext(context); + ok(ret_info->dwKeySpec == AT_SIGNATURE, "got %#lx.\n", ret_info->dwKeySpec); + ok(!ret_info->dwFlags, "got %#lx.\n", ret_info->dwFlags); + ok(ret_info->pwszContainerName && *ret_info->pwszContainerName, "got %s.\n", + debugstr_w(ret_info->pwszContainerName)); + ret = CryptAcquireContextW(&csp, ret_info->pwszContainerName, ret_info->pwszProvName, ret_info->dwProvType, 0); + ok(ret, "failed, error %#lx.\n", GetLastError()); + ret = CryptGetUserKey(csp, AT_SIGNATURE, &key); + ok(ret, "failed, error %#lx.\n", GetLastError()); + ret = CryptDestroyKey(key); + ok(ret, "failed, error %#lx.\n", GetLastError()); + ret = CryptGetUserKey(csp, AT_KEYEXCHANGE, &key); + ok(!ret && GetLastError() == NTE_NO_KEY, "got ret %d, error %#lx.\n", ret, GetLastError()); + CryptReleaseContext(csp, 0); + csp = 0xdeadbeef; + ret = CryptAcquireContextW(&csp, ret_info->pwszContainerName, ret_info->pwszProvName, + ret_info->dwProvType, CRYPT_DELETEKEYSET); + ok(ret, "failed, error %#lx.\n", GetLastError()); + ok(!csp, "got %p.\n", (void *)csp); + ret = CryptAcquireContextW(&csp, ret_info->pwszContainerName, ret_info->pwszProvName, ret_info->dwProvType, 0); + ok(!ret && GetLastError() == NTE_BAD_KEYSET, "got ret %d, error %#lx.\n", ret, GetLastError()); + free(ret_info);
/* Acquire a CSP */ CryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
v2: - add a test for this behaviour.
This merge request was approved by Hans Leidekker.