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;
|
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,
|
PCRYPT_ATTRIBUTE WINAPI CertFindAttribute(LPCSTR pszObjId, DWORD cAttr,
|
||||||
CRYPT_ATTRIBUTE rgAttr[])
|
CRYPT_ATTRIBUTE rgAttr[])
|
||||||
{
|
{
|
||||||
|
|
|
@ -2537,209 +2537,6 @@ BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
|
||||||
return TRUE;
|
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,
|
BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore,
|
||||||
HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority)
|
HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue