You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1206 lines
38 KiB
1206 lines
38 KiB
//+-------------------------------------------------------------------------
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1999
|
|
//
|
|
// File: msrevoke.cpp
|
|
//
|
|
// Contents: CRL Distribution Points version of CertDllVerifyRevocation.
|
|
//
|
|
// Restrictions:
|
|
// - Only support CRYPT_ASN_ENCODING
|
|
// - Only processes certificates having the
|
|
// szOID_CRL_DIST_POINTS extension.
|
|
// - For szOID_CRL_DIST_POINTS extension: only URL FullName,
|
|
// no ReasonFlags or CRLIssuer.
|
|
// - URLs: http:, file:
|
|
// - CRL must be issued and signed by the issuer of the
|
|
// certificate
|
|
// - CRL must not have any critical extensions
|
|
//
|
|
// Functions: DllMain
|
|
// DllRegisterServer
|
|
// DllUnregisterServer
|
|
// CertDllVerifyRevocation
|
|
//
|
|
// History: 10-Apr-97 philh created
|
|
// 01-Oct-97 kirtd major simplification, use
|
|
// CryptGetTimeValidObject
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
#include "global.hxx"
|
|
#include <dbgdef.h>
|
|
|
|
|
|
#define MSREVOKE_TIMEOUT 15000
|
|
//+-------------------------------------------------------------------------
|
|
// Default stores searched to find an issuer of the subject certificate
|
|
//--------------------------------------------------------------------------
|
|
static struct {
|
|
LPCWSTR pwszStore;
|
|
DWORD dwFlags;
|
|
} rgDefaultIssuerStores[] = {
|
|
L"CA", CERT_SYSTEM_STORE_CURRENT_USER,
|
|
L"ROOT", CERT_SYSTEM_STORE_CURRENT_USER,
|
|
L"SPC", CERT_SYSTEM_STORE_LOCAL_MACHINE
|
|
};
|
|
|
|
#define NUM_DEFAULT_ISSUER_STORES (sizeof(rgDefaultIssuerStores) / \
|
|
sizeof(rgDefaultIssuerStores[0]))
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Local functions called by MicrosoftCertDllVerifyRevocation
|
|
//--------------------------------------------------------------------------
|
|
PCCERT_CONTEXT GetIssuerCert(
|
|
IN DWORD cCert,
|
|
IN PCCERT_CONTEXT rgpCert[],
|
|
IN DWORD dwFlags,
|
|
IN PCERT_REVOCATION_PARA pRevPara
|
|
);
|
|
|
|
BOOL HasUnsupportedCrlCriticalExtension(
|
|
IN PCCRL_CONTEXT pCrl
|
|
);
|
|
|
|
|
|
// msrevoke specific flags that can be passed to GetTimeValidCrl
|
|
#define MSREVOKE_DONT_CHECK_TIME_VALIDITY_FLAG 0x1
|
|
#define MSREVOKE_DELTA_CRL_FLAG 0x2
|
|
|
|
BOOL GetTimeValidCrl (
|
|
IN LPCSTR pszTimeValidOid,
|
|
IN LPVOID pvTimeValidPara,
|
|
IN PCCERT_CONTEXT pSubject,
|
|
IN PCCERT_CONTEXT pIssuer,
|
|
IN PCERT_REVOCATION_PARA pRevPara,
|
|
IN PCERT_EXTENSION pCDPExt,
|
|
IN DWORD dwRevFlags,
|
|
IN DWORD dwMsrevokeFlags,
|
|
IN FILETIME *pftEndUrlRetrieval,
|
|
OUT PCCRL_CONTEXT *ppCrl,
|
|
IN OUT BOOL *pfWireRetrieval
|
|
);
|
|
BOOL GetBaseCrl (
|
|
IN PCCERT_CONTEXT pSubject,
|
|
IN PCCERT_CONTEXT pIssuer,
|
|
IN PCERT_REVOCATION_PARA pRevPara,
|
|
IN PCERT_EXTENSION pCDPExt,
|
|
IN DWORD dwRevFlags,
|
|
IN FILETIME *pftEndUrlRetrieval,
|
|
OUT PCCRL_CONTEXT *ppBaseCrl,
|
|
OUT BOOL *pfBaseCrlTimeValid,
|
|
OUT BOOL *pfBaseWireRetrieval
|
|
);
|
|
BOOL GetDeltaCrl (
|
|
IN PCCERT_CONTEXT pSubject,
|
|
IN PCCERT_CONTEXT pIssuer,
|
|
IN PCERT_REVOCATION_PARA pRevPara,
|
|
IN DWORD dwRevFlags,
|
|
IN BOOL fBaseWireRetrieval,
|
|
IN FILETIME *pftEndUrlRetrieval,
|
|
IN OUT PCCRL_CONTEXT *ppBaseCrl,
|
|
IN OUT BOOL *pfCrlTimeValid,
|
|
OUT PCCRL_CONTEXT *ppDeltaCrl,
|
|
OUT DWORD *pdwFreshnessTime
|
|
);
|
|
|
|
DWORD GetCrlReason(
|
|
IN PCRL_ENTRY pCrlEntry
|
|
);
|
|
|
|
BOOL CrlIssuerIsCertIssuer (
|
|
IN PCCERT_CONTEXT pCert,
|
|
IN PCERT_EXTENSION pCrlDistPointExt
|
|
);
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// External functions called by CertDllVerifyRevocation
|
|
//--------------------------------------------------------------------------
|
|
|
|
BOOL
|
|
WINAPI
|
|
NetscapeCertDllVerifyRevocation(
|
|
IN DWORD dwEncodingType,
|
|
IN DWORD dwRevType,
|
|
IN DWORD cContext,
|
|
IN PVOID rgpvContext[],
|
|
IN DWORD dwFlags,
|
|
IN PVOID pvReserved,
|
|
IN OUT PCERT_REVOCATION_STATUS pRevStatus
|
|
);
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// MicrosoftCertDllVerifyRevocation using CRL Distribution Points extension.
|
|
//--------------------------------------------------------------------------
|
|
BOOL
|
|
WINAPI
|
|
MicrosoftCertDllVerifyRevocation(
|
|
IN DWORD dwEncodingType,
|
|
IN DWORD dwRevType,
|
|
IN DWORD cContext,
|
|
IN PVOID rgpvContext[],
|
|
IN DWORD dwFlags,
|
|
IN PCERT_REVOCATION_PARA pRevPara,
|
|
IN OUT PCERT_REVOCATION_STATUS pRevStatus
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
DWORD dwIndex = 0;
|
|
DWORD dwError = (DWORD) CRYPT_E_NO_REVOCATION_CHECK;
|
|
DWORD dwReason = 0;
|
|
PCCERT_CONTEXT pCert; // not allocated
|
|
PCCERT_CONTEXT pIssuer = NULL;
|
|
PCCRL_CONTEXT pBaseCrl = NULL;
|
|
PCCRL_CONTEXT pDeltaCrl = NULL;
|
|
PCRL_ENTRY pCrlEntry = NULL; // not allocated
|
|
BOOL fDeltaCrlEntry = FALSE;
|
|
BOOL fCrlTimeValid = FALSE;
|
|
BOOL fBaseWireRetrieval = FALSE;
|
|
PCERT_EXTENSION pCDPExt;
|
|
BOOL fSaveCheckFreshnessTime;
|
|
DWORD dwFreshnessTime;
|
|
|
|
CERT_REVOCATION_PARA RevPara;
|
|
FILETIME ftCurrent;
|
|
|
|
// Following is only used for CERT_VERIFY_REV_ACCUMULATIVE_TIMEOUT_FLAG
|
|
FILETIME ftEndUrlRetrieval;
|
|
|
|
// Ensure we have a structure containing all the possible parameters
|
|
memset(&RevPara, 0, sizeof(RevPara));
|
|
if (pRevPara != NULL)
|
|
memcpy(&RevPara, pRevPara, min(pRevPara->cbSize, sizeof(RevPara)));
|
|
RevPara.cbSize = sizeof(RevPara);
|
|
if (0 == RevPara.dwUrlRetrievalTimeout)
|
|
RevPara.dwUrlRetrievalTimeout = MSREVOKE_TIMEOUT;
|
|
if (NULL == RevPara.pftCurrentTime) {
|
|
GetSystemTimeAsFileTime(&ftCurrent);
|
|
RevPara.pftCurrentTime = &ftCurrent;
|
|
}
|
|
pRevPara = &RevPara;
|
|
|
|
if (dwFlags & CERT_VERIFY_REV_ACCUMULATIVE_TIMEOUT_FLAG) {
|
|
FILETIME ftStartUrlRetrieval;
|
|
|
|
GetSystemTimeAsFileTime(&ftStartUrlRetrieval);
|
|
I_CryptIncrementFileTimeByMilliseconds(
|
|
&ftStartUrlRetrieval, pRevPara->dwUrlRetrievalTimeout,
|
|
&ftEndUrlRetrieval);
|
|
}
|
|
|
|
if (cContext == 0)
|
|
goto NoContextError;
|
|
if (GET_CERT_ENCODING_TYPE(dwEncodingType) != CRYPT_ASN_ENCODING)
|
|
goto NoRevocationCheckForEncodingTypeError;
|
|
if (dwRevType != CERT_CONTEXT_REVOCATION_TYPE)
|
|
goto NoRevocationCheckForRevTypeError;
|
|
|
|
pCert = (PCCERT_CONTEXT) rgpvContext[0];
|
|
|
|
// Check if we have a CRL dist point
|
|
pCDPExt = CertFindExtension(
|
|
szOID_CRL_DIST_POINTS,
|
|
pCert->pCertInfo->cExtension,
|
|
pCert->pCertInfo->rgExtension
|
|
);
|
|
|
|
// On 04-05-01 changed back to W2K semantics. Continue to check
|
|
// if expired certificates are on the CRL.
|
|
|
|
// If we have a CDP and an expired certificate,
|
|
// then, the CA no longer maintains CRL information for the
|
|
// certificate. We must consider it as being revoked.
|
|
// if (NULL != pCDPExt &&
|
|
// 0 < CompareFileTime(RevPara.pftCurrentTime,
|
|
// &pCert->pCertInfo->NotAfter)) {
|
|
// dwReason = CRL_REASON_CESSATION_OF_OPERATION;
|
|
// goto ExpiredCertError;
|
|
// }
|
|
|
|
// Get the certificate's issuer
|
|
if (NULL == (pIssuer = GetIssuerCert(
|
|
cContext,
|
|
(PCCERT_CONTEXT *) rgpvContext,
|
|
dwFlags,
|
|
&RevPara
|
|
)))
|
|
goto NoIssuerError;
|
|
|
|
|
|
// Get the Base CRL for the subject certificate.
|
|
//
|
|
// Remember and disable the freshness retrieval option.
|
|
fSaveCheckFreshnessTime = RevPara.fCheckFreshnessTime;
|
|
RevPara.fCheckFreshnessTime = FALSE;
|
|
if (!GetBaseCrl(
|
|
pCert,
|
|
pIssuer,
|
|
&RevPara,
|
|
pCDPExt,
|
|
dwFlags,
|
|
&ftEndUrlRetrieval,
|
|
&pBaseCrl,
|
|
&fCrlTimeValid,
|
|
&fBaseWireRetrieval
|
|
))
|
|
goto GetBaseCrlError;
|
|
RevPara.fCheckFreshnessTime = fSaveCheckFreshnessTime;
|
|
|
|
|
|
// If either the base crl or subject cert has a freshest, delta CRL,
|
|
// get it
|
|
if (!GetDeltaCrl(
|
|
pCert,
|
|
pIssuer,
|
|
&RevPara,
|
|
dwFlags,
|
|
fBaseWireRetrieval,
|
|
&ftEndUrlRetrieval,
|
|
&pBaseCrl,
|
|
&fCrlTimeValid,
|
|
&pDeltaCrl,
|
|
&dwFreshnessTime
|
|
))
|
|
goto GetDeltaCrlError;
|
|
|
|
if (NULL == pDeltaCrl) {
|
|
dwFreshnessTime = I_CryptSubtractFileTimes(
|
|
RevPara.pftCurrentTime, &pBaseCrl->pCrlInfo->ThisUpdate);
|
|
|
|
if (RevPara.fCheckFreshnessTime) {
|
|
if (RevPara.dwFreshnessTime >= dwFreshnessTime)
|
|
fCrlTimeValid = TRUE;
|
|
else {
|
|
// Attempt to get a base CRL with better "freshness"
|
|
PCCRL_CONTEXT pNewCrl;
|
|
|
|
if (GetBaseCrl(
|
|
pCert,
|
|
pIssuer,
|
|
&RevPara,
|
|
pCDPExt,
|
|
dwFlags,
|
|
&ftEndUrlRetrieval,
|
|
&pNewCrl,
|
|
&fCrlTimeValid,
|
|
&fBaseWireRetrieval
|
|
)) {
|
|
CertFreeCRLContext(pBaseCrl);
|
|
pBaseCrl = pNewCrl;
|
|
dwFreshnessTime = I_CryptSubtractFileTimes(
|
|
RevPara.pftCurrentTime,
|
|
&pBaseCrl->pCrlInfo->ThisUpdate);
|
|
} else
|
|
fCrlTimeValid = FALSE;
|
|
}
|
|
}
|
|
} else {
|
|
if (!CertFindCertificateInCRL(
|
|
pCert,
|
|
pDeltaCrl,
|
|
0, // dwFlags
|
|
NULL, // pvReserved
|
|
&pCrlEntry
|
|
))
|
|
goto CertFindCertificateInDeltaCRLError;
|
|
}
|
|
|
|
if (pCrlEntry) {
|
|
// Delta CRL entry
|
|
|
|
dwReason = GetCrlReason(pCrlEntry);
|
|
if (CRL_REASON_REMOVE_FROM_CRL != dwReason)
|
|
fDeltaCrlEntry = TRUE;
|
|
else {
|
|
if (!CertFindCertificateInCRL(
|
|
pCert,
|
|
pBaseCrl,
|
|
0, // dwFlags
|
|
NULL, // pvReserved
|
|
&pCrlEntry
|
|
))
|
|
goto CertFindCertificateInBaseCRLError;
|
|
if (pCrlEntry) {
|
|
dwReason = GetCrlReason(pCrlEntry);
|
|
if (CRL_REASON_CERTIFICATE_HOLD == dwReason)
|
|
pCrlEntry = NULL;
|
|
}
|
|
|
|
if (NULL == pCrlEntry)
|
|
dwReason = 0;
|
|
}
|
|
} else {
|
|
if (!CertFindCertificateInCRL(
|
|
pCert,
|
|
pBaseCrl,
|
|
0, // dwFlags
|
|
NULL, // pvReserved
|
|
&pCrlEntry
|
|
))
|
|
goto CertFindCertificateInBaseCRLError;
|
|
|
|
if (pCrlEntry)
|
|
dwReason = GetCrlReason(pCrlEntry);
|
|
}
|
|
|
|
dwError = 0;
|
|
if ( ( pCrlEntry != NULL ) &&
|
|
( ( RevPara.pftTimeToUse == NULL ) ||
|
|
( CompareFileTime(
|
|
RevPara.pftTimeToUse,
|
|
&pCrlEntry->RevocationDate ) >= 0 ) ) )
|
|
{
|
|
dwError = (DWORD) CRYPT_E_REVOKED;
|
|
}
|
|
else if (!fCrlTimeValid)
|
|
{
|
|
dwError = (DWORD) CRYPT_E_REVOCATION_OFFLINE;
|
|
}
|
|
|
|
if (pRevStatus->cbSize >=
|
|
(offsetof(CERT_REVOCATION_STATUS, dwFreshnessTime) +
|
|
sizeof(pRevStatus->dwFreshnessTime))) {
|
|
pRevStatus->fHasFreshnessTime = TRUE;
|
|
pRevStatus->dwFreshnessTime = dwFreshnessTime;
|
|
}
|
|
|
|
if (RevPara.pCrlInfo) {
|
|
PCERT_REVOCATION_CRL_INFO pInfo = RevPara.pCrlInfo;
|
|
|
|
if (pInfo->cbSize >= sizeof(*pInfo)) {
|
|
if (pInfo->pBaseCrlContext)
|
|
CertFreeCRLContext(pInfo->pBaseCrlContext);
|
|
pInfo->pBaseCrlContext = CertDuplicateCRLContext(pBaseCrl);
|
|
if (pInfo->pDeltaCrlContext) {
|
|
CertFreeCRLContext(pInfo->pDeltaCrlContext);
|
|
pInfo->pDeltaCrlContext = NULL;
|
|
}
|
|
|
|
if (pDeltaCrl)
|
|
pInfo->pDeltaCrlContext = CertDuplicateCRLContext(pDeltaCrl);
|
|
|
|
pInfo->fDeltaCrlEntry = fDeltaCrlEntry;
|
|
pInfo->pCrlEntry = pCrlEntry;
|
|
|
|
}
|
|
}
|
|
|
|
CommonReturn:
|
|
if (0 == dwError) {
|
|
// Successfully checked that the certificate wasn't revoked
|
|
if (1 < cContext) {
|
|
dwIndex = 1;
|
|
dwError = (DWORD) CRYPT_E_NO_REVOCATION_CHECK;
|
|
fResult = FALSE;
|
|
} else
|
|
fResult = TRUE;
|
|
} else
|
|
fResult = FALSE;
|
|
|
|
|
|
if (pIssuer)
|
|
CertFreeCertificateContext(pIssuer);
|
|
if (pBaseCrl)
|
|
CertFreeCRLContext(pBaseCrl);
|
|
if (pDeltaCrl)
|
|
CertFreeCRLContext(pDeltaCrl);
|
|
|
|
pRevStatus->dwIndex = dwIndex;
|
|
pRevStatus->dwError = dwError;
|
|
pRevStatus->dwReason = dwReason;
|
|
SetLastError(dwError);
|
|
return fResult;
|
|
ErrorReturn:
|
|
dwError = GetLastError();
|
|
if (0 == dwError)
|
|
dwError = (DWORD) E_UNEXPECTED;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(NoContextError, E_INVALIDARG)
|
|
SET_ERROR(NoRevocationCheckForEncodingTypeError, CRYPT_E_NO_REVOCATION_CHECK)
|
|
SET_ERROR(NoRevocationCheckForRevTypeError, CRYPT_E_NO_REVOCATION_CHECK)
|
|
// SET_ERROR(ExpiredCertError, CRYPT_E_REVOKED)
|
|
TRACE_ERROR(NoIssuerError)
|
|
TRACE_ERROR(GetBaseCrlError)
|
|
TRACE_ERROR(GetDeltaCrlError)
|
|
TRACE_ERROR(CertFindCertificateInDeltaCRLError)
|
|
TRACE_ERROR(CertFindCertificateInBaseCRLError)
|
|
}
|
|
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HasUnsupportedCrlCriticalExtension
|
|
//
|
|
// Synopsis: checks if the CRL has an unsupported critical section
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
LPCSTR rgpszSupportedCrlExtensionOID[] = {
|
|
szOID_DELTA_CRL_INDICATOR,
|
|
szOID_ISSUING_DIST_POINT,
|
|
szOID_FRESHEST_CRL,
|
|
szOID_CRL_NUMBER,
|
|
szOID_AUTHORITY_KEY_IDENTIFIER2,
|
|
NULL
|
|
};
|
|
|
|
BOOL IsSupportedCrlExtension(
|
|
PCERT_EXTENSION pExt
|
|
)
|
|
{
|
|
LPSTR pszExtOID = pExt->pszObjId;
|
|
LPCSTR *ppSupOID;
|
|
for (ppSupOID = rgpszSupportedCrlExtensionOID;
|
|
NULL != *ppSupOID; ppSupOID++) {
|
|
if (0 == strcmp(pszExtOID, *ppSupOID))
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL HasUnsupportedCrlCriticalExtension(
|
|
IN PCCRL_CONTEXT pCrl
|
|
)
|
|
{
|
|
PCRL_INFO pCrlInfo = pCrl->pCrlInfo;
|
|
DWORD cExt = pCrlInfo->cExtension;
|
|
PCERT_EXTENSION pExt = pCrlInfo->rgExtension;
|
|
|
|
for ( ; 0 < cExt; cExt--, pExt++) {
|
|
if (pExt->fCritical && !IsSupportedCrlExtension(pExt))
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: GetTimeValidCrl
|
|
//
|
|
// Synopsis: get a time valid base or delta CRL
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
BOOL GetTimeValidCrl (
|
|
IN LPCSTR pszTimeValidOid,
|
|
IN LPVOID pvTimeValidPara,
|
|
IN PCCERT_CONTEXT pSubject,
|
|
IN PCCERT_CONTEXT pIssuer,
|
|
IN PCERT_REVOCATION_PARA pRevPara,
|
|
IN PCERT_EXTENSION pCDPExt,
|
|
IN DWORD dwRevFlags,
|
|
IN DWORD dwMsrevokeFlags,
|
|
IN FILETIME *pftEndUrlRetrieval,
|
|
OUT PCCRL_CONTEXT *ppCrl,
|
|
IN OUT BOOL *pfWireRetrieval
|
|
)
|
|
{
|
|
BOOL fResult = FALSE;
|
|
DWORD dwFlags = 0;
|
|
FILETIME ftFreshness;
|
|
LPFILETIME pftValidFor;
|
|
|
|
if (pRevPara->fCheckFreshnessTime)
|
|
{
|
|
I_CryptDecrementFileTimeBySeconds(
|
|
pRevPara->pftCurrentTime,
|
|
pRevPara->dwFreshnessTime,
|
|
&ftFreshness);
|
|
pftValidFor = &ftFreshness;
|
|
|
|
dwFlags |= CRYPT_CHECK_FRESHNESS_TIME_VALIDITY;
|
|
}
|
|
else
|
|
{
|
|
pftValidFor = pRevPara->pftCurrentTime;
|
|
}
|
|
|
|
if ( dwMsrevokeFlags & MSREVOKE_DONT_CHECK_TIME_VALIDITY_FLAG )
|
|
{
|
|
dwFlags |= CRYPT_DONT_CHECK_TIME_VALIDITY;
|
|
}
|
|
|
|
if ( pCDPExt != NULL )
|
|
{
|
|
fResult = CryptGetTimeValidObject(
|
|
pszTimeValidOid,
|
|
pvTimeValidPara,
|
|
pIssuer,
|
|
pftValidFor,
|
|
dwFlags | CRYPT_CACHE_ONLY_RETRIEVAL,
|
|
0, // dwTimeout
|
|
(LPVOID *)ppCrl,
|
|
NULL, // pCredentials
|
|
NULL // pvReserved
|
|
);
|
|
}
|
|
|
|
if ( fResult == FALSE )
|
|
{
|
|
DWORD dwSaveErr = 0;
|
|
HCERTSTORE hCrlStore = pRevPara->hCrlStore;
|
|
|
|
*ppCrl = NULL;
|
|
|
|
if ( hCrlStore != NULL )
|
|
{
|
|
PCCRL_CONTEXT pFindCrl = NULL;
|
|
DWORD dwFindFlags;
|
|
CRL_FIND_ISSUED_FOR_PARA FindPara;
|
|
|
|
dwSaveErr = GetLastError();
|
|
|
|
dwFindFlags = CRL_FIND_ISSUED_BY_AKI_FLAG |
|
|
CRL_FIND_ISSUED_BY_SIGNATURE_FLAG;
|
|
if (dwMsrevokeFlags & MSREVOKE_DELTA_CRL_FLAG)
|
|
dwFindFlags |= CRL_FIND_ISSUED_BY_DELTA_FLAG;
|
|
else
|
|
dwFindFlags |= CRL_FIND_ISSUED_BY_BASE_FLAG;
|
|
|
|
FindPara.pSubjectCert = pSubject;
|
|
FindPara.pIssuerCert = pIssuer;
|
|
|
|
while ((pFindCrl = CertFindCRLInStore(
|
|
hCrlStore,
|
|
pIssuer->dwCertEncodingType,
|
|
dwFindFlags,
|
|
CRL_FIND_ISSUED_FOR,
|
|
(const void *) &FindPara,
|
|
pFindCrl
|
|
)))
|
|
{
|
|
if (!CertIsValidCRLForCertificate(
|
|
pSubject,
|
|
pFindCrl,
|
|
0, // dwFlags
|
|
NULL // pvReserved
|
|
))
|
|
continue;
|
|
|
|
if ( !(dwMsrevokeFlags &
|
|
MSREVOKE_DONT_CHECK_TIME_VALIDITY_FLAG ))
|
|
{
|
|
if (pRevPara->fCheckFreshnessTime)
|
|
{
|
|
if (CompareFileTime(pftValidFor,
|
|
&pFindCrl->pCrlInfo->ThisUpdate) > 0)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( CompareFileTime(
|
|
pftValidFor,
|
|
&pFindCrl->pCrlInfo->NextUpdate
|
|
) > 0 &&
|
|
!I_CryptIsZeroFileTime(
|
|
&pFindCrl->pCrlInfo->NextUpdate) )
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( NULL == *ppCrl )
|
|
{
|
|
*ppCrl = CertDuplicateCRLContext(pFindCrl);
|
|
}
|
|
else
|
|
{
|
|
PCCRL_CONTEXT pPrevCrl = *ppCrl;
|
|
|
|
// See if this CRL is newer
|
|
if ( CompareFileTime(
|
|
&pFindCrl->pCrlInfo->ThisUpdate,
|
|
&pPrevCrl->pCrlInfo->ThisUpdate
|
|
) > 0 )
|
|
{
|
|
CertFreeCRLContext(pPrevCrl);
|
|
*ppCrl = CertDuplicateCRLContext(pFindCrl);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( *ppCrl != NULL )
|
|
{
|
|
return( TRUE );
|
|
}
|
|
else if ( pCDPExt == NULL )
|
|
{
|
|
SetLastError( (DWORD) CRYPT_E_NO_REVOCATION_CHECK );
|
|
return( FALSE );
|
|
}
|
|
|
|
if ( !( dwRevFlags & CERT_VERIFY_CACHE_ONLY_BASED_REVOCATION ) )
|
|
{
|
|
if (dwRevFlags & CERT_VERIFY_REV_ACCUMULATIVE_TIMEOUT_FLAG) {
|
|
pRevPara->dwUrlRetrievalTimeout =
|
|
I_CryptRemainingMilliseconds(pftEndUrlRetrieval);
|
|
if (0 == pRevPara->dwUrlRetrievalTimeout)
|
|
pRevPara->dwUrlRetrievalTimeout = 1;
|
|
|
|
dwFlags |= CRYPT_ACCUMULATIVE_TIMEOUT;
|
|
}
|
|
|
|
fResult = CryptGetTimeValidObject(
|
|
pszTimeValidOid,
|
|
pvTimeValidPara,
|
|
pIssuer,
|
|
pftValidFor,
|
|
dwFlags | CRYPT_WIRE_ONLY_RETRIEVAL,
|
|
pRevPara->dwUrlRetrievalTimeout,
|
|
(LPVOID *)ppCrl,
|
|
NULL, // pCredentials
|
|
NULL // pvReserved
|
|
);
|
|
*pfWireRetrieval = TRUE;
|
|
}
|
|
else if ( hCrlStore != NULL )
|
|
{
|
|
SetLastError( dwSaveErr );
|
|
}
|
|
|
|
assert( pCDPExt );
|
|
if (!fResult)
|
|
{
|
|
if ( CRYPT_E_NOT_FOUND == GetLastError() )
|
|
{
|
|
SetLastError( (DWORD) CRYPT_E_NO_REVOCATION_CHECK );
|
|
}
|
|
else
|
|
{
|
|
SetLastError( (DWORD) CRYPT_E_REVOCATION_OFFLINE );
|
|
}
|
|
}
|
|
}
|
|
|
|
return( fResult );
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: GetBaseCrl
|
|
//
|
|
// Synopsis: get the base CRL associated with the subject certificate
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
BOOL GetBaseCrl (
|
|
IN PCCERT_CONTEXT pSubject,
|
|
IN PCCERT_CONTEXT pIssuer,
|
|
IN PCERT_REVOCATION_PARA pRevPara,
|
|
IN PCERT_EXTENSION pCDPExt,
|
|
IN DWORD dwRevFlags,
|
|
IN FILETIME *pftEndUrlRetrieval,
|
|
OUT PCCRL_CONTEXT *ppBaseCrl,
|
|
OUT BOOL *pfBaseCrlTimeValid,
|
|
OUT BOOL *pfBaseWireRetrieval
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
PCCRL_CONTEXT pBaseCrl = NULL;
|
|
|
|
*pfBaseWireRetrieval = FALSE;
|
|
|
|
if (GetTimeValidCrl(
|
|
TIME_VALID_OID_GET_CRL_FROM_CERT,
|
|
(LPVOID) pSubject,
|
|
pSubject,
|
|
pIssuer,
|
|
pRevPara,
|
|
pCDPExt,
|
|
dwRevFlags,
|
|
0, // dwMsrevokeFlags
|
|
pftEndUrlRetrieval,
|
|
&pBaseCrl,
|
|
pfBaseWireRetrieval
|
|
)) {
|
|
*pfBaseCrlTimeValid = TRUE;
|
|
} else {
|
|
*pfBaseCrlTimeValid = FALSE;
|
|
|
|
if (!GetTimeValidCrl(
|
|
TIME_VALID_OID_GET_CRL_FROM_CERT,
|
|
(LPVOID) pSubject,
|
|
pSubject,
|
|
pIssuer,
|
|
pRevPara,
|
|
pCDPExt,
|
|
dwRevFlags,
|
|
MSREVOKE_DONT_CHECK_TIME_VALIDITY_FLAG,
|
|
pftEndUrlRetrieval,
|
|
&pBaseCrl,
|
|
pfBaseWireRetrieval
|
|
))
|
|
{
|
|
goto GetTimeInvalidCrlError;
|
|
}
|
|
}
|
|
|
|
if (HasUnsupportedCrlCriticalExtension(pBaseCrl))
|
|
goto HasUnsupportedCriticalExtensionError;
|
|
|
|
fResult = TRUE;
|
|
|
|
CommonReturn:
|
|
*ppBaseCrl = pBaseCrl;
|
|
return fResult;
|
|
ErrorReturn:
|
|
if (pBaseCrl) {
|
|
CertFreeCRLContext(pBaseCrl);
|
|
pBaseCrl = NULL;
|
|
}
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
TRACE_ERROR(GetTimeInvalidCrlError)
|
|
SET_ERROR(HasUnsupportedCriticalExtensionError, CRYPT_E_NO_REVOCATION_CHECK)
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: GetDeltaCrl
|
|
//
|
|
// Synopsis: get the delta CRL associated with the subject certificate and
|
|
// its base CRL
|
|
//
|
|
// For now, always return TRUE. If not able to find a delta CRL, set
|
|
// *pfCrlTimeValid to FALSE.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
BOOL GetDeltaCrl (
|
|
IN PCCERT_CONTEXT pSubject,
|
|
IN PCCERT_CONTEXT pIssuer,
|
|
IN PCERT_REVOCATION_PARA pRevPara,
|
|
IN DWORD dwRevFlags,
|
|
IN BOOL fBaseWireRetrieval,
|
|
IN FILETIME *pftEndUrlRetrieval,
|
|
IN OUT PCCRL_CONTEXT *ppBaseCrl,
|
|
IN OUT BOOL *pfCrlTimeValid,
|
|
OUT PCCRL_CONTEXT *ppDeltaCrl,
|
|
OUT DWORD *pdwFreshnessTime
|
|
)
|
|
{
|
|
PCERT_EXTENSION pFreshestExt;
|
|
PCCRL_CONTEXT pBaseCrl = *ppBaseCrl;
|
|
PCCRL_CONTEXT pDeltaCrl = NULL;
|
|
LPCSTR pszTimeValidOid;
|
|
LPVOID pvTimeValidPara;
|
|
CERT_CRL_CONTEXT_PAIR CertCrlPair;
|
|
BOOL fDeltaWireRetrieval;
|
|
|
|
PCERT_EXTENSION pBaseCrlNumberExt;
|
|
PCERT_EXTENSION pDeltaCrlIndicatorExt;
|
|
int iBaseCrlNumber = 0;
|
|
int iDeltaCrlIndicator = 0;
|
|
DWORD cbInt;
|
|
|
|
LPFILETIME pFreshnessThisUpdate;
|
|
|
|
assert(pBaseCrl);
|
|
|
|
// Check if the base CRL or the subject certificate has a freshest
|
|
// ext
|
|
if (pFreshestExt = CertFindExtension(
|
|
szOID_FRESHEST_CRL,
|
|
pBaseCrl->pCrlInfo->cExtension,
|
|
pBaseCrl->pCrlInfo->rgExtension
|
|
)) {
|
|
pszTimeValidOid = TIME_VALID_OID_GET_FRESHEST_CRL_FROM_CRL;
|
|
|
|
CertCrlPair.pCertContext = pSubject;
|
|
CertCrlPair.pCrlContext = pBaseCrl;
|
|
pvTimeValidPara = (LPVOID) &CertCrlPair;
|
|
} else if (pFreshestExt = CertFindExtension(
|
|
szOID_FRESHEST_CRL,
|
|
pSubject->pCertInfo->cExtension,
|
|
pSubject->pCertInfo->rgExtension
|
|
)) {
|
|
pszTimeValidOid = TIME_VALID_OID_GET_FRESHEST_CRL_FROM_CERT;
|
|
pvTimeValidPara = (LPVOID) pSubject;
|
|
} else {
|
|
goto NoDeltaCrlReturn;
|
|
}
|
|
|
|
if (GetTimeValidCrl(
|
|
pszTimeValidOid,
|
|
pvTimeValidPara,
|
|
pSubject,
|
|
pIssuer,
|
|
pRevPara,
|
|
pFreshestExt,
|
|
dwRevFlags,
|
|
MSREVOKE_DELTA_CRL_FLAG,
|
|
pftEndUrlRetrieval,
|
|
&pDeltaCrl,
|
|
&fDeltaWireRetrieval
|
|
)) {
|
|
*pfCrlTimeValid = TRUE;
|
|
} else {
|
|
*pfCrlTimeValid = FALSE;
|
|
|
|
if (!GetTimeValidCrl(
|
|
pszTimeValidOid,
|
|
pvTimeValidPara,
|
|
pSubject,
|
|
pIssuer,
|
|
pRevPara,
|
|
pFreshestExt,
|
|
dwRevFlags,
|
|
MSREVOKE_DELTA_CRL_FLAG |
|
|
MSREVOKE_DONT_CHECK_TIME_VALIDITY_FLAG,
|
|
pftEndUrlRetrieval,
|
|
&pDeltaCrl,
|
|
&fDeltaWireRetrieval
|
|
))
|
|
{
|
|
goto GetTimeInvalidCrlError;
|
|
}
|
|
}
|
|
|
|
if (HasUnsupportedCrlCriticalExtension(pDeltaCrl))
|
|
goto HasUnsupportedCriticalExtensionError;
|
|
|
|
// Check that the base CRL number >= delta CRL indicator
|
|
if (NULL == (pBaseCrlNumberExt = CertFindExtension(
|
|
szOID_CRL_NUMBER,
|
|
pBaseCrl->pCrlInfo->cExtension,
|
|
pBaseCrl->pCrlInfo->rgExtension
|
|
)))
|
|
goto MissingBaseCrlNumberError;
|
|
if (NULL == (pDeltaCrlIndicatorExt = CertFindExtension(
|
|
szOID_DELTA_CRL_INDICATOR,
|
|
pDeltaCrl->pCrlInfo->cExtension,
|
|
pDeltaCrl->pCrlInfo->rgExtension
|
|
)))
|
|
goto MissingDeltaCrlIndicatorError;
|
|
|
|
cbInt = sizeof(iBaseCrlNumber);
|
|
if (!CryptDecodeObject(
|
|
pBaseCrl->dwCertEncodingType,
|
|
X509_INTEGER,
|
|
pBaseCrlNumberExt->Value.pbData,
|
|
pBaseCrlNumberExt->Value.cbData,
|
|
0, // dwFlags
|
|
&iBaseCrlNumber,
|
|
&cbInt
|
|
))
|
|
goto DecodeBaseCrlNumberError;
|
|
|
|
cbInt = sizeof(iDeltaCrlIndicator);
|
|
if (!CryptDecodeObject(
|
|
pDeltaCrl->dwCertEncodingType,
|
|
X509_INTEGER,
|
|
pDeltaCrlIndicatorExt->Value.pbData,
|
|
pDeltaCrlIndicatorExt->Value.cbData,
|
|
0, // dwFlags
|
|
&iDeltaCrlIndicator,
|
|
&cbInt
|
|
))
|
|
goto DecodeDeltaCrlIndicatorError;
|
|
|
|
pFreshnessThisUpdate = &pDeltaCrl->pCrlInfo->ThisUpdate;
|
|
|
|
if (iBaseCrlNumber < iDeltaCrlIndicator) {
|
|
BOOL fValidBaseCrl = FALSE;
|
|
|
|
if (!fBaseWireRetrieval &&
|
|
0 == (dwRevFlags & CERT_VERIFY_CACHE_ONLY_BASED_REVOCATION)) {
|
|
// Attempt to get a more recent base CRL by hitting the wire
|
|
PCCRL_CONTEXT pWireBaseCrl = NULL;
|
|
|
|
CRL_IS_VALID_EXTRA_INFO CrlIsValidExtraInfo =
|
|
{ iDeltaCrlIndicator };
|
|
|
|
|
|
if (CryptGetTimeValidObject(
|
|
TIME_VALID_OID_GET_CRL_FROM_CERT,
|
|
(LPVOID)pSubject,
|
|
pIssuer,
|
|
NULL, // pftValidFor
|
|
CRYPT_WIRE_ONLY_RETRIEVAL | CRYPT_DONT_CHECK_TIME_VALIDITY,
|
|
pRevPara->dwUrlRetrievalTimeout,
|
|
(LPVOID *) &pWireBaseCrl,
|
|
NULL, // pCredentials
|
|
&CrlIsValidExtraInfo
|
|
)) {
|
|
|
|
// Already checked that the new Base CRL number is valid
|
|
CertFreeCRLContext(pBaseCrl);
|
|
*ppBaseCrl = pBaseCrl = pWireBaseCrl;
|
|
fValidBaseCrl = TRUE;
|
|
}
|
|
}
|
|
|
|
if (!fValidBaseCrl) {
|
|
*pfCrlTimeValid = FALSE;
|
|
pFreshnessThisUpdate = &pBaseCrl->pCrlInfo->ThisUpdate;
|
|
}
|
|
}
|
|
|
|
*pdwFreshnessTime = I_CryptSubtractFileTimes(
|
|
pRevPara->pftCurrentTime, pFreshnessThisUpdate);
|
|
|
|
if (pRevPara->fCheckFreshnessTime) {
|
|
if (pRevPara->dwFreshnessTime >= *pdwFreshnessTime)
|
|
*pfCrlTimeValid = TRUE;
|
|
else
|
|
*pfCrlTimeValid = FALSE;
|
|
}
|
|
|
|
NoDeltaCrlReturn:
|
|
|
|
CommonReturn:
|
|
*ppDeltaCrl = pDeltaCrl;
|
|
return TRUE;
|
|
ErrorReturn:
|
|
if (pDeltaCrl) {
|
|
CertFreeCRLContext(pDeltaCrl);
|
|
pDeltaCrl = NULL;
|
|
}
|
|
*pfCrlTimeValid = FALSE;
|
|
goto CommonReturn;
|
|
|
|
TRACE_ERROR(GetTimeInvalidCrlError)
|
|
SET_ERROR(HasUnsupportedCriticalExtensionError, CRYPT_E_NO_REVOCATION_CHECK)
|
|
SET_ERROR(MissingBaseCrlNumberError, CRYPT_E_NO_REVOCATION_CHECK)
|
|
SET_ERROR(MissingDeltaCrlIndicatorError, CRYPT_E_NO_REVOCATION_CHECK)
|
|
TRACE_ERROR(DecodeBaseCrlNumberError)
|
|
TRACE_ERROR(DecodeDeltaCrlIndicatorError)
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// If the CRL entry has a CRL Reason extension, the enumerated reason
|
|
// code is returned. Otherwise, a reason code of 0 is returned.
|
|
//--------------------------------------------------------------------------
|
|
DWORD GetCrlReason(
|
|
IN PCRL_ENTRY pCrlEntry
|
|
)
|
|
{
|
|
DWORD dwReason = 0;
|
|
PCERT_EXTENSION pExt;
|
|
|
|
// Check if the certificate has a szOID_CRL_REASON_CODE extension
|
|
if (pExt = CertFindExtension(
|
|
szOID_CRL_REASON_CODE,
|
|
pCrlEntry->cExtension,
|
|
pCrlEntry->rgExtension
|
|
)) {
|
|
DWORD cbInfo = sizeof(dwReason);
|
|
CryptDecodeObject(
|
|
CRYPT_ASN_ENCODING,
|
|
X509_CRL_REASON_CODE,
|
|
pExt->Value.pbData,
|
|
pExt->Value.cbData,
|
|
0, // dwFlags
|
|
&dwReason,
|
|
&cbInfo);
|
|
}
|
|
return dwReason;
|
|
}
|
|
|
|
//+=========================================================================
|
|
// Get Issuer Certificate Functions
|
|
//==========================================================================
|
|
|
|
PCCERT_CONTEXT FindIssuerCertInStores(
|
|
IN PCCERT_CONTEXT pSubjectCert,
|
|
IN DWORD cStore,
|
|
IN HCERTSTORE rgStore[]
|
|
)
|
|
{
|
|
PCCERT_CONTEXT pIssuerCert = NULL;
|
|
DWORD i;
|
|
|
|
for (i = 0; i < cStore; i++) {
|
|
while (TRUE) {
|
|
DWORD dwFlags = CERT_STORE_SIGNATURE_FLAG;
|
|
pIssuerCert = CertGetIssuerCertificateFromStore(
|
|
rgStore[i],
|
|
pSubjectCert,
|
|
pIssuerCert,
|
|
&dwFlags);
|
|
if (NULL == pIssuerCert) {
|
|
if (CRYPT_E_SELF_SIGNED == GetLastError()) {
|
|
if (0 == (dwFlags & CERT_STORE_SIGNATURE_FLAG))
|
|
pIssuerCert = CertDuplicateCertificateContext(
|
|
pSubjectCert);
|
|
return pIssuerCert;
|
|
}
|
|
break;
|
|
} else if (0 == (dwFlags & CERT_STORE_SIGNATURE_FLAG))
|
|
return pIssuerCert;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static PCCERT_CONTEXT FindIssuerCertInDefaultStores(
|
|
IN PCCERT_CONTEXT pSubjectCert
|
|
)
|
|
{
|
|
PCCERT_CONTEXT pIssuerCert;
|
|
HCERTSTORE hStore;
|
|
DWORD i;
|
|
|
|
for (i = 0; i < NUM_DEFAULT_ISSUER_STORES; i++) {
|
|
if (hStore = CertOpenStore(
|
|
CERT_STORE_PROV_SYSTEM_W,
|
|
0, // dwEncodingType
|
|
0, // hCryptProv
|
|
rgDefaultIssuerStores[i].dwFlags | CERT_STORE_READONLY_FLAG,
|
|
(const void *) rgDefaultIssuerStores[i].pwszStore
|
|
)) {
|
|
pIssuerCert = FindIssuerCertInStores(pSubjectCert, 1, &hStore);
|
|
CertCloseStore(hStore, 0);
|
|
if (pIssuerCert)
|
|
return pIssuerCert;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
// Get the issuer of the first certificate in the array
|
|
//
|
|
// Note, pRevPara is our copy and guaranteed to contain all the fields.
|
|
//--------------------------------------------------------------------------
|
|
PCCERT_CONTEXT GetIssuerCert(
|
|
IN DWORD cCert,
|
|
IN PCCERT_CONTEXT rgpCert[],
|
|
IN DWORD dwFlags,
|
|
IN PCERT_REVOCATION_PARA pRevPara
|
|
)
|
|
{
|
|
PCCERT_CONTEXT pSubjectCert;
|
|
PCCERT_CONTEXT pIssuerCert = NULL;
|
|
|
|
assert(cCert >= 1);
|
|
pSubjectCert = rgpCert[0];
|
|
if (cCert == 1) {
|
|
pIssuerCert = pRevPara->pIssuerCert;
|
|
if (NULL == pIssuerCert && CertCompareCertificateName(
|
|
pSubjectCert->dwCertEncodingType,
|
|
&pSubjectCert->pCertInfo->Subject,
|
|
&pSubjectCert->pCertInfo->Issuer))
|
|
// Self issued
|
|
pIssuerCert = pSubjectCert;
|
|
} else if (dwFlags & CERT_VERIFY_REV_CHAIN_FLAG)
|
|
pIssuerCert = rgpCert[1];
|
|
|
|
if (pIssuerCert)
|
|
pIssuerCert = CertDuplicateCertificateContext(pIssuerCert);
|
|
else {
|
|
pIssuerCert = FindIssuerCertInStores(
|
|
pSubjectCert, pRevPara->cCertStore, pRevPara->rgCertStore);
|
|
if (NULL == pIssuerCert)
|
|
pIssuerCert = FindIssuerCertInDefaultStores(pSubjectCert);
|
|
}
|
|
|
|
if (NULL == pIssuerCert)
|
|
SetLastError((DWORD) CRYPT_E_REVOCATION_OFFLINE);
|
|
return pIssuerCert;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: CrlIssuerIsCertIssuer
|
|
//
|
|
// Synopsis: is the issuer of the CRL the issuer of the cert
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
BOOL CrlIssuerIsCertIssuer (
|
|
IN PCCERT_CONTEXT pCert,
|
|
IN PCERT_EXTENSION pCrlDistPointExt
|
|
)
|
|
{
|
|
BOOL fResult = FALSE;
|
|
DWORD cb = sizeof( PCRL_DIST_POINTS_INFO );
|
|
PCRL_DIST_POINTS_INFO pDistPointInfo;
|
|
|
|
if ( pCrlDistPointExt == NULL )
|
|
{
|
|
return( TRUE );
|
|
}
|
|
|
|
if ( CryptDecodeObjectEx(
|
|
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
|
szOID_CRL_DIST_POINTS,
|
|
pCrlDistPointExt->Value.pbData,
|
|
pCrlDistPointExt->Value.cbData,
|
|
CRYPT_DECODE_ALLOC_FLAG,
|
|
NULL,
|
|
(void *)&pDistPointInfo,
|
|
&cb
|
|
) == TRUE )
|
|
{
|
|
if ( pDistPointInfo->cDistPoint > 0 )
|
|
{
|
|
if ( pDistPointInfo->rgDistPoint[ 0 ].CRLIssuer.cAltEntry == 0 )
|
|
{
|
|
fResult = TRUE;
|
|
}
|
|
else if ( pDistPointInfo->rgDistPoint[ 0 ].CRLIssuer.rgAltEntry[ 0 ].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME )
|
|
{
|
|
if ( pDistPointInfo->rgDistPoint[ 0 ].CRLIssuer.rgAltEntry[ 0 ].DirectoryName.cbData == 0 )
|
|
{
|
|
fResult = TRUE;
|
|
}
|
|
else if ( ( pDistPointInfo->rgDistPoint[ 0 ].CRLIssuer.rgAltEntry[ 0 ].DirectoryName.cbData ==
|
|
pCert->pCertInfo->Issuer.cbData ) &&
|
|
( memcmp(
|
|
pDistPointInfo->rgDistPoint[ 0 ].CRLIssuer.rgAltEntry[ 0 ].DirectoryName.pbData,
|
|
pCert->pCertInfo->Issuer.pbData,
|
|
pCert->pCertInfo->Issuer.cbData
|
|
) == 0 ) )
|
|
{
|
|
fResult = TRUE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fResult = TRUE;
|
|
}
|
|
|
|
LocalFree( pDistPointInfo );
|
|
}
|
|
|
|
return( fResult );
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: CertDllVerifyRevocation
|
|
//
|
|
// Synopsis: Dispatches to msrevoke
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
BOOL WINAPI
|
|
CertDllVerifyRevocation(
|
|
IN DWORD dwEncodingType,
|
|
IN DWORD dwRevType,
|
|
IN DWORD cContext,
|
|
IN PVOID rgpvContext[],
|
|
IN DWORD dwFlags,
|
|
IN PCERT_REVOCATION_PARA pRevPara,
|
|
IN OUT PCERT_REVOCATION_STATUS pRevStatus
|
|
)
|
|
{
|
|
return MicrosoftCertDllVerifyRevocation(
|
|
dwEncodingType,
|
|
dwRevType,
|
|
cContext,
|
|
rgpvContext,
|
|
dwFlags,
|
|
pRevPara,
|
|
pRevStatus
|
|
);
|
|
}
|