windows-nt/Source/XPSP1/NT/ds/security/csps/cryptoflex/slbcsp/hashctx.cpp
2020-09-26 16:20:57 +08:00

303 lines
7.1 KiB
C++

// HashCtx.cpp -- definition of CHashContext
// (c) Copyright Schlumberger Technology Corp., unpublished work, created
// 1998. This computer program includes Confidential, Proprietary
// Information and is a Trade Secret of Schlumberger Technology Corp. All
// use, disclosure, and/or reproduction is prohibited unless authorized
// in writing. All Rights Reserved.
#include "stdafx.h" // because handles.h uses the ASSERT macro
#include <memory> // for auto_ptr
#include <malloc.h> // for _alloca
#include <scuOsVersion.h>
#include "HashCtx.h"
#include "HashMD2.h"
#include "HashMD4.h"
#include "HashMD5.h"
#include "HashSHA1.h"
#include "HashSHAMD5.h"
using namespace std;
/////////////////////////// LOCAL/HELPER /////////////////////////////////
/////////////////////////// PUBLIC /////////////////////////////////
// Types
// C'tors/D'tors
CHashContext::~CHashContext() throw()
{
try
{
Close();
}
catch (...)
{
}
}
// Operators
// Operations
void
CHashContext::Close()
{
if (m_HashHandle)
{
if (!CryptDestroyHash(m_HashHandle))
throw scu::OsException(GetLastError());
m_HashHandle = NULL;
}
}
void
CHashContext::ExportFromAuxCSP()
{
if (!m_HashHandle)
throw scu::OsException(ERROR_INVALID_PARAMETER);
if (m_fJustCreated)
{
DWORD dwNeedLen;
DWORD dwDataLen = sizeof DWORD;
if (!CryptGetHashParam(m_HashHandle, HP_HASHSIZE,
reinterpret_cast<BYTE *>(&dwNeedLen),
&dwDataLen, 0))
throw scu::OsException(GetLastError());
BYTE *pbHashValue = reinterpret_cast<BYTE *>(_alloca(dwNeedLen));
if (!CryptGetHashParam(m_HashHandle, HP_HASHVAL,
pbHashValue, &dwNeedLen, 0))
throw scu::OsException(GetLastError());
Value(Blob(pbHashValue, dwNeedLen));
}
}
void CHashContext::Hash(BYTE const *pbData,
DWORD dwLength)
{
HCRYPTHASH hch = HashHandleInAuxCSP();
if (!CryptHashData(hch, pbData, dwLength, 0))
throw scu::OsException(GetLastError());
m_fJustCreated = false;
}
void
CHashContext::ImportToAuxCSP()
{
if (!m_HashHandle)
{
if (!CryptCreateHash(m_rcryptctx.AuxContext(),
m_algid, 0, 0, &m_HashHandle))
throw scu::OsException(GetLastError());
}
if (!m_fJustCreated && !m_fDone)
{
if (!CryptSetHashParam(m_HashHandle, HP_HASHVAL,
const_cast<Blob::value_type *>(Value().data()),
0))
throw scu::OsException(GetLastError());
}
}
void
CHashContext::Initialize()
{
m_fDone = false;
}
auto_ptr<CHashContext>
CHashContext::Make(ALG_ID algid,
CryptContext const &rcryptctx)
{
auto_ptr<CHashContext> apHash;
switch (algid)
{
case CALG_MD2:
apHash = auto_ptr<CHashContext>(new CHashMD2(rcryptctx));
break;
case CALG_MD4:
apHash = auto_ptr<CHashContext>(new CHashMD4(rcryptctx));
break;
case CALG_MD5:
apHash = auto_ptr<CHashContext>(new CHashMD5(rcryptctx));
break;
case CALG_SHA:
apHash = auto_ptr<CHashContext>(new CHashSHA1(rcryptctx));
break;
case CALG_SSL3_SHAMD5:
apHash = auto_ptr<CHashContext>(new CHashSHAMD5(rcryptctx));
break;
default:
throw scu::OsException(NTE_BAD_ALGID);
break;
}
return apHash;
}
void
CHashContext::Value(Blob const &rhs)
{
if (!m_fJustCreated)
throw scu::OsException(NTE_PERM);
m_blbValue = rhs;
m_fJustCreated = false;
m_fDone = true;
}
// Access
ALG_ID
CHashContext::AlgId()
{
return m_algid;
}
Blob
CHashContext::EncodedValue()
{
return EncodedAlgorithmOid() + Value();
}
HCRYPTHASH
CHashContext::HashHandleInAuxCSP()
{
ImportToAuxCSP();
return m_HashHandle;
}
CHashContext::SizeType
CHashContext::Length() const
{
SizeType cHashLength;
if (!m_fDone)
{
DWORD dwData;
DWORD dwDataLength = sizeof dwData;
if (!CryptGetHashParam(m_HashHandle, HP_HASHSIZE,
reinterpret_cast<BYTE *>(&dwData),
&dwDataLength, 0))
throw scu::OsException(GetLastError());
cHashLength = dwData;
}
else
cHashLength = m_blbValue.length();
return cHashLength;
}
Blob
CHashContext::Value()
{
if (!m_fDone)
ExportFromAuxCSP();
return m_blbValue;
}
// Predicates
bool
CHashContext::IsSupported(ALG_ID algid)
{
bool IsSupported = true;
switch (algid)
{
case CALG_MD2:
case CALG_MD4:
case CALG_MD5:
case CALG_SHA:
case CALG_SSL3_SHAMD5:
break;
default:
IsSupported = false;
break;
}
return IsSupported;
}
// Static Variables
/////////////////////////// PROTECTED /////////////////////////////////
// C'tors/D'tors
CHashContext::CHashContext(CryptContext const &rcryptctx,
ALG_ID algid)
: CHandle(),
m_rcryptctx(rcryptctx),
m_algid(algid),
m_blbValue(),
m_fDone(false),
m_fJustCreated(true),
m_HashHandle(NULL)
{}
// Duplicate the hash and its state
CHashContext::CHashContext(CHashContext const &rhs,
DWORD const *pdwReserved,
DWORD dwFlags)
: CHandle(),
m_rcryptctx(rhs.m_rcryptctx),
m_algid(rhs.m_algid),
m_blbValue(rhs.m_blbValue),
m_fDone(rhs.m_fDone),
m_fJustCreated(rhs.m_fJustCreated)
{
#if defined(SLB_WIN2K_BUILD)
if (!CryptDuplicateHash(HashHandleInAuxCSP(),
const_cast<DWORD *>(pdwReserved),
dwFlags,
&m_HashHandle))
throw scu::OsException(GetLastError());
#else
throw scu::OsException(ERROR_NOT_SUPPORTED);
#endif
}
// Operators
// Operations
// Access
// Predicates
// Static Variables
/////////////////////////// PRIVATE /////////////////////////////////
// C'tors/D'tors
// Operators
// Operations
// Access
// Predicates
// Static Variables