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.
 
 
 
 
 
 

260 lines
7.4 KiB

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Microsoft Windows, Copyright (C) Microsoft Corporation, 2000 - 2001.
File: MsgHlpr.cpp
Content: Helper functions for messaging.
History: 11-15-99 dsie created
------------------------------------------------------------------------------*/
#include "StdAfx.h"
#include "CAPICOM.h"
#include "MsgHlpr.h"
////////////////////////////////////////////////////////////////////////////////
//
// Exported functions.
//
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : GetMsgParam
Synopsis : Allocate memory and retrieve requested message parameter using
CryptGetMsgParam() API.
Parameter: HCRYPTMSG hMsg - Message handler.
DWORD dwMsgType - Message param type to retrieve.
DWORD dwIndex - Index (should be 0 most of the time).
void ** ppvData - Pointer to receive buffer.
DWORD * pcbData - Size of buffer.
Remark :
------------------------------------------------------------------------------*/
HRESULT GetMsgParam (HCRYPTMSG hMsg,
DWORD dwMsgType,
DWORD dwIndex,
void ** ppvData,
DWORD * pcbData)
{
HRESULT hr = S_OK;
DWORD cbData = 0;
void * pvData = NULL;
DebugTrace("Entering GetMsgParam().\n");
//
// Sanity check.
//
ATLASSERT(ppvData);
ATLASSERT(pcbData);
//
// Determine data buffer size.
//
if (!::CryptMsgGetParam(hMsg,
dwMsgType,
dwIndex,
NULL,
&cbData))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Error [%#x]: CryptMsgGetParam() failed.\n", hr);
goto ErrorExit;
}
//
// Allocate memory for buffer.
//
if (!(pvData = (void *) ::CoTaskMemAlloc(cbData)))
{
hr = E_OUTOFMEMORY;
DebugTrace("Error: out of memory.\n");
goto ErrorExit;
}
//
// Now get the data.
//
if (!::CryptMsgGetParam(hMsg,
dwMsgType,
dwIndex,
pvData,
&cbData))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Error [%#x]: CryptMsgGetParam() failed.\n", hr);
goto ErrorExit;
}
//
// Return msg param to caller.
//
*ppvData = pvData;
*pcbData = cbData;
CommonExit:
DebugTrace("Leaving GetMsgParam().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
//
// Free resources.
//
if (pvData)
{
::CoTaskMemFree(pvData);
}
goto CommonExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : FindSignerCertInMessage
Synopsis : Find the signer's cert in the bag of certs of the message for the
specified signer.
Parameter: HCRYPTMSG hMsg - Message handle.
CERT_NAME_BLOB * pIssuerNameBlob - Pointer to issuer' name
blob of signer's cert.
CRYPT_INTEGERT_BLOB * pSerialNumberBlob - Pointer to serial number
blob of signer's cert.
PCERT_CONTEXT * ppCertContext - Pointer to PCERT_CONTEXT
to receive the found
cert, or NULL to only
know the result.
Remark :
------------------------------------------------------------------------------*/
HRESULT FindSignerCertInMessage (HCRYPTMSG hMsg,
CERT_NAME_BLOB * pIssuerNameBlob,
CRYPT_INTEGER_BLOB * pSerialNumberBlob,
PCERT_CONTEXT * ppCertContext)
{
HRESULT hr = S_OK;
DWORD dwCertCount = 0;
DWORD cbCertCount = sizeof(dwCertCount);
DebugTrace("Entering FindSignerCertInMessage().\n");
//
// Sanity check.
//
ATLASSERT(NULL != hMsg);
ATLASSERT(NULL != pIssuerNameBlob);
ATLASSERT(NULL != pSerialNumberBlob);
ATLASSERT(0 < pIssuerNameBlob->cbData);
ATLASSERT(NULL != pIssuerNameBlob->pbData);
ATLASSERT(0 < pSerialNumberBlob->cbData);
ATLASSERT(NULL != pSerialNumberBlob->pbData);
//
// Get count of certs in message.
//
if (!::CryptMsgGetParam(hMsg,
CMSG_CERT_COUNT_PARAM,
0,
&dwCertCount,
&cbCertCount))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Error [%#x]: CryptMsgGetParam() failed.\n", hr);
return hr;
}
//
// See if the signer's cert is in the bag of certs.
//
while (dwCertCount--)
{
PCCERT_CONTEXT pCertContext = NULL;
CRYPT_DATA_BLOB EncodedCertBlob = {0, NULL};
//
// Get a cert from the bag of certs.
//
hr = ::GetMsgParam(hMsg,
CMSG_CERT_PARAM,
dwCertCount,
(void **) &EncodedCertBlob.pbData,
&EncodedCertBlob.cbData);
if (FAILED(hr))
{
DebugTrace("Error [%#x]: GetMsgParam() failed.\n", hr);
return hr;
}
//
// Create a context for the cert.
//
pCertContext = ::CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
(const BYTE *) EncodedCertBlob.pbData,
EncodedCertBlob.cbData);
//
// Free encoded cert blob memory before checking result.
//
::CoTaskMemFree((LPVOID) EncodedCertBlob.pbData);
if (NULL == pCertContext)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Error [%#x]: CertCreateCertificateContext() failed.\n", hr);
return hr;
}
//
// Compare.
//
if (::CertCompareCertificateName(CAPICOM_ASN_ENCODING,
pIssuerNameBlob,
&pCertContext->pCertInfo->Issuer) &&
::CertCompareIntegerBlob(pSerialNumberBlob,
&pCertContext->pCertInfo->SerialNumber))
{
if (NULL != ppCertContext)
{
*ppCertContext = (PCERT_CONTEXT) pCertContext;
}
else
{
::CertFreeCertificateContext(pCertContext);
}
return S_OK;
}
else
{
//
// No, keep looking.
//
::CertFreeCertificateContext(pCertContext);
}
}
//
// If we get here, that means we never found the cert.
//
return CAPICOM_E_SIGNER_NOT_FOUND;
}