mirror of https://github.com/tongzx/nt5src
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.
288 lines
9.1 KiB
288 lines
9.1 KiB
// SesKeyCtx.cpp -- definition of CSessionKeyContext
|
|
|
|
// (c) Copyright Schlumberger Technology Corp., unpublished work, created
|
|
// 1999. 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 <malloc.h> // for _alloca
|
|
|
|
#include <scuOsExc.h>
|
|
|
|
#include "SesKeyCtx.h"
|
|
#include "slbKeyStruct.h"
|
|
#include "AlignedBlob.h"
|
|
|
|
using namespace std;
|
|
using namespace scu;
|
|
|
|
/////////////////////////// LOCAL/HELPER /////////////////////////////////
|
|
|
|
/////////////////////////// PUBLIC /////////////////////////////////
|
|
|
|
// Types
|
|
// C'tors/D'tors
|
|
|
|
CSessionKeyContext::CSessionKeyContext(HCRYPTPROV hProv)
|
|
: CKeyContext(hProv, KT_SESSIONKEY),
|
|
m_dwImportFlags(0)
|
|
{}
|
|
|
|
CSessionKeyContext::~CSessionKeyContext()
|
|
{}
|
|
|
|
// Operators
|
|
// Operations
|
|
|
|
auto_ptr<CKeyContext>
|
|
CSessionKeyContext::Clone(DWORD const *pdwReserved,
|
|
DWORD dwFlags) const
|
|
{
|
|
return auto_ptr<CKeyContext>(new CSessionKeyContext(*this,
|
|
pdwReserved,
|
|
dwFlags));
|
|
}
|
|
|
|
void
|
|
CSessionKeyContext::Derive(ALG_ID algid,
|
|
HCRYPTHASH hAuxBaseData,
|
|
DWORD dwFlags)
|
|
{
|
|
if (!CryptDeriveKey(AuxProvider(), algid, hAuxBaseData, dwFlags,
|
|
&m_hKey))
|
|
throw scu::OsException(GetLastError());
|
|
}
|
|
|
|
void
|
|
CSessionKeyContext::Generate(ALG_ID algid,
|
|
DWORD dwFlags)
|
|
{
|
|
// TO DO: BUG ?? : Do not allow Session with NO SALT (it's always
|
|
// better with than without)
|
|
|
|
if (!CryptGenKey(AuxProvider(), algid, dwFlags, &m_hKey))
|
|
throw scu::OsException(GetLastError());
|
|
}
|
|
|
|
void
|
|
CSessionKeyContext::ImportToAuxCSP()
|
|
{
|
|
if (!m_hKey)
|
|
{
|
|
if (!m_apabKey.get())
|
|
throw OsException(NTE_NO_KEY);
|
|
|
|
HCRYPTKEY hPkiKey;
|
|
|
|
if (!CryptImportKey(AuxProvider(),
|
|
PrivateKeyForNoRSA,
|
|
SIZE_OF_PRIVATEKEYFORNORSA_BLOB,
|
|
0, 0, &hPkiKey))
|
|
throw scu::OsException(GetLastError());
|
|
|
|
// import the key blob into the Aux CSP
|
|
if (!CryptImportKey(AuxProvider(), m_apabKey->Data(),
|
|
m_apabKey->Length(), NULL, m_dwImportFlags,
|
|
&m_hKey))
|
|
throw scu::OsException(GetLastError());
|
|
|
|
// have to destroy key before generating another
|
|
if (!CryptDestroyKey(hPkiKey))
|
|
throw scu::OsException(GetLastError());
|
|
|
|
hPkiKey = NULL;
|
|
if (!CryptGenKey(AuxProvider(), AT_KEYEXCHANGE, 0, &hPkiKey))
|
|
throw scu::OsException(GetLastError());
|
|
|
|
if (!CryptDestroyKey(hPkiKey))
|
|
throw scu::OsException(GetLastError());
|
|
}
|
|
}
|
|
|
|
// CSessionKeyContext::LoadKey
|
|
// This function is called by CCryptContext::UseSessionKey
|
|
// which is called by the CPImportKey function
|
|
// Load the key blob into the Auxiliary CSP,
|
|
// and Save the key blob in m_bfSessionKey
|
|
// If hImpKey is NULL the key has been decrypted
|
|
// otherwise it is still encrypted with the corresponding session key
|
|
// If session key is still encrypted then decrypt with help of Aux CSP
|
|
void
|
|
CSessionKeyContext::LoadKey(IN const BYTE *pbKeyBlob,
|
|
IN DWORD cbKeyBlobLen,
|
|
IN HCRYPTKEY hAuxImpKey,
|
|
IN DWORD dwImportFlags)
|
|
{
|
|
m_dwImportFlags = dwImportFlags;
|
|
|
|
if (hAuxImpKey)
|
|
{
|
|
DWORD dwDataLen = cbKeyBlobLen - (sizeof BLOBHEADER + sizeof ALG_ID);
|
|
BYTE *pbData =
|
|
reinterpret_cast<BYTE *>(_alloca(dwDataLen * sizeof *pbData));
|
|
memcpy(pbData, pbKeyBlob + (sizeof BLOBHEADER +
|
|
sizeof ALG_ID), dwDataLen);
|
|
|
|
// Decrypt the key blob with this session key with the Aux CSP
|
|
if (!CryptDecrypt(hAuxImpKey, 0, TRUE, 0, pbData, &dwDataLen))
|
|
throw scu::OsException(GetLastError());
|
|
|
|
// Construct the key blob
|
|
Blob blbKey(pbKeyBlob, sizeof BLOBHEADER);
|
|
|
|
// Set the Alg Id for the blob as encrypted with Key Exchange key
|
|
ALG_ID algid = CALG_RSA_KEYX;
|
|
blbKey.append(reinterpret_cast<Blob::value_type *>(&algid),
|
|
sizeof ALG_ID);
|
|
blbKey.append(pbData, dwDataLen);
|
|
|
|
// Save it
|
|
m_apabKey = auto_ptr<AlignedBlob>(new AlignedBlob(blbKey));
|
|
}
|
|
else
|
|
{
|
|
// Save key blob
|
|
m_apabKey =
|
|
auto_ptr<AlignedBlob>(new AlignedBlob(pbKeyBlob, cbKeyBlobLen));
|
|
}
|
|
}
|
|
|
|
|
|
// Access
|
|
|
|
AlignedBlob
|
|
CSessionKeyContext::AsAlignedBlob(HCRYPTKEY hcryptkey,
|
|
DWORD dwBlobType) const
|
|
{
|
|
DWORD dwRequiredLength;
|
|
if (!CryptExportKey(m_hKey, hcryptkey, dwBlobType,
|
|
0, 0, &dwRequiredLength))
|
|
throw scu::OsException(GetLastError());
|
|
|
|
BYTE *pbKeyBlob =
|
|
reinterpret_cast<BYTE *>(_alloca(dwRequiredLength));
|
|
if (!CryptExportKey(m_hKey, hcryptkey, dwBlobType,
|
|
0, pbKeyBlob, &dwRequiredLength))
|
|
throw scu::OsException(GetLastError());
|
|
|
|
return AlignedBlob(pbKeyBlob, dwRequiredLength);
|
|
|
|
// The following commented code is for DEBUGGING purposes only,
|
|
// when one needs to be able to see the unencrypted session key
|
|
// material.
|
|
|
|
// Now also Export it with the identity key, so we can see the
|
|
// session key material in the clear
|
|
/*
|
|
#include "slbKeyStruct.h"
|
|
DWORD dwErr;
|
|
BYTE *pbBlob = NULL;
|
|
DWORD cbBlob;
|
|
HCRYPTKEY hPkiKey;
|
|
int i;
|
|
if (!CryptImportKey(g_AuxProvider, PrivateKeyForNoRSA,
|
|
SIZE_OF_PRIVATEKEYFORNORSA_BLOB,
|
|
0, 0, &hPkiKey))
|
|
{
|
|
dwErr = GetLastError();
|
|
TRACE("ERROR - CryptImportKey : %X\n", dwErr);
|
|
goto Ret;
|
|
|
|
}
|
|
|
|
if (!CryptExportKey(m_hKey, hPkiKey, SIMPLEBLOB, 0, NULL, &cbBlob))
|
|
{
|
|
dwErr = GetLastError();
|
|
TRACE("ERROR - CryptExportKey : %X\n", dwErr);
|
|
goto Ret;
|
|
}
|
|
|
|
if (NULL == (pbBlob = (BYTE *)LocalAlloc(LMEM_ZEROINIT, cbBlob)))
|
|
{
|
|
TRACE("ERROR - LocalAlloc Failed\n");
|
|
goto Ret;
|
|
}
|
|
|
|
if (!CryptExportKey(m_hKey, hPkiKey, SIMPLEBLOB, 0, pbBlob, &cbBlob))
|
|
{
|
|
dwErr = GetLastError();
|
|
TRACE("ERROR - CryptExportKey : %X\n", dwErr);
|
|
goto Ret;
|
|
}
|
|
|
|
TRACE("The Simple Blob\n\n");
|
|
|
|
for(i=0;i<(int)cbBlob;i++)
|
|
{
|
|
TRACE("0x%02X, ", pbBlob[i]);
|
|
if (0 == ((i + 1) % 8))
|
|
TRACE("\n");
|
|
}
|
|
|
|
Ret:
|
|
|
|
TRACE ("Bye\n");
|
|
*/
|
|
|
|
}
|
|
|
|
// CSessionKeyContext::BlobSize
|
|
// CSessionKeyContext::BlobLength() const
|
|
// {
|
|
// DWORD dwLength;
|
|
|
|
// if (!CryptExportKey(m_hKey, hAuxExpKey, SIMPLEBLOB,
|
|
// dwFlags, 0, &dwLength))
|
|
// throw scu::OsException(GetLastError());
|
|
|
|
// return dwLength;
|
|
// }
|
|
|
|
CSessionKeyContext::StrengthType
|
|
CSessionKeyContext::MaxStrength() const
|
|
{
|
|
// TO DO: Implement in terms of Auxillary provider...or don't define?
|
|
return 56;
|
|
}
|
|
|
|
CSessionKeyContext::StrengthType
|
|
CSessionKeyContext::MinStrength() const
|
|
{
|
|
// TO DO: Implement in terms of Auxillary provider...or don't define?
|
|
return 56;
|
|
}
|
|
|
|
// Predicates
|
|
// Static Variables
|
|
|
|
/////////////////////////// PROTECTED /////////////////////////////////
|
|
|
|
// C'tors/D'tors
|
|
|
|
// Duplicate key context and its current state
|
|
CSessionKeyContext::CSessionKeyContext(CSessionKeyContext const &rhs,
|
|
DWORD const *pdwReserved,
|
|
DWORD dwFlags)
|
|
: CKeyContext(rhs, pdwReserved, dwFlags),
|
|
m_dwImportFlags(rhs.m_dwImportFlags)
|
|
{}
|
|
|
|
|
|
// Operators
|
|
// Operations
|
|
// Access
|
|
// Predicates
|
|
// Static Variables
|
|
|
|
|
|
/////////////////////////// PRIVATE /////////////////////////////////
|
|
|
|
// C'tors/D'tors
|
|
// Operators
|
|
// Operations
|
|
// Access
|
|
// Predicates
|
|
// Static Variables
|