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.

285 lines
9.2 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 <scuOsExc.h>
  9. #include <scuArrayP.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.data())
  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. SecureArray<BYTE> apbData( dwDataLen * sizeof BYTE );
  100. memcpy(apbData.data(), pbKeyBlob + (sizeof BLOBHEADER +
  101. sizeof ALG_ID), dwDataLen);
  102. // Decrypt the key blob with this session key with the Aux CSP
  103. if (!CryptDecrypt(hAuxImpKey, 0, TRUE, 0, apbData.data(), &dwDataLen))
  104. throw scu::OsException(GetLastError());
  105. // Construct an empty key blob
  106. SecureArray<BYTE> blbKey(0);//(pbKeyBlob, sizeof BLOBHEADER);
  107. // Set the Alg Id for the blob as encrypted with Key Exchange key
  108. ALG_ID algid = CALG_RSA_KEYX;
  109. blbKey.append(reinterpret_cast<BYTE *>(&algid),
  110. sizeof ALG_ID);
  111. blbKey.append(apbData.data(), dwDataLen);
  112. // Save it
  113. m_apabKey = blbKey;
  114. }
  115. else
  116. {
  117. // Save key blob
  118. m_apabKey =
  119. SecureArray<BYTE>(pbKeyBlob, cbKeyBlobLen);
  120. }
  121. }
  122. // Access
  123. SecureArray<BYTE>
  124. CSessionKeyContext::AsAlignedBlob(HCRYPTKEY hcryptkey,
  125. DWORD dwBlobType) const
  126. {
  127. DWORD dwRequiredLength;
  128. if (!CryptExportKey(m_hKey, hcryptkey, dwBlobType,
  129. 0, 0, &dwRequiredLength))
  130. throw scu::OsException(GetLastError());
  131. SecureArray<BYTE> apbKeyBlob(dwRequiredLength);
  132. if (!CryptExportKey(m_hKey, hcryptkey, dwBlobType,
  133. 0, apbKeyBlob.data(), &dwRequiredLength))
  134. throw scu::OsException(GetLastError());
  135. return apbKeyBlob;
  136. // The following commented code is for DEBUGGING purposes only,
  137. // when one needs to be able to see the unencrypted session key
  138. // material.
  139. // Now also Export it with the identity key, so we can see the
  140. // session key material in the clear
  141. /*
  142. #include "slbKeyStruct.h"
  143. DWORD dwErr;
  144. BYTE *pbBlob = NULL;
  145. DWORD cbBlob;
  146. HCRYPTKEY hPkiKey;
  147. int i;
  148. if (!CryptImportKey(g_AuxProvider, PrivateKeyForNoRSA,
  149. SIZE_OF_PRIVATEKEYFORNORSA_BLOB,
  150. 0, 0, &hPkiKey))
  151. {
  152. dwErr = GetLastError();
  153. TRACE("ERROR - CryptImportKey : %X\n", dwErr);
  154. goto Ret;
  155. }
  156. if (!CryptExportKey(m_hKey, hPkiKey, SIMPLEBLOB, 0, NULL, &cbBlob))
  157. {
  158. dwErr = GetLastError();
  159. TRACE("ERROR - CryptExportKey : %X\n", dwErr);
  160. goto Ret;
  161. }
  162. if (NULL == (pbBlob = (BYTE *)LocalAlloc(LMEM_ZEROINIT, cbBlob)))
  163. {
  164. TRACE("ERROR - LocalAlloc Failed\n");
  165. goto Ret;
  166. }
  167. if (!CryptExportKey(m_hKey, hPkiKey, SIMPLEBLOB, 0, pbBlob, &cbBlob))
  168. {
  169. dwErr = GetLastError();
  170. TRACE("ERROR - CryptExportKey : %X\n", dwErr);
  171. goto Ret;
  172. }
  173. TRACE("The Simple Blob\n\n");
  174. for(i=0;i<(int)cbBlob;i++)
  175. {
  176. TRACE("0x%02X, ", pbBlob[i]);
  177. if (0 == ((i + 1) % 8))
  178. TRACE("\n");
  179. }
  180. Ret:
  181. TRACE ("Bye\n");
  182. */
  183. }
  184. // CSessionKeyContext::BlobSize
  185. // CSessionKeyContext::BlobLength() const
  186. // {
  187. // DWORD dwLength;
  188. // if (!CryptExportKey(m_hKey, hAuxExpKey, SIMPLEBLOB,
  189. // dwFlags, 0, &dwLength))
  190. // throw scu::OsException(GetLastError());
  191. // return dwLength;
  192. // }
  193. CSessionKeyContext::StrengthType
  194. CSessionKeyContext::MaxStrength() const
  195. {
  196. // TO DO: Implement in terms of Auxillary provider...or don't define?
  197. return 56;
  198. }
  199. CSessionKeyContext::StrengthType
  200. CSessionKeyContext::MinStrength() const
  201. {
  202. // TO DO: Implement in terms of Auxillary provider...or don't define?
  203. return 56;
  204. }
  205. // Predicates
  206. // Static Variables
  207. /////////////////////////// PROTECTED /////////////////////////////////
  208. // C'tors/D'tors
  209. // Duplicate key context and its current state
  210. CSessionKeyContext::CSessionKeyContext(CSessionKeyContext const &rhs,
  211. DWORD const *pdwReserved,
  212. DWORD dwFlags)
  213. : CKeyContext(rhs, pdwReserved, dwFlags),
  214. m_dwImportFlags(rhs.m_dwImportFlags)
  215. {}
  216. // Operators
  217. // Operations
  218. // Access
  219. // Predicates
  220. // Static Variables
  221. /////////////////////////// PRIVATE /////////////////////////////////
  222. // C'tors/D'tors
  223. // Operators
  224. // Operations
  225. // Access
  226. // Predicates
  227. // Static Variables