2025-04-27 07:49:33 -04:00

443 lines
10 KiB
C++

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Microsoft Windows, Copyright (C) Microsoft Corporation, 2000
File: Signer.cpp
Content: Implementation of CSigner.
History: 11-15-99 dsie created
------------------------------------------------------------------------------*/
//
// Turn off:
//
// - Unreferenced formal parameter warning.
// - Assignment within conditional expression warning.
//
#pragma warning (disable: 4100)
#pragma warning (disable: 4706)
#include "stdafx.h"
#include "CAPICOM.h"
#include "Attributes.h"
#include "Signer.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.
ISigner ** ppISigner - Pointer to pointer to ISigner object to
receive the interface pointer.
Remark :
------------------------------------------------------------------------------*/
HRESULT CreateSignerObject (PCCERT_CONTEXT pCertContext,
CRYPT_ATTRIBUTES * pAuthAttrs,
ISigner ** ppISigner)
{
HRESULT hr = S_OK;
CComObject<CSigner> * pCSigner = NULL;
DebugTrace("Entering CreateSignerObject().\n");
//
// Sanity check.
//
ATLASSERT(pCertContext);
ATLASSERT(pAuthAttrs);
ATLASSERT(ppISigner);
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)))
{
DebugTrace("Error [%#x]: pCSigner->Init() failed.\n", hr);
goto ErrorExit;
}
//
// Return interface pointer to caller.
//
if (FAILED(hr = pCSigner->QueryInterface(ppISigner)))
{
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;
}
///////////////////////////////////////////////////////////////////////////////
//
// 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");
//
// Lock access to this object.
//
m_Lock.Lock();
try
{
//
// Make sure we indeed have a certificate.
//
if (!m_pICertificate)
{
hr = CAPICOM_E_SIGNER_NOT_INITIALIZED;
DebugTrace("Error: signer object currently does not have a certificate.\n");
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_INVALIDARG;
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");
//
// Lock access to this object.
//
m_Lock.Lock();
try
{
//
// 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;
}
//
// Clear all attributes.
//
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_INVALIDARG;
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::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");
//
// Lock access to this object.
//
m_Lock.Lock();
try
{
//
// 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;
}
////////////////////////////////////////////////////////////////////////////////
//
// 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.
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)
{
HRESULT hr = S_OK;
DebugTrace("Entering CSigner::Init().\n");
//
// Sanity check.
//
ATLASSERT(pCertContext);
ATLASSERT(pAuthAttrs);
//
// Reset.
//
m_pICertificate.Release();
m_pIAttributes.Release();
//
// Create the embeded ICertificate object.
//
if (FAILED(hr = ::CreateCertificateObject(pCertContext, &m_pICertificate)))
{
DebugTrace("Error [%#x]: CreateCertificateObject() failed.\n", hr);
goto CommonExit;
}
//
// Create the embeded IAttributes collection object.
//
if (FAILED(hr = ::CreateAttributesObject(pAuthAttrs, &m_pIAttributes)))
{
DebugTrace("Error [%#x]: CreateAttributesObject() failed.\n", hr);
goto CommonExit;
}
CommonExit:
DebugTrace("Leaving CSigner::Init().\n");
return hr;
}