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.

463 lines
8.8 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. exchange.cxx
  5. Abstract:
  6. This module implements the IIS_CRYPTO_EXCHANGE_CLIENT 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_EXCHANGE_CLIENT::IIS_CRYPTO_EXCHANGE_CLIENT()
  29. /*++
  30. Routine Description:
  31. IIS_CRYPTO_EXCHANGE_CLIENT class constructor.
  32. Arguments:
  33. None.
  34. Return Value:
  35. None.
  36. --*/
  37. {
  38. //
  39. // Just put the member variables into known states.
  40. //
  41. m_hServerKeyExchangeKey = CRYPT_NULL;
  42. m_hServerSignatureKey = CRYPT_NULL;
  43. } // IIS_CRYPTO_EXCHANGE_CLIENT::IIS_CRYPTO_EXCHANGE_CLIENT
  44. IIS_CRYPTO_EXCHANGE_CLIENT::~IIS_CRYPTO_EXCHANGE_CLIENT()
  45. /*++
  46. Routine Description:
  47. IIS_CRYPTO_EXCHANGE_CLIENT class destructor.
  48. Arguments:
  49. None.
  50. Return Value:
  51. None.
  52. --*/
  53. {
  54. //
  55. // Close any open keys.
  56. //
  57. CLOSE_KEY( m_hServerKeyExchangeKey );
  58. CLOSE_KEY( m_hServerSignatureKey );
  59. } // IIS_CRYPTO_EXCHANGE_CLIENT::~IIS_CRYPTO_EXCHANGE_CLIENT
  60. HRESULT
  61. IIS_CRYPTO_EXCHANGE_CLIENT::ClientPhase1(
  62. OUT PIIS_CRYPTO_BLOB * ppClientKeyExchangeKeyBlob,
  63. OUT PIIS_CRYPTO_BLOB * ppClientSignatureKeyBlob
  64. )
  65. /*++
  66. Routine Description:
  67. Performs client-side phase 1 of the multi-phase key exchange protocol.
  68. Arguments:
  69. ppClientKeyExchangeKeyBlob - Receives a pointer to the client's key
  70. exchange key public blob if successful. It is the client's
  71. responsibility to (somehow) transmit this to the server.
  72. ppClientSignatureKeyBlob - Receives a pointer to the client's signature
  73. public blob if successful. It is the client's responsibility to
  74. (somehow) transmit this to the server.
  75. Return Value:
  76. HRESULT - Completion status, 0 if successful, !0 otherwise.
  77. --*/
  78. {
  79. HRESULT result;
  80. PIIS_CRYPTO_BLOB keyExchangeKeyBlob;
  81. PIIS_CRYPTO_BLOB signatureKeyBlob;
  82. //
  83. // Sanity check.
  84. //
  85. DBG_ASSERT( ValidateState() );
  86. DBG_ASSERT( ppClientKeyExchangeKeyBlob != NULL );
  87. DBG_ASSERT( ppClientSignatureKeyBlob != NULL );
  88. //
  89. // Setup our locals so we know how to cleanup on exit.
  90. //
  91. keyExchangeKeyBlob = NULL;
  92. signatureKeyBlob = NULL;
  93. //
  94. // Export the key exchange key blob.
  95. //
  96. result = ::IISCryptoExportPublicKeyBlob(
  97. &keyExchangeKeyBlob,
  98. m_hProv,
  99. m_hKeyExchangeKey
  100. );
  101. if( FAILED(result) ) {
  102. goto fatal;
  103. }
  104. //
  105. // Export the signature key blob.
  106. //
  107. result = ::IISCryptoExportPublicKeyBlob(
  108. &signatureKeyBlob,
  109. m_hProv,
  110. m_hSignatureKey
  111. );
  112. if( FAILED(result) ) {
  113. goto fatal;
  114. }
  115. //
  116. // Success!
  117. //
  118. DBG_ASSERT( keyExchangeKeyBlob != NULL );
  119. DBG_ASSERT( signatureKeyBlob != NULL );
  120. *ppClientKeyExchangeKeyBlob = keyExchangeKeyBlob;
  121. *ppClientSignatureKeyBlob = signatureKeyBlob;
  122. return NO_ERROR;
  123. fatal:
  124. FREE_BLOB( keyExchangeKeyBlob );
  125. FREE_BLOB( signatureKeyBlob );
  126. DBG_ASSERT( FAILED(result) );
  127. return result;
  128. } // IIS_CRYPTO_EXCHANGE_CLIENT::ClientPhase1
  129. HRESULT
  130. IIS_CRYPTO_EXCHANGE_CLIENT::ClientPhase2(
  131. IN PIIS_CRYPTO_BLOB pServerKeyExchangeKeyBlob,
  132. IN PIIS_CRYPTO_BLOB pServerSignatureKeyBlob,
  133. IN PIIS_CRYPTO_BLOB pServerSessionKeyBlob,
  134. OUT PIIS_CRYPTO_BLOB * ppClientSessionKeyBlob,
  135. OUT PIIS_CRYPTO_BLOB * ppClientHashBlob
  136. )
  137. /*++
  138. Routine Description:
  139. Performs client-side phase 2 of the multi-phase key exchange protocol.
  140. Arguments:
  141. pServerKeyExchangeKeyBlob - Pointer to the server's key exchange
  142. public key blob.
  143. pServerSignatureKeyBlob - Pointer to the server's signature public
  144. key blob.
  145. pServerSessionKeyBlob - Pointer to the server's session key
  146. blob.
  147. ppClientSessionKeyBlob - Receives a pointer to the client's
  148. session key blob if successful.
  149. ppClientHashBlob - Receives a pointer to the client's hash
  150. blob if successful.
  151. Return Value:
  152. HRESULT - Completion status, 0 if successful, !0 otherwise.
  153. --*/
  154. {
  155. HRESULT result;
  156. PIIS_CRYPTO_BLOB sessionKeyBlob;
  157. PIIS_CRYPTO_BLOB hashBlob;
  158. //
  159. // Sanity check.
  160. //
  161. DBG_ASSERT( ValidateState() );
  162. DBG_ASSERT( pServerKeyExchangeKeyBlob != NULL );
  163. DBG_ASSERT( IISCryptoIsValidBlob( pServerKeyExchangeKeyBlob ) );
  164. DBG_ASSERT( pServerSignatureKeyBlob != NULL );
  165. DBG_ASSERT( IISCryptoIsValidBlob( pServerSignatureKeyBlob ) );
  166. DBG_ASSERT( pServerSessionKeyBlob != NULL );
  167. DBG_ASSERT( IISCryptoIsValidBlob( pServerSessionKeyBlob ) );
  168. DBG_ASSERT( ppClientSessionKeyBlob != NULL );
  169. DBG_ASSERT( ppClientHashBlob != NULL );
  170. //
  171. // Setup our locals so we know how to cleanup on exit.
  172. //
  173. sessionKeyBlob = NULL;
  174. hashBlob = NULL;
  175. //
  176. // Import the server's keys.
  177. //
  178. DBG_ASSERT( m_hServerKeyExchangeKey == CRYPT_NULL );
  179. result = ::IISCryptoImportPublicKeyBlob(
  180. &m_hServerKeyExchangeKey,
  181. pServerKeyExchangeKeyBlob,
  182. m_hProv
  183. );
  184. if( FAILED(result) ) {
  185. goto fatal;
  186. }
  187. DBG_ASSERT( m_hServerSignatureKey == CRYPT_NULL );
  188. result = ::IISCryptoImportPublicKeyBlob(
  189. &m_hServerSignatureKey,
  190. pServerSignatureKeyBlob,
  191. m_hProv
  192. );
  193. if( FAILED(result) ) {
  194. goto fatal;
  195. }
  196. DBG_ASSERT( m_hServerSessionKey == CRYPT_NULL );
  197. result = SafeImportSessionKeyBlob(
  198. &m_hServerSessionKey,
  199. pServerSessionKeyBlob,
  200. m_hProv,
  201. m_hServerSignatureKey
  202. );
  203. if( FAILED(result) ) {
  204. goto fatal;
  205. }
  206. //
  207. // Generate our local session key.
  208. //
  209. DBG_ASSERT( m_hClientSessionKey == CRYPT_NULL );
  210. result = ::IISCryptoGenerateSessionKey(
  211. &m_hClientSessionKey,
  212. m_hProv
  213. );
  214. if( FAILED(result) ) {
  215. goto fatal;
  216. }
  217. //
  218. // Export it.
  219. //
  220. result = SafeExportSessionKeyBlob(
  221. &sessionKeyBlob,
  222. m_hProv,
  223. m_hClientSessionKey,
  224. m_hServerKeyExchangeKey
  225. );
  226. if( FAILED(result) ) {
  227. goto fatal;
  228. }
  229. //
  230. // Create the phase 3 hash blob.
  231. //
  232. result = CreatePhase3Hash(
  233. &hashBlob
  234. );
  235. if( FAILED(result) ) {
  236. goto fatal;
  237. }
  238. //
  239. // Success!
  240. //
  241. *ppClientSessionKeyBlob = sessionKeyBlob;
  242. *ppClientHashBlob = hashBlob;
  243. return NO_ERROR;
  244. fatal:
  245. FREE_BLOB( sessionKeyBlob );
  246. FREE_BLOB( hashBlob );
  247. DBG_ASSERT( FAILED(result) );
  248. return result;
  249. } // IIS_CRYPTO_EXCHANGE_CLIENT::ClientPhase2
  250. HRESULT
  251. IIS_CRYPTO_EXCHANGE_CLIENT::ClientPhase3(
  252. IN PIIS_CRYPTO_BLOB pServerHashBlob
  253. )
  254. /*++
  255. Routine Description:
  256. Performs client-side phase 3 of the multi-phase key exchange protocol.
  257. Arguments:
  258. pServerHashBlob - Pointer to the server's hash blob.
  259. Return Value:
  260. HRESULT - Completion status, 0 if successful, !0 otherwise.
  261. --*/
  262. {
  263. HRESULT result;
  264. PIIS_CRYPTO_BLOB hashBlob;
  265. //
  266. // Sanity check.
  267. //
  268. DBG_ASSERT( ValidateState() );
  269. DBG_ASSERT( pServerHashBlob != NULL );
  270. DBG_ASSERT( IISCryptoIsValidBlob( pServerHashBlob ) );
  271. //
  272. // Setup our locals so we know how to cleanup on exit.
  273. //
  274. hashBlob = NULL;
  275. //
  276. // Create the phase 4 hash blob.
  277. //
  278. result = CreatePhase4Hash(
  279. &hashBlob
  280. );
  281. if( FAILED(result) ) {
  282. goto fatal;
  283. }
  284. //
  285. // Compare this blob with the one we got from the server.
  286. // If they match, then the exchange is complete.
  287. //
  288. if( !::IISCryptoCompareBlobs(
  289. pServerHashBlob,
  290. hashBlob
  291. ) ) {
  292. result = ERROR_INVALID_DATA;
  293. goto fatal;
  294. }
  295. //
  296. // Success!
  297. //
  298. FREE_BLOB(hashBlob);
  299. return NO_ERROR;
  300. fatal:
  301. FREE_BLOB(hashBlob);
  302. DBG_ASSERT( FAILED(result) );
  303. return result;
  304. } // IIS_CRYPTO_EXCHANGE_CLIENT::ClientPhase3
  305. //
  306. // Private functions.
  307. //