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.
 
 
 
 
 
 

509 lines
12 KiB

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Microsoft Windows, Copyright (C) Microsoft Corporation, 2000
File: HashedData.cpp
Content: Implementation of CHashedData.
History: 11-12-2001 dsie created
------------------------------------------------------------------------------*/
#include "stdafx.h"
#include "CAPICOM.h"
#include "HashedData.h"
#include "Common.h"
#include "Convert.h"
typedef struct _tagHashAlgoTable
{
CAPICOM_HASH_ALGORITHM CapicomHashAlg;
ALG_ID AlgId;
} HASH_ALGO_TABLE;
static HASH_ALGO_TABLE HashAlgoTable[] = {
{CAPICOM_HASH_ALGORITHM_SHA1, CALG_SHA1},
{CAPICOM_HASH_ALGORITHM_MD2, CALG_MD2},
{CAPICOM_HASH_ALGORITHM_MD4, CALG_MD4},
{CAPICOM_HASH_ALGORITHM_MD5, CALG_MD5},
// {CAPICOM_HASH_ALGORITHM_SHA_256, CALG_SHA_256},
// {CAPICOM_HASH_ALGORITHM_SHA_384, CALG_SHA_384},
// {CAPICOM_HASH_ALGORITHM_SHA_512, CALG_SHA_512}
};
////////////////////////////////////////////////////////////////////////////////
//
// CHashedData
//
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CHashedData::get_Value
Synopsis : Return the hash value.
Parameter: BSTR * pVal - Pointer to BSTR to receive the hashed value blob.
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CHashedData::get_Value (BSTR * pVal)
{
HRESULT hr = S_OK;
DWORD dwDataLen = sizeof(DWORD);
CRYPT_DATA_BLOB HashData = {0, NULL};
DebugTrace("Entering CHashedData::get_Value().\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;
}
//
// Make sure we have hash data.
//
if (!m_hCryptHash)
{
hr = CAPICOM_E_HASH_NO_DATA;
DebugTrace("Error [%#x]: no value for HashedData.\n", hr);
goto ErrorExit;
}
//
// Get size of hashed value.
//
if (!::CryptGetHashParam(m_hCryptHash,
HP_HASHSIZE,
(LPBYTE) &HashData.cbData,
&dwDataLen,
0))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Error [%#x]: CryptGetHashParam() failed to get size.\n", hr);
goto ErrorExit;
}
//
// Allocate memory.
//
if (!(HashData.pbData = (LPBYTE) ::CoTaskMemAlloc(HashData.cbData)))
{
hr = E_OUTOFMEMORY;
DebugTrace("Error [%#x]: CoTaskMemAlloc() failed.\n", hr);
goto ErrorExit;
}
//
// Now get the hashed value.
//
if (!::CryptGetHashParam(m_hCryptHash, HP_HASHVAL, HashData.pbData, &HashData.cbData, 0))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Error [%#x]: CryptGetHashParam() failed to get data.\n", hr);
goto ErrorExit;
}
//
// Export HashedData.
//
if (FAILED(hr = ::BinaryToHexString(HashData.pbData, HashData.cbData, pVal)))
{
DebugTrace("Error [%#x]: BinaryToHexString() failed.\n", hr);
goto ErrorExit;
}
//
// Reset state.
//
m_HashState = CAPICOM_HASH_INIT_STATE;
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
UnlockExit:
//
// Free resources.
//
if (HashData.pbData)
{
::CoTaskMemFree((LPVOID) HashData.pbData);
}
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CHashedData::get_Value().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CHashedData::get_Algorithm
Synopsis : Return the agorithm.
Parameter: CAPICOM_HASH_ALGORITHM * pVal - Pointer to CAPICOM_HASH_ALGORITHM
to receive result.
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CHashedData::get_Algorithm (CAPICOM_HASH_ALGORITHM * pVal)
{
HRESULT hr = S_OK;
DebugTrace("Entering CHashedData::get_Algorithm().\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 result.
//
*pVal = m_Algorithm;
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
UnlockExit:
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CHashedData::get_Algorithm().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CHashedData::put_Algorithm
Synopsis : Set algorithm.
Parameter: CAPICOM_HASH_ALGORITHM newVal - Algorithm enum name.
Remark : The object state is reset..
------------------------------------------------------------------------------*/
STDMETHODIMP CHashedData::put_Algorithm (CAPICOM_HASH_ALGORITHM newVal)
{
HRESULT hr = S_OK;
DebugTrace("Entering CHashedData::put_Algorithm().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
//
// Make sure algo is supported.
//
switch (newVal)
{
case CAPICOM_HASH_ALGORITHM_SHA1:
case CAPICOM_HASH_ALGORITHM_MD2:
case CAPICOM_HASH_ALGORITHM_MD4:
case CAPICOM_HASH_ALGORITHM_MD5:
// case CAPICOM_HASH_ALGORITHM_SHA_256:
// case CAPICOM_HASH_ALGORITHM_SHA_384:
// case CAPICOM_HASH_ALGORITHM_SHA_512:
{
break;
}
default:
{
hr = CAPICOM_E_INVALID_ALGORITHM;
DebugTrace("Error [%#x]: Unknown hash algorithm (%u).\n", hr, newVal);
goto ErrorExit;
}
}
m_Algorithm = newVal;
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
UnlockExit:
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CHashedData::put_Algorithm().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : CHashedData::Hash
Synopsis : Hash data.
Parameter: BSTR newVal - BSTR of value to hash.
Remark :
------------------------------------------------------------------------------*/
STDMETHODIMP CHashedData::Hash (BSTR newVal)
{
HRESULT hr = S_OK;
DebugTrace("Entering CHashedData::Hash().\n");
try
{
//
// Lock access to this object.
//
m_Lock.Lock();
//
// Check parameters.
//
if (NULL == newVal)
{
hr = E_INVALIDARG;
DebugTrace("Error [%#x]: Parameter newVal is NULL.\n", hr);
goto ErrorExit;
}
//
// Check our state.
//
switch (m_HashState)
{
case CAPICOM_HASH_INIT_STATE:
{
DWORD Index = 0;
ALG_ID AlgId = 0;
//
// Map algorithm to ALG_ID.
//
for (Index = 0; Index < ARRAYSIZE(HashAlgoTable); Index++)
{
if (HashAlgoTable[Index].CapicomHashAlg == m_Algorithm)
{
AlgId = HashAlgoTable[Index].AlgId;
break;
}
}
//
// Get the provider, if needed.
//
if (!m_hCryptProv)
{
if (FAILED(hr = ::AcquireContext(AlgId, &m_hCryptProv)))
{
DebugTrace("Error [%#x]: AcquireContext() failed.\n", hr);
goto ErrorExit;
}
}
//
// Sanity check.
//
ATLASSERT(Index < ARRAYSIZE(HashAlgoTable));
//
// Free handles if still available.
//
if (m_hCryptHash)
{
if (!::CryptDestroyHash(m_hCryptHash))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Error [%#x]: CryptDestroyHash() failed.\n", hr);
goto ErrorExit;
}
m_hCryptHash = NULL;
}
//
// Create a new hash handle.
//
if (!::CryptCreateHash(m_hCryptProv, AlgId, NULL, 0, &m_hCryptHash))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Error [%#x]: CryptCreateHash() failed.\n", hr);
goto ErrorExit;
}
//
// Update hash handle and state.
//
m_HashState = CAPICOM_HASH_DATA_STATE;
//
// Fall thru to hash data.
//
}
case CAPICOM_HASH_DATA_STATE:
{
//
// Sanity check.
//
ATLASSERT(m_hCryptProv);
ATLASSERT(m_hCryptHash);
//
// Hash the data.
//
if (!::CryptHashData(m_hCryptHash,
(PBYTE) newVal,
::SysStringByteLen(newVal),
0))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Error [%#x]: CryptHashData() failed.\n", hr);
goto ErrorExit;
}
break;
}
default:
{
hr = CAPICOM_E_INTERNAL;
DebugTrace("Error [%#x]: Unknown hash state (%d).\n", hr, m_HashState);
goto ErrorExit;
}
}
}
catch(...)
{
hr = E_POINTER;
DebugTrace("Exception: invalid parameter.\n");
goto ErrorExit;
}
UnlockExit:
//
// Unlock access to this object.
//
m_Lock.Unlock();
DebugTrace("Leaving CHashedData::Hash().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
ReportError(hr);
goto UnlockExit;
}