// 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 // for _alloca #include #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 CSessionKeyContext::Clone(DWORD const *pdwReserved, DWORD dwFlags) const { return auto_ptr(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(_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(&algid), sizeof ALG_ID); blbKey.append(pbData, dwDataLen); // Save it m_apabKey = auto_ptr(new AlignedBlob(blbKey)); } else { // Save key blob m_apabKey = auto_ptr(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(_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