📄 cert.c
字号:
SetLastError(CRYPT_E_ASN1_BADTAG);
}
else
{
DWORD size;
PBYTE buf;
BOOL ret = CryptDecodeObjectEx(dwCertEncodingType,
RSA_CSP_PUBLICKEYBLOB, pPublicKey->PublicKey.pbData,
pPublicKey->PublicKey.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
&size);
if (ret)
{
RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)((LPBYTE)buf +
sizeof(BLOBHEADER));
len = rsaPubKey->bitlen;
LocalFree(buf);
}
}
return len;
}
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)
{
CERT_NAME_BLOB *blob = (CERT_NAME_BLOB *)pvPara, *toCompare;
BOOL ret;
if (dwType & CERT_INFO_SUBJECT_FLAG)
toCompare = &pCertContext->pCertInfo->Subject;
else
toCompare = &pCertContext->pCertInfo->Issuer;
ret = CertCompareCertificateName(pCertContext->dwCertEncodingType,
toCompare, blob);
return ret;
}
static BOOL compare_cert_by_subject_cert(PCCERT_CONTEXT pCertContext,
DWORD dwType, DWORD dwFlags, const void *pvPara)
{
CERT_INFO *pCertInfo = (CERT_INFO *)pvPara;
return CertCompareCertificateName(pCertContext->dwCertEncodingType,
&pCertInfo->Issuer, &pCertContext->pCertInfo->Subject);
}
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, %d, %d, %d, %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 %08x 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, %08x, %p)\n", hCertStore, dwCertEncodingType, pCertId);
if (!pCertId)
{
SetLastError(E_INVALIDARG);
return NULL;
}
return CertFindCertificateInStore(hCertStore, dwCertEncodingType, 0,
CERT_FIND_SUBJECT_CERT, pCertId, NULL);
}
BOOL WINAPI CertVerifySubjectCertificateContext(PCCERT_CONTEXT pSubject,
PCCERT_CONTEXT pIssuer, DWORD *pdwFlags)
{
static const DWORD supportedFlags = CERT_STORE_REVOCATION_FLAG |
CERT_STORE_SIGNATURE_FLAG | CERT_STORE_TIME_VALIDITY_FLAG;
if (*pdwFlags & ~supportedFlags)
{
SetLastError(E_INVALIDARG);
return FALSE;
}
if (*pdwFlags & CERT_STORE_REVOCATION_FLAG)
{
DWORD flags = 0;
PCCRL_CONTEXT crl = CertGetCRLFromStore(pSubject->hCertStore, pSubject,
NULL, &flags);
/* FIXME: what if the CRL has expired? */
if (crl)
{
if (CertVerifyCRLRevocation(pSubject->dwCertEncodingType,
pSubject->pCertInfo, 1, (PCRL_INFO *)&crl->pCrlInfo))
*pdwFlags &= CERT_STORE_REVOCATION_FLAG;
}
else
*pdwFlags |= CERT_STORE_NO_CRL_FLAG;
}
if (*pdwFlags & CERT_STORE_TIME_VALIDITY_FLAG)
{
if (0 == CertVerifyTimeValidity(NULL, pSubject->pCertInfo))
*pdwFlags &= ~CERT_STORE_TIME_VALIDITY_FLAG;
}
if (*pdwFlags & CERT_STORE_SIGNATURE_FLAG)
{
if (CryptVerifyCertificateSignatureEx(0, pSubject->dwCertEncodingType,
CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT, (void *)pSubject,
CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT, (void *)pIssuer, 0, NULL))
*pdwFlags &= ~CERT_STORE_SIGNATURE_FLAG;
}
return TRUE;
}
PCCERT_CONTEXT WINAPI CertGetIssuerCertificateFromStore(HCERTSTORE hCertStore,
PCCERT_CONTEXT pSubjectContext, PCCERT_CONTEXT pPrevIssuerContext,
DWORD *pdwFlags)
{
PCCERT_CONTEXT ret;
TRACE("(%p, %p, %p, %08x)\n", hCertStore, pSubjectContext,
pPrevIssuerContext, *pdwFlags);
if (!pSubjectContext)
{
SetLastError(E_INVALIDARG);
return NULL;
}
ret = CertFindCertificateInStore(hCertStore,
pSubjectContext->dwCertEncodingType, 0, CERT_FIND_ISSUER_OF,
pSubjectContext, pPrevIssuerContext);
if (ret)
{
if (!CertVerifySubjectCertificateContext(pSubjectContext, ret,
pdwFlags))
{
CertFreeCertificateContext(ret);
ret = NULL;
}
}
return ret;
}
PCRYPT_ATTRIBUTE WINAPI CertFindAttribute(LPCSTR pszObjId, DWORD cAttr,
CRYPT_ATTRIBUTE rgAttr[])
{
PCRYPT_ATTRIBUTE ret = NULL;
DWORD i;
TRACE("%s %d %p\n", debugstr_a(pszObjId), cAttr, rgAttr);
if (!cAttr)
return NULL;
if (!pszObjId)
{
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
for (i = 0; !ret && i < cAttr; i++)
if (rgAttr[i].pszObjId && !strcmp(pszObjId, rgAttr[i].pszObjId))
ret = &rgAttr[i];
return ret;
}
PCERT_EXTENSION WINAPI CertFindExtension(LPCSTR pszObjId, DWORD cExtensions,
CERT_EXTENSION rgExtensions[])
{
PCERT_EXTENSION ret = NULL;
DWORD i;
TRACE("%s %d %p\n", debugstr_a(pszObjId), cExtensions, rgExtensions);
if (!cExtensions)
return NULL;
if (!pszObjId)
{
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
for (i = 0; !ret && i < cExtensions; i++)
if (rgExtensions[i].pszObjId && !strcmp(pszObjId,
rgExtensions[i].pszObjId))
ret = &rgExtensions[i];
return ret;
}
PCERT_RDN_ATTR WINAPI CertFindRDNAttr(LPCSTR pszObjId, PCERT_NAME_INFO pName)
{
PCERT_RDN_ATTR ret = NULL;
DWORD i, j;
TRACE("%s %p\n", debugstr_a(pszObjId), pName);
if (!pszObjId)
{
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
for (i = 0; !ret && i < pName->cRDN; i++)
for (j = 0; !ret && j < pName->rgRDN[i].cRDNAttr; j++)
if (pName->rgRDN[i].rgRDNAttr[j].pszObjId && !strcmp(pszObjId,
pName->rgRDN[i].rgRDNAttr[j].pszObjId))
ret = &pName->rgRDN[i].rgRDNAttr[j];
return ret;
}
LONG WINAPI CertVerifyTimeValidity(LPFILETIME pTimeToVerify,
PCERT_INFO pCertInfo)
{
FILETIME fileTime;
LONG ret;
if (!pTimeToVerify)
{
SYSTEMTIME sysTime;
GetSystemTime(&sysTime);
SystemTimeToFileTime(&sysTime, &fileTime);
pTimeToVerify = &fileTime;
}
if ((ret = CompareFileTime(pTimeToVerify, &pCertInfo->NotBefore)) >= 0)
{
ret = CompareFileTime(pTimeToVerify, &pCertInfo->NotAfter);
if (ret < 0)
ret = 0;
}
return ret;
}
BOOL WINAPI CertVerifyValidityNesting(PCERT_INFO pSubjectInfo,
PCERT_INFO pIssuerInfo)
{
TRACE("(%p, %p)\n", pSubjectInfo, pIssuerInfo);
return CertVerifyTimeValidity(&pSubjectInfo->NotBefore, pIssuerInfo) == 0
&& CertVerifyTimeValidity(&pSubjectInfo->NotAfter, pIssuerInfo) == 0;
}
BOOL WINAPI CryptHashCertificate(HCRYPTPROV hCryptProv, ALG_ID Algid,
DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash,
DWORD *pcbComputedHash)
{
BOOL ret = TRUE;
HCRYPTHASH hHash = 0;
TRACE("(%08lx, %d, %08x, %p, %d, %p, %p)\n", hCryptProv, Algid, dwFlags,
pbEncoded, cbEncoded, pbComputedHash, pcbComputedHash);
if (!hCryptProv)
hCryptProv = CRYPT_GetDefaultProvider();
if (!Algid)
Algid = CALG_SHA1;
if (ret)
{
ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash);
if (ret)
{
ret = CryptHashData(hHash, pbEncoded, cbEncoded, 0);
if (ret)
ret = CryptGetHashParam(hHash, HP_HASHVAL, pbComputedHash,
pcbComputedHash, 0);
CryptDestroyHash(hHash);
}
}
return ret;
}
BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV hCryptProv, ALG_ID Algid,
DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo,
BYTE *pbComputedHash, DWORD *pcbComputedHash)
{
BOOL ret = TRUE;
HCRYPTHASH hHash = 0;
TRACE("(%08lx, %d, %08x, %d, %p, %p, %p)\n", hCryptProv, Algid, dwFlags,
dwCertEncodingType, pInfo, pbComputedHash, pcbComputedHash);
if (!hCryptProv)
hCryptProv = CRYPT_GetDefaultProvider();
if (!Algid)
Algid = CALG_MD5;
if (ret)
{
BYTE *buf;
DWORD size = 0;
ret = CryptEncodeObjectEx(dwCertEncodingType, X509_PUBLIC_KEY_INFO,
pInfo, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
if (ret)
{
ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash);
if (ret)
{
ret = CryptHashData(hHash, buf, size, 0);
if (ret)
ret = CryptGetHashParam(hHash, HP_HASHVAL, pbComputedHash,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -