crypt32: Move CertFindCertificateInStore and related functions to cert.c.
This commit is contained in:
parent
d9a027952d
commit
b564ef5b03
|
@ -117,6 +117,209 @@ BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType,
|
|||
return ret;
|
||||
}
|
||||
|
||||
typedef BOOL (*CertCompareFunc)(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
||||
DWORD dwFlags, const void *pvPara);
|
||||
|
||||
static BOOL compare_cert_any(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL compare_cert_by_md5_hash(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
BOOL ret;
|
||||
BYTE hash[16];
|
||||
DWORD size = sizeof(hash);
|
||||
|
||||
ret = CertGetCertificateContextProperty(pCertContext,
|
||||
CERT_MD5_HASH_PROP_ID, hash, &size);
|
||||
if (ret)
|
||||
{
|
||||
const CRYPT_HASH_BLOB *pHash = (const CRYPT_HASH_BLOB *)pvPara;
|
||||
|
||||
if (size == pHash->cbData)
|
||||
ret = !memcmp(pHash->pbData, hash, size);
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL compare_cert_by_sha1_hash(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
BOOL ret;
|
||||
BYTE hash[20];
|
||||
DWORD size = sizeof(hash);
|
||||
|
||||
ret = CertGetCertificateContextProperty(pCertContext,
|
||||
CERT_SHA1_HASH_PROP_ID, hash, &size);
|
||||
if (ret)
|
||||
{
|
||||
const CRYPT_HASH_BLOB *pHash = (const CRYPT_HASH_BLOB *)pvPara;
|
||||
|
||||
if (size == pHash->cbData)
|
||||
ret = !memcmp(pHash->pbData, hash, size);
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL compare_cert_by_name(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
const CERT_NAME_BLOB *blob = (const CERT_NAME_BLOB *)pvPara, *toCompare;
|
||||
BOOL ret;
|
||||
|
||||
if (dwType & CERT_INFO_SUBJECT_FLAG)
|
||||
toCompare = &pCertContext->pCertInfo->Subject;
|
||||
else
|
||||
toCompare = &pCertContext->pCertInfo->Issuer;
|
||||
if (toCompare->cbData == blob->cbData)
|
||||
ret = !memcmp(toCompare->pbData, blob->pbData, blob->cbData);
|
||||
else
|
||||
ret = FALSE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL compare_cert_by_subject_cert(PCCERT_CONTEXT pCertContext,
|
||||
DWORD dwType, DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
const CERT_INFO *pCertInfo = (const CERT_INFO *)pvPara;
|
||||
BOOL ret;
|
||||
|
||||
if (pCertInfo->Issuer.cbData == pCertContext->pCertInfo->Subject.cbData)
|
||||
ret = !memcmp(pCertInfo->Issuer.pbData,
|
||||
pCertContext->pCertInfo->Subject.pbData, pCertInfo->Issuer.cbData);
|
||||
else
|
||||
ret = FALSE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL compare_cert_by_issuer(PCCERT_CONTEXT pCertContext,
|
||||
DWORD dwType, DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
return compare_cert_by_subject_cert(pCertContext, dwType, dwFlags,
|
||||
((PCCERT_CONTEXT)pvPara)->pCertInfo);
|
||||
}
|
||||
|
||||
PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
|
||||
DWORD dwCertEncodingType, DWORD dwFlags, DWORD dwType, const void *pvPara,
|
||||
PCCERT_CONTEXT pPrevCertContext)
|
||||
{
|
||||
PCCERT_CONTEXT ret;
|
||||
CertCompareFunc compare;
|
||||
|
||||
TRACE("(%p, %ld, %ld, %ld, %p, %p)\n", hCertStore, dwCertEncodingType,
|
||||
dwFlags, dwType, pvPara, pPrevCertContext);
|
||||
|
||||
switch (dwType >> CERT_COMPARE_SHIFT)
|
||||
{
|
||||
case CERT_COMPARE_ANY:
|
||||
compare = compare_cert_any;
|
||||
break;
|
||||
case CERT_COMPARE_MD5_HASH:
|
||||
compare = compare_cert_by_md5_hash;
|
||||
break;
|
||||
case CERT_COMPARE_SHA1_HASH:
|
||||
compare = compare_cert_by_sha1_hash;
|
||||
break;
|
||||
case CERT_COMPARE_NAME:
|
||||
compare = compare_cert_by_name;
|
||||
break;
|
||||
case CERT_COMPARE_SUBJECT_CERT:
|
||||
compare = compare_cert_by_subject_cert;
|
||||
break;
|
||||
case CERT_COMPARE_ISSUER_OF:
|
||||
compare = compare_cert_by_issuer;
|
||||
break;
|
||||
default:
|
||||
FIXME("find type %08lx unimplemented\n", dwType);
|
||||
compare = NULL;
|
||||
}
|
||||
|
||||
if (compare)
|
||||
{
|
||||
BOOL matches = FALSE;
|
||||
|
||||
ret = pPrevCertContext;
|
||||
do {
|
||||
ret = CertEnumCertificatesInStore(hCertStore, ret);
|
||||
if (ret)
|
||||
matches = compare(ret, dwType, dwFlags, pvPara);
|
||||
} while (ret != NULL && !matches);
|
||||
if (!ret)
|
||||
SetLastError(CRYPT_E_NOT_FOUND);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(CRYPT_E_NOT_FOUND);
|
||||
ret = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
PCCERT_CONTEXT WINAPI CertGetSubjectCertificateFromStore(HCERTSTORE hCertStore,
|
||||
DWORD dwCertEncodingType, PCERT_INFO pCertId)
|
||||
{
|
||||
TRACE("(%p, %08lx, %p)\n", hCertStore, dwCertEncodingType, pCertId);
|
||||
|
||||
if (!pCertId)
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return NULL;
|
||||
}
|
||||
return CertFindCertificateInStore(hCertStore, dwCertEncodingType, 0,
|
||||
CERT_FIND_SUBJECT_CERT, pCertId, NULL);
|
||||
}
|
||||
|
||||
PCCERT_CONTEXT WINAPI CertGetIssuerCertificateFromStore(HCERTSTORE hCertStore,
|
||||
PCCERT_CONTEXT pSubjectContext, PCCERT_CONTEXT pPrevIssuerContext,
|
||||
DWORD *pdwFlags)
|
||||
{
|
||||
static const DWORD supportedFlags = CERT_STORE_REVOCATION_FLAG |
|
||||
CERT_STORE_SIGNATURE_FLAG | CERT_STORE_TIME_VALIDITY_FLAG;
|
||||
PCCERT_CONTEXT ret;
|
||||
|
||||
TRACE("(%p, %p, %p, %08lx)\n", hCertStore, pSubjectContext,
|
||||
pPrevIssuerContext, *pdwFlags);
|
||||
|
||||
if (*pdwFlags & ~supportedFlags)
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return NULL;
|
||||
}
|
||||
ret = CertFindCertificateInStore(hCertStore,
|
||||
pSubjectContext->dwCertEncodingType, 0, CERT_FIND_ISSUER_OF,
|
||||
pSubjectContext, pPrevIssuerContext);
|
||||
if (ret)
|
||||
{
|
||||
if (*pdwFlags & CERT_STORE_REVOCATION_FLAG)
|
||||
{
|
||||
FIXME("revocation check requires CRL support\n");
|
||||
*pdwFlags |= CERT_STORE_NO_CRL_FLAG;
|
||||
}
|
||||
if (*pdwFlags & CERT_STORE_TIME_VALIDITY_FLAG)
|
||||
{
|
||||
if (0 == CertVerifyTimeValidity(NULL, pSubjectContext->pCertInfo))
|
||||
*pdwFlags &= ~CERT_STORE_TIME_VALIDITY_FLAG;
|
||||
}
|
||||
if (*pdwFlags & CERT_STORE_SIGNATURE_FLAG)
|
||||
{
|
||||
if (CryptVerifyCertificateSignatureEx(0,
|
||||
pSubjectContext->dwCertEncodingType,
|
||||
CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT, (void *)pSubjectContext,
|
||||
CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT, (void *)ret, 0, NULL))
|
||||
*pdwFlags &= ~CERT_STORE_SIGNATURE_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
PCRYPT_ATTRIBUTE WINAPI CertFindAttribute(LPCSTR pszObjId, DWORD cAttr,
|
||||
CRYPT_ATTRIBUTE rgAttr[])
|
||||
{
|
||||
|
|
|
@ -2537,209 +2537,6 @@ BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
typedef BOOL (*CertCompareFunc)(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
||||
DWORD dwFlags, const void *pvPara);
|
||||
|
||||
static BOOL compare_cert_any(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL compare_cert_by_md5_hash(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
BOOL ret;
|
||||
BYTE hash[16];
|
||||
DWORD size = sizeof(hash);
|
||||
|
||||
ret = CertGetCertificateContextProperty(pCertContext,
|
||||
CERT_MD5_HASH_PROP_ID, hash, &size);
|
||||
if (ret)
|
||||
{
|
||||
const CRYPT_HASH_BLOB *pHash = (const CRYPT_HASH_BLOB *)pvPara;
|
||||
|
||||
if (size == pHash->cbData)
|
||||
ret = !memcmp(pHash->pbData, hash, size);
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL compare_cert_by_sha1_hash(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
BOOL ret;
|
||||
BYTE hash[20];
|
||||
DWORD size = sizeof(hash);
|
||||
|
||||
ret = CertGetCertificateContextProperty(pCertContext,
|
||||
CERT_SHA1_HASH_PROP_ID, hash, &size);
|
||||
if (ret)
|
||||
{
|
||||
const CRYPT_HASH_BLOB *pHash = (const CRYPT_HASH_BLOB *)pvPara;
|
||||
|
||||
if (size == pHash->cbData)
|
||||
ret = !memcmp(pHash->pbData, hash, size);
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL compare_cert_by_name(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
const CERT_NAME_BLOB *blob = (const CERT_NAME_BLOB *)pvPara, *toCompare;
|
||||
BOOL ret;
|
||||
|
||||
if (dwType & CERT_INFO_SUBJECT_FLAG)
|
||||
toCompare = &pCertContext->pCertInfo->Subject;
|
||||
else
|
||||
toCompare = &pCertContext->pCertInfo->Issuer;
|
||||
if (toCompare->cbData == blob->cbData)
|
||||
ret = !memcmp(toCompare->pbData, blob->pbData, blob->cbData);
|
||||
else
|
||||
ret = FALSE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL compare_cert_by_subject_cert(PCCERT_CONTEXT pCertContext,
|
||||
DWORD dwType, DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
const CERT_INFO *pCertInfo = (const CERT_INFO *)pvPara;
|
||||
BOOL ret;
|
||||
|
||||
if (pCertInfo->Issuer.cbData == pCertContext->pCertInfo->Subject.cbData)
|
||||
ret = !memcmp(pCertInfo->Issuer.pbData,
|
||||
pCertContext->pCertInfo->Subject.pbData, pCertInfo->Issuer.cbData);
|
||||
else
|
||||
ret = FALSE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL compare_cert_by_issuer(PCCERT_CONTEXT pCertContext,
|
||||
DWORD dwType, DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
return compare_cert_by_subject_cert(pCertContext, dwType, dwFlags,
|
||||
((PCCERT_CONTEXT)pvPara)->pCertInfo);
|
||||
}
|
||||
|
||||
PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
|
||||
DWORD dwCertEncodingType, DWORD dwFlags, DWORD dwType,
|
||||
const void *pvPara, PCCERT_CONTEXT pPrevCertContext)
|
||||
{
|
||||
PCCERT_CONTEXT ret;
|
||||
CertCompareFunc compare;
|
||||
|
||||
TRACE("(%p, %ld, %ld, %ld, %p, %p)\n", hCertStore, dwCertEncodingType,
|
||||
dwFlags, dwType, pvPara, pPrevCertContext);
|
||||
|
||||
switch (dwType >> CERT_COMPARE_SHIFT)
|
||||
{
|
||||
case CERT_COMPARE_ANY:
|
||||
compare = compare_cert_any;
|
||||
break;
|
||||
case CERT_COMPARE_MD5_HASH:
|
||||
compare = compare_cert_by_md5_hash;
|
||||
break;
|
||||
case CERT_COMPARE_SHA1_HASH:
|
||||
compare = compare_cert_by_sha1_hash;
|
||||
break;
|
||||
case CERT_COMPARE_NAME:
|
||||
compare = compare_cert_by_name;
|
||||
break;
|
||||
case CERT_COMPARE_SUBJECT_CERT:
|
||||
compare = compare_cert_by_subject_cert;
|
||||
break;
|
||||
case CERT_COMPARE_ISSUER_OF:
|
||||
compare = compare_cert_by_issuer;
|
||||
break;
|
||||
default:
|
||||
FIXME("find type %08lx unimplemented\n", dwType);
|
||||
compare = NULL;
|
||||
}
|
||||
|
||||
if (compare)
|
||||
{
|
||||
BOOL matches = FALSE;
|
||||
|
||||
ret = pPrevCertContext;
|
||||
do {
|
||||
ret = CertEnumCertificatesInStore(hCertStore, ret);
|
||||
if (ret)
|
||||
matches = compare(ret, dwType, dwFlags, pvPara);
|
||||
} while (ret != NULL && !matches);
|
||||
if (!ret)
|
||||
SetLastError(CRYPT_E_NOT_FOUND);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(CRYPT_E_NOT_FOUND);
|
||||
ret = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
PCCERT_CONTEXT WINAPI CertGetSubjectCertificateFromStore(HCERTSTORE hCertStore,
|
||||
DWORD dwCertEncodingType, PCERT_INFO pCertId)
|
||||
{
|
||||
TRACE("(%p, %08lx, %p)\n", hCertStore, dwCertEncodingType, pCertId);
|
||||
|
||||
if (!pCertId)
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return NULL;
|
||||
}
|
||||
return CertFindCertificateInStore(hCertStore, dwCertEncodingType, 0,
|
||||
CERT_FIND_SUBJECT_CERT, pCertId, NULL);
|
||||
}
|
||||
|
||||
PCCERT_CONTEXT WINAPI CertGetIssuerCertificateFromStore(HCERTSTORE hCertStore,
|
||||
PCCERT_CONTEXT pSubjectContext, PCCERT_CONTEXT pPrevIssuerContext,
|
||||
DWORD *pdwFlags)
|
||||
{
|
||||
static const DWORD supportedFlags = CERT_STORE_REVOCATION_FLAG |
|
||||
CERT_STORE_SIGNATURE_FLAG | CERT_STORE_TIME_VALIDITY_FLAG;
|
||||
PCCERT_CONTEXT ret;
|
||||
|
||||
TRACE("(%p, %p, %p, %08lx)\n", hCertStore, pSubjectContext,
|
||||
pPrevIssuerContext, *pdwFlags);
|
||||
|
||||
if (*pdwFlags & ~supportedFlags)
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return NULL;
|
||||
}
|
||||
ret = CertFindCertificateInStore(hCertStore,
|
||||
pSubjectContext->dwCertEncodingType, 0, CERT_FIND_ISSUER_OF,
|
||||
pSubjectContext, pPrevIssuerContext);
|
||||
if (ret)
|
||||
{
|
||||
if (*pdwFlags & CERT_STORE_REVOCATION_FLAG)
|
||||
{
|
||||
FIXME("revocation check requires CRL support\n");
|
||||
*pdwFlags |= CERT_STORE_NO_CRL_FLAG;
|
||||
}
|
||||
if (*pdwFlags & CERT_STORE_TIME_VALIDITY_FLAG)
|
||||
{
|
||||
if (0 == CertVerifyTimeValidity(NULL, pSubjectContext->pCertInfo))
|
||||
*pdwFlags &= ~CERT_STORE_TIME_VALIDITY_FLAG;
|
||||
}
|
||||
if (*pdwFlags & CERT_STORE_SIGNATURE_FLAG)
|
||||
{
|
||||
if (CryptVerifyCertificateSignatureEx(0,
|
||||
pSubjectContext->dwCertEncodingType,
|
||||
CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT, (void *)pSubjectContext,
|
||||
CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT, (void *)ret, 0, NULL))
|
||||
*pdwFlags &= ~CERT_STORE_SIGNATURE_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore,
|
||||
HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue