1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/base/ssl_config_service_win.h" 6 7 #include "base/registry.h" 8 9 using base::TimeDelta; 10 using base::TimeTicks; 11 12 namespace net { 13 14 static const int kConfigUpdateInterval = 10; // seconds 15 16 static const wchar_t kInternetSettingsSubKeyName[] = 17 L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"; 18 19 static const wchar_t kRevocationValueName[] = L"CertificateRevocation"; 20 21 static const wchar_t kProtocolsValueName[] = L"SecureProtocols"; 22 23 // In SecureProtocols, each SSL version is represented by a bit: 24 // SSL 2.0: 0x08 25 // SSL 3.0: 0x20 26 // TLS 1.0: 0x80 27 // The bits are OR'ed to form the DWORD value. So 0xa0 means SSL 3.0 and 28 // TLS 1.0. 29 enum { 30 SSL2 = 0x08, 31 SSL3 = 0x20, 32 TLS1 = 0x80 33 }; 34 35 // If CertificateRevocation or SecureProtocols is missing, IE uses a default 36 // value. Unfortunately the default is IE version specific. We use WinHTTP's 37 // default. 38 enum { 39 REVOCATION_DEFAULT = 0, 40 PROTOCOLS_DEFAULT = SSL3 | TLS1 41 }; 42 43 SSLConfigServiceWin::SSLConfigServiceWin() : ever_updated_(false) { 44 // We defer retrieving the settings until the first call to GetSSLConfig, to 45 // avoid an expensive call on the UI thread, which could affect startup time. 46 } 47 48 SSLConfigServiceWin::SSLConfigServiceWin(TimeTicks now) : ever_updated_(false) { 49 UpdateConfig(now); 50 } 51 52 void SSLConfigServiceWin::GetSSLConfigAt(SSLConfig* config, TimeTicks now) { 53 if (!ever_updated_ || 54 now - config_time_ > TimeDelta::FromSeconds(kConfigUpdateInterval)) 55 UpdateConfig(now); 56 *config = config_info_; 57 } 58 59 // static 60 bool SSLConfigServiceWin::GetSSLConfigNow(SSLConfig* config) { 61 RegKey internet_settings; 62 if (!internet_settings.Open(HKEY_CURRENT_USER, kInternetSettingsSubKeyName, 63 KEY_READ)) 64 return false; 65 66 DWORD revocation; 67 if (!internet_settings.ReadValueDW(kRevocationValueName, &revocation)) 68 revocation = REVOCATION_DEFAULT; 69 70 DWORD protocols; 71 if (!internet_settings.ReadValueDW(kProtocolsValueName, &protocols)) 72 protocols = PROTOCOLS_DEFAULT; 73 74 config->rev_checking_enabled = (revocation != 0); 75 config->ssl2_enabled = ((protocols & SSL2) != 0); 76 config->ssl3_enabled = ((protocols & SSL3) != 0); 77 config->tls1_enabled = ((protocols & TLS1) != 0); 78 79 return true; 80 } 81 82 // static 83 void SSLConfigServiceWin::SetRevCheckingEnabled(bool enabled) { 84 DWORD value = enabled; 85 RegKey internet_settings(HKEY_CURRENT_USER, kInternetSettingsSubKeyName, 86 KEY_WRITE); 87 internet_settings.WriteValue(kRevocationValueName, value); 88 // TODO(mattm): We should call UpdateConfig after updating settings, but these 89 // methods are static. 90 } 91 92 // static 93 void SSLConfigServiceWin::SetSSL2Enabled(bool enabled) { 94 RegKey internet_settings(HKEY_CURRENT_USER, kInternetSettingsSubKeyName, 95 KEY_READ | KEY_WRITE); 96 DWORD value; 97 if (!internet_settings.ReadValueDW(kProtocolsValueName, &value)) 98 value = PROTOCOLS_DEFAULT; 99 if (enabled) 100 value |= SSL2; 101 else 102 value &= ~SSL2; 103 internet_settings.WriteValue(kProtocolsValueName, value); 104 // TODO(mattm): We should call UpdateConfig after updating settings, but these 105 // methods are static. 106 } 107 108 void SSLConfigServiceWin::UpdateConfig(TimeTicks now) { 109 GetSSLConfigNow(&config_info_); 110 config_time_ = now; 111 ever_updated_ = true; 112 } 113 114 } // namespace net 115