crypt32: Implement key context property, with tests.
This commit is contained in:
parent
ac857cb31a
commit
4b8845ae12
|
@ -307,6 +307,40 @@ BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext,
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case CERT_KEY_PROV_INFO_PROP_ID:
|
||||||
ret = CertContext_GetProperty((void *)pCertContext, dwPropId, pvData,
|
ret = CertContext_GetProperty((void *)pCertContext, dwPropId, pvData,
|
||||||
pcbData);
|
pcbData);
|
||||||
|
@ -397,11 +431,6 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId,
|
||||||
|
|
||||||
if (!properties)
|
if (!properties)
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
else if (!pvData)
|
|
||||||
{
|
|
||||||
ContextPropertyList_RemoveProperty(properties, dwPropId);
|
|
||||||
ret = TRUE;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (dwPropId)
|
switch (dwPropId)
|
||||||
|
@ -423,21 +452,77 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId,
|
||||||
case CERT_ENROLLMENT_PROP_ID:
|
case CERT_ENROLLMENT_PROP_ID:
|
||||||
case CERT_CROSS_CERT_DIST_POINTS_PROP_ID:
|
case CERT_CROSS_CERT_DIST_POINTS_PROP_ID:
|
||||||
case CERT_RENEWAL_PROP_ID:
|
case CERT_RENEWAL_PROP_ID:
|
||||||
|
{
|
||||||
|
if (pvData)
|
||||||
{
|
{
|
||||||
PCRYPT_DATA_BLOB blob = (PCRYPT_DATA_BLOB)pvData;
|
PCRYPT_DATA_BLOB blob = (PCRYPT_DATA_BLOB)pvData;
|
||||||
|
|
||||||
ret = ContextPropertyList_SetProperty(properties, dwPropId,
|
ret = ContextPropertyList_SetProperty(properties, dwPropId,
|
||||||
blob->pbData, blob->cbData);
|
blob->pbData, blob->cbData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ContextPropertyList_RemoveProperty(properties, dwPropId);
|
||||||
|
ret = TRUE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CERT_DATE_STAMP_PROP_ID:
|
case CERT_DATE_STAMP_PROP_ID:
|
||||||
|
if (pvData)
|
||||||
ret = ContextPropertyList_SetProperty(properties, dwPropId,
|
ret = ContextPropertyList_SetProperty(properties, dwPropId,
|
||||||
(LPBYTE)pvData, sizeof(FILETIME));
|
(LPBYTE)pvData, sizeof(FILETIME));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ContextPropertyList_RemoveProperty(properties, dwPropId);
|
||||||
|
ret = TRUE;
|
||||||
|
}
|
||||||
break;
|
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:
|
case CERT_KEY_PROV_INFO_PROP_ID:
|
||||||
|
if (pvData)
|
||||||
ret = CertContext_SetKeyProvInfoProperty(properties,
|
ret = CertContext_SetKeyProvInfoProperty(properties,
|
||||||
(PCRYPT_KEY_PROV_INFO)pvData);
|
(PCRYPT_KEY_PROV_INFO)pvData);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ContextPropertyList_RemoveProperty(properties, dwPropId);
|
||||||
|
ret = TRUE;
|
||||||
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
FIXME("%ld: stub\n", dwPropId);
|
FIXME("%ld: stub\n", dwPropId);
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
|
|
|
@ -310,6 +310,9 @@ static void checkHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
|
||||||
propID);
|
propID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
|
||||||
|
'm','p',0 };
|
||||||
|
|
||||||
static void testCertProperties(void)
|
static void testCertProperties(void)
|
||||||
{
|
{
|
||||||
PCCERT_CONTEXT context = CertCreateCertificateContext(X509_ASN_ENCODING,
|
PCCERT_CONTEXT context = CertCreateCertificateContext(X509_ASN_ENCODING,
|
||||||
|
@ -323,6 +326,8 @@ static void testCertProperties(void)
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
BYTE hash[20] = { 0 }, hashProperty[20];
|
BYTE hash[20] = { 0 }, hashProperty[20];
|
||||||
CRYPT_DATA_BLOB blob;
|
CRYPT_DATA_BLOB blob;
|
||||||
|
CERT_KEY_CONTEXT keyContext;
|
||||||
|
HCRYPTPROV csp;
|
||||||
|
|
||||||
/* This crashes
|
/* This crashes
|
||||||
propID = CertEnumCertificateContextProperties(NULL, 0);
|
propID = CertEnumCertificateContextProperties(NULL, 0);
|
||||||
|
@ -425,14 +430,71 @@ static void testCertProperties(void)
|
||||||
context->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData,
|
context->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData,
|
||||||
CALG_MD5, context, CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID);
|
CALG_MD5, context, CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID);
|
||||||
|
|
||||||
/* Odd: this doesn't fail on other certificates, so there must be
|
/* Test key identifiers and handles and such */
|
||||||
* something weird about this cert that causes it to fail.
|
|
||||||
*/
|
|
||||||
size = 0;
|
size = 0;
|
||||||
ret = CertGetCertificateContextProperty(context,
|
ret = CertGetCertificateContextProperty(context,
|
||||||
CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
|
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());
|
"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);
|
CertFreeCertificateContext(context);
|
||||||
}
|
}
|
||||||
|
@ -799,9 +861,6 @@ static void testCryptHashCert(void)
|
||||||
ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n");
|
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,
|
static void verifySig(HCRYPTPROV csp, const BYTE *toSign, size_t toSignLen,
|
||||||
const BYTE *sig, unsigned int sigLen)
|
const BYTE *sig, unsigned int sigLen)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue