Juan Lang : crypt32: Implement key context property, with tests.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Jul 11 06:10:38 CDT 2006
Module: wine
Branch: refs/heads/master
Commit: 4b8845ae12f944980971440f3f48d1a4701a64e4
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=4b8845ae12f944980971440f3f48d1a4701a64e4
Author: Juan Lang <juan_lang at yahoo.com>
Date: Mon Jul 10 09:10:36 2006 -0700
crypt32: Implement key context property, with tests.
---
dlls/crypt32/cert.c | 109 ++++++++++++++++++++++++++++++++++++++++-----
dlls/crypt32/tests/cert.c | 73 +++++++++++++++++++++++++++---
2 files changed, 163 insertions(+), 19 deletions(-)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c
index eabea82..3af7fa1 100644
--- a/dlls/crypt32/cert.c
+++ b/dlls/crypt32/cert.c
@@ -307,6 +307,40 @@ BOOL WINAPI CertGetCertificateContextPro
ret = TRUE;
}
break;
+ case CERT_KEY_IDENTIFIER_PROP_ID:
+ ret = CertContext_GetProperty((void *)pCertContext, dwPropId,
+ pvData, pcbData);
+ if (!ret)
+ SetLastError(ERROR_INVALID_DATA);
+ break;
+ case CERT_KEY_PROV_HANDLE_PROP_ID:
+ {
+ CERT_KEY_CONTEXT keyContext;
+ DWORD size = sizeof(keyContext);
+
+ ret = CertContext_GetProperty((void *)pCertContext,
+ CERT_KEY_CONTEXT_PROP_ID, &keyContext, &size);
+ if (ret)
+ {
+ if (!pvData)
+ {
+ *pcbData = sizeof(HCRYPTPROV);
+ ret = TRUE;
+ }
+ else if (*pcbData < sizeof(HCRYPTPROV))
+ {
+ SetLastError(ERROR_MORE_DATA);
+ *pcbData = sizeof(HCRYPTPROV);
+ ret = FALSE;
+ }
+ else
+ {
+ *(HCRYPTPROV *)pvData = keyContext.hCryptProv;
+ ret = TRUE;
+ }
+ }
+ break;
+ }
case CERT_KEY_PROV_INFO_PROP_ID:
ret = CertContext_GetProperty((void *)pCertContext, dwPropId, pvData,
pcbData);
@@ -397,11 +431,6 @@ static BOOL WINAPI CertContext_SetProper
if (!properties)
ret = FALSE;
- else if (!pvData)
- {
- ContextPropertyList_RemoveProperty(properties, dwPropId);
- ret = TRUE;
- }
else
{
switch (dwPropId)
@@ -424,20 +453,76 @@ static BOOL WINAPI CertContext_SetProper
case CERT_CROSS_CERT_DIST_POINTS_PROP_ID:
case CERT_RENEWAL_PROP_ID:
{
- PCRYPT_DATA_BLOB blob = (PCRYPT_DATA_BLOB)pvData;
+ if (pvData)
+ {
+ PCRYPT_DATA_BLOB blob = (PCRYPT_DATA_BLOB)pvData;
- ret = ContextPropertyList_SetProperty(properties, dwPropId,
- blob->pbData, blob->cbData);
+ ret = ContextPropertyList_SetProperty(properties, dwPropId,
+ blob->pbData, blob->cbData);
+ }
+ else
+ {
+ ContextPropertyList_RemoveProperty(properties, dwPropId);
+ ret = TRUE;
+ }
break;
}
case CERT_DATE_STAMP_PROP_ID:
- ret = ContextPropertyList_SetProperty(properties, dwPropId,
- (LPBYTE)pvData, sizeof(FILETIME));
+ if (pvData)
+ ret = ContextPropertyList_SetProperty(properties, dwPropId,
+ (LPBYTE)pvData, sizeof(FILETIME));
+ else
+ {
+ ContextPropertyList_RemoveProperty(properties, dwPropId);
+ ret = TRUE;
+ }
+ break;
+ case CERT_KEY_CONTEXT_PROP_ID:
+ {
+ if (pvData)
+ {
+ PCERT_KEY_CONTEXT keyContext = (PCERT_KEY_CONTEXT)pvData;
+
+ ret = ContextPropertyList_SetProperty(properties, dwPropId,
+ (const BYTE *)keyContext, keyContext->cbSize);
+ }
+ else
+ {
+ ContextPropertyList_RemoveProperty(properties, dwPropId);
+ ret = TRUE;
+ }
break;
+ }
case CERT_KEY_PROV_INFO_PROP_ID:
- ret = CertContext_SetKeyProvInfoProperty(properties,
- (PCRYPT_KEY_PROV_INFO)pvData);
+ if (pvData)
+ ret = CertContext_SetKeyProvInfoProperty(properties,
+ (PCRYPT_KEY_PROV_INFO)pvData);
+ else
+ {
+ ContextPropertyList_RemoveProperty(properties, dwPropId);
+ ret = TRUE;
+ }
+ break;
+ case CERT_KEY_PROV_HANDLE_PROP_ID:
+ {
+ CERT_KEY_CONTEXT keyContext;
+ DWORD size = sizeof(keyContext);
+
+ ret = CertContext_GetProperty(context, CERT_KEY_CONTEXT_PROP_ID,
+ &keyContext, &size);
+ if (ret)
+ {
+ if (!(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
+ CryptReleaseContext(keyContext.hCryptProv, 0);
+ if (pvData)
+ keyContext.hCryptProv = *(HCRYPTPROV *)pvData;
+ else
+ keyContext.hCryptProv = 0;
+ ret = CertContext_SetProperty(context, CERT_KEY_CONTEXT_PROP_ID,
+ 0, &keyContext);
+ }
break;
+ }
default:
FIXME("%ld: stub\n", dwPropId);
ret = FALSE;
diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c
index 917236d..b03d61e 100644
--- a/dlls/crypt32/tests/cert.c
+++ b/dlls/crypt32/tests/cert.c
@@ -310,6 +310,9 @@ static void checkHash(const BYTE *data,
propID);
}
+static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
+ 'm','p',0 };
+
static void testCertProperties(void)
{
PCCERT_CONTEXT context = CertCreateCertificateContext(X509_ASN_ENCODING,
@@ -323,6 +326,8 @@ static void testCertProperties(void)
BOOL ret;
BYTE hash[20] = { 0 }, hashProperty[20];
CRYPT_DATA_BLOB blob;
+ CERT_KEY_CONTEXT keyContext;
+ HCRYPTPROV csp;
/* This crashes
propID = CertEnumCertificateContextProperties(NULL, 0);
@@ -425,14 +430,71 @@ static void testCertProperties(void)
context->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData,
CALG_MD5, context, CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID);
- /* Odd: this doesn't fail on other certificates, so there must be
- * something weird about this cert that causes it to fail.
- */
+ /* Test key identifiers and handles and such */
size = 0;
ret = CertGetCertificateContextProperty(context,
CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
- todo_wine ok(!ret && GetLastError() == ERROR_INVALID_DATA,
+ ok(!ret && GetLastError() == ERROR_INVALID_DATA,
+ "Expected ERROR_INVALID_DATA, got %08lx\n", GetLastError());
+ size = sizeof(CERT_KEY_CONTEXT);
+ ret = CertGetCertificateContextProperty(context,
+ CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
+ ok(!ret && GetLastError() == ERROR_INVALID_DATA,
+ "Expected ERROR_INVALID_DATA, got %08lx\n", GetLastError());
+ ret = CertGetCertificateContextProperty(context,
+ CERT_KEY_IDENTIFIER_PROP_ID, &keyContext, &size);
+ ok(!ret && GetLastError() == ERROR_INVALID_DATA,
"Expected ERROR_INVALID_DATA, got %08lx\n", GetLastError());
+ /* Key context with an invalid size */
+ keyContext.cbSize = 0;
+ ret = CertSetCertificateContextProperty(context,
+ CERT_KEY_IDENTIFIER_PROP_ID, 0, &keyContext);
+ ok(ret, "CertSetCertificateContextProperty failed: %08lx\n",
+ GetLastError());
+ size = sizeof(keyContext);
+ ret = CertGetCertificateContextProperty(context,
+ CERT_KEY_IDENTIFIER_PROP_ID, &keyContext, &size);
+ ok(ret, "CertGetCertificateContextProperty failed: %08lx\n",
+ GetLastError());
+ keyContext.cbSize = sizeof(keyContext);
+ keyContext.hCryptProv = 0;
+ keyContext.dwKeySpec = AT_SIGNATURE;
+ /* Crash
+ ret = CertSetCertificateContextProperty(context,
+ CERT_KEY_IDENTIFIER_PROP_ID, 0, &keyContext);
+ ret = CertSetCertificateContextProperty(context,
+ CERT_KEY_IDENTIFIER_PROP_ID, CERT_STORE_NO_CRYPT_RELEASE_FLAG,
+ &keyContext);
+ */
+ ret = CryptAcquireContextW(&csp, cspNameW,
+ MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_NEWKEYSET);
+ ok(ret, "CryptAcquireContextW failed: %08lx\n", GetLastError());
+ keyContext.hCryptProv = csp;
+ ret = CertSetCertificateContextProperty(context,
+ CERT_KEY_CONTEXT_PROP_ID, 0, &keyContext);
+ ok(ret, "CertSetCertificateContextProperty failed: %08lx\n",
+ GetLastError());
+ /* Now that that's set, the key prov handle property is also gettable.
+ */
+ size = sizeof(DWORD);
+ ret = CertGetCertificateContextProperty(context,
+ CERT_KEY_PROV_HANDLE_PROP_ID, &keyContext.hCryptProv, &size);
+ ok(ret, "Expected to get the CERT_KEY_PROV_HANDLE_PROP_ID, got %08lx\n",
+ GetLastError());
+ /* Remove the key prov handle property.. */
+ ret = CertSetCertificateContextProperty(context,
+ CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL);
+ ok(ret, "CertSetCertificateContextProperty failed: %08lx\n",
+ GetLastError());
+ /* and the key context's CSP is set to NULL. */
+ size = sizeof(keyContext);
+ ret = CertGetCertificateContextProperty(context,
+ CERT_KEY_CONTEXT_PROP_ID, &keyContext, &size);
+ ok(ret, "CertGetCertificateContextProperty failed: %08lx\n",
+ GetLastError());
+ ok(keyContext.hCryptProv == 0, "Expected no hCryptProv\n");
+
+ CryptReleaseContext(csp, 0);
CertFreeCertificateContext(context);
}
@@ -799,9 +861,6 @@ static void testCryptHashCert(void)
ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n");
}
-static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
- 'm','p',0 };
-
static void verifySig(HCRYPTPROV csp, const BYTE *toSign, size_t toSignLen,
const BYTE *sig, unsigned int sigLen)
{
More information about the wine-cvs
mailing list