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.

879 lines
16 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. storage.cxx
  5. Abstract:
  6. This module implements the IIS_CRYPTO_STORAGE class.
  7. Author:
  8. Keith Moore (keithmo) 02-Dec-1996
  9. Revision History:
  10. --*/
  11. #include "precomp.hxx"
  12. #pragma hdrstop
  13. //
  14. // Private constants.
  15. //
  16. //
  17. // Private types.
  18. //
  19. //
  20. // Private globals.
  21. //
  22. //
  23. // Private prototypes.
  24. //
  25. //
  26. // Public functions.
  27. //
  28. IIS_CRYPTO_STORAGE::IIS_CRYPTO_STORAGE()
  29. /*++
  30. Routine Description:
  31. IIS_CRYPTO_STORAGE class constructor. Just sets the member variables
  32. to known values; does nothing that can actually fail. All of the
  33. hard work is in the Initialize() methods.
  34. Arguments:
  35. None.
  36. Return Value:
  37. None.
  38. --*/
  39. {
  40. //
  41. // Set the handles to known values so we know what to cleanup
  42. // in the destructor.
  43. //
  44. m_hSessionKey = CRYPT_NULL;
  45. } // IIS_CRYPTO_STORAGE::IIS_CRYPTO_STORAGE
  46. IIS_CRYPTO_STORAGE::~IIS_CRYPTO_STORAGE()
  47. /*++
  48. Routine Description:
  49. IIS_CRYPTO_STORAGE class destructor. Performs any necessary cleanup.
  50. Arguments:
  51. None.
  52. Return Value:
  53. None.
  54. --*/
  55. {
  56. //
  57. // Close any open keys.
  58. //
  59. CLOSE_KEY( m_hSessionKey );
  60. } // IIS_CRYPTO_STORAGE::~IIS_CRYPTO_STORAGE
  61. HRESULT
  62. IIS_CRYPTO_STORAGE::Initialize(
  63. IN BOOL fUseMachineKeyset,
  64. IN HCRYPTPROV hProv
  65. )
  66. /*++
  67. Routine Description:
  68. Generates a new (random) session key.
  69. Arguments:
  70. fUseMachineKeyset - TRUE if the per-machine keyset container should
  71. be used, as opposed to the per-user keyset container.
  72. hProv - Optional handle to a pre-opened crypto provider.
  73. Return Value:
  74. HRESULT - Completion status, 0 if successful, !0 otherwise.
  75. --*/
  76. {
  77. HRESULT result;
  78. //
  79. // Sanity check.
  80. //
  81. DBG_ASSERT( m_hSessionKey == CRYPT_NULL );
  82. //
  83. // Initialize the base class.
  84. //
  85. result = IIS_CRYPTO_BASE::Initialize(
  86. hProv,
  87. CRYPT_NULL,
  88. CRYPT_NULL,
  89. fUseMachineKeyset
  90. );
  91. if( SUCCEEDED(result) ) {
  92. //
  93. // Generate the session key.
  94. //
  95. result = ::IISCryptoGenerateSessionKey(
  96. &m_hSessionKey,
  97. m_hProv
  98. );
  99. if( FAILED(result) ) {
  100. DBGPRINTF(( DBG_CONTEXT,"IIS_CRYPTO_STORAGE::Initialize IISCryptoGenerateSessionKey err=0x%x.\n",result));
  101. }
  102. }
  103. else
  104. {
  105. // something failed.
  106. DBGPRINTF(( DBG_CONTEXT,"IIS_CRYPTO_STORAGE::Initialize:IIS_CRYPTO_BASE::Initialize Failed err=0x%x.\n",result));
  107. }
  108. return result;
  109. } // IIS_CRYPTO_STORAGE::Initialize
  110. HRESULT
  111. IIS_CRYPTO_STORAGE2::Initialize(
  112. IN HCRYPTPROV hProv
  113. )
  114. /*++
  115. Routine Description:
  116. Generates a new (random) session key.
  117. Arguments:
  118. hProv - Optional handle to a pre-opened crypto provider.
  119. Return Value:
  120. HRESULT - Completion status, 0 if successful, !0 otherwise.
  121. --*/
  122. {
  123. HRESULT result;
  124. //
  125. // Sanity check.
  126. //
  127. DBG_ASSERT( m_hSessionKey == CRYPT_NULL );
  128. //
  129. // Initialize the base class.
  130. //
  131. result = Initialize2( hProv );
  132. if( SUCCEEDED(result) ) {
  133. //
  134. // Generate the session key.
  135. //
  136. result = ::IISCryptoGenerateSessionKey(
  137. &m_hSessionKey,
  138. m_hProv
  139. );
  140. if( FAILED(result) ) {
  141. DBGPRINTF(( DBG_CONTEXT,"IIS_CRYPTO_STORAGE::Initialize IISCryptoGenerateSessionKey err=0x%x.\n",result));
  142. }
  143. }
  144. else
  145. {
  146. // something failed.
  147. DBGPRINTF(( DBG_CONTEXT,"IIS_CRYPTO_STORAGE::Initialize:IIS_CRYPTO_BASE::Initialize Failed err=0x%x.\n",result));
  148. }
  149. return result;
  150. } // IIS_CRYPTO_STORAGE2::Initialize
  151. HRESULT
  152. IIS_CRYPTO_STORAGE::Initialize(
  153. IN PIIS_CRYPTO_BLOB pSessionKeyBlob,
  154. IN BOOL fUseMachineKeyset,
  155. IN HCRYPTPROV hProv
  156. )
  157. /*++
  158. Routine Description:
  159. Imports the specified session key blob.
  160. Arguments:
  161. pSessionKeyBlob - Points to the secure key blob to import.
  162. fUseMachineKeyset - TRUE if the per-machine keyset container should
  163. be used, as opposed to the per-user keyset container.
  164. hProv - Optional handle to a pre-opened crypto provider.
  165. Return Value:
  166. HRESULT - Completion status, 0 if successful, !0 otherwise.
  167. --*/
  168. {
  169. HRESULT result;
  170. //
  171. // Sanity check.
  172. //
  173. DBG_ASSERT( m_hSessionKey == CRYPT_NULL );
  174. DBG_ASSERT( pSessionKeyBlob != NULL );
  175. //
  176. // Initialize the base class.
  177. //
  178. result = IIS_CRYPTO_BASE::Initialize(
  179. hProv,
  180. CRYPT_NULL,
  181. CRYPT_NULL,
  182. fUseMachineKeyset
  183. );
  184. if( SUCCEEDED(result) ) {
  185. //
  186. // Import the session key blob.
  187. //
  188. result = SafeImportSessionKeyBlob(
  189. &m_hSessionKey,
  190. pSessionKeyBlob,
  191. m_hProv,
  192. m_hSignatureKey
  193. );
  194. if( FAILED(result) ) {
  195. DBGPRINTF(( DBG_CONTEXT,"IIS_CRYPTO_STORAGE::Initialize SafeImportSessionKeyBlob failed err=0x%x.\n",result));
  196. }
  197. }
  198. else
  199. {
  200. DBGPRINTF(( DBG_CONTEXT,"IIS_CRYPTO_STORAGE::Initialize IIS_CRYPTO_BASE::Initialize failed err=0x%x.\n",result));
  201. }
  202. return result;
  203. } // IIS_CRYPTO_STORAGE::Initialize
  204. HRESULT
  205. IIS_CRYPTO_STORAGE2::Initialize(
  206. IN PIIS_CRYPTO_BLOB pSessionKeyBlob,
  207. IN LPSTR pszPasswd,
  208. IN HCRYPTPROV hProv
  209. )
  210. /*++
  211. Routine Description:
  212. Imports the specified session key blob.
  213. Arguments:
  214. pSessionKeyBlob - Points to the secure key blob to import.
  215. hProv - Optional handle to a pre-opened crypto provider.
  216. Return Value:
  217. HRESULT - Completion status, 0 if successful, !0 otherwise.
  218. --*/
  219. {
  220. HRESULT result;
  221. //
  222. // Sanity check.
  223. //
  224. DBG_ASSERT( m_hSessionKey == CRYPT_NULL );
  225. DBG_ASSERT( pszPasswd != NULL );
  226. DBG_ASSERT( pSessionKeyBlob != NULL );
  227. //
  228. // Initialize the base class.
  229. //
  230. result = IIS_CRYPTO_BASE::Initialize( hProv );
  231. if( SUCCEEDED(result) ) {
  232. //
  233. // Import the session key blob.
  234. //
  235. result = SafeImportSessionKeyBlob2(
  236. &m_hSessionKey,
  237. pSessionKeyBlob,
  238. m_hProv,
  239. pszPasswd
  240. );
  241. if( FAILED(result) ) {
  242. DBGPRINTF(( DBG_CONTEXT,"IIS_CRYPTO_STORAGE::Initialize SafeImportSessionKeyBlob failed err=0x%x.\n",result));
  243. }
  244. }
  245. else
  246. {
  247. DBGPRINTF(( DBG_CONTEXT,"IIS_CRYPTO_STORAGE::Initialize IIS_CRYPTO_BASE::Initialize failed err=0x%x.\n",result));
  248. }
  249. return result;
  250. } // IIS_CRYPTO_STORAGE2::Initialize
  251. HRESULT
  252. IIS_CRYPTO_STORAGE::Initialize(
  253. IN HCRYPTPROV hProv,
  254. IN HCRYPTKEY hSessionKey,
  255. IN HCRYPTKEY hKeyExchangeKey,
  256. IN HCRYPTKEY hSignatureKey,
  257. IN BOOL fUseMachineKeyset
  258. )
  259. /*++
  260. Routine Description:
  261. Initializes the object using pre-created provider and session key.
  262. Arguments:
  263. hProv - An open handle to a crypto provider.
  264. hSessionKey - The session key for the object.
  265. hKeyExchangeKey - A pre-opened key exchange key.
  266. hSignatureKey - A pre-opened signature key.
  267. fUseMachineKeyset - TRUE if the per-machine keyset container should
  268. be used, as opposed to the per-user keyset container.
  269. Return Value:
  270. HRESULT - Completion status, 0 if successful, !0 otherwise.
  271. --*/
  272. {
  273. HRESULT result;
  274. //
  275. // Sanity check.
  276. //
  277. DBG_ASSERT( m_hSessionKey == CRYPT_NULL );
  278. DBG_ASSERT( hSessionKey != CRYPT_NULL );
  279. //
  280. // Initialize the base class.
  281. //
  282. result = IIS_CRYPTO_BASE::Initialize(
  283. hProv,
  284. hKeyExchangeKey,
  285. hSignatureKey,
  286. fUseMachineKeyset
  287. );
  288. if( SUCCEEDED(result) ) {
  289. //
  290. // Save the session key.
  291. //
  292. m_hSessionKey = hSessionKey;
  293. }
  294. else
  295. {
  296. DBGPRINTF(( DBG_CONTEXT,"IIS_CRYPTO_STORAGE::Initialize IIS_CRYPTO_BASE::Initialize failed err=0x%x.\n",result));
  297. }
  298. return result;
  299. } // IIS_CRYPTO_STORAGE::Initialize
  300. HRESULT
  301. IIS_CRYPTO_STORAGE::GetSessionKeyBlob(
  302. OUT PIIS_CRYPTO_BLOB * ppSessionKeyBlob
  303. )
  304. /*++
  305. Routine Description:
  306. Exports the session key as a secure key blob.
  307. Arguments:
  308. ppSessionKeyBlob - Receives a pointer to the session key secure
  309. blob if successful.
  310. Return Value:
  311. HRESULT - Completion status, 0 if successful, !0 otherwise.
  312. --*/
  313. {
  314. HRESULT result;
  315. //
  316. // Sanity check.
  317. //
  318. DBG_ASSERT( ValidateState() );
  319. DBG_ASSERT( ppSessionKeyBlob != NULL );
  320. //
  321. // Let the IIS Crypto APIs do the dirty work.
  322. //
  323. result = SafeExportSessionKeyBlob(
  324. ppSessionKeyBlob,
  325. m_hProv,
  326. m_hSessionKey,
  327. m_hKeyExchangeKey
  328. );
  329. return result;
  330. } // IIS_CRYPTO_STORAGE::GetSessionKeyBlob
  331. HRESULT
  332. IIS_CRYPTO_STORAGE2::GetSessionKeyBlob(
  333. IN LPSTR pszPasswd,
  334. OUT PIIS_CRYPTO_BLOB * ppSessionKeyBlob
  335. )
  336. /*++
  337. Routine Description:
  338. Exports the session key as a secure key blob.
  339. Arguments:
  340. ppSessionKeyBlob - Receives a pointer to the session key secure
  341. blob if successful.
  342. Return Value:
  343. HRESULT - Completion status, 0 if successful, !0 otherwise.
  344. --*/
  345. {
  346. HRESULT result;
  347. //
  348. // Sanity check.
  349. //
  350. DBG_ASSERT( ValidateState() );
  351. DBG_ASSERT( ppSessionKeyBlob != NULL );
  352. //
  353. // Let the IIS Crypto APIs do the dirty work.
  354. //
  355. result = SafeExportSessionKeyBlob2(
  356. ppSessionKeyBlob,
  357. m_hProv,
  358. m_hSessionKey,
  359. pszPasswd
  360. );
  361. return result;
  362. } // IIS_CRYPTO_STORAGE2::GetSessionKeyBlob
  363. HRESULT
  364. IIS_CRYPTO_STORAGE::EncryptData(
  365. OUT PIIS_CRYPTO_BLOB * ppDataBlob,
  366. IN PVOID pBuffer,
  367. IN DWORD dwBufferLength,
  368. IN DWORD dwRegType
  369. )
  370. /*++
  371. Routine Description:
  372. Encrypts a block of data and produces a secure data blob.
  373. Arguments:
  374. ppDataBlob - Receives a pointer to the secure data blob if
  375. successful.
  376. pBuffer - Pointer to the buffer to encrypt.
  377. dwBufferLength - The length of the data buffer.
  378. dwRegType - The REG_* type for the data.
  379. Return Value:
  380. HRESULT - Completion status, 0 if successful, !0 otherwise.
  381. --*/
  382. {
  383. HRESULT result;
  384. //
  385. // Sanity check.
  386. //
  387. DBG_ASSERT( ValidateState() );
  388. DBG_ASSERT( ppDataBlob != NULL );
  389. DBG_ASSERT( pBuffer != NULL );
  390. //
  391. // Let the IIS Crypto APIs do the dirty work.
  392. //
  393. result = SafeEncryptDataBlob(
  394. ppDataBlob,
  395. pBuffer,
  396. dwBufferLength,
  397. dwRegType,
  398. m_hProv,
  399. m_hSessionKey
  400. );
  401. return result;
  402. } // IIS_CRYPTO_STORAGE::EncryptData
  403. HRESULT
  404. IIS_CRYPTO_STORAGE2::EncryptData(
  405. OUT PIIS_CRYPTO_BLOB * ppDataBlob,
  406. IN PVOID pBuffer,
  407. IN DWORD dwBufferLength,
  408. IN DWORD dwRegType
  409. )
  410. /*++
  411. Routine Description:
  412. Encrypts a block of data and produces a secure data blob.
  413. Arguments:
  414. ppDataBlob - Receives a pointer to the secure data blob if
  415. successful.
  416. pBuffer - Pointer to the buffer to encrypt.
  417. dwBufferLength - The length of the data buffer.
  418. dwRegType - The REG_* type for the data.
  419. Return Value:
  420. HRESULT - Completion status, 0 if successful, !0 otherwise.
  421. --*/
  422. {
  423. HRESULT result;
  424. //
  425. // Sanity check.
  426. //
  427. DBG_ASSERT( ValidateState() );
  428. DBG_ASSERT( ppDataBlob != NULL );
  429. DBG_ASSERT( pBuffer != NULL );
  430. //
  431. // Let the IIS Crypto APIs do the dirty work.
  432. //
  433. result = SafeEncryptDataBlob2(
  434. ppDataBlob,
  435. pBuffer,
  436. dwBufferLength,
  437. dwRegType,
  438. m_hProv,
  439. m_hSessionKey
  440. );
  441. return result;
  442. } // IIS_CRYPTO_STORAGE2::EncryptData
  443. HRESULT
  444. IIS_CRYPTO_STORAGE::DecryptData(
  445. OUT PVOID * ppBuffer,
  446. OUT LPDWORD pdwBufferLength,
  447. OUT LPDWORD pdwRegType,
  448. IN PIIS_CRYPTO_BLOB pDataBlob
  449. )
  450. /*++
  451. Routine Description:
  452. Decrypts a secure data blob, producing a data pointer and data
  453. length.
  454. Arguments:
  455. ppBuffer - Receives a pointer to the decrypted data if succesful.
  456. pdwBufferLength - Receives the length of the data buffer.
  457. pdwRegType - Receives the REG_* type of the data.
  458. pDataBlob - A pointer to the data blob to decrypt.
  459. Return Value:
  460. HRESULT - Completion status, 0 if successful, !0 otherwise.
  461. --*/
  462. {
  463. HRESULT result;
  464. //
  465. // Sanity check.
  466. //
  467. DBG_ASSERT( ValidateState() );
  468. DBG_ASSERT( ppBuffer != NULL );
  469. DBG_ASSERT( pdwBufferLength != NULL );
  470. DBG_ASSERT( pdwRegType != NULL );
  471. DBG_ASSERT( pDataBlob != NULL );
  472. //
  473. // Let the IIS Crypto APIs do the dirty work.
  474. //
  475. result = ::IISCryptoDecryptDataBlob(
  476. ppBuffer,
  477. pdwBufferLength,
  478. pdwRegType,
  479. pDataBlob,
  480. m_hProv,
  481. m_hSessionKey,
  482. m_hSignatureKey
  483. );
  484. return result;
  485. } // IIS_CRYPTO_STORAGE::DecryptData
  486. HRESULT
  487. IIS_CRYPTO_STORAGE2::DecryptData(
  488. OUT PVOID * ppBuffer,
  489. OUT LPDWORD pdwBufferLength,
  490. OUT LPDWORD pdwRegType,
  491. IN PIIS_CRYPTO_BLOB pDataBlob
  492. )
  493. /*++
  494. Routine Description:
  495. Decrypts a secure data blob, producing a data pointer and data
  496. length.
  497. Arguments:
  498. ppBuffer - Receives a pointer to the decrypted data if succesful.
  499. pdwBufferLength - Receives the length of the data buffer.
  500. pdwRegType - Receives the REG_* type of the data.
  501. pDataBlob - A pointer to the data blob to decrypt.
  502. Return Value:
  503. HRESULT - Completion status, 0 if successful, !0 otherwise.
  504. --*/
  505. {
  506. HRESULT result;
  507. //
  508. // Sanity check.
  509. //
  510. DBG_ASSERT( ValidateState() );
  511. DBG_ASSERT( ppBuffer != NULL );
  512. DBG_ASSERT( pdwBufferLength != NULL );
  513. DBG_ASSERT( pdwRegType != NULL );
  514. DBG_ASSERT( pDataBlob != NULL );
  515. //
  516. // Let the IIS Crypto APIs do the dirty work.
  517. //
  518. result = ::IISCryptoDecryptDataBlob2(
  519. ppBuffer,
  520. pdwBufferLength,
  521. pdwRegType,
  522. pDataBlob,
  523. m_hProv,
  524. m_hSessionKey
  525. );
  526. return result;
  527. } // IIS_CRYPTO_STORAGE2::DecryptData
  528. //
  529. // Private functions.
  530. //
  531. #if DBG
  532. BOOL
  533. IIS_CRYPTO_STORAGE::ValidateState()
  534. /*++
  535. Routine Description:
  536. This debug-only routine validates the current object state.
  537. Arguments:
  538. None.
  539. Return Value:
  540. BOOL - TRUE if state is valid, FALSE otherwise.
  541. --*/
  542. {
  543. if( m_hSessionKey != CRYPT_NULL ) {
  544. return IIS_CRYPTO_BASE::ValidateState();
  545. }
  546. return FALSE;
  547. } // IIS_CRYPTO_STORAGE::ValidateState
  548. BOOL
  549. IIS_CRYPTO_STORAGE2::ValidateState()
  550. /*++
  551. Routine Description:
  552. This debug-only routine validates the current object state.
  553. Arguments:
  554. None.
  555. Return Value:
  556. BOOL - TRUE if state is valid, FALSE otherwise.
  557. --*/
  558. {
  559. if( m_hSessionKey != CRYPT_NULL ) {
  560. return IIS_CRYPTO_BASE::ValidateState2();
  561. }
  562. return FALSE;
  563. } // IIS_CRYPTO_STORAGE::ValidateState
  564. #endif // DBG