Leaked source code of windows server 2003
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.
 
 
 
 
 
 

975 lines
22 KiB

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Microsoft Windows, Copyright (C) Microsoft Corporation, 2000
File: CertificateStatus.cpp
Contents: Implementation of CCertificateStatus
Remarks: This object is not creatable by user directly. It can only be
created via property/method of other CAPICOM objects.
History: 11-15-99 dsie created
------------------------------------------------------------------------------*/
#include "StdAfx.h"
#include "CAPICOM.h"
#include "CertificateStatus.h"
#include "Chain.h"
#include "OIDs.h"
///////////////
//
// Local
//
#define DEFAULT_CHECK_FLAGS ((CAPICOM_CHECK_FLAG) (CAPICOM_CHECK_SIGNATURE_VALIDITY | \
CAPICOM_CHECK_TIME_VALIDITY | \
CAPICOM_CHECK_TRUSTED_ROOT))
////////////////////////////////////////////////////////////////////////////////
//
// Exported functions.
//
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CreateCertificateStatusObject
Synopsis : Create an ICertificateStatus object.
Parameter: PCCERT_CONTEXT pCertContext - Pointer to CERT_CONTEXT.
ICertificateStatus ** ppICertificateStatus - Pointer to pointer
ICertificateStatus
object.
Remark :
------------------------------------------------------------------------------*/
HRESULT CreateCertificateStatusObject (PCCERT_CONTEXT pCertContext,
ICertificateStatus ** ppICertificateStatus)
{
HRESULT hr = S_OK;
CComObject<CCertificateStatus> * pCCertificateStatus = NULL;
DebugTrace("Entering CreateCertificateStatusObject().\n");
//
// Sanity check.
//
ATLASSERT(pCertContext);
ATLASSERT(ppICertificateStatus);
try
{
//
// Create the object. Note that the ref count will still be 0
// after the object is created.
//
if (FAILED(hr = CComObject<CCertificateStatus>::CreateInstance(&pCCertificateStatus)))
{
DebugTrace("Error [%#x]: CComObject<CCertificateStatus>::CreateInstance() failed.\n", hr);
goto ErrorExit;
}
//
// Initialize the object.
//
if (FAILED(hr = pCCertificateStatus->Init(pCertContext)))
{
DebugTrace("Error [%#x]: pCCertificateStatus->Init() failed.\n", hr);
goto ErrorExit;
}
//
// Return ICertificateStatus pointer to caller.
//
if (FAILED(hr = pCCertificateStatus->QueryInterface(ppICertificateStatus)))
{
DebugTrace("Error [%#x]: pCCertificateStatus->QueryInterface() failed.\n", hr);
goto ErrorExit;
}
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
CommonExit:
DebugTrace("Leaving CreateCertificateStatusObject().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
//
// Free resource.
//
if (pCCertificateStatus)
{
delete pCCertificateStatus;
}
goto CommonExit;
}
////////////////////////////////////////////////////////////////////////////////
//
// CCertificateStatus
//
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CCertificateStatus::get_Result
Synopsis : Return the overall validity result of the cert, based on the
currently set check flags and EKU.
Parameter: VARIANT_BOOL * pVal - Pointer to VARIANT_BOOL to receive result.
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CCertificateStatus::get_Result (VARIANT_BOOL * pVal)
{
HRESULT hr = S_OK;
CComPtr<IChain> pIChain = NULL;
DebugTrace("Entering CCertificateStatus::get_Result().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
//
// Check parameters.
//
if (NULL == pVal)
{
hr = E_INVALIDARG;
DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
goto ErrorExit;
}
//
// Sanity check.
//
ATLASSERT(m_pCertContext);
//
// Build the chain and return the result.
//
if (FAILED(hr = ::CreateChainObject(m_pCertContext, this, NULL, pVal, &pIChain)))
{
DebugTrace("Error [%#x]: CreateChainObject() failed.\n", hr);
goto ErrorExit;
}
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
UnlockExit:
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CCertificateStatus::get_Result().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CCertificateStatus::get_CheckFlag
Synopsis : Return the currently set validity check flag.
Parameter: CAPICOM_CHECK_FLAG * pVal - Pointer to CAPICOM_CHECK_FLAG to
receive check flag.
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CCertificateStatus::get_CheckFlag (CAPICOM_CHECK_FLAG * pVal)
{
HRESULT hr = S_OK;
DebugTrace("Entering CCertificateStatus::get_CheckFlag().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
//
// Check parameters.
//
if (NULL == pVal)
{
hr = E_INVALIDARG;
DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
goto ErrorExit;
}
//
// Return flag to user.
//
*pVal = m_CheckFlag;
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
UnlockExit:
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CCertificateStatus::get_CheckFlag().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CCertificateStatus::put_CheckFlag
Synopsis : Set validity check flag.
Parameter: CAPICOM_CHECK_FLAG newVal - Check flag.
Remark : Note that CHECK_ONLINE_REVOCATION_STATUS and
CHECK_OFFLINE_REVOCATION_STATUS is mutually exclusive.
------------------------------------------------------------------------------*/
STDMETHODIMP CCertificateStatus::put_CheckFlag (CAPICOM_CHECK_FLAG newVal)
{
HRESULT hr = S_OK;
DebugTrace("Entering CCertificateStatus::put_CheckFlag().\n");
//
// Lock access to this object.
//
m_Lock.Lock();
//
// Make sure flag is valid (maximum is CAPICOM_CHECK_OFFLINE_ALL).
//
if ((newVal & CAPICOM_CHECK_FLAG_LO_MASK) > CAPICOM_CHECK_OFFLINE_ALL)
{
hr = E_INVALIDARG;
DebugTrace("Error [%#x]: invalid check flag (%#x).\n", hr, newVal);
goto ErrorExit;
}
//
// Store check flag.
//
m_CheckFlag = newVal;
UnlockExit:
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CCertificateStatus::put_CheckFlag().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CCertificateStatus::EKU
Synopsis : Return the EKU object.
Parameter: IEKU ** pVal - Pointer to pointer to IEKU to receive the
interface pointer.
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CCertificateStatus::EKU (IEKU ** pVal)
{
HRESULT hr = S_OK;
DebugTrace("Entering CCertificateStatus::EKU().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
//
// Check parameters.
//
if (NULL == pVal)
{
hr = E_INVALIDARG;
DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
goto ErrorExit;
}
//
// Sanity check.
//
ATLASSERT(m_pIEKU);
//
// Return interface pointer to user.
//
if (FAILED(hr = m_pIEKU->QueryInterface(pVal)))
{
DebugTrace("Error [%#x]: m_pIEKU->QueryInterface() failed.\n", hr);
goto ErrorExit;
}
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
UnlockExit:
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CCertificateStatus::EKU().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CCertificateStatus::get_VerificationTime
Synopsis : Return the verification time.
Parameter: DATE * pVal - Pointer to DATE to receive the value.
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CCertificateStatus::get_VerificationTime (DATE * pVal)
{
HRESULT hr = S_OK;
SYSTEMTIME st = {0};
DebugTrace("Entering CCertificateStatus::get_VerificationTime().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
//
// Make sure paremeters are valid.
//
if (NULL == pVal)
{
hr = E_INVALIDARG;
DebugTrace("Error [%#x]: Paremeter pVal is NULL.\n", hr);
goto ErrorExit;
}
//
// If the time was never explicit set by user, return the current time.
//
if ((DATE) 0 == m_VerificationTime)
{
::GetLocalTime(&st);
//
// Convert to DATE.
//
if (0 == ::SystemTimeToVariantTime(&st, pVal))
{
hr = E_INVALIDARG;
DebugTrace("Error [%#x]: SystemTimeToVariantTime() failed.\n", hr);
goto ErrorExit;
}
}
else
{
//
// Return previously set verification time to caller.
//
*pVal = m_VerificationTime;
}
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
UnlockExit:
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CCertificateStatus::get_VerificationTime().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CCertificateStatus::put_VerificationTime
Synopsis : Set the verification time.
Parameter: DATE newVal - New DATE value.
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CCertificateStatus::put_VerificationTime (DATE newVal)
{
HRESULT hr = S_OK;
DebugTrace("Entering CCertificateStatus::put_VerificationTime().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
//
// Update verification time.
//
m_VerificationTime = newVal;
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
UnlockExit:
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CCertificateStatus::put_VerificationTime().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CCertificateStatus::get_UrlRetrievalTimeout
Synopsis : Get the URL retrieval timeout value in seconds.
Parameter: long * pVal - Pointer to long to receive the value.
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CCertificateStatus::get_UrlRetrievalTimeout (long * pVal)
{
HRESULT hr = S_OK;
DebugTrace("Entering CCertificateStatus::get_UrlRetrievalTimeout().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
//
// Make sure paremeters are valid.
//
if (NULL == pVal)
{
hr = E_INVALIDARG;
DebugTrace("Error [%#x]: Paremeter pVal is NULL.\n", hr);
goto ErrorExit;
}
//
// Return previously set URL retrieval timeout to caller.
//
*pVal = m_dwUrlRetrievalTimeout;
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
UnlockExit:
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CCertificateStatus::get_UrlRetrievalTimeout().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CCertificateStatus::put_UrlRetrievalTimeout
Synopsis : Set the URL retrieval timeout value in seconds.
Parameter: long newVal - New URL retrieval timeout value..
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CCertificateStatus::put_UrlRetrievalTimeout (long newVal)
{
HRESULT hr = S_OK;
DebugTrace("Entering CCertificateStatus::put_UrlRetrievalTimeout().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
//
// Make sure paremeters are valid.
//
if (CAPICOM_MAX_URL_RETRIEVAL_TIMEOUT < (DWORD) newVal)
{
hr = E_INVALIDARG;
DebugTrace("Error [%#x]: newVal (%#x) is greater than max retrieval timeout allowed.\n",
hr, newVal);
goto ErrorExit;
}
//
// Update URL retrieval timeout.
//
m_dwUrlRetrievalTimeout = newVal;
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
UnlockExit:
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CCertificateStatus::put_UrlRetrievalTimeout().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CCertificateStatus::CertificatePolicies
Synopsis : Return the certificate policies OIDs collection for which this
chain is valid.
Parameter: IOID ** pVal - Pointer to pointer to IOIDs to receive the
interface pointer.
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CCertificateStatus::CertificatePolicies (IOIDs ** pVal)
{
HRESULT hr = S_OK;
DebugTrace("Entering CCertificateStatus::CertificatePolicies().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
//
// Check parameters.
//
if (NULL == pVal)
{
hr = E_INVALIDARG;
DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
goto ErrorExit;
}
//
// Sanity check.
//
ATLASSERT(m_pICertificatePolicies);
//
// Return interface pointer to user.
//
if (FAILED(hr = m_pICertificatePolicies->QueryInterface(pVal)))
{
DebugTrace("Error [%#x]: m_pICertificatePolicies->QueryInterface() failed.\n", hr);
goto ErrorExit;
}
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
UnlockExit:
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CCertificateStatus::CertificatePolicies().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CCertificateStatus::ApplicationPolicies
Synopsis : Return the application policies OIDs collection for which this
chain is valid.
Parameter: IOID ** pVal - Pointer to pointer to IOIDs to receive the
interface pointer.
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CCertificateStatus::ApplicationPolicies (IOIDs ** pVal)
{
HRESULT hr = S_OK;
DebugTrace("Entering CCertificateStatus::ApplicationPolicies().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
//
// Check parameters.
//
if (NULL == pVal)
{
hr = E_INVALIDARG;
DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
goto ErrorExit;
}
//
// Sanity check.
//
ATLASSERT(m_pIApplicationPolicies);
//
// Return interface pointer to user.
//
if (FAILED(hr = m_pIApplicationPolicies->QueryInterface(pVal)))
{
DebugTrace("Error [%#x]: m_pIApplicationPolicies->QueryInterface() failed.\n", hr);
goto ErrorExit;
}
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
UnlockExit:
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CCertificateStatus::ApplicationPolicies().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
////////////////////////////////////////////////////////////////////////////////
//
// Private methods.
//
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CCertificateStatus::Init
Synopsis : Initialize the object.
Parameter: PCCERT_CONTEXT pCertContext - Pointer to CERT_CONTEXT.
Remark : This method is not part of the COM interface (it is a normal C++
member function). We need it to initialize the object created
internally by us with CERT_CONTEXT.
Since it is only a normal C++ member function, this function can
only be called from a C++ class pointer, not an interface pointer.
------------------------------------------------------------------------------*/
STDMETHODIMP CCertificateStatus::Init (PCCERT_CONTEXT pCertContext)
{
HRESULT hr = S_OK;
CERT_ENHKEY_USAGE eku = {0, NULL};
DebugTrace("Entering CCertificateStatus::Init().\n");
//
// Sanity check.
//
ATLASSERT(pCertContext);
//
// Set default check flags.
//
m_CheckFlag = DEFAULT_CHECK_FLAGS;
//
// Create the EKU object (default no EKU check).
//
if (FAILED(hr = ::CreateEKUObject(NULL, &m_pIEKU)))
{
DebugTrace("Error [%#x]: CreateEKUObject() failed.\n", hr);
goto CommonExit;
}
//
// Create the OIDs collection for certificate policies.
//
if (FAILED(hr = ::CreateOIDsObject(&eku, TRUE, &m_pICertificatePolicies)))
{
DebugTrace("Error [%#x]: CreateOIDsObject() failed.\n", hr);
goto CommonExit;
}
//
// Create the OIDs collection for application policies.
//
if (FAILED(hr = ::CreateOIDsObject(&eku, FALSE, &m_pIApplicationPolicies)))
{
DebugTrace("Error [%#x]: CreateOIDsObject() failed.\n", hr);
goto CommonExit;
}
//
// Save cert context.
//
if (!(m_pCertContext = ::CertDuplicateCertificateContext(pCertContext)))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Error [%#x]: CertDuplicateCertificateContext() failed.\n", hr);
}
m_VerificationTime = (DATE) 0;
m_dwUrlRetrievalTimeout = 0;
CommonExit:
DebugTrace("Leaving CCertificateStatus::Init().\n");
return hr;
}