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.

521 lines
12 KiB

  1. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Microsoft Windows, Copyright (C) Microsoft Corporation, 2000
  3. File: Algorithm.cpp
  4. Content: Implementation of CAlgorithm.
  5. History: 11-15-99 dsie created
  6. ------------------------------------------------------------------------------*/
  7. #include "StdAfx.h"
  8. #include "CAPICOM.h"
  9. #include "Algorithm.h"
  10. #include "Common.h"
  11. ////////////////////////////////////////////////////////////////////////////////
  12. //
  13. // Exported functions.
  14. //
  15. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  16. Function : CreateAlgorithmObject
  17. Synopsis : Create an IAlgorithm object.
  18. Parameter: BOOL bReadOnly - TRUE if read-only, else FASLE.
  19. BOOL bAESAllowed - TRUE if AES algorithm is allowed.
  20. IAlgorithm ** ppIAlgorithm - Pointer to pointer to IAlgorithm
  21. to receive the interface pointer.
  22. Remark :
  23. ------------------------------------------------------------------------------*/
  24. HRESULT CreateAlgorithmObject (BOOL bReadOnly, BOOL bAESAllowed, IAlgorithm ** ppIAlgorithm)
  25. {
  26. HRESULT hr = S_OK;
  27. CComObject<CAlgorithm> * pCAlgorithm = NULL;
  28. DebugTrace("Entering CreateAlgorithmObject().\n");
  29. //
  30. // Sanity check.
  31. //
  32. ATLASSERT(ppIAlgorithm);
  33. try
  34. {
  35. //
  36. // Create the object. Note that the ref count will still be 0
  37. // after the object is created.
  38. //
  39. if (FAILED(hr = CComObject<CAlgorithm>::CreateInstance(&pCAlgorithm)))
  40. {
  41. DebugTrace("Error [%#x]: CComObject<CAlgorithm>::CreateInstance() failed.\n", hr);
  42. goto ErrorExit;
  43. }
  44. //
  45. // Initialize object.
  46. //
  47. if (FAILED(hr = pCAlgorithm->Init(bReadOnly, bAESAllowed)))
  48. {
  49. DebugTrace("Error [%#x]: pCAlgorithm->Init() failed.\n", hr);
  50. goto ErrorExit;
  51. }
  52. //
  53. // Return interface pointer to caller.
  54. //
  55. if (FAILED(hr = pCAlgorithm->QueryInterface(ppIAlgorithm)))
  56. {
  57. DebugTrace("Error [%#x]: pCAlgorithm->QueryInterface() failed.\n", hr);
  58. goto ErrorExit;
  59. }
  60. }
  61. catch(...)
  62. {
  63. hr = E_POINTER;
  64. DebugTrace("Exception: invalid parameter.\n");
  65. goto ErrorExit;
  66. }
  67. CommonExit:
  68. DebugTrace("Leaving CreateAlgorithmObject().\n");
  69. return hr;
  70. ErrorExit:
  71. //
  72. // Sanity check.
  73. //
  74. ATLASSERT(FAILED(hr));
  75. //
  76. // Free resource.
  77. //
  78. if (pCAlgorithm)
  79. {
  80. delete pCAlgorithm;
  81. }
  82. goto CommonExit;
  83. }
  84. ///////////////////////////////////////////////////////////////////////////////
  85. //
  86. // CAlgorithm
  87. //
  88. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  89. Function : CAlgorithm::get_Name
  90. Synopsis : Return the enum name of the algorithm.
  91. Parameter: CAPICOM_ENCRYPTION_ALGORITHM * pVal - Pointer to
  92. CAPICOM_ENCRYPTION_ALGORITHM
  93. to receive result.
  94. Remark :
  95. ------------------------------------------------------------------------------*/
  96. STDMETHODIMP CAlgorithm::get_Name (CAPICOM_ENCRYPTION_ALGORITHM * pVal)
  97. {
  98. HRESULT hr = S_OK;
  99. DebugTrace("Entering CAlgorithm::get_Name().\n");
  100. try
  101. {
  102. //
  103. // Lock access to this object.
  104. //
  105. m_Lock.Lock();
  106. //
  107. // Check parameters.
  108. //
  109. if (NULL == pVal)
  110. {
  111. hr = E_INVALIDARG;
  112. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  113. goto ErrorExit;
  114. }
  115. //
  116. // Return result.
  117. //
  118. *pVal = m_Name;
  119. }
  120. catch(...)
  121. {
  122. hr = E_POINTER;
  123. DebugTrace("Exception: invalid parameter.\n");
  124. goto ErrorExit;
  125. }
  126. UnlockExit:
  127. //
  128. // Unlock access to this object.
  129. //
  130. m_Lock.Unlock();
  131. DebugTrace("Leaving CAlgorithm:get_Name().\n");
  132. return hr;
  133. ErrorExit:
  134. //
  135. // Sanity check.
  136. //
  137. ATLASSERT(FAILED(hr));
  138. ReportError(hr);
  139. goto UnlockExit;
  140. }
  141. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  142. Function : CAlgorithm::put_Name
  143. Synopsis : Set algorithm enum name.
  144. Parameter: CAPICOM_ENCRYPTION_ALGORITHM newVal - Algorithm enum name.
  145. Remark :
  146. ------------------------------------------------------------------------------*/
  147. STDMETHODIMP CAlgorithm::put_Name (CAPICOM_ENCRYPTION_ALGORITHM newVal)
  148. {
  149. HRESULT hr = S_OK;
  150. HCRYPTPROV hCryptProv = NULL;
  151. DebugTrace("Entering CAlgorithm::put_Name().\n");
  152. try
  153. {
  154. //
  155. // Lock access to this object.
  156. //
  157. m_Lock.Lock();
  158. //
  159. // Make sure it is not read only.
  160. //
  161. if (m_bReadOnly)
  162. {
  163. hr = CAPICOM_E_NOT_ALLOWED;
  164. DebugTrace("Error [%#x]: Writing to read-only Algorithm object is not allowed.\n", hr);
  165. goto ErrorExit;
  166. }
  167. //
  168. // Make sure algo is valid.
  169. //
  170. switch (newVal)
  171. {
  172. case CAPICOM_ENCRYPTION_ALGORITHM_RC2:
  173. case CAPICOM_ENCRYPTION_ALGORITHM_RC4:
  174. case CAPICOM_ENCRYPTION_ALGORITHM_DES:
  175. case CAPICOM_ENCRYPTION_ALGORITHM_3DES:
  176. {
  177. break;
  178. }
  179. case CAPICOM_ENCRYPTION_ALGORITHM_AES:
  180. {
  181. //
  182. // Make sure AES is allowed.
  183. //
  184. if (!m_bAESAllowed)
  185. {
  186. hr = CAPICOM_E_NOT_ALLOWED;
  187. DebugTrace("Error [%#x]: AES encryption is specifically not allowed.\n", hr);
  188. goto ErrorExit;
  189. }
  190. break;
  191. }
  192. default:
  193. {
  194. hr = CAPICOM_E_INVALID_ALGORITHM;
  195. DebugTrace("Error [%#x]: Unknown algorithm enum name (%#x).\n", hr, newVal);
  196. goto ErrorExit;
  197. }
  198. }
  199. //
  200. // Store name.
  201. //
  202. m_Name = newVal;
  203. }
  204. catch(...)
  205. {
  206. hr = E_POINTER;
  207. DebugTrace("Exception: invalid parameter.\n");
  208. goto ErrorExit;
  209. }
  210. UnlockExit:
  211. //
  212. // Free resources.
  213. //
  214. if (hCryptProv)
  215. {
  216. ::ReleaseContext(hCryptProv);
  217. }
  218. //
  219. // Unlock access to this object.
  220. //
  221. m_Lock.Unlock();
  222. DebugTrace("Leaving CAlgorithm::put_Name().\n");
  223. return hr;
  224. ErrorExit:
  225. //
  226. // Sanity check.
  227. //
  228. ATLASSERT(FAILED(hr));
  229. ReportError(hr);
  230. goto UnlockExit;
  231. }
  232. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  233. Function : CAlgorithm::get_KeyLength
  234. Synopsis : Return the enum name of the key length.
  235. Parameter: CAPICOM_ENCRYPTION_KEY_LENGTH * pVal - Pointer to
  236. CAPICOM_ENCRYPTION_KEY_LENGTH
  237. to receive result.
  238. Remark :
  239. ------------------------------------------------------------------------------*/
  240. STDMETHODIMP CAlgorithm::get_KeyLength (CAPICOM_ENCRYPTION_KEY_LENGTH * pVal)
  241. {
  242. HRESULT hr = S_OK;
  243. DebugTrace("Entering CAlgorithm::get_KeyLength().\n");
  244. try
  245. {
  246. //
  247. // Lock access to this object.
  248. //
  249. m_Lock.Lock();
  250. //
  251. // Check parameters.
  252. //
  253. if (NULL == pVal)
  254. {
  255. hr = E_INVALIDARG;
  256. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  257. goto ErrorExit;
  258. }
  259. //
  260. // Return result.
  261. //
  262. *pVal = m_KeyLength;
  263. }
  264. catch(...)
  265. {
  266. hr = E_POINTER;
  267. DebugTrace("Exception: invalid parameter.\n");
  268. goto ErrorExit;
  269. }
  270. UnlockExit:
  271. //
  272. // Unlock access to this object.
  273. //
  274. m_Lock.Unlock();
  275. DebugTrace("Leaving CAlgorithm:get_KeyLength().\n");
  276. return hr;
  277. ErrorExit:
  278. //
  279. // Sanity check.
  280. //
  281. ATLASSERT(FAILED(hr));
  282. ReportError(hr);
  283. goto UnlockExit;
  284. }
  285. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  286. Function : CAlgorithm::put_KeyLength
  287. Synopsis : Set key length enum name.
  288. Parameter: CAPICOM_ENCRYPTION_KEY_LENGTH newVal - Key length enum name.
  289. Remark :
  290. ------------------------------------------------------------------------------*/
  291. STDMETHODIMP CAlgorithm::put_KeyLength (CAPICOM_ENCRYPTION_KEY_LENGTH newVal)
  292. {
  293. HRESULT hr = S_OK;
  294. HCRYPTPROV hCryptProv = NULL;
  295. DebugTrace("Entering CAlgorithm::put_KeyLength().\n");
  296. try
  297. {
  298. //
  299. // Lock access to this object.
  300. //
  301. m_Lock.Lock();
  302. //
  303. //
  304. // Make sure it is not read only.
  305. //
  306. if (m_bReadOnly)
  307. {
  308. hr = CAPICOM_E_NOT_ALLOWED;
  309. DebugTrace("Error [%#x]: Writing to read-only Algorithm object is not allowed.\n", hr);
  310. goto ErrorExit;
  311. }
  312. // Determine key length requested.
  313. //
  314. switch (newVal)
  315. {
  316. case CAPICOM_ENCRYPTION_KEY_LENGTH_MAXIMUM:
  317. case CAPICOM_ENCRYPTION_KEY_LENGTH_40_BITS:
  318. case CAPICOM_ENCRYPTION_KEY_LENGTH_56_BITS:
  319. case CAPICOM_ENCRYPTION_KEY_LENGTH_128_BITS:
  320. case CAPICOM_ENCRYPTION_KEY_LENGTH_192_BITS:
  321. case CAPICOM_ENCRYPTION_KEY_LENGTH_256_BITS:
  322. {
  323. break;
  324. }
  325. default:
  326. {
  327. hr = CAPICOM_E_INVALID_KEY_LENGTH;
  328. DebugTrace("Error [%#x]: Unknown key length enum name (%#x).\n", hr, newVal);
  329. goto ErrorExit;
  330. }
  331. }
  332. //
  333. // Store name.
  334. //
  335. m_KeyLength = newVal;
  336. }
  337. catch(...)
  338. {
  339. hr = E_POINTER;
  340. DebugTrace("Exception: invalid parameter.\n");
  341. goto ErrorExit;
  342. }
  343. UnlockExit:
  344. //
  345. // Free resources.
  346. //
  347. if (hCryptProv)
  348. {
  349. ::ReleaseContext(hCryptProv);
  350. }
  351. //
  352. // Unlock access to this object.
  353. //
  354. m_Lock.Unlock();
  355. DebugTrace("Leaving CAlgorithm::put_KeyLength().\n");
  356. return hr;
  357. ErrorExit:
  358. //
  359. // Sanity check.
  360. //
  361. ATLASSERT(FAILED(hr));
  362. ReportError(hr);
  363. goto UnlockExit;
  364. }
  365. ////////////////////////////////////////////////////////////////////////////////
  366. //
  367. // Private methods.
  368. //
  369. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  370. Function : CAlgorithm::Init
  371. Synopsis : Initialize the object.
  372. Parameter: BOOL bReadOnly - TRUE for Read only, else FALSE.
  373. BOOL bAESAllowed - TRUE if AES algorithm is allowed.
  374. Remark : This method is not part of the COM interface (it is a normal C++
  375. member function). We need it to initialize the object created
  376. internally by us.
  377. Since it is only a normal C++ member function, this function can
  378. only be called from a C++ class pointer, not an interface pointer.
  379. ------------------------------------------------------------------------------*/
  380. STDMETHODIMP CAlgorithm::Init (BOOL bReadOnly, BOOL bAESAllowed)
  381. {
  382. HRESULT hr = S_OK;
  383. DebugTrace("Entering CAlgorithm::Init().\n");
  384. m_bReadOnly = bReadOnly;
  385. m_bAESAllowed = bAESAllowed;
  386. DebugTrace("Leaving CAlgorithm::Init().\n");
  387. return hr;
  388. }