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.
 
 
 
 
 
 

1262 lines
30 KiB

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Microsoft Windows, Copyright (C) Microsoft Corporation, 2000
File: Signer.cpp
Content: Implementation of CSigner.
History: 11-15-99 dsie created
------------------------------------------------------------------------------*/
#include "StdAfx.h"
#include "CAPICOM.h"
#include "Signer2.h"
#include "CertHlpr.h"
#include "Certificate.h"
#include "Chain.h"
#include "PFXHlpr.h"
#include "SignHlpr.h"
////////////////////////////////////////////////////////////////////////////////
//
// Exported functions.
//
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CreateSignerObject
Synopsis : Create a ISigner object and initialize the object with the
specified certificate.
Parameter: PCCERT_CONTEXT pCertContext - Pointer to CERT_CONTEXT.
CRYPT_ATTRIBUTES * pAuthAttrs - Pointer to CRYPT_ATTRIBUTES
of authenticated attributes.
PCCERT_CHAIN_CONTEXT pChainContext - Chain context.
DWORD dwCurrentSafety - Current safety setting.
ISigner2 ** ppISigner2 - Pointer to pointer to ISigner object to
receive the interface pointer.
Remark :
------------------------------------------------------------------------------*/
HRESULT CreateSignerObject (PCCERT_CONTEXT pCertContext,
CRYPT_ATTRIBUTES * pAuthAttrs,
PCCERT_CHAIN_CONTEXT pChainContext,
DWORD dwCurrentSafety,
ISigner2 ** ppISigner2)
{
HRESULT hr = S_OK;
CComObject<CSigner> * pCSigner = NULL;
DebugTrace("Entering CreateSignerObject().\n");
//
// Sanity check.
//
ATLASSERT(pCertContext);
ATLASSERT(pAuthAttrs);
ATLASSERT(ppISigner2);
try
{
//
// Create the object. Note that the ref count will still be 0
// after the object is created.
//
if (FAILED(hr = CComObject<CSigner>::CreateInstance(&pCSigner)))
{
DebugTrace("Error [%#x]: CComObject<CSigner>::CreateInstance() failed.\n", hr);
goto ErrorExit;
}
//
// Initialize object.
//
if (FAILED(hr = pCSigner->Init(pCertContext,
pAuthAttrs,
pChainContext,
dwCurrentSafety)))
{
DebugTrace("Error [%#x]: pCSigner->Init() failed.\n", hr);
goto ErrorExit;
}
//
// Return interface pointer to caller.
//
if (FAILED(hr = pCSigner->QueryInterface(ppISigner2)))
{
DebugTrace("Error [%#x]: pCSigner->QueryInterface() failed.\n", hr);
goto ErrorExit;
}
}
catch(...)
{
hr = E_INVALIDARG;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
CommonExit:
DebugTrace("Leaving CreateSignerObject().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
//
// Free resource.
//
if (pCSigner)
{
delete pCSigner;
}
goto CommonExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : GetSignerAdditionalStore
Synopsis : Return the additional store, if any.
Parameter: ISigner2 * pISigner - Pointer to signer object.
HCERTSTORE * phCertStore - Pointer to HCERTSOTRE.
Remark : Caller must call CertCloseStore() for the handle returned.
------------------------------------------------------------------------------*/
HRESULT GetSignerAdditionalStore (ISigner2 * pISigner,
HCERTSTORE * phCertStore)
{
HRESULT hr = S_OK;
CComPtr<ICSigner> pICSigner = NULL;
DebugTrace("Entering GetSignerAdditionalStore().\n");
//
// Sanity check.
//
ATLASSERT(pISigner);
ATLASSERT(phCertStore);
//
// Get ICSigner interface pointer.
//
if (FAILED(hr = pISigner->QueryInterface(IID_ICSigner, (void **) &pICSigner)))
{
DebugTrace("Error [%#x]: pISigner->QueryInterface() failed.\n", hr);
goto ErrorExit;
}
//
// Get the HCERTSTORE.
//
if (FAILED(hr = pICSigner->get_AdditionalStore((long *) phCertStore)))
{
DebugTrace("Error [%#x]: pICSigner->get_AdditionalStore() failed.\n", hr);
goto ErrorExit;
}
CommonExit:
DebugTrace("Leaving GetSignerAdditionalStore().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
goto CommonExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : PutSignerAdditionalStore
Synopsis : Set the additional store.
Parameter: ISigner2 * pISigner - Pointer to signer object.
HCERTSTORE hCertStore - Additional store handle.
Remark :
------------------------------------------------------------------------------*/
HRESULT PutSignerAdditionalStore (ISigner2 * pISigner,
HCERTSTORE hCertStore)
{
HRESULT hr = S_OK;
CComPtr<ICSigner> pICSigner = NULL;
DebugTrace("Entering PutSignerAdditionalStore().\n");
//
// Sanity check.
//
ATLASSERT(pISigner);
ATLASSERT(hCertStore);
//
// Get ICSigner interface pointer.
//
if (FAILED(hr = pISigner->QueryInterface(IID_ICSigner, (void **) &pICSigner)))
{
DebugTrace("Error [%#x]: pISigner->QueryInterface() failed.\n", hr);
goto ErrorExit;
}
//
// Get the HCERTSTORE.
//
if (FAILED(hr = pICSigner->put_AdditionalStore((long) hCertStore)))
{
DebugTrace("Error [%#x]: pICSigner->put_AdditionalStore() failed.\n", hr);
goto ErrorExit;
}
CommonExit:
DebugTrace("Leaving PutSignerAdditionalStore().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
goto CommonExit;
}
////////////////////////////////////////////////////////////////////////////////
//
// Local functions.
//
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : SelectSignerCertCallback
Synopsis : Callback routine for CryptUIDlgSelectCertificateW() API for
signer's cert selection.
Parameter: See CryptUI.h for defination.
Remark : Filter out any cert that is not time valid or has no associated
private key.
Also, note that we are not building chain here, since chain
building is costly, and thus present poor user's experience.
Instead, we will build the chain and check validity of the cert
selected (see GetSignerCert function).
------------------------------------------------------------------------------*/
static BOOL WINAPI SelectSignerCertCallback (PCCERT_CONTEXT pCertContext,
BOOL * pfInitialSelectedCert,
void * pvCallbackData)
{
BOOL bResult = FALSE;
int nValidity = 0;
DWORD cb = 0;
//
// Check availability of private key.
//
if (!::CertGetCertificateContextProperty(pCertContext,
CERT_KEY_PROV_INFO_PROP_ID,
NULL,
&cb))
{
DebugTrace("Info: SelectSignerCertCallback() - private key not found.\n");
goto CommonExit;
}
//
// Check cert time validity.
//
if (0 != (nValidity = ::CertVerifyTimeValidity(NULL, pCertContext->pCertInfo)))
{
DebugTrace("Info: SelectSignerCertCallback() - invalid time (%s).\n",
nValidity < 0 ? "not yet valid" : "expired");
goto CommonExit;
}
bResult = TRUE;
CommonExit:
return bResult;
}
///////////////////////////////////////////////////////////////////////////////
//
// CSigner
//
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CSigner::get_Certificate
Synopsis : Return the signer's cert as an ICertificate object.
Parameter: ICertificate ** pVal - Pointer to pointer to ICertificate to receive
interface pointer.
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CSigner::get_Certificate (ICertificate ** pVal)
{
HRESULT hr = S_OK;
DebugTrace("Entering CSigner::get_Certificate().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
//
// Make sure we indeed have a certificate.
//
if (!m_pICertificate)
{
hr = CAPICOM_E_SIGNER_NOT_INITIALIZED;
DebugTrace("Error [%#x]: signer object currently does not have a certificate.\n", hr);
goto ErrorExit;
}
//
// Return interface pointer.
//
if (FAILED(hr = m_pICertificate->QueryInterface(pVal)))
{
DebugTrace("Unexpected error [%#x]: m_pICertificate->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 CSigner::get_Certificate().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CSigner::put_Certificate
Synopsis : Set signer's cert.
Parameter: ICertificate * newVal - Pointer to ICertificate.
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CSigner::put_Certificate (ICertificate * newVal)
{
HRESULT hr = S_OK;
PCCERT_CONTEXT pCertContext = NULL;
DebugTrace("Entering CSigner::put_Certificate().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
//
// Make sure is a valid ICertificate by getting its CERT_CONTEXT.
//
if (FAILED(hr = ::GetCertContext(newVal, &pCertContext)))
{
DebugTrace("Error [%#x]: GetCertContext() failed.\n", hr);
goto ErrorExit;
}
//
// Free the CERT_CONTEXT.
//
if (!::CertFreeCertificateContext(pCertContext))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Error [%#x]: CertFreeCertificateContext() failed.\n", hr);
goto ErrorExit;
}
//
// Reset.
//
if (FAILED(hr = m_pIAttributes->Clear()))
{
DebugTrace("Error [%#x]: m_pIAttributes->Clear() failed.\n", hr);
goto ErrorExit;
}
//
// Store new ICertificate.
//
m_pICertificate = newVal;
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
UnlockExit:
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CSigner::put_Certificate().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CSigner::get_AuthenticatedAttributes
Synopsis : Property to return the IAttributes collection object authenticated
attributes.
Parameter: IAttributes ** pVal - Pointer to pointer to IAttributes to receive
the interface pointer.
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CSigner::get_AuthenticatedAttributes (IAttributes ** pVal)
{
HRESULT hr = S_OK;
DebugTrace("Entering CSigner::get_AuthenticatedAttributes().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
//
// Sanity check.
//
ATLASSERT(m_pIAttributes);
//
// Return interface pointer to caller.
//
if (FAILED(hr = m_pIAttributes->QueryInterface(pVal)))
{
DebugTrace("Unexpected error [%#x]: m_pIAttributes->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 CSigner::get_AuthenticatedAttributes().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CSigner::get_Chain
Synopsis : Return the signer's chain as an IChain object.
Parameter: ICertificate ** pVal - Pointer to pointer to ICertificate to receive
interface pointer.
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CSigner::get_Chain (IChain ** pVal)
{
HRESULT hr = S_OK;
PCCERT_CONTEXT pCertContext = NULL;
PCCERT_CHAIN_CONTEXT pChainContext = NULL;
DebugTrace("Entering CSigner::get_Chain().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
//
// Build the chain, if not available.
//
if (!m_pIChain)
{
//
// Make sure we have a certificate to build the chain.
//
if (!m_pICertificate)
{
hr = CAPICOM_E_SIGNER_NOT_INITIALIZED;
DebugTrace("Error [%#x]: signer object currently does not have a certificate.\n", hr);
goto ErrorExit;
}
if (FAILED(hr = ::GetCertContext(m_pICertificate, &pCertContext)))
{
DebugTrace("Error [%#x]: GetCertContext() failed.\n", hr);
goto ErrorExit;
}
if (FAILED(hr = ::BuildChain(pCertContext, NULL, CERT_CHAIN_POLICY_BASE, &pChainContext)))
{
DebugTrace("Error [%#x]: BuildChain() failed.\n", hr);
goto ErrorExit;
}
//
// Now create the chain object.
//
if (FAILED(hr = ::CreateChainObject(pChainContext, &m_pIChain)))
{
DebugTrace("Error [%#x]: CreateChainObject() failed.\n", hr);
goto ErrorExit;
}
}
//
// Return the signer's chain.
//
if (FAILED(hr = m_pIChain->QueryInterface(pVal)))
{
DebugTrace("Unexpected error [%#x]: m_pIChain->QueryInterface() failed.\n", hr);
goto ErrorExit;
}
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
UnlockExit:
//
// Free resources.
//
if (pCertContext)
{
::CertFreeCertificateContext(pCertContext);
}
if (pChainContext)
{
::CertFreeCertificateChain(pChainContext);
}
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CSigner::get_Chain().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CSigner::get_Options
Synopsis : Get signer's options.
Parameter: CAPICOM_CERTIFICATE_INCLUDE_OPTION * pVal - Pointer to variable
receive value.
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CSigner::get_Options (CAPICOM_CERTIFICATE_INCLUDE_OPTION * pVal)
{
HRESULT hr = S_OK;
DebugTrace("Entering CSigner::get_Options().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
*pVal = (CAPICOM_CERTIFICATE_INCLUDE_OPTION) m_dwIncludeOption;
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
UnlockExit:
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CSigner::get_Options().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CSigner::put_Options
Synopsis : Set signer's options.
Parameter: CAPICOM_CERTIFICATE_INCLUDE_OPTION newVal - Include option.
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CSigner::put_Options (CAPICOM_CERTIFICATE_INCLUDE_OPTION newVal)
{
HRESULT hr = S_OK;
DebugTrace("Entering CSigner::put_Options().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
m_dwIncludeOption = (DWORD) newVal;
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
UnlockExit:
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CSigner::put_Options().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CSigner::Load
Synopsis : Method to load signing certificate from a PFX file.
Parameter: BSTR FileName - PFX file name.
BSTR Password - Password.
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CSigner::Load (BSTR FileName,
BSTR Password)
{
HRESULT hr = S_OK;
CAPICOM_STORE_INFO StoreInfo = {CAPICOM_STORE_INFO_HCERTSTORE, NULL};
CComPtr<ICertificate2> pICertificate = NULL;
DebugTrace("Entering CSigner::Load().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
//
// Not allowed if called from WEB script.
//
if (m_dwCurrentSafety)
{
hr = CAPICOM_E_NOT_ALLOWED;
DebugTrace("Error [%#x]: Loading cert file from WEB script is not allowed.\n", hr);
goto ErrorExit;
}
//
// Check parameters.
//
if (NULL == FileName)
{
hr = E_INVALIDARG;
DebugTrace("Error [%#x]: FileName parameter is NULL.\n", hr);
goto ErrorExit;
}
//
// Work around MIDL problem.
//
if (0 == ::SysStringLen(Password))
{
Password = NULL;
}
//
// Load the PFX.
//
if (FAILED(hr = ::PFXLoadStore((LPWSTR) FileName,
(LPWSTR) Password,
0,
&StoreInfo.hCertStore)))
{
DebugTrace("Error [%#x]: PFXLoadStore() failed.\n", hr);
goto ErrorExit;
}
//
// Get the signer's cert (may prompt user to select signer's cert).
//
if (FAILED(hr = ::SelectCertificate(StoreInfo,
SelectSignerCertCallback,
&pICertificate)))
{
DebugTrace("Error [%#x]: SelectCertificate() failed.\n", hr);
goto ErrorExit;
}
if (FAILED(hr = pICertificate->QueryInterface(__uuidof(ICertificate), (void **) &m_pICertificate)))
{
DebugTrace("Error [%#x]: pICertificate2->QueryInterface() failed.\n", hr);
goto ErrorExit;
}
//
// Free any existing store, and then update the store.
//
if (m_hCertStore)
{
HRESULT hr2;
//
// Ignore error.
//
if (m_bPFXStore)
{
if (FAILED(hr2 = ::PFXFreeStore(m_hCertStore)))
{
DebugTrace("Info [%#x]: PFXFreeStore() failed.\n", hr2);
}
}
else
{
if (!::CertCloseStore(m_hCertStore, 0))
{
hr2 = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Info [%#x]: CertCloseStore() failed.\n", hr2);
}
}
}
m_hCertStore = StoreInfo.hCertStore;
m_bPFXStore = TRUE;
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
UnlockExit:
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CSigner::Load().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
//
// Free resources.
//
if (StoreInfo.hCertStore)
{
::PFXFreeStore(StoreInfo.hCertStore);
}
ReportError(hr);
goto UnlockExit;
}
////////////////////////////////////////////////////////////////////////////////
//
// Custom interfaces.
//
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CSigner::get_AdditionalStore
Synopsis : Return the signer additional store handle.
Parameter: long * phAdditionalStore - Pointer to long to receive the HCERTSTORE.
Remark : Caller must call CertCloseStore() for the handle returned.
------------------------------------------------------------------------------*/
STDMETHODIMP CSigner::get_AdditionalStore (long * phAdditionalStore)
{
HRESULT hr = S_OK;
HCERTSTORE hCertStore = NULL;
DebugTrace("Entering CSigner::get_AdditionalStore().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
//
// Check parameter.
//
if (NULL == phAdditionalStore)
{
hr = E_INVALIDARG;
DebugTrace("Error [%#x]: Parameter phAdditionalStore is NULL.\n", hr);
goto ErrorExit;
}
//
// Initialize.
//
*phAdditionalStore = NULL;
//
// Duplicate store handle, if available.
//
if (NULL != m_hCertStore)
{
if (NULL == (hCertStore = ::CertDuplicateStore(m_hCertStore)))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Error [%#x]: CertDuplicateStore() failed.\n", hr);
goto ErrorExit;
}
*phAdditionalStore = (long) hCertStore;
}
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
UnlockExit:
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CSigner::get_AdditionalStore().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
//
// Release resources.
//
if (hCertStore)
{
::CertCloseStore(hCertStore, 0);
}
goto UnlockExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CSigner::put_AdditionalStore
Synopsis : Set the additional sore handle.
Parameter: long hAdditionalStore - Additional store handle.
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CSigner::put_AdditionalStore (long hAdditionalStore)
{
HRESULT hr = S_OK;
HCERTSTORE hCertStore = (HCERTSTORE) hAdditionalStore;
DebugTrace("Entering CSigner::put_AdditionalStore().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
//
// Check parameter.
//
if (NULL == hCertStore)
{
hr = E_INVALIDARG;
DebugTrace("Error [%#x]: Parameter hAdditionalStore is NULL.\n", hr);
goto ErrorExit;
}
//
// Free any existing store, and then update the store.
//
if (m_hCertStore)
{
HRESULT hr2;
//
// Ignore error.
//
if (m_bPFXStore)
{
if (FAILED(hr2 = ::PFXFreeStore(m_hCertStore)))
{
DebugTrace("Info [%#x]: PFXFreeStore() failed.\n", hr2);
}
}
else
{
if (!::CertCloseStore(m_hCertStore, 0))
{
hr2 = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Info [%#x]: CertCloseStore() failed.\n", hr2);
}
}
}
//
// Don't know what kind of store this is, so mark it as such so that we
// will always close it with CertCloseStore(), instead of PFXFreeStore().
//
m_bPFXStore = FALSE;
//
// Duplicate store handle.
//
if (NULL == (m_hCertStore = ::CertDuplicateStore(hCertStore)))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Error [%#x]: CertDuplicateStore() 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 CSigner::put_AdditionalStore().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
////////////////////////////////////////////////////////////////////////////////
//
// Private methods.
//
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CSigner::Init
Synopsis : Initialize the object.
Parameter: PCERT_CONTEXT pCertContext - Poiner to CERT_CONTEXT used to
initialize this object, or NULL.
CRYPT_ATTRIBUTES * pAuthAttrs - Pointer to CRYPT_ATTRIBUTES
of authenticated attributes.
PCCERT_CHAIN_CONTEXT pChainContext - Chain context.
DWORD dwCurrentSafety - Current safety setting.
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.
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 CSigner::Init (PCCERT_CONTEXT pCertContext,
CRYPT_ATTRIBUTES * pAuthAttrs,
PCCERT_CHAIN_CONTEXT pChainContext,
DWORD dwCurrentSafety)
{
HRESULT hr = S_OK;
CComPtr<ICertificate2> pICertificate = NULL;
CComPtr<IAttributes> pIAttributes = NULL;
CComPtr<IChain> pIChain = NULL;
DebugTrace("Entering CSigner::Init().\n");
//
// Sanity check.
//
ATLASSERT(pCertContext);
ATLASSERT(pAuthAttrs);
//
// Create the embeded ICertificate2 object.
//
if (FAILED(hr = ::CreateCertificateObject(pCertContext, dwCurrentSafety, &pICertificate)))
{
DebugTrace("Error [%#x]: CreateCertificateObject() failed.\n", hr);
goto ErrorExit;
}
//
// Create the embeded IAttributes collection object.
//
if (FAILED(hr = ::CreateAttributesObject(pAuthAttrs, &pIAttributes)))
{
DebugTrace("Error [%#x]: CreateAttributesObject() failed.\n", hr);
goto ErrorExit;
}
//
// Created the embeded IChain object if available.
//
if (pChainContext)
{
if (FAILED(hr = ::CreateChainObject(pChainContext, &pIChain)))
{
DebugTrace("Error [%#x]: CreateChainObject() failed.\n", hr);
goto ErrorExit;
}
}
//
// Reset.
//
m_pICertificate = pICertificate;
m_pIAttributes = pIAttributes;
m_pIChain = pIChain;
m_dwCurrentSafety = dwCurrentSafety;
CommonExit:
DebugTrace("Leaving CSigner::Init().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
goto CommonExit;
}