Juan Lang : crypt32: Avoid repeatedly decoding authority key id extensions when searching for a cert 's issuer.
Alexandre Julliard
julliard at winehq.org
Mon Oct 19 09:56:07 CDT 2009
Module: wine
Branch: master
Commit: 3740e4150ba3f9333ca701d346422bcce8106329
URL: http://source.winehq.org/git/wine.git/?a=commit;h=3740e4150ba3f9333ca701d346422bcce8106329
Author: Juan Lang <juan.lang at 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;
More information about the wine-cvs
mailing list