Source code of Windows XP (NT5)
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

  1. // SesKeyCtx.cpp -- definition of CSessionKeyContext
  2. // (c) Copyright Schlumberger Technology Corp., unpublished work, created
  3. // 1999. This computer program includes Confidential, Proprietary
  4. // Information and is a Trade Secret of Schlumberger Technology Corp. All
  5. // use, disclosure, and/or reproduction is prohibited unless authorized
  6. // in writing. All Rights Reserved.
  7. #include "stdafx.h" // because handles.h uses the ASSERT macro
  8. #include <malloc.h> // for _alloca
  9. #include <scuOsExc.h>
  10. #include "SesKeyCtx.h"
  11. #include "slbKeyStruct.h"
  12. #include "AlignedBlob.h"
  13. using namespace std;
  14. using namespace scu;
  15. /////////////////////////// LOCAL/HELPER /////////////////////////////////
  16. /////////////////////////// PUBLIC /////////////////////////////////
  17. // Types
  18. // C'tors/D'tors
  19. CSessionKeyContext::CSessionKeyContext(HCRYPTPROV hProv)
  20. : CKeyContext(hProv, KT_SESSIONKEY),
  21. m_dwImportFlags(0)
  22. {}
  23. CSessionKeyContext::~CSessionKeyContext()
  24. {}
  25. // Operators
  26. // Operations
  27. auto_ptr<CKeyContext>
  28. CSessionKeyContext::Clone(DWORD const *pdwReserved,
  29. DWORD dwFlags) const
  30. {
  31. return auto_ptr<CKeyContext>(new CSessionKeyContext(*this,
  32. pdwReserved,
  33. dwFlags));
  34. }
  35. void
  36. CSessionKeyContext::Derive(ALG_ID algid,
  37. HCRYPTHASH hAuxBaseData,
  38. DWORD dwFlags)
  39. {
  40. if (!CryptDeriveKey(AuxProvider(), algid, hAuxBaseData, dwFlags,
  41. &m_hKey))
  42. throw scu::OsException(GetLastError());
  43. }
  44. void
  45. CSessionKeyContext::Generate(ALG_ID algid,
  46. DWORD dwFlags)
  47. {
  48. // TO DO: BUG ?? : Do not allow Session with NO SALT (it's always
  49. // better with than without)
  50. if (!CryptGenKey(AuxProvider(), algid, dwFlags, &m_hKey))
  51. throw scu::OsException(GetLastError());
  52. }
  53. void
  54. CSessionKeyContext::ImportToAuxCSP()
  55. {
  56. if (!m_hKey)
  57. {
  58. if (!m_apabKey.get())
  59. throw OsException(NTE_NO_KEY);
  60. HCRYPTKEY hPkiKey;
  61. if (!CryptImportKey(AuxProvider(),
  62. PrivateKeyForNoRSA,
  63. SIZE_OF_PRIVATEKEYFORNORSA_BLOB,
  64. 0, 0, &hPkiKey))
  65. throw scu::OsException(GetLastError());
  66. // import the key blob into the Aux CSP
  67. if (!CryptImportKey(AuxProvider(), m_apabKey->Data(),
  68. m_apabKey->Length(), NULL, m_dwImportFlags,
  69. &m_hKey))
  70. throw scu::OsException(GetLastError());
  71. // have to destroy key before generating another
  72. if (!CryptDestroyKey(hPkiKey))
  73. throw scu::OsException(GetLastError());
  74. hPkiKey = NULL;
  75. if (!CryptGenKey(AuxProvider(), AT_KEYEXCHANGE, 0, &hPkiKey))
  76. throw scu::OsException(GetLastError());
  77. if (!CryptDestroyKey(hPkiKey))
  78. throw scu::OsException(GetLastError());
  79. }
  80. }
  81. // CSessionKeyContext::LoadKey
  82. // This function is called by CCryptContext::UseSessionKey
  83. // which is called by the CPImportKey function
  84. // Load the key blob into the Auxiliary CSP,
  85. // and Save the key blob in m_bfSessionKey
  86. // If hImpKey is NULL the key has been decrypted
  87. // otherwise it is still encrypted with the corresponding session key
  88. // If session key is still encrypted then decrypt with help of Aux CSP
  89. void
  90. CSessionKeyContext::LoadKey(IN const BYTE *pbKeyBlob,
  91. IN DWORD cbKeyBlobLen,
  92. IN HCRYPTKEY hAuxImpKey,
  93. IN DWORD dwImportFlags)
  94. {
  95. m_dwImportFlags = dwImportFlags;
  96. if (hAuxImpKey)
  97. {
  98. DWORD dwDataLen = cbKeyBlobLen - (sizeof BLOBHEADER + sizeof ALG_ID);
  99. BYTE *pbData =
  100. reinterpret_cast<BYTE *>(_alloca(dwDataLen * sizeof *pbData));
  101. memcpy(pbData, pbKeyBlob + (sizeof BLOBHEADER +
  102. sizeof ALG_ID), dwDataLen);
  103. // Decrypt the key blob with this session key with the Aux CSP
  104. if (!CryptDecrypt(hAuxImpKey, 0, TRUE, 0, pbData, &dwDataLen))
  105. throw scu::OsException(GetLastError());
  106. // Construct the key blob
  107. Blob blbKey(pbKeyBlob, sizeof BLOBHEADER);
  108. // Set the Alg Id for the blob as encrypted with Key Exchange key
  109. ALG_ID algid = CALG_RSA_KEYX;
  110. blbKey.append(reinterpret_cast<Blob::value_type *>(&algid),
  111. sizeof ALG_ID);
  112. blbKey.append(pbData, dwDataLen);
  113. // Save it
  114. m_apabKey = auto_ptr<AlignedBlob>(new AlignedBlob(blbKey));
  115. }
  116. else
  117. {
  118. // Save key blob
  119. m_apabKey =
  120. auto_ptr<AlignedBlob>(new AlignedBlob(pbKeyBlob, cbKeyBlobLen));
  121. }
  122. }
  123. // Access
  124. AlignedBlob
  125. CSessionKeyContext::AsAlignedBlob(HCRYPTKEY hcryptkey,
  126. DWORD dwBlobType) const
  127. {
  128. DWORD dwRequiredLength;
  129. if (!CryptExportKey(m_hKey, hcryptkey, dwBlobType,
  130. 0, 0, &dwRequiredLength))
  131. throw scu::OsException(GetLastError());
  132. BYTE *pbKeyBlob =
  133. reinterpret_cast<BYTE *>(_alloca(dwRequiredLength));
  134. if (!CryptExportKey(m_hKey, hcryptkey, dwBlobType,
  135. 0, pbKeyBlob, &dwRequiredLength))
  136. throw scu::OsException(GetLastError());
  137. return AlignedBlob(pbKeyBlob, dwRequiredLength);
  138. // The following commented code is for DEBUGGING purposes only,
  139. // when one needs to be able to see the unencrypted session key
  140. // material.
  141. // Now also Export it with the identity key, so we can see the
  142. // session key material in the clear
  143. /*
  144. #include "slbKeyStruct.h"
  145. DWORD dwErr;
  146. BYTE *pbBlob = NULL;
  147. DWORD cbBlob;
  148. HCRYPTKEY hPkiKey;
  149. int i;
  150. if (!CryptImportKey(g_AuxProvider, PrivateKeyForNoRSA,
  151. SIZE_OF_PRIVATEKEYFORNORSA_BLOB,
  152. 0, 0, &hPkiKey))
  153. {
  154. dwErr = GetLastError();
  155. TRACE("ERROR - CryptImportKey : %X\n", dwErr);
  156. goto Ret;
  157. }
  158. if (!CryptExportKey(m_hKey, hPkiKey, SIMPLEBLOB, 0, NULL, &cbBlob))
  159. {
  160. dwErr = GetLastError();
  161. TRACE("ERROR - CryptExportKey : %X\n", dwErr);
  162. goto Ret;
  163. }
  164. if (NULL == (pbBlob = (BYTE *)LocalAlloc(LMEM_ZEROINIT, cbBlob)))
  165. {
  166. TRACE("ERROR - LocalAlloc Failed\n");
  167. goto Ret;
  168. }
  169. if (!CryptExportKey(m_hKey, hPkiKey, SIMPLEBLOB, 0, pbBlob, &cbBlob))
  170. {
  171. dwErr = GetLastError();
  172. TRACE("ERROR - CryptExportKey : %X\n", dwErr);
  173. goto Ret;
  174. }
  175. TRACE("The Simple Blob\n\n");
  176. for(i=0;i<(int)cbBlob;i++)
  177. {
  178. TRACE("0x%02X, ", pbBlob[i]);
  179. if (0 == ((i + 1) % 8))
  180. TRACE("\n");
  181. }
  182. Ret:
  183. TRACE ("Bye\n");
  184. */
  185. }
  186. // CSessionKeyContext::BlobSize
  187. // CSessionKeyContext::BlobLength() const
  188. // {
  189. // DWORD dwLength;
  190. // if (!CryptExportKey(m_hKey, hAuxExpKey, SIMPLEBLOB,
  191. // dwFlags, 0, &dwLength))
  192. // throw scu::OsException(GetLastError());
  193. // return dwLength;
  194. // }
  195. CSessionKeyContext::StrengthType
  196. CSessionKeyContext::MaxStrength() const
  197. {
  198. // TO DO: Implement in terms of Auxillary provider...or don't define?
  199. return 56;
  200. }
  201. CSessionKeyContext::StrengthType
  202. CSessionKeyContext::MinStrength() const
  203. {
  204. // TO DO: Implement in terms of Auxillary provider...or don't define?
  205. return 56;
  206. }
  207. // Predicates
  208. // Static Variables
  209. /////////////////////////// PROTECTED /////////////////////////////////
  210. // C'tors/D'tors
  211. // Duplicate key context and its current state
  212. CSessionKeyContext::CSessionKeyContext(CSessionKeyContext const &rhs,
  213. DWORD const *pdwReserved,
  214. DWORD dwFlags)
  215. : CKeyContext(rhs, pdwReserved, dwFlags),
  216. m_dwImportFlags(rhs.m_dwImportFlags)
  217. {}
  218. // Operators
  219. // Operations
  220. // Access
  221. // Predicates
  222. // Static Variables
  223. /////////////////////////// PRIVATE /////////////////////////////////
  224. // C'tors/D'tors
  225. // Operators
  226. // Operations
  227. // Access
  228. // Predicates
  229. // Static Variables