Module: wine Branch: master Commit: 3740e4150ba3f9333ca701d346422bcce8106329 URL: http://source.winehq.org/git/wine.git/?a=commit;h=3740e4150ba3f9333ca701d346...
Author: Juan Lang juan.lang@gmail.com Date: Thu Oct 15 11:14:23 2009 -0700
crypt32: Avoid repeatedly decoding authority key id extensions when searching for a cert's issuer.
---
dlls/crypt32/cert.c | 148 +++++++++++++++++++++++++-------------------------- 1 files changed, 73 insertions(+), 75 deletions(-)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c index 618c578..281f55f 100644 --- a/dlls/crypt32/cert.c +++ b/dlls/crypt32/cert.c @@ -1261,11 +1261,70 @@ static BOOL compare_cert_by_cert_id(PCCERT_CONTEXT pCertContext, DWORD dwType, return ret; }
-static BOOL compare_cert_by_issuer(PCCERT_CONTEXT pCertContext, DWORD dwType, +static BOOL compare_existing_cert(PCCERT_CONTEXT pCertContext, DWORD dwType, + DWORD dwFlags, const void *pvPara) +{ + PCCERT_CONTEXT toCompare = pvPara; + return CertCompareCertificate(pCertContext->dwCertEncodingType, + pCertContext->pCertInfo, toCompare->pCertInfo); +} + +static BOOL compare_cert_by_signature_hash(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, const void *pvPara) { - BOOL ret = FALSE; - PCCERT_CONTEXT subject = pvPara; + const CRYPT_HASH_BLOB *hash = pvPara; + DWORD size = 0; + BOOL ret; + + ret = CertGetCertificateContextProperty(pCertContext, + CERT_SIGNATURE_HASH_PROP_ID, NULL, &size); + if (ret && size == hash->cbData) + { + LPBYTE buf = CryptMemAlloc(size); + + if (buf) + { + CertGetCertificateContextProperty(pCertContext, + CERT_SIGNATURE_HASH_PROP_ID, buf, &size); + ret = !memcmp(buf, hash->pbData, size); + CryptMemFree(buf); + } + } + else + ret = FALSE; + return ret; +} + +static inline PCCERT_CONTEXT cert_compare_certs_in_store(HCERTSTORE store, + PCCERT_CONTEXT prev, CertCompareFunc compare, DWORD dwType, DWORD dwFlags, + const void *pvPara) +{ + BOOL matches = FALSE; + PCCERT_CONTEXT ret; + + ret = prev; + do { + ret = CertEnumCertificatesInStore(store, ret); + if (ret) + matches = compare(ret, dwType, dwFlags, pvPara); + } while (ret != NULL && !matches); + return ret; +} + +typedef PCCERT_CONTEXT (*CertFindFunc)(HCERTSTORE store, DWORD dwType, + DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev); + +static PCCERT_CONTEXT find_cert_any(HCERTSTORE store, DWORD dwType, + DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev) +{ + return CertEnumCertificatesInStore(store, prev); +} + +static PCCERT_CONTEXT find_cert_by_issuer(HCERTSTORE store, DWORD dwType, + DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev) +{ + BOOL ret; + PCCERT_CONTEXT found = NULL, subject = pvPara; PCERT_EXTENSION ext; DWORD size;
@@ -1289,18 +1348,17 @@ static BOOL compare_cert_by_issuer(PCCERT_CONTEXT pCertContext, DWORD dwType, sizeof(CERT_NAME_BLOB)); memcpy(&id.u.IssuerSerialNumber.SerialNumber, &info->CertSerialNumber, sizeof(CRYPT_INTEGER_BLOB)); - ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags, - &id); } else if (info->KeyId.cbData) { id.dwIdChoice = CERT_ID_KEY_IDENTIFIER; memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB)); - ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags, - &id); } else ret = FALSE; + if (ret) + found = cert_compare_certs_in_store(store, prev, + compare_cert_by_cert_id, dwType, dwFlags, &id); LocalFree(info); } } @@ -1337,8 +1395,6 @@ static BOOL compare_cert_by_issuer(PCCERT_CONTEXT pCertContext, DWORD dwType, memcpy(&id.u.IssuerSerialNumber.SerialNumber, &info->AuthorityCertSerialNumber, sizeof(CRYPT_INTEGER_BLOB)); - ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags, - &id); } else { @@ -1350,78 +1406,20 @@ static BOOL compare_cert_by_issuer(PCCERT_CONTEXT pCertContext, DWORD dwType, { id.dwIdChoice = CERT_ID_KEY_IDENTIFIER; memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB)); - ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags, - &id); } else ret = FALSE; + if (ret) + found = cert_compare_certs_in_store(store, prev, + compare_cert_by_cert_id, dwType, dwFlags, &id); LocalFree(info); } } else - ret = compare_cert_by_name(pCertContext, - CERT_COMPARE_NAME | CERT_COMPARE_SUBJECT_CERT, dwFlags, - &subject->pCertInfo->Issuer); - return ret; -} - -static BOOL compare_existing_cert(PCCERT_CONTEXT pCertContext, DWORD dwType, - DWORD dwFlags, const void *pvPara) -{ - PCCERT_CONTEXT toCompare = pvPara; - return CertCompareCertificate(pCertContext->dwCertEncodingType, - pCertContext->pCertInfo, toCompare->pCertInfo); -} - -static BOOL compare_cert_by_signature_hash(PCCERT_CONTEXT pCertContext, DWORD dwType, - DWORD dwFlags, const void *pvPara) -{ - const CRYPT_HASH_BLOB *hash = pvPara; - DWORD size = 0; - BOOL ret; - - ret = CertGetCertificateContextProperty(pCertContext, - CERT_SIGNATURE_HASH_PROP_ID, NULL, &size); - if (ret && size == hash->cbData) - { - LPBYTE buf = CryptMemAlloc(size); - - if (buf) - { - CertGetCertificateContextProperty(pCertContext, - CERT_SIGNATURE_HASH_PROP_ID, buf, &size); - ret = !memcmp(buf, hash->pbData, size); - CryptMemFree(buf); - } - } - else - ret = FALSE; - return ret; -} - -static inline PCCERT_CONTEXT cert_compare_certs_in_store(HCERTSTORE store, - PCCERT_CONTEXT prev, CertCompareFunc compare, DWORD dwType, DWORD dwFlags, - const void *pvPara) -{ - BOOL matches = FALSE; - PCCERT_CONTEXT ret; - - ret = prev; - do { - ret = CertEnumCertificatesInStore(store, ret); - if (ret) - matches = compare(ret, dwType, dwFlags, pvPara); - } while (ret != NULL && !matches); - return ret; -} - -typedef PCCERT_CONTEXT (*CertFindFunc)(HCERTSTORE store, DWORD dwType, - DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev); - -static PCCERT_CONTEXT find_cert_any(HCERTSTORE store, DWORD dwType, - DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev) -{ - return CertEnumCertificatesInStore(store, prev); + found = cert_compare_certs_in_store(store, prev, + compare_cert_by_name, CERT_COMPARE_NAME | CERT_COMPARE_SUBJECT_CERT, + dwFlags, &subject->pCertInfo->Issuer); + return found; }
PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, @@ -1459,7 +1457,7 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, compare = compare_cert_by_cert_id; break; case CERT_COMPARE_ISSUER_OF: - compare = compare_cert_by_issuer; + find = find_cert_by_issuer; break; case CERT_COMPARE_EXISTING: compare = compare_existing_cert;