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
887 lines
25 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 2000.
|
|
//
|
|
// File: spreg.c
|
|
//
|
|
// Contents: Schannel registry management routines.
|
|
//
|
|
// Classes:
|
|
//
|
|
// Functions:
|
|
//
|
|
// History: 11-24-97 jbanes Enabled TLS
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include <sslp.h>
|
|
#include "spreg.h"
|
|
#include <mapper.h>
|
|
#include <sidfilter.h>
|
|
|
|
HKEY g_hkBase = NULL;
|
|
HANDLE g_hParamEvent = NULL;
|
|
HANDLE g_hWait = NULL;
|
|
|
|
HKEY g_hkFipsBase = NULL;
|
|
HANDLE g_hFipsParamEvent = NULL;
|
|
HANDLE g_hFipsWait = NULL;
|
|
|
|
BOOL g_fManualCredValidation = MANUAL_CRED_VALIDATION_SETTING;
|
|
BOOL g_PctClientDisabledByDefault = PCT_CLIENT_DISABLED_SETTING;
|
|
BOOL g_Ssl2ClientDisabledByDefault = SSL2_CLIENT_DISABLED_SETTING;
|
|
|
|
DWORD g_dwEventLogging = DEFAULT_EVENT_LOGGING_SETTING;
|
|
DWORD g_ProtEnabled = DEFAULT_ENABLED_PROTOCOLS_SETTING;
|
|
|
|
BOOL g_fSendIssuerList = TRUE;
|
|
|
|
DWORD g_dwCertMappingMethods = DEFAULT_CERTMAP_SETTING;
|
|
|
|
BOOL g_fFipsMode = FALSE;
|
|
BOOL g_fFranceLocale = FALSE;
|
|
|
|
BOOL g_SslS4U2SelfInitialized = FALSE;
|
|
|
|
typedef struct enamap
|
|
{
|
|
TCHAR *pKey;
|
|
DWORD Mask;
|
|
} enamap;
|
|
|
|
enamap g_ProtMap[] =
|
|
{
|
|
{SP_REG_KEY_PCT1 TEXT("\\") SP_REG_KEY_CLIENT, SP_PROT_PCT1_CLIENT},
|
|
{SP_REG_KEY_PCT1 TEXT("\\") SP_REG_KEY_SERVER, SP_PROT_PCT1_SERVER},
|
|
{SP_REG_KEY_SSL2 TEXT("\\") SP_REG_KEY_CLIENT, SP_PROT_SSL2_CLIENT},
|
|
{SP_REG_KEY_SSL2 TEXT("\\") SP_REG_KEY_SERVER, SP_PROT_SSL2_SERVER},
|
|
{SP_REG_KEY_SSL3 TEXT("\\") SP_REG_KEY_CLIENT, SP_PROT_SSL3_CLIENT},
|
|
{SP_REG_KEY_SSL3 TEXT("\\") SP_REG_KEY_SERVER, SP_PROT_SSL3_SERVER},
|
|
{SP_REG_KEY_TLS1 TEXT("\\") SP_REG_KEY_CLIENT, SP_PROT_TLS1_CLIENT},
|
|
{SP_REG_KEY_TLS1 TEXT("\\") SP_REG_KEY_SERVER, SP_PROT_TLS1_SERVER}
|
|
};
|
|
|
|
VOID
|
|
SslWatchParamKey(
|
|
PVOID pCtxt,
|
|
BOOLEAN fWaitStatus);
|
|
|
|
VOID
|
|
FipsWatchParamKey(
|
|
PVOID pCtxt,
|
|
BOOLEAN fWaitStatus);
|
|
|
|
BOOL
|
|
SslReadRegOptions(
|
|
BOOL fFirstTime);
|
|
|
|
BOOL SPLoadRegOptions(void)
|
|
{
|
|
g_hParamEvent = CreateEvent(NULL,
|
|
FALSE,
|
|
FALSE,
|
|
NULL);
|
|
|
|
SslWatchParamKey(g_hParamEvent, FALSE);
|
|
|
|
g_hFipsParamEvent = CreateEvent(NULL,
|
|
FALSE,
|
|
FALSE,
|
|
NULL);
|
|
|
|
FipsWatchParamKey(g_hFipsParamEvent, FALSE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void SPUnloadRegOptions(void)
|
|
{
|
|
if (NULL != g_hWait)
|
|
{
|
|
RtlDeregisterWait(g_hWait);
|
|
g_hWait = NULL;
|
|
}
|
|
|
|
if(NULL != g_hkBase)
|
|
{
|
|
RegCloseKey(g_hkBase);
|
|
}
|
|
|
|
if(NULL != g_hParamEvent)
|
|
{
|
|
CloseHandle(g_hParamEvent);
|
|
}
|
|
|
|
if (NULL != g_hFipsWait)
|
|
{
|
|
RtlDeregisterWait(g_hFipsWait);
|
|
g_hFipsWait = NULL;
|
|
}
|
|
|
|
if(NULL != g_hkFipsBase)
|
|
{
|
|
RegCloseKey(g_hkFipsBase);
|
|
}
|
|
|
|
if(NULL != g_hFipsParamEvent)
|
|
{
|
|
CloseHandle(g_hFipsParamEvent);
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
ReadRegistrySetting(
|
|
HKEY hReadKey,
|
|
HKEY hWriteKey,
|
|
LPCTSTR pszValueName,
|
|
DWORD * pdwValue,
|
|
DWORD dwDefaultValue)
|
|
{
|
|
DWORD dwSize;
|
|
DWORD dwType;
|
|
DWORD dwOriginalValue = *pdwValue;
|
|
|
|
dwSize = sizeof(DWORD);
|
|
if(RegQueryValueEx(hReadKey,
|
|
pszValueName,
|
|
NULL,
|
|
&dwType,
|
|
(PUCHAR)pdwValue,
|
|
&dwSize) != STATUS_SUCCESS)
|
|
{
|
|
*pdwValue = dwDefaultValue;
|
|
|
|
if(hWriteKey)
|
|
{
|
|
RegSetValueEx(hWriteKey,
|
|
pszValueName,
|
|
0,
|
|
REG_DWORD,
|
|
(PUCHAR)pdwValue,
|
|
sizeof(DWORD));
|
|
}
|
|
}
|
|
|
|
return (dwOriginalValue != *pdwValue);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Name: SslWatchParamKey
|
|
//
|
|
// Synopsis: Sets RegNotifyChangeKeyValue() on param key, initializes
|
|
// debug level, then utilizes thread pool to wait on
|
|
// changes to this registry key. Enables dynamic debug
|
|
// level changes, as this function will also be callback
|
|
// if registry key modified.
|
|
//
|
|
// Arguments: pCtxt is actually a HANDLE to an event. This event
|
|
// will be triggered when key is modified.
|
|
//
|
|
// Notes: .
|
|
//
|
|
VOID
|
|
SslWatchParamKey(
|
|
PVOID pCtxt,
|
|
BOOLEAN fWaitStatus)
|
|
{
|
|
NTSTATUS Status;
|
|
LONG lRes = ERROR_SUCCESS;
|
|
BOOL fFirstTime = FALSE;
|
|
DWORD disp;
|
|
|
|
UNREFERENCED_PARAMETER(fWaitStatus);
|
|
|
|
if(g_hkBase == NULL)
|
|
{
|
|
// First time we've been called.
|
|
Status = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
|
|
SP_REG_KEY_BASE,
|
|
0,
|
|
TEXT(""),
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ,
|
|
NULL,
|
|
&g_hkBase,
|
|
&disp);
|
|
if(Status)
|
|
{
|
|
DebugLog((DEB_WARN,"Failed to open SCHANNEL key: 0x%x\n", Status));
|
|
return;
|
|
}
|
|
|
|
fFirstTime = TRUE;
|
|
}
|
|
|
|
if(pCtxt != NULL)
|
|
{
|
|
if (NULL != g_hWait)
|
|
{
|
|
Status = RtlDeregisterWait(g_hWait);
|
|
if(!NT_SUCCESS(Status))
|
|
{
|
|
DebugLog((DEB_WARN, "Failed to Deregister wait on registry key: 0x%x\n", Status));
|
|
goto Reregister;
|
|
}
|
|
}
|
|
|
|
lRes = RegNotifyChangeKeyValue(
|
|
g_hkBase,
|
|
TRUE,
|
|
REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET,
|
|
(HANDLE)pCtxt,
|
|
TRUE);
|
|
|
|
if (ERROR_SUCCESS != lRes)
|
|
{
|
|
DebugLog((DEB_ERROR,"Debug RegNotify setup failed: 0x%x\n", lRes));
|
|
// we're tanked now. No further notifications, so get this one
|
|
}
|
|
}
|
|
|
|
SslReadRegOptions(fFirstTime);
|
|
|
|
#if DBG
|
|
InitDebugSupport(g_hkBase);
|
|
#endif
|
|
|
|
Reregister:
|
|
|
|
if(pCtxt != NULL)
|
|
{
|
|
Status = RtlRegisterWait(&g_hWait,
|
|
(HANDLE)pCtxt,
|
|
SslWatchParamKey,
|
|
(HANDLE)pCtxt,
|
|
INFINITE,
|
|
WT_EXECUTEINPERSISTENTIOTHREAD|
|
|
WT_EXECUTEONLYONCE);
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Name: FipsWatchParamKey
|
|
//
|
|
// Synopsis: Sets RegNotifyChangeKeyValue() on param key, initializes
|
|
// debug level, then utilizes thread pool to wait on
|
|
// changes to this registry key. Enables dynamic debug
|
|
// level changes, as this function will also be callback
|
|
// if registry key modified.
|
|
//
|
|
// Arguments: pCtxt is actually a HANDLE to an event. This event
|
|
// will be triggered when key is modified.
|
|
//
|
|
// Notes: .
|
|
//
|
|
VOID
|
|
FipsWatchParamKey(
|
|
PVOID pCtxt,
|
|
BOOLEAN fWaitStatus)
|
|
{
|
|
NTSTATUS Status;
|
|
LONG lRes = ERROR_SUCCESS;
|
|
DWORD disp;
|
|
|
|
UNREFERENCED_PARAMETER(fWaitStatus);
|
|
|
|
if(g_hkFipsBase == NULL)
|
|
{
|
|
// First time we've been called.
|
|
Status = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
|
|
SP_REG_FIPS_BASE_KEY,
|
|
0,
|
|
TEXT(""),
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ,
|
|
NULL,
|
|
&g_hkFipsBase,
|
|
&disp);
|
|
if(Status)
|
|
{
|
|
DebugLog((DEB_WARN,"Failed to open FIPS key: 0x%x\n", Status));
|
|
return;
|
|
}
|
|
}
|
|
|
|
if(pCtxt != NULL)
|
|
{
|
|
if (NULL != g_hFipsWait)
|
|
{
|
|
Status = RtlDeregisterWait(g_hFipsWait);
|
|
if(!NT_SUCCESS(Status))
|
|
{
|
|
DebugLog((DEB_WARN, "Failed to Deregister wait on registry key: 0x%x\n", Status));
|
|
goto Reregister;
|
|
}
|
|
}
|
|
|
|
lRes = RegNotifyChangeKeyValue(
|
|
g_hkFipsBase,
|
|
TRUE,
|
|
REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET,
|
|
(HANDLE)pCtxt,
|
|
TRUE);
|
|
|
|
if (ERROR_SUCCESS != lRes)
|
|
{
|
|
DebugLog((DEB_ERROR,"Debug RegNotify setup failed: 0x%x\n", lRes));
|
|
// we're tanked now. No further notifications, so get this one
|
|
}
|
|
}
|
|
|
|
SslReadRegOptions(FALSE);
|
|
|
|
Reregister:
|
|
|
|
if(pCtxt != NULL)
|
|
{
|
|
Status = RtlRegisterWait(&g_hFipsWait,
|
|
(HANDLE)pCtxt,
|
|
FipsWatchParamKey,
|
|
(HANDLE)pCtxt,
|
|
INFINITE,
|
|
WT_EXECUTEINPERSISTENTIOTHREAD|
|
|
WT_EXECUTEONLYONCE);
|
|
}
|
|
}
|
|
|
|
|
|
BOOL
|
|
SslReadRegOptions(
|
|
BOOL fFirstTime)
|
|
{
|
|
DWORD err;
|
|
DWORD dwType;
|
|
DWORD fVal;
|
|
DWORD dwSize;
|
|
HKEY hKey;
|
|
HKEY hWriteKey;
|
|
DWORD disp;
|
|
DWORD i;
|
|
HKEY hkProtocols = NULL;
|
|
HKEY hkCiphers = NULL;
|
|
HKEY hkHashes = NULL;
|
|
HKEY hkKeyExch = NULL;
|
|
DWORD dwSetting = 0;
|
|
BOOL fSettingsChanged = FALSE;
|
|
DWORD dwOriginalValue;
|
|
|
|
DebugLog((DEB_TRACE,"Load configuration parameters from registry.\n"));
|
|
|
|
|
|
// "FipsAlgorithmPolicy"
|
|
ReadRegistrySetting(
|
|
g_hkFipsBase,
|
|
0,
|
|
SP_REG_FIPS_POLICY,
|
|
&dwSetting,
|
|
0);
|
|
if((dwSetting == 1) != g_fFipsMode)
|
|
{
|
|
g_fFipsMode = (dwSetting == 1);
|
|
fSettingsChanged = TRUE;
|
|
}
|
|
|
|
|
|
//
|
|
// Read top-level configuration options.
|
|
//
|
|
|
|
// Open top-level key that has write access.
|
|
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
SP_REG_KEY_BASE,
|
|
0,
|
|
KEY_READ | KEY_SET_VALUE,
|
|
&hWriteKey) != STATUS_SUCCESS)
|
|
{
|
|
hWriteKey = 0;
|
|
}
|
|
|
|
// "EventLogging"
|
|
if(ReadRegistrySetting(
|
|
g_hkBase,
|
|
hWriteKey,
|
|
SP_REG_VAL_EVENTLOG,
|
|
&g_dwEventLogging,
|
|
DEFAULT_EVENT_LOGGING_SETTING))
|
|
{
|
|
fSettingsChanged = TRUE;
|
|
}
|
|
|
|
// "ManualCredValidation"
|
|
ReadRegistrySetting(
|
|
g_hkBase,
|
|
0,
|
|
SP_REG_VAL_MANUAL_CRED_VALIDATION,
|
|
&dwSetting,
|
|
MANUAL_CRED_VALIDATION_SETTING);
|
|
if((dwSetting != 0) != g_fManualCredValidation)
|
|
{
|
|
g_fManualCredValidation = (dwSetting != 0);
|
|
fSettingsChanged = TRUE;
|
|
}
|
|
|
|
// "ClientCacheTime"
|
|
if(ReadRegistrySetting(
|
|
g_hkBase,
|
|
0,
|
|
SP_REG_VAL_CLIENT_CACHE_TIME,
|
|
&SchannelCache.dwClientLifespan,
|
|
SP_CACHE_CLIENT_LIFESPAN))
|
|
{
|
|
fSettingsChanged = TRUE;
|
|
}
|
|
|
|
// "ServerCacheTime"
|
|
if(ReadRegistrySetting(
|
|
g_hkBase,
|
|
0,
|
|
SP_REG_VAL_SERVER_CACHE_TIME,
|
|
&SchannelCache.dwServerLifespan,
|
|
SP_CACHE_SERVER_LIFESPAN))
|
|
{
|
|
fSettingsChanged = TRUE;
|
|
}
|
|
|
|
// "MaximumCacheSize"
|
|
if(ReadRegistrySetting(
|
|
g_hkBase,
|
|
0,
|
|
SP_REG_VAL_MAXUMUM_CACHE_SIZE,
|
|
&SchannelCache.dwMaximumEntries,
|
|
SP_MAXIMUM_CACHE_ELEMENTS))
|
|
{
|
|
fSettingsChanged = TRUE;
|
|
}
|
|
|
|
if(fFirstTime)
|
|
{
|
|
SchannelCache.dwCacheSize = SchannelCache.dwMaximumEntries;
|
|
}
|
|
|
|
// "MultipleProcessClientCache"
|
|
ReadRegistrySetting(
|
|
g_hkBase,
|
|
0,
|
|
SP_REG_VAL_MULTI_PROC_CLIENT_CACHE,
|
|
&dwSetting,
|
|
FALSE);
|
|
if((dwSetting != 0) != g_fMultipleProcessClientCache)
|
|
{
|
|
g_fMultipleProcessClientCache = (dwSetting != 0);
|
|
fSettingsChanged = TRUE;
|
|
}
|
|
|
|
// "SendTrustedIssuerList"
|
|
ReadRegistrySetting(
|
|
g_hkBase,
|
|
0,
|
|
SP_REG_VAL_SEND_ISSUER_LIST,
|
|
&dwSetting,
|
|
TRUE);
|
|
if((dwSetting != 0) != g_fSendIssuerList)
|
|
{
|
|
g_fSendIssuerList = (dwSetting != 0);
|
|
fSettingsChanged = TRUE;
|
|
}
|
|
|
|
// "CertificateMappingMethods"
|
|
if(ReadRegistrySetting(
|
|
g_hkBase,
|
|
0,
|
|
SP_REG_VAL_CERT_MAPPING_METHODS,
|
|
&g_dwCertMappingMethods,
|
|
DEFAULT_CERTMAP_SETTING))
|
|
{
|
|
fSettingsChanged = TRUE;
|
|
|
|
if((g_dwCertMappingMethods & SP_REG_CERTMAP_SUBJECT_FLAG) == 0)
|
|
{
|
|
DebugLog((DEB_TRACE, "Subject/Issuer certificate mapping disabled\n"));
|
|
}
|
|
if((g_dwCertMappingMethods & SP_REG_CERTMAP_ISSUER_FLAG) == 0)
|
|
{
|
|
DebugLog((DEB_TRACE, "Issuer certificate mapping disabled\n"));
|
|
}
|
|
if((g_dwCertMappingMethods & SP_REG_CERTMAP_UPN_FLAG) == 0)
|
|
{
|
|
DebugLog((DEB_TRACE, "UPN certificate mapping disabled\n"));
|
|
}
|
|
if((g_dwCertMappingMethods & SP_REG_CERTMAP_S4U2SELF_FLAG) == 0)
|
|
{
|
|
DebugLog((DEB_TRACE, "S4U2Self certificate mapping disabled\n"));
|
|
}
|
|
}
|
|
|
|
if(hWriteKey)
|
|
{
|
|
RegCloseKey(hWriteKey);
|
|
hWriteKey = 0;
|
|
}
|
|
|
|
|
|
// "IssuerCacheTime"
|
|
ReadRegistrySetting(
|
|
g_hkBase,
|
|
0,
|
|
SP_REG_VAL_ISSUER_CACHE_TIME,
|
|
&IssuerCache.dwLifespan,
|
|
ISSUER_CACHE_LIFESPAN);
|
|
|
|
// "IssuerCacheSize"
|
|
ReadRegistrySetting(
|
|
g_hkBase,
|
|
0,
|
|
SP_REG_VAL_ISSUER_CACHE_SIZE,
|
|
&IssuerCache.dwMaximumEntries,
|
|
ISSUER_CACHE_SIZE);
|
|
|
|
if(fFirstTime)
|
|
{
|
|
IssuerCache.dwCacheSize = IssuerCache.dwMaximumEntries;
|
|
}
|
|
|
|
|
|
#ifdef ROGUE_DC
|
|
if(g_hSslRogueKey == NULL)
|
|
{
|
|
if(RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
|
SP_REG_ROGUE_BASE_KEY,
|
|
0,
|
|
KEY_READ,
|
|
&g_hSslRogueKey) != STATUS_SUCCESS)
|
|
{
|
|
DebugLog((DEB_WARN,"Failed to open \"rogue\" ssl key\n" ));
|
|
g_hSslRogueKey = NULL;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
//
|
|
// Enable/Disable Protocols
|
|
//
|
|
|
|
if(g_fFipsMode)
|
|
{
|
|
// Disable everything except TLS.
|
|
g_ProtEnabled = SP_PROT_TLS1;
|
|
}
|
|
else
|
|
{
|
|
DWORD dwProtEnabled = DEFAULT_ENABLED_PROTOCOLS_SETTING;
|
|
|
|
err = RegCreateKeyEx( g_hkBase,
|
|
SP_REG_KEY_PROTOCOL,
|
|
0,
|
|
TEXT(""),
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ,
|
|
NULL,
|
|
&hkProtocols,
|
|
&disp);
|
|
|
|
if(err == ERROR_SUCCESS)
|
|
{
|
|
for(i=0; i < (sizeof(g_ProtMap)/sizeof(enamap)); i++)
|
|
{
|
|
if(g_ProtMap[i].Mask & SP_PROT_PCT1)
|
|
{
|
|
if(g_fFranceLocale)
|
|
{
|
|
// Don't allow PCT to be enabled in France.
|
|
continue;
|
|
}
|
|
}
|
|
|
|
err = RegCreateKeyEx( hkProtocols,
|
|
g_ProtMap[i].pKey,
|
|
0,
|
|
TEXT(""),
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ,
|
|
NULL,
|
|
&hKey,
|
|
&disp);
|
|
if(!err)
|
|
{
|
|
dwSize = sizeof(DWORD);
|
|
err = RegQueryValueEx(hKey,
|
|
SP_REG_VAL_ENABLED,
|
|
NULL, &dwType,
|
|
(PUCHAR)&fVal,
|
|
&dwSize);
|
|
if(!err)
|
|
{
|
|
if(fVal)
|
|
{
|
|
dwProtEnabled |= g_ProtMap[i].Mask;
|
|
}
|
|
else
|
|
{
|
|
dwProtEnabled &= ~g_ProtMap[i].Mask;
|
|
}
|
|
}
|
|
|
|
if(g_ProtMap[i].Mask & SP_PROT_PCT1_CLIENT)
|
|
{
|
|
// "DisabledByDefault"
|
|
ReadRegistrySetting(
|
|
hKey,
|
|
0,
|
|
SP_REG_VAL_DISABLED_BY_DEFAULT,
|
|
&dwSetting,
|
|
PCT_CLIENT_DISABLED_SETTING);
|
|
g_PctClientDisabledByDefault = (dwSetting != 0);
|
|
}
|
|
|
|
if(g_ProtMap[i].Mask & SP_PROT_SSL2_CLIENT)
|
|
{
|
|
// "DisabledByDefault"
|
|
ReadRegistrySetting(
|
|
hKey,
|
|
0,
|
|
SP_REG_VAL_DISABLED_BY_DEFAULT,
|
|
&dwSetting,
|
|
SSL2_CLIENT_DISABLED_SETTING);
|
|
g_Ssl2ClientDisabledByDefault = (dwSetting != 0);
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hkProtocols);
|
|
}
|
|
|
|
if(g_ProtEnabled != dwProtEnabled)
|
|
{
|
|
g_ProtEnabled = dwProtEnabled;
|
|
fSettingsChanged = TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Enable/Disable Ciphers
|
|
//
|
|
|
|
if(g_fFipsMode)
|
|
{
|
|
// Disable everything except 3DES.
|
|
for(i=0; i < g_cAvailableCiphers; i++)
|
|
{
|
|
if(g_AvailableCiphers[i].aiCipher != CALG_3DES)
|
|
{
|
|
g_AvailableCiphers[i].fProtocol = 0;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
err = RegCreateKeyEx( g_hkBase,
|
|
SP_REG_KEY_CIPHERS,
|
|
0,
|
|
TEXT(""),
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ,
|
|
NULL,
|
|
&hkCiphers,
|
|
&disp);
|
|
|
|
if(err == ERROR_SUCCESS)
|
|
{
|
|
for(i=0; i < g_cAvailableCiphers; i++)
|
|
{
|
|
dwOriginalValue = g_AvailableCiphers[i].fProtocol;
|
|
|
|
g_AvailableCiphers[i].fProtocol = g_AvailableCiphers[i].fDefault;
|
|
fVal = g_AvailableCiphers[i].fDefault;
|
|
err = RegCreateKeyExA( hkCiphers,
|
|
g_AvailableCiphers[i].szName,
|
|
0,
|
|
"",
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ,
|
|
NULL,
|
|
&hKey,
|
|
&disp);
|
|
if(!err)
|
|
{
|
|
dwSize = sizeof(DWORD);
|
|
err = RegQueryValueEx(hKey,
|
|
SP_REG_VAL_ENABLED,
|
|
NULL,
|
|
&dwType,
|
|
(PUCHAR)&fVal,
|
|
&dwSize);
|
|
if(err)
|
|
{
|
|
fVal = g_AvailableCiphers[i].fDefault;
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
g_AvailableCiphers[i].fProtocol &= fVal;
|
|
|
|
if(g_AvailableCiphers[i].fProtocol != dwOriginalValue)
|
|
{
|
|
fSettingsChanged = TRUE;
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hkCiphers);
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Enable/Disable Hashes
|
|
//
|
|
|
|
err = RegCreateKeyEx( g_hkBase,
|
|
SP_REG_KEY_HASHES,
|
|
0,
|
|
TEXT(""),
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ,
|
|
NULL,
|
|
&hkHashes,
|
|
&disp);
|
|
|
|
if(err == ERROR_SUCCESS)
|
|
{
|
|
for(i = 0; i < g_cAvailableHashes; i++)
|
|
{
|
|
dwOriginalValue = g_AvailableHashes[i].fProtocol;
|
|
|
|
g_AvailableHashes[i].fProtocol = g_AvailableHashes[i].fDefault;
|
|
fVal = g_AvailableHashes[i].fDefault;
|
|
err = RegCreateKeyExA( hkHashes,
|
|
g_AvailableHashes[i].szName,
|
|
0,
|
|
"",
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ,
|
|
NULL,
|
|
&hKey,
|
|
&disp);
|
|
if(!err)
|
|
{
|
|
dwSize = sizeof(DWORD);
|
|
err = RegQueryValueEx(hKey,
|
|
SP_REG_VAL_ENABLED,
|
|
NULL,
|
|
&dwType,
|
|
(PUCHAR)&fVal,
|
|
&dwSize);
|
|
|
|
if(err)
|
|
{
|
|
fVal = g_AvailableHashes[i].fDefault;
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
g_AvailableHashes[i].fProtocol &= fVal;
|
|
|
|
if(dwOriginalValue != g_AvailableHashes[i].fProtocol)
|
|
{
|
|
fSettingsChanged = TRUE;
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hkHashes);
|
|
}
|
|
|
|
|
|
//
|
|
// Enable/Disable Key Exchange algs.
|
|
//
|
|
|
|
if(g_fFipsMode)
|
|
{
|
|
// Disable everything except RSA.
|
|
for(i=0; i < g_cAvailableExch; i++)
|
|
{
|
|
if(g_AvailableExch[i].aiExch != CALG_RSA_KEYX &&
|
|
g_AvailableExch[i].aiExch != CALG_RSA_SIGN)
|
|
{
|
|
g_AvailableExch[i].fProtocol = 0;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
err = RegCreateKeyEx( g_hkBase,
|
|
SP_REG_KEY_KEYEXCH,
|
|
0,
|
|
TEXT(""),
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ,
|
|
NULL,
|
|
&hkKeyExch,
|
|
&disp);
|
|
|
|
if(err == ERROR_SUCCESS)
|
|
{
|
|
for(i = 0; i < g_cAvailableExch; i++)
|
|
{
|
|
dwOriginalValue = g_AvailableExch[i].fProtocol;
|
|
|
|
g_AvailableExch[i].fProtocol = g_AvailableExch[i].fDefault;
|
|
fVal = g_AvailableExch[i].fDefault;
|
|
err = RegCreateKeyExA( hkKeyExch,
|
|
g_AvailableExch[i].szName,
|
|
0,
|
|
"",
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ,
|
|
NULL,
|
|
&hKey,
|
|
&disp);
|
|
if(!err)
|
|
{
|
|
dwSize = sizeof(DWORD);
|
|
err = RegQueryValueEx(hKey,
|
|
SP_REG_VAL_ENABLED,
|
|
NULL,
|
|
&dwType,
|
|
(PUCHAR)&fVal,
|
|
&dwSize);
|
|
if(err)
|
|
{
|
|
fVal = g_AvailableExch[i].fDefault;
|
|
}
|
|
g_AvailableExch[i].fProtocol &= fVal;
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
if(dwOriginalValue != g_AvailableExch[i].fProtocol)
|
|
{
|
|
fSettingsChanged = TRUE;
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hkKeyExch);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Purge the session cache.
|
|
//
|
|
|
|
if(g_fCacheInitialized && fSettingsChanged)
|
|
{
|
|
SPCachePurgeEntries(NULL,
|
|
0,
|
|
NULL,
|
|
SSL_PURGE_CLIENT_ALL_ENTRIES |
|
|
SSL_PURGE_SERVER_ALL_ENTRIES);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|