Module: wine Branch: refs/heads/master Commit: a67b6f49ecc8beefe91f91ce9e2b26e8414d93f6 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=a67b6f49ecc8beefe91f91ce...
Author: Juan Lang juan_lang@yahoo.com Date: Sat Dec 17 12:24:59 2005 +0100
crypt32: Implement more implicit properties, with tests.
---
dlls/crypt32/cert.c | 49 ++++++++++++++++++++++++++-------- dlls/crypt32/tests/cert.c | 65 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 92 insertions(+), 22 deletions(-)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c index 4911090..4f822d1 100644 --- a/dlls/crypt32/cert.c +++ b/dlls/crypt32/cert.c @@ -1877,6 +1877,22 @@ DWORD WINAPI CertEnumCertificateContextP 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( PWINE_CERT_CONTEXT context, DWORD dwPropId, void *pvData, DWORD *pcbData) { @@ -1919,26 +1935,34 @@ static BOOL WINAPI CRYPT_GetCertificateC switch (dwPropId) { 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, pcbData); - if (ret) - { - CRYPT_DATA_BLOB blob = { *pcbData, pvData }; - - ret = CRYPT_SetCertificateContextProperty(context, dwPropId, - 0, &blob); - } break; - case CERT_KEY_PROV_INFO_PROP_ID: case CERT_MD5_HASH_PROP_ID: - case CERT_SIGNATURE_HASH_PROP_ID: - case CERT_KEY_IDENTIFIER_PROP_ID: + ret = CRYPT_GetCertHashProp(context, dwPropId, CALG_MD5, + context->cert.pbCertEncoded, context->cert.cbCertEncoded, pvData, + pcbData); + 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: - case CERT_SUBJECT_NAME_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); @@ -2100,6 +2124,7 @@ static BOOL WINAPI CRYPT_SetCertificateC case CERT_PVK_FILE_PROP_ID: case CERT_SIGNATURE_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_ENROLLMENT_PROP_ID: case CERT_CROSS_CERT_DIST_POINTS_PROP_ID: diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c index a2c2b15..3ce36fb 100644 --- a/dlls/crypt32/tests/cert.c +++ b/dlls/crypt32/tests/cert.c @@ -1100,6 +1100,26 @@ static void testCertOpenSystemStore(void 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) { PCCERT_CONTEXT context = CertCreateCertificateContext(X509_ASN_ENCODING, @@ -1148,10 +1168,21 @@ static void testCertProperties(void) CERT_CERT_PROP_ID, 0, bigCert2); */
- /* This crashes. + /* These all crash. ret = CertGetCertificateContextProperty(context, 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); ret = CertGetCertificateContextProperty(context, CERT_ACCESS_STATE_PROP_ID, &access, &size); @@ -1181,15 +1212,8 @@ static void testCertProperties(void) NULL); ok(ret, "CertSetCertificateContextProperty failed: %08lx\n", GetLastError()); - size = sizeof(hash); - ret = CryptHashCertificate(0, 0, 0, bigCert, sizeof(bigCert) - 1, - 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"); + checkHash(bigCert, sizeof(bigCert) - 1, CALG_SHA1, context, + CERT_HASH_PROP_ID);
/* Now that the hash property is set, we should get one property when * enumerating. @@ -1203,6 +1227,27 @@ static void testCertProperties(void) } while (propID != 0); 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); } }