// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "net/base/ssl_config_service_win.h" #include "base/registry.h" using base::TimeDelta; using base::TimeTicks; namespace net { static const int kConfigUpdateInterval = 10; // seconds static const wchar_t kInternetSettingsSubKeyName[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"; static const wchar_t kRevocationValueName[] = L"CertificateRevocation"; static const wchar_t kProtocolsValueName[] = L"SecureProtocols"; // In SecureProtocols, each SSL version is represented by a bit: // SSL 2.0: 0x08 // SSL 3.0: 0x20 // TLS 1.0: 0x80 // The bits are OR'ed to form the DWORD value. So 0xa0 means SSL 3.0 and // TLS 1.0. enum { SSL2 = 0x08, SSL3 = 0x20, TLS1 = 0x80 }; // If CertificateRevocation or SecureProtocols is missing, IE uses a default // value. Unfortunately the default is IE version specific. We use WinHTTP's // default. enum { REVOCATION_DEFAULT = 0, PROTOCOLS_DEFAULT = SSL3 | TLS1 }; SSLConfigServiceWin::SSLConfigServiceWin() : ever_updated_(false) { // We defer retrieving the settings until the first call to GetSSLConfig, to // avoid an expensive call on the UI thread, which could affect startup time. } SSLConfigServiceWin::SSLConfigServiceWin(TimeTicks now) : ever_updated_(false) { UpdateConfig(now); } void SSLConfigServiceWin::GetSSLConfigAt(SSLConfig* config, TimeTicks now) { if (!ever_updated_ || now - config_time_ > TimeDelta::FromSeconds(kConfigUpdateInterval)) UpdateConfig(now); *config = config_info_; } // static bool SSLConfigServiceWin::GetSSLConfigNow(SSLConfig* config) { RegKey internet_settings; if (!internet_settings.Open(HKEY_CURRENT_USER, kInternetSettingsSubKeyName, KEY_READ)) return false; DWORD revocation; if (!internet_settings.ReadValueDW(kRevocationValueName, &revocation)) revocation = REVOCATION_DEFAULT; DWORD protocols; if (!internet_settings.ReadValueDW(kProtocolsValueName, &protocols)) protocols = PROTOCOLS_DEFAULT; config->rev_checking_enabled = (revocation != 0); config->ssl2_enabled = ((protocols & SSL2) != 0); config->ssl3_enabled = ((protocols & SSL3) != 0); config->tls1_enabled = ((protocols & TLS1) != 0); return true; } // static void SSLConfigServiceWin::SetRevCheckingEnabled(bool enabled) { DWORD value = enabled; RegKey internet_settings(HKEY_CURRENT_USER, kInternetSettingsSubKeyName, KEY_WRITE); internet_settings.WriteValue(kRevocationValueName, value); // TODO(mattm): We should call UpdateConfig after updating settings, but these // methods are static. } // static void SSLConfigServiceWin::SetSSL2Enabled(bool enabled) { RegKey internet_settings(HKEY_CURRENT_USER, kInternetSettingsSubKeyName, KEY_READ | KEY_WRITE); DWORD value; if (!internet_settings.ReadValueDW(kProtocolsValueName, &value)) value = PROTOCOLS_DEFAULT; if (enabled) value |= SSL2; else value &= ~SSL2; internet_settings.WriteValue(kProtocolsValueName, value); // TODO(mattm): We should call UpdateConfig after updating settings, but these // methods are static. } void SSLConfigServiceWin::UpdateConfig(TimeTicks now) { GetSSLConfigNow(&config_info_); config_time_ = now; ever_updated_ = true; } } // namespace net