crypt32: Implement key context property, with tests.

This commit is contained in:
Juan Lang 2006-07-10 09:10:36 -07:00 committed by Alexandre Julliard
parent ac857cb31a
commit 4b8845ae12
2 changed files with 163 additions and 19 deletions

View File

@ -307,6 +307,40 @@ BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext,
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_SetProperty(void *context, DWORD dwPropId,
if (!properties)
ret = FALSE;
else if (!pvData)
{
ContextPropertyList_RemoveProperty(properties, dwPropId);
ret = TRUE;
}
else
{
switch (dwPropId)
@ -424,20 +453,76 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId,
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;

View File

@ -310,6 +310,9 @@ static void checkHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
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)
{