crypt32: Implement more implicit properties, with tests.
This commit is contained in:
parent
33832c95d8
commit
a67b6f49ec
|
@ -1877,6 +1877,22 @@ DWORD WINAPI CertEnumCertificateContextProperties(PCCERT_CONTEXT pCertContext,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL CRYPT_GetCertHashProp(PWINE_CERT_CONTEXT context, DWORD dwPropId,
|
||||||
|
ALG_ID algID, const BYTE *toHash, DWORD toHashLen, void *pvData,
|
||||||
|
DWORD *pcbData)
|
||||||
|
{
|
||||||
|
BOOL ret = CryptHashCertificate(0, algID, 0, toHash, toHashLen, pvData,
|
||||||
|
pcbData);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
CRYPT_DATA_BLOB blob = { *pcbData, pvData };
|
||||||
|
|
||||||
|
ret = CRYPT_SetCertificateContextProperty(context, dwPropId,
|
||||||
|
0, &blob);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL WINAPI CRYPT_GetCertificateContextProperty(
|
static BOOL WINAPI CRYPT_GetCertificateContextProperty(
|
||||||
PWINE_CERT_CONTEXT context, DWORD dwPropId, void *pvData, DWORD *pcbData)
|
PWINE_CERT_CONTEXT context, DWORD dwPropId, void *pvData, DWORD *pcbData)
|
||||||
{
|
{
|
||||||
|
@ -1919,26 +1935,34 @@ static BOOL WINAPI CRYPT_GetCertificateContextProperty(
|
||||||
switch (dwPropId)
|
switch (dwPropId)
|
||||||
{
|
{
|
||||||
case CERT_SHA1_HASH_PROP_ID:
|
case CERT_SHA1_HASH_PROP_ID:
|
||||||
ret = CryptHashCertificate(0, CALG_SHA1, 0,
|
ret = CRYPT_GetCertHashProp(context, dwPropId, CALG_SHA1,
|
||||||
context->cert.pbCertEncoded, context->cert.cbCertEncoded, pvData,
|
context->cert.pbCertEncoded, context->cert.cbCertEncoded, pvData,
|
||||||
pcbData);
|
pcbData);
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
CRYPT_DATA_BLOB blob = { *pcbData, pvData };
|
|
||||||
|
|
||||||
ret = CRYPT_SetCertificateContextProperty(context, dwPropId,
|
|
||||||
0, &blob);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case CERT_KEY_PROV_INFO_PROP_ID:
|
|
||||||
case CERT_MD5_HASH_PROP_ID:
|
case CERT_MD5_HASH_PROP_ID:
|
||||||
case CERT_SIGNATURE_HASH_PROP_ID:
|
ret = CRYPT_GetCertHashProp(context, dwPropId, CALG_MD5,
|
||||||
case CERT_KEY_IDENTIFIER_PROP_ID:
|
context->cert.pbCertEncoded, context->cert.cbCertEncoded, pvData,
|
||||||
case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID:
|
pcbData);
|
||||||
case CERT_ISSUER_SERIAL_NUMBER_MD5_HASH_PROP_ID:
|
|
||||||
case CERT_SUBJECT_NAME_MD5_HASH_PROP_ID:
|
|
||||||
FIXME("implicit property %ld\n", dwPropId);
|
|
||||||
break;
|
break;
|
||||||
|
case CERT_SUBJECT_NAME_MD5_HASH_PROP_ID:
|
||||||
|
ret = CRYPT_GetCertHashProp(context, dwPropId, CALG_MD5,
|
||||||
|
context->cert.pCertInfo->Subject.pbData,
|
||||||
|
context->cert.pCertInfo->Subject.cbData,
|
||||||
|
pvData, pcbData);
|
||||||
|
break;
|
||||||
|
case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID:
|
||||||
|
ret = CRYPT_GetCertHashProp(context, dwPropId, CALG_MD5,
|
||||||
|
context->cert.pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
|
||||||
|
context->cert.pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData,
|
||||||
|
pvData, pcbData);
|
||||||
|
break;
|
||||||
|
case CERT_SIGNATURE_HASH_PROP_ID:
|
||||||
|
case CERT_ISSUER_SERIAL_NUMBER_MD5_HASH_PROP_ID:
|
||||||
|
FIXME("implicit property %ld\n", dwPropId);
|
||||||
|
SetLastError(CRYPT_E_NOT_FOUND);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SetLastError(CRYPT_E_NOT_FOUND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&context->cs);
|
LeaveCriticalSection(&context->cs);
|
||||||
|
@ -2100,6 +2124,7 @@ static BOOL WINAPI CRYPT_SetCertificateContextProperty(
|
||||||
case CERT_PVK_FILE_PROP_ID:
|
case CERT_PVK_FILE_PROP_ID:
|
||||||
case CERT_SIGNATURE_HASH_PROP_ID:
|
case CERT_SIGNATURE_HASH_PROP_ID:
|
||||||
case CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID:
|
case CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID:
|
||||||
|
case CERT_SUBJECT_NAME_MD5_HASH_PROP_ID:
|
||||||
case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID:
|
case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID:
|
||||||
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:
|
||||||
|
|
|
@ -1100,6 +1100,26 @@ static void testCertOpenSystemStore(void)
|
||||||
RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW);
|
RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void checkHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
|
||||||
|
PCCERT_CONTEXT context, DWORD propID)
|
||||||
|
{
|
||||||
|
BYTE hash[20] = { 0 }, hashProperty[20];
|
||||||
|
BOOL ret;
|
||||||
|
DWORD size;
|
||||||
|
|
||||||
|
memset(hash, 0, sizeof(hash));
|
||||||
|
memset(hashProperty, 0, sizeof(hashProperty));
|
||||||
|
size = sizeof(hash);
|
||||||
|
ret = CryptHashCertificate(0, algID, 0, data, dataLen, hash, &size);
|
||||||
|
ok(ret, "CryptHashCertificate failed: %08lx\n", GetLastError());
|
||||||
|
ret = CertGetCertificateContextProperty(context, propID, hashProperty,
|
||||||
|
&size);
|
||||||
|
ok(ret, "CertGetCertificateContextProperty failed: %08lx\n",
|
||||||
|
GetLastError());
|
||||||
|
ok(!memcmp(hash, hashProperty, size), "Unexpected hash for property %ld\n",
|
||||||
|
propID);
|
||||||
|
}
|
||||||
|
|
||||||
static void testCertProperties(void)
|
static void testCertProperties(void)
|
||||||
{
|
{
|
||||||
PCCERT_CONTEXT context = CertCreateCertificateContext(X509_ASN_ENCODING,
|
PCCERT_CONTEXT context = CertCreateCertificateContext(X509_ASN_ENCODING,
|
||||||
|
@ -1148,10 +1168,21 @@ static void testCertProperties(void)
|
||||||
CERT_CERT_PROP_ID, 0, bigCert2);
|
CERT_CERT_PROP_ID, 0, bigCert2);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* This crashes.
|
/* These all crash.
|
||||||
ret = CertGetCertificateContextProperty(context,
|
ret = CertGetCertificateContextProperty(context,
|
||||||
CERT_ACCESS_STATE_PROP_ID, 0, NULL);
|
CERT_ACCESS_STATE_PROP_ID, 0, NULL);
|
||||||
|
ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
|
||||||
|
NULL, NULL);
|
||||||
|
ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
|
||||||
|
hashProperty, NULL);
|
||||||
*/
|
*/
|
||||||
|
/* A missing prop */
|
||||||
|
size = 0;
|
||||||
|
ret = CertGetCertificateContextProperty(context,
|
||||||
|
CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
|
||||||
|
ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
|
||||||
|
"Expected CRYPT_E_NOT_FOUND, got %08lx\n", GetLastError());
|
||||||
|
/* And, an implicit property */
|
||||||
size = sizeof(access);
|
size = sizeof(access);
|
||||||
ret = CertGetCertificateContextProperty(context,
|
ret = CertGetCertificateContextProperty(context,
|
||||||
CERT_ACCESS_STATE_PROP_ID, &access, &size);
|
CERT_ACCESS_STATE_PROP_ID, &access, &size);
|
||||||
|
@ -1181,15 +1212,8 @@ static void testCertProperties(void)
|
||||||
NULL);
|
NULL);
|
||||||
ok(ret, "CertSetCertificateContextProperty failed: %08lx\n",
|
ok(ret, "CertSetCertificateContextProperty failed: %08lx\n",
|
||||||
GetLastError());
|
GetLastError());
|
||||||
size = sizeof(hash);
|
checkHash(bigCert, sizeof(bigCert) - 1, CALG_SHA1, context,
|
||||||
ret = CryptHashCertificate(0, 0, 0, bigCert, sizeof(bigCert) - 1,
|
CERT_HASH_PROP_ID);
|
||||||
hash, &size);
|
|
||||||
ok(ret, "CryptHashCertificate failed: %08lx\n", GetLastError());
|
|
||||||
ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
|
|
||||||
hashProperty, &size);
|
|
||||||
ok(ret, "CertGetCertificateContextProperty failed: %08lx\n",
|
|
||||||
GetLastError());
|
|
||||||
ok(!memcmp(hash, hashProperty, sizeof(hash)), "Unexpected hash\n");
|
|
||||||
|
|
||||||
/* Now that the hash property is set, we should get one property when
|
/* Now that the hash property is set, we should get one property when
|
||||||
* enumerating.
|
* enumerating.
|
||||||
|
@ -1203,6 +1227,27 @@ static void testCertProperties(void)
|
||||||
} while (propID != 0);
|
} while (propID != 0);
|
||||||
ok(numProps == 1, "Expected 1 properties, got %ld\n", numProps);
|
ok(numProps == 1, "Expected 1 properties, got %ld\n", numProps);
|
||||||
|
|
||||||
|
/* Check a few other implicit properties */
|
||||||
|
checkHash(bigCert, sizeof(bigCert) - 1, CALG_MD5, context,
|
||||||
|
CERT_MD5_HASH_PROP_ID);
|
||||||
|
checkHash(
|
||||||
|
context->pCertInfo->Subject.pbData,
|
||||||
|
context->pCertInfo->Subject.cbData,
|
||||||
|
CALG_MD5, context, CERT_SUBJECT_NAME_MD5_HASH_PROP_ID);
|
||||||
|
checkHash(
|
||||||
|
context->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
size = 0;
|
||||||
|
ret = CertGetCertificateContextProperty(context,
|
||||||
|
CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
|
||||||
|
todo_wine ok(!ret && GetLastError() == ERROR_INVALID_DATA,
|
||||||
|
"Expected ERROR_INVALID_DATA, got %08lx\n", GetLastError());
|
||||||
|
|
||||||
CertFreeCertificateContext(context);
|
CertFreeCertificateContext(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue