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.

887 lines
25 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 2000.
  5. //
  6. // File: spreg.c
  7. //
  8. // Contents: Schannel registry management routines.
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 11-24-97 jbanes Enabled TLS
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <sslp.h>
  18. #include "spreg.h"
  19. #include <mapper.h>
  20. #include <sidfilter.h>
  21. HKEY g_hkBase = NULL;
  22. HANDLE g_hParamEvent = NULL;
  23. HANDLE g_hWait = NULL;
  24. HKEY g_hkFipsBase = NULL;
  25. HANDLE g_hFipsParamEvent = NULL;
  26. HANDLE g_hFipsWait = NULL;
  27. BOOL g_fManualCredValidation = MANUAL_CRED_VALIDATION_SETTING;
  28. BOOL g_PctClientDisabledByDefault = PCT_CLIENT_DISABLED_SETTING;
  29. BOOL g_Ssl2ClientDisabledByDefault = SSL2_CLIENT_DISABLED_SETTING;
  30. DWORD g_dwEventLogging = DEFAULT_EVENT_LOGGING_SETTING;
  31. DWORD g_ProtEnabled = DEFAULT_ENABLED_PROTOCOLS_SETTING;
  32. BOOL g_fSendIssuerList = TRUE;
  33. DWORD g_dwCertMappingMethods = DEFAULT_CERTMAP_SETTING;
  34. BOOL g_fFipsMode = FALSE;
  35. BOOL g_fFranceLocale = FALSE;
  36. BOOL g_SslS4U2SelfInitialized = FALSE;
  37. typedef struct enamap
  38. {
  39. TCHAR *pKey;
  40. DWORD Mask;
  41. } enamap;
  42. enamap g_ProtMap[] =
  43. {
  44. {SP_REG_KEY_PCT1 TEXT("\\") SP_REG_KEY_CLIENT, SP_PROT_PCT1_CLIENT},
  45. {SP_REG_KEY_PCT1 TEXT("\\") SP_REG_KEY_SERVER, SP_PROT_PCT1_SERVER},
  46. {SP_REG_KEY_SSL2 TEXT("\\") SP_REG_KEY_CLIENT, SP_PROT_SSL2_CLIENT},
  47. {SP_REG_KEY_SSL2 TEXT("\\") SP_REG_KEY_SERVER, SP_PROT_SSL2_SERVER},
  48. {SP_REG_KEY_SSL3 TEXT("\\") SP_REG_KEY_CLIENT, SP_PROT_SSL3_CLIENT},
  49. {SP_REG_KEY_SSL3 TEXT("\\") SP_REG_KEY_SERVER, SP_PROT_SSL3_SERVER},
  50. {SP_REG_KEY_TLS1 TEXT("\\") SP_REG_KEY_CLIENT, SP_PROT_TLS1_CLIENT},
  51. {SP_REG_KEY_TLS1 TEXT("\\") SP_REG_KEY_SERVER, SP_PROT_TLS1_SERVER}
  52. };
  53. VOID
  54. SslWatchParamKey(
  55. PVOID pCtxt,
  56. BOOLEAN fWaitStatus);
  57. VOID
  58. FipsWatchParamKey(
  59. PVOID pCtxt,
  60. BOOLEAN fWaitStatus);
  61. BOOL
  62. SslReadRegOptions(
  63. BOOL fFirstTime);
  64. BOOL SPLoadRegOptions(void)
  65. {
  66. g_hParamEvent = CreateEvent(NULL,
  67. FALSE,
  68. FALSE,
  69. NULL);
  70. SslWatchParamKey(g_hParamEvent, FALSE);
  71. g_hFipsParamEvent = CreateEvent(NULL,
  72. FALSE,
  73. FALSE,
  74. NULL);
  75. FipsWatchParamKey(g_hFipsParamEvent, FALSE);
  76. return TRUE;
  77. }
  78. void SPUnloadRegOptions(void)
  79. {
  80. if (NULL != g_hWait)
  81. {
  82. RtlDeregisterWait(g_hWait);
  83. g_hWait = NULL;
  84. }
  85. if(NULL != g_hkBase)
  86. {
  87. RegCloseKey(g_hkBase);
  88. }
  89. if(NULL != g_hParamEvent)
  90. {
  91. CloseHandle(g_hParamEvent);
  92. }
  93. if (NULL != g_hFipsWait)
  94. {
  95. RtlDeregisterWait(g_hFipsWait);
  96. g_hFipsWait = NULL;
  97. }
  98. if(NULL != g_hkFipsBase)
  99. {
  100. RegCloseKey(g_hkFipsBase);
  101. }
  102. if(NULL != g_hFipsParamEvent)
  103. {
  104. CloseHandle(g_hFipsParamEvent);
  105. }
  106. }
  107. BOOL
  108. ReadRegistrySetting(
  109. HKEY hReadKey,
  110. HKEY hWriteKey,
  111. LPCTSTR pszValueName,
  112. DWORD * pdwValue,
  113. DWORD dwDefaultValue)
  114. {
  115. DWORD dwSize;
  116. DWORD dwType;
  117. DWORD dwOriginalValue = *pdwValue;
  118. dwSize = sizeof(DWORD);
  119. if(RegQueryValueEx(hReadKey,
  120. pszValueName,
  121. NULL,
  122. &dwType,
  123. (PUCHAR)pdwValue,
  124. &dwSize) != STATUS_SUCCESS)
  125. {
  126. *pdwValue = dwDefaultValue;
  127. if(hWriteKey)
  128. {
  129. RegSetValueEx(hWriteKey,
  130. pszValueName,
  131. 0,
  132. REG_DWORD,
  133. (PUCHAR)pdwValue,
  134. sizeof(DWORD));
  135. }
  136. }
  137. return (dwOriginalValue != *pdwValue);
  138. }
  139. ////////////////////////////////////////////////////////////////////
  140. //
  141. // Name: SslWatchParamKey
  142. //
  143. // Synopsis: Sets RegNotifyChangeKeyValue() on param key, initializes
  144. // debug level, then utilizes thread pool to wait on
  145. // changes to this registry key. Enables dynamic debug
  146. // level changes, as this function will also be callback
  147. // if registry key modified.
  148. //
  149. // Arguments: pCtxt is actually a HANDLE to an event. This event
  150. // will be triggered when key is modified.
  151. //
  152. // Notes: .
  153. //
  154. VOID
  155. SslWatchParamKey(
  156. PVOID pCtxt,
  157. BOOLEAN fWaitStatus)
  158. {
  159. NTSTATUS Status;
  160. LONG lRes = ERROR_SUCCESS;
  161. BOOL fFirstTime = FALSE;
  162. DWORD disp;
  163. UNREFERENCED_PARAMETER(fWaitStatus);
  164. if(g_hkBase == NULL)
  165. {
  166. // First time we've been called.
  167. Status = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  168. SP_REG_KEY_BASE,
  169. 0,
  170. TEXT(""),
  171. REG_OPTION_NON_VOLATILE,
  172. KEY_READ,
  173. NULL,
  174. &g_hkBase,
  175. &disp);
  176. if(Status)
  177. {
  178. DebugLog((DEB_WARN,"Failed to open SCHANNEL key: 0x%x\n", Status));
  179. return;
  180. }
  181. fFirstTime = TRUE;
  182. }
  183. if(pCtxt != NULL)
  184. {
  185. if (NULL != g_hWait)
  186. {
  187. Status = RtlDeregisterWait(g_hWait);
  188. if(!NT_SUCCESS(Status))
  189. {
  190. DebugLog((DEB_WARN, "Failed to Deregister wait on registry key: 0x%x\n", Status));
  191. goto Reregister;
  192. }
  193. }
  194. lRes = RegNotifyChangeKeyValue(
  195. g_hkBase,
  196. TRUE,
  197. REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET,
  198. (HANDLE)pCtxt,
  199. TRUE);
  200. if (ERROR_SUCCESS != lRes)
  201. {
  202. DebugLog((DEB_ERROR,"Debug RegNotify setup failed: 0x%x\n", lRes));
  203. // we're tanked now. No further notifications, so get this one
  204. }
  205. }
  206. SslReadRegOptions(fFirstTime);
  207. #if DBG
  208. InitDebugSupport(g_hkBase);
  209. #endif
  210. Reregister:
  211. if(pCtxt != NULL)
  212. {
  213. Status = RtlRegisterWait(&g_hWait,
  214. (HANDLE)pCtxt,
  215. SslWatchParamKey,
  216. (HANDLE)pCtxt,
  217. INFINITE,
  218. WT_EXECUTEINPERSISTENTIOTHREAD|
  219. WT_EXECUTEONLYONCE);
  220. }
  221. }
  222. ////////////////////////////////////////////////////////////////////
  223. //
  224. // Name: FipsWatchParamKey
  225. //
  226. // Synopsis: Sets RegNotifyChangeKeyValue() on param key, initializes
  227. // debug level, then utilizes thread pool to wait on
  228. // changes to this registry key. Enables dynamic debug
  229. // level changes, as this function will also be callback
  230. // if registry key modified.
  231. //
  232. // Arguments: pCtxt is actually a HANDLE to an event. This event
  233. // will be triggered when key is modified.
  234. //
  235. // Notes: .
  236. //
  237. VOID
  238. FipsWatchParamKey(
  239. PVOID pCtxt,
  240. BOOLEAN fWaitStatus)
  241. {
  242. NTSTATUS Status;
  243. LONG lRes = ERROR_SUCCESS;
  244. DWORD disp;
  245. UNREFERENCED_PARAMETER(fWaitStatus);
  246. if(g_hkFipsBase == NULL)
  247. {
  248. // First time we've been called.
  249. Status = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  250. SP_REG_FIPS_BASE_KEY,
  251. 0,
  252. TEXT(""),
  253. REG_OPTION_NON_VOLATILE,
  254. KEY_READ,
  255. NULL,
  256. &g_hkFipsBase,
  257. &disp);
  258. if(Status)
  259. {
  260. DebugLog((DEB_WARN,"Failed to open FIPS key: 0x%x\n", Status));
  261. return;
  262. }
  263. }
  264. if(pCtxt != NULL)
  265. {
  266. if (NULL != g_hFipsWait)
  267. {
  268. Status = RtlDeregisterWait(g_hFipsWait);
  269. if(!NT_SUCCESS(Status))
  270. {
  271. DebugLog((DEB_WARN, "Failed to Deregister wait on registry key: 0x%x\n", Status));
  272. goto Reregister;
  273. }
  274. }
  275. lRes = RegNotifyChangeKeyValue(
  276. g_hkFipsBase,
  277. TRUE,
  278. REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET,
  279. (HANDLE)pCtxt,
  280. TRUE);
  281. if (ERROR_SUCCESS != lRes)
  282. {
  283. DebugLog((DEB_ERROR,"Debug RegNotify setup failed: 0x%x\n", lRes));
  284. // we're tanked now. No further notifications, so get this one
  285. }
  286. }
  287. SslReadRegOptions(FALSE);
  288. Reregister:
  289. if(pCtxt != NULL)
  290. {
  291. Status = RtlRegisterWait(&g_hFipsWait,
  292. (HANDLE)pCtxt,
  293. FipsWatchParamKey,
  294. (HANDLE)pCtxt,
  295. INFINITE,
  296. WT_EXECUTEINPERSISTENTIOTHREAD|
  297. WT_EXECUTEONLYONCE);
  298. }
  299. }
  300. BOOL
  301. SslReadRegOptions(
  302. BOOL fFirstTime)
  303. {
  304. DWORD err;
  305. DWORD dwType;
  306. DWORD fVal;
  307. DWORD dwSize;
  308. HKEY hKey;
  309. HKEY hWriteKey;
  310. DWORD disp;
  311. DWORD i;
  312. HKEY hkProtocols = NULL;
  313. HKEY hkCiphers = NULL;
  314. HKEY hkHashes = NULL;
  315. HKEY hkKeyExch = NULL;
  316. DWORD dwSetting = 0;
  317. BOOL fSettingsChanged = FALSE;
  318. DWORD dwOriginalValue;
  319. DebugLog((DEB_TRACE,"Load configuration parameters from registry.\n"));
  320. // "FipsAlgorithmPolicy"
  321. ReadRegistrySetting(
  322. g_hkFipsBase,
  323. 0,
  324. SP_REG_FIPS_POLICY,
  325. &dwSetting,
  326. 0);
  327. if((dwSetting == 1) != g_fFipsMode)
  328. {
  329. g_fFipsMode = (dwSetting == 1);
  330. fSettingsChanged = TRUE;
  331. }
  332. //
  333. // Read top-level configuration options.
  334. //
  335. // Open top-level key that has write access.
  336. if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  337. SP_REG_KEY_BASE,
  338. 0,
  339. KEY_READ | KEY_SET_VALUE,
  340. &hWriteKey) != STATUS_SUCCESS)
  341. {
  342. hWriteKey = 0;
  343. }
  344. // "EventLogging"
  345. if(ReadRegistrySetting(
  346. g_hkBase,
  347. hWriteKey,
  348. SP_REG_VAL_EVENTLOG,
  349. &g_dwEventLogging,
  350. DEFAULT_EVENT_LOGGING_SETTING))
  351. {
  352. fSettingsChanged = TRUE;
  353. }
  354. // "ManualCredValidation"
  355. ReadRegistrySetting(
  356. g_hkBase,
  357. 0,
  358. SP_REG_VAL_MANUAL_CRED_VALIDATION,
  359. &dwSetting,
  360. MANUAL_CRED_VALIDATION_SETTING);
  361. if((dwSetting != 0) != g_fManualCredValidation)
  362. {
  363. g_fManualCredValidation = (dwSetting != 0);
  364. fSettingsChanged = TRUE;
  365. }
  366. // "ClientCacheTime"
  367. if(ReadRegistrySetting(
  368. g_hkBase,
  369. 0,
  370. SP_REG_VAL_CLIENT_CACHE_TIME,
  371. &SchannelCache.dwClientLifespan,
  372. SP_CACHE_CLIENT_LIFESPAN))
  373. {
  374. fSettingsChanged = TRUE;
  375. }
  376. // "ServerCacheTime"
  377. if(ReadRegistrySetting(
  378. g_hkBase,
  379. 0,
  380. SP_REG_VAL_SERVER_CACHE_TIME,
  381. &SchannelCache.dwServerLifespan,
  382. SP_CACHE_SERVER_LIFESPAN))
  383. {
  384. fSettingsChanged = TRUE;
  385. }
  386. // "MaximumCacheSize"
  387. if(ReadRegistrySetting(
  388. g_hkBase,
  389. 0,
  390. SP_REG_VAL_MAXUMUM_CACHE_SIZE,
  391. &SchannelCache.dwMaximumEntries,
  392. SP_MAXIMUM_CACHE_ELEMENTS))
  393. {
  394. fSettingsChanged = TRUE;
  395. }
  396. if(fFirstTime)
  397. {
  398. SchannelCache.dwCacheSize = SchannelCache.dwMaximumEntries;
  399. }
  400. // "MultipleProcessClientCache"
  401. ReadRegistrySetting(
  402. g_hkBase,
  403. 0,
  404. SP_REG_VAL_MULTI_PROC_CLIENT_CACHE,
  405. &dwSetting,
  406. FALSE);
  407. if((dwSetting != 0) != g_fMultipleProcessClientCache)
  408. {
  409. g_fMultipleProcessClientCache = (dwSetting != 0);
  410. fSettingsChanged = TRUE;
  411. }
  412. // "SendTrustedIssuerList"
  413. ReadRegistrySetting(
  414. g_hkBase,
  415. 0,
  416. SP_REG_VAL_SEND_ISSUER_LIST,
  417. &dwSetting,
  418. TRUE);
  419. if((dwSetting != 0) != g_fSendIssuerList)
  420. {
  421. g_fSendIssuerList = (dwSetting != 0);
  422. fSettingsChanged = TRUE;
  423. }
  424. // "CertificateMappingMethods"
  425. if(ReadRegistrySetting(
  426. g_hkBase,
  427. 0,
  428. SP_REG_VAL_CERT_MAPPING_METHODS,
  429. &g_dwCertMappingMethods,
  430. DEFAULT_CERTMAP_SETTING))
  431. {
  432. fSettingsChanged = TRUE;
  433. if((g_dwCertMappingMethods & SP_REG_CERTMAP_SUBJECT_FLAG) == 0)
  434. {
  435. DebugLog((DEB_TRACE, "Subject/Issuer certificate mapping disabled\n"));
  436. }
  437. if((g_dwCertMappingMethods & SP_REG_CERTMAP_ISSUER_FLAG) == 0)
  438. {
  439. DebugLog((DEB_TRACE, "Issuer certificate mapping disabled\n"));
  440. }
  441. if((g_dwCertMappingMethods & SP_REG_CERTMAP_UPN_FLAG) == 0)
  442. {
  443. DebugLog((DEB_TRACE, "UPN certificate mapping disabled\n"));
  444. }
  445. if((g_dwCertMappingMethods & SP_REG_CERTMAP_S4U2SELF_FLAG) == 0)
  446. {
  447. DebugLog((DEB_TRACE, "S4U2Self certificate mapping disabled\n"));
  448. }
  449. }
  450. if(hWriteKey)
  451. {
  452. RegCloseKey(hWriteKey);
  453. hWriteKey = 0;
  454. }
  455. // "IssuerCacheTime"
  456. ReadRegistrySetting(
  457. g_hkBase,
  458. 0,
  459. SP_REG_VAL_ISSUER_CACHE_TIME,
  460. &IssuerCache.dwLifespan,
  461. ISSUER_CACHE_LIFESPAN);
  462. // "IssuerCacheSize"
  463. ReadRegistrySetting(
  464. g_hkBase,
  465. 0,
  466. SP_REG_VAL_ISSUER_CACHE_SIZE,
  467. &IssuerCache.dwMaximumEntries,
  468. ISSUER_CACHE_SIZE);
  469. if(fFirstTime)
  470. {
  471. IssuerCache.dwCacheSize = IssuerCache.dwMaximumEntries;
  472. }
  473. #ifdef ROGUE_DC
  474. if(g_hSslRogueKey == NULL)
  475. {
  476. if(RegOpenKeyExW(HKEY_LOCAL_MACHINE,
  477. SP_REG_ROGUE_BASE_KEY,
  478. 0,
  479. KEY_READ,
  480. &g_hSslRogueKey) != STATUS_SUCCESS)
  481. {
  482. DebugLog((DEB_WARN,"Failed to open \"rogue\" ssl key\n" ));
  483. g_hSslRogueKey = NULL;
  484. }
  485. }
  486. #endif
  487. //
  488. // Enable/Disable Protocols
  489. //
  490. if(g_fFipsMode)
  491. {
  492. // Disable everything except TLS.
  493. g_ProtEnabled = SP_PROT_TLS1;
  494. }
  495. else
  496. {
  497. DWORD dwProtEnabled = DEFAULT_ENABLED_PROTOCOLS_SETTING;
  498. err = RegCreateKeyEx( g_hkBase,
  499. SP_REG_KEY_PROTOCOL,
  500. 0,
  501. TEXT(""),
  502. REG_OPTION_NON_VOLATILE,
  503. KEY_READ,
  504. NULL,
  505. &hkProtocols,
  506. &disp);
  507. if(err == ERROR_SUCCESS)
  508. {
  509. for(i=0; i < (sizeof(g_ProtMap)/sizeof(enamap)); i++)
  510. {
  511. if(g_ProtMap[i].Mask & SP_PROT_PCT1)
  512. {
  513. if(g_fFranceLocale)
  514. {
  515. // Don't allow PCT to be enabled in France.
  516. continue;
  517. }
  518. }
  519. err = RegCreateKeyEx( hkProtocols,
  520. g_ProtMap[i].pKey,
  521. 0,
  522. TEXT(""),
  523. REG_OPTION_NON_VOLATILE,
  524. KEY_READ,
  525. NULL,
  526. &hKey,
  527. &disp);
  528. if(!err)
  529. {
  530. dwSize = sizeof(DWORD);
  531. err = RegQueryValueEx(hKey,
  532. SP_REG_VAL_ENABLED,
  533. NULL, &dwType,
  534. (PUCHAR)&fVal,
  535. &dwSize);
  536. if(!err)
  537. {
  538. if(fVal)
  539. {
  540. dwProtEnabled |= g_ProtMap[i].Mask;
  541. }
  542. else
  543. {
  544. dwProtEnabled &= ~g_ProtMap[i].Mask;
  545. }
  546. }
  547. if(g_ProtMap[i].Mask & SP_PROT_PCT1_CLIENT)
  548. {
  549. // "DisabledByDefault"
  550. ReadRegistrySetting(
  551. hKey,
  552. 0,
  553. SP_REG_VAL_DISABLED_BY_DEFAULT,
  554. &dwSetting,
  555. PCT_CLIENT_DISABLED_SETTING);
  556. g_PctClientDisabledByDefault = (dwSetting != 0);
  557. }
  558. if(g_ProtMap[i].Mask & SP_PROT_SSL2_CLIENT)
  559. {
  560. // "DisabledByDefault"
  561. ReadRegistrySetting(
  562. hKey,
  563. 0,
  564. SP_REG_VAL_DISABLED_BY_DEFAULT,
  565. &dwSetting,
  566. SSL2_CLIENT_DISABLED_SETTING);
  567. g_Ssl2ClientDisabledByDefault = (dwSetting != 0);
  568. }
  569. RegCloseKey(hKey);
  570. }
  571. }
  572. RegCloseKey(hkProtocols);
  573. }
  574. if(g_ProtEnabled != dwProtEnabled)
  575. {
  576. g_ProtEnabled = dwProtEnabled;
  577. fSettingsChanged = TRUE;
  578. }
  579. }
  580. //
  581. // Enable/Disable Ciphers
  582. //
  583. if(g_fFipsMode)
  584. {
  585. // Disable everything except 3DES.
  586. for(i=0; i < g_cAvailableCiphers; i++)
  587. {
  588. if(g_AvailableCiphers[i].aiCipher != CALG_3DES)
  589. {
  590. g_AvailableCiphers[i].fProtocol = 0;
  591. }
  592. }
  593. }
  594. else
  595. {
  596. err = RegCreateKeyEx( g_hkBase,
  597. SP_REG_KEY_CIPHERS,
  598. 0,
  599. TEXT(""),
  600. REG_OPTION_NON_VOLATILE,
  601. KEY_READ,
  602. NULL,
  603. &hkCiphers,
  604. &disp);
  605. if(err == ERROR_SUCCESS)
  606. {
  607. for(i=0; i < g_cAvailableCiphers; i++)
  608. {
  609. dwOriginalValue = g_AvailableCiphers[i].fProtocol;
  610. g_AvailableCiphers[i].fProtocol = g_AvailableCiphers[i].fDefault;
  611. fVal = g_AvailableCiphers[i].fDefault;
  612. err = RegCreateKeyExA( hkCiphers,
  613. g_AvailableCiphers[i].szName,
  614. 0,
  615. "",
  616. REG_OPTION_NON_VOLATILE,
  617. KEY_READ,
  618. NULL,
  619. &hKey,
  620. &disp);
  621. if(!err)
  622. {
  623. dwSize = sizeof(DWORD);
  624. err = RegQueryValueEx(hKey,
  625. SP_REG_VAL_ENABLED,
  626. NULL,
  627. &dwType,
  628. (PUCHAR)&fVal,
  629. &dwSize);
  630. if(err)
  631. {
  632. fVal = g_AvailableCiphers[i].fDefault;
  633. }
  634. RegCloseKey(hKey);
  635. }
  636. g_AvailableCiphers[i].fProtocol &= fVal;
  637. if(g_AvailableCiphers[i].fProtocol != dwOriginalValue)
  638. {
  639. fSettingsChanged = TRUE;
  640. }
  641. }
  642. RegCloseKey(hkCiphers);
  643. }
  644. }
  645. //
  646. // Enable/Disable Hashes
  647. //
  648. err = RegCreateKeyEx( g_hkBase,
  649. SP_REG_KEY_HASHES,
  650. 0,
  651. TEXT(""),
  652. REG_OPTION_NON_VOLATILE,
  653. KEY_READ,
  654. NULL,
  655. &hkHashes,
  656. &disp);
  657. if(err == ERROR_SUCCESS)
  658. {
  659. for(i = 0; i < g_cAvailableHashes; i++)
  660. {
  661. dwOriginalValue = g_AvailableHashes[i].fProtocol;
  662. g_AvailableHashes[i].fProtocol = g_AvailableHashes[i].fDefault;
  663. fVal = g_AvailableHashes[i].fDefault;
  664. err = RegCreateKeyExA( hkHashes,
  665. g_AvailableHashes[i].szName,
  666. 0,
  667. "",
  668. REG_OPTION_NON_VOLATILE,
  669. KEY_READ,
  670. NULL,
  671. &hKey,
  672. &disp);
  673. if(!err)
  674. {
  675. dwSize = sizeof(DWORD);
  676. err = RegQueryValueEx(hKey,
  677. SP_REG_VAL_ENABLED,
  678. NULL,
  679. &dwType,
  680. (PUCHAR)&fVal,
  681. &dwSize);
  682. if(err)
  683. {
  684. fVal = g_AvailableHashes[i].fDefault;
  685. }
  686. RegCloseKey(hKey);
  687. }
  688. g_AvailableHashes[i].fProtocol &= fVal;
  689. if(dwOriginalValue != g_AvailableHashes[i].fProtocol)
  690. {
  691. fSettingsChanged = TRUE;
  692. }
  693. }
  694. RegCloseKey(hkHashes);
  695. }
  696. //
  697. // Enable/Disable Key Exchange algs.
  698. //
  699. if(g_fFipsMode)
  700. {
  701. // Disable everything except RSA.
  702. for(i=0; i < g_cAvailableExch; i++)
  703. {
  704. if(g_AvailableExch[i].aiExch != CALG_RSA_KEYX &&
  705. g_AvailableExch[i].aiExch != CALG_RSA_SIGN)
  706. {
  707. g_AvailableExch[i].fProtocol = 0;
  708. }
  709. }
  710. }
  711. else
  712. {
  713. err = RegCreateKeyEx( g_hkBase,
  714. SP_REG_KEY_KEYEXCH,
  715. 0,
  716. TEXT(""),
  717. REG_OPTION_NON_VOLATILE,
  718. KEY_READ,
  719. NULL,
  720. &hkKeyExch,
  721. &disp);
  722. if(err == ERROR_SUCCESS)
  723. {
  724. for(i = 0; i < g_cAvailableExch; i++)
  725. {
  726. dwOriginalValue = g_AvailableExch[i].fProtocol;
  727. g_AvailableExch[i].fProtocol = g_AvailableExch[i].fDefault;
  728. fVal = g_AvailableExch[i].fDefault;
  729. err = RegCreateKeyExA( hkKeyExch,
  730. g_AvailableExch[i].szName,
  731. 0,
  732. "",
  733. REG_OPTION_NON_VOLATILE,
  734. KEY_READ,
  735. NULL,
  736. &hKey,
  737. &disp);
  738. if(!err)
  739. {
  740. dwSize = sizeof(DWORD);
  741. err = RegQueryValueEx(hKey,
  742. SP_REG_VAL_ENABLED,
  743. NULL,
  744. &dwType,
  745. (PUCHAR)&fVal,
  746. &dwSize);
  747. if(err)
  748. {
  749. fVal = g_AvailableExch[i].fDefault;
  750. }
  751. g_AvailableExch[i].fProtocol &= fVal;
  752. RegCloseKey(hKey);
  753. }
  754. if(dwOriginalValue != g_AvailableExch[i].fProtocol)
  755. {
  756. fSettingsChanged = TRUE;
  757. }
  758. }
  759. RegCloseKey(hkKeyExch);
  760. }
  761. }
  762. //
  763. // Purge the session cache.
  764. //
  765. if(g_fCacheInitialized && fSettingsChanged)
  766. {
  767. SPCachePurgeEntries(NULL,
  768. 0,
  769. NULL,
  770. SSL_PURGE_CLIENT_ALL_ENTRIES |
  771. SSL_PURGE_SERVER_ALL_ENTRIES);
  772. }
  773. return TRUE;
  774. }