advapi32: Allow setting CRYPT_VERIFYCONTEXT and CRYPT_NEWKEYSET in CryptAcquireContext

Maarten Lankhorst m.b.lankhorst at gmail.com
Tue Jun 12 12:46:48 CDT 2007


With tests. I think this is the correct way to do this: First try to
Acquire with CRYPT_NEWKEYSET, then CRYPT_VERIFYCONTEXT if it already exists.
-------------- next part --------------
>From bfc53884a2ce5865628715aec39a60de5199866a Mon Sep 17 00:00:00 2001
From: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date: Tue, 12 Jun 2007 19:41:44 +0200
Subject: [PATCH] advapi32: Allow setting CRYPT_VERIFYCONTEXT and CRYPT_NEWKEYSET in CryptAcquireContext

---
 dlls/advapi32/crypt.c       |   19 ++++++++++++++++++-
 dlls/advapi32/tests/crypt.c |   19 +++++++++++++++++++
 2 files changed, 37 insertions(+), 1 deletions(-)

diff --git a/dlls/advapi32/crypt.c b/dlls/advapi32/crypt.c
index a7273b9..d2d5462 100644
--- a/dlls/advapi32/crypt.c
+++ b/dlls/advapi32/crypt.c
@@ -290,6 +290,8 @@ BOOL WINAPI CryptAcquireContextW (HCRYPTPROV *phProv, LPCWSTR pszContainer,
 	PSTR provnameA = NULL, pszContainerA = NULL;
 	DWORD keytype, type, len;
 	ULONG r;
+	BOOL ret;
+
 	static const WCHAR nameW[] = {'N','a','m','e',0};
 	static const WCHAR typeW[] = {'T','y','p','e',0};
 	static const WCHAR imagepathW[] = {'I','m','a','g','e',' ','P','a','t','h',0};
@@ -442,7 +444,22 @@ BOOL WINAPI CryptAcquireContextW (HCRYPTPROV *phProv, LPCWSTR pszContainer,
 		/* CRYPT_UnicodeToANSI calls SetLastError */
 		goto error;
 	}
-	if (pProv->pFuncs->pCPAcquireContext(&pProv->hPrivate, pszContainerA, dwFlags, pProv->pVTable))
+
+	if (dwFlags & CRYPT_VERIFYCONTEXT && dwFlags & CRYPT_NEWKEYSET)
+	{
+		if (pszContainer)
+		{
+			SetLastError(NTE_BAD_FLAGS);
+			goto error;
+		}
+		ret = pProv->pFuncs->pCPAcquireContext(&pProv->hPrivate, pszContainerA, dwFlags & ~CRYPT_VERIFYCONTEXT, pProv->pVTable);
+		if (!ret && GetLastError() == NTE_EXISTS)
+			ret = pProv->pFuncs->pCPAcquireContext(&pProv->hPrivate, pszContainerA, dwFlags & ~CRYPT_NEWKEYSET, pProv->pVTable);
+	}
+	else
+		ret = pProv->pFuncs->pCPAcquireContext(&pProv->hPrivate, pszContainerA, dwFlags, pProv->pVTable);
+
+	if (ret)
 	{
 		/* MSDN: When this flag is set, the value returned in phProv is undefined,
 		 *       and thus, the CryptReleaseContext function need not be called afterwards.
diff --git a/dlls/advapi32/tests/crypt.c b/dlls/advapi32/tests/crypt.c
index def6c82..458fe8b 100644
--- a/dlls/advapi32/tests/crypt.c
+++ b/dlls/advapi32/tests/crypt.c
@@ -193,6 +193,25 @@ static void test_acquire_context(void)
 	if (hProv) 
 		pCryptReleaseContext(hProv, 0);
 
+	SetLastError(0xdeadbeef);
+	result = pCryptAcquireContextA(&hProv, NULL, szRsaBaseProv, PROV_RSA_FULL, CRYPT_NEWKEYSET|CRYPT_VERIFYCONTEXT);
+	GLE = GetLastError();
+	ok(result && (GLE == ERROR_ENVVAR_NOT_FOUND   || 
+		      GLE == ERROR_SUCCESS            || 
+		      GLE == ERROR_RING2_STACK_IN_USE || 
+		      GLE == NTE_FAIL                 ||
+		      GLE == ERROR_NOT_LOGGED_ON), "%d/%08x\n", result, GLE);
+	if (hProv) 
+		pCryptReleaseContext(hProv, 0);
+
+	SetLastError(0xdeadbeef);
+	result = pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_NEWKEYSET|CRYPT_VERIFYCONTEXT);
+	GLE = GetLastError();
+	ok(!result && (GLE == NTE_BAD_FLAGS), "%d/%08x\n", result, GLE);
+	if (hProv) 
+		pCryptReleaseContext(hProv, 0);
+
+
 	/* Try again, witch an empty ("\0") szProvider parameter */
 	hProv = 0;
 	SetLastError(0xdeadbeef);
-- 
1.4.4.2



More information about the wine-patches mailing list