| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/ssl_config_service_win.h" | 5 #include "net/base/ssl_config_service_mac.h" |
| 6 | 6 |
| 7 #include "base/registry.h" | 7 #include <CoreFoundation/CoreFoundation.h> |
| 8 |
| 9 #include "base/scoped_cftyperef.h" |
| 8 | 10 |
| 9 using base::TimeDelta; | 11 using base::TimeDelta; |
| 10 using base::TimeTicks; | 12 using base::TimeTicks; |
| 11 | 13 |
| 12 namespace net { | 14 namespace net { |
| 13 | 15 |
| 16 namespace { |
| 17 |
| 14 static const int kConfigUpdateInterval = 10; // seconds | 18 static const int kConfigUpdateInterval = 10; // seconds |
| 15 | 19 |
| 16 static const wchar_t kInternetSettingsSubKeyName[] = | 20 static const bool kSSL2EnabledDefaultValue = false; |
| 17 L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"; | 21 static const bool kSSL3EnabledDefaultValue = true; |
| 22 static const bool kTLS1EnabledDefaultValue = true; |
| 18 | 23 |
| 19 static const wchar_t kRevocationValueName[] = L"CertificateRevocation"; | 24 static CFStringRef kRevocationPreferencesIdentifier = |
| 25 CFSTR("com.apple.security.revocation"); |
| 26 static CFStringRef kOCSPStyleKey = CFSTR("OCSPStyle"); |
| 27 static CFStringRef kCRLStyleKey = CFSTR("CRLStyle"); |
| 28 static CFStringRef kNoneRevocationValue = CFSTR("None"); |
| 29 static CFStringRef kBestAttemptRevocationValue = CFSTR("BestAttempt"); |
| 30 static CFStringRef kSSL2EnabledKey = CFSTR("org.chromium.ssl.ssl2"); |
| 31 static CFStringRef kSSL3EnabledKey = CFSTR("org.chromium.ssl.ssl3"); |
| 32 static CFStringRef kTLS1EnabledKey = CFSTR("org.chromium.ssl.tls1"); |
| 20 | 33 |
| 21 static const wchar_t kProtocolsValueName[] = L"SecureProtocols"; | 34 bool RevocationStyleIsEnabled(CFStringRef key) { |
| 35 CFPropertyListRef plist_ref = CFPreferencesCopyValue(kOCSPStyleKey, |
| 36 kRevocationPreferencesIdentifier, kCFPreferencesCurrentUser, |
| 37 kCFPreferencesAnyHost); |
| 38 if (plist_ref) { |
| 39 scoped_cftyperef<CFPropertyListRef> scoped_plist_ref(plist_ref); |
| 40 if (CFGetTypeID(plist_ref) == CFStringGetTypeID()) { |
| 41 CFStringRef style = reinterpret_cast<CFStringRef>(plist_ref); |
| 42 if (CFStringCompare(kNoneRevocationValue, style, |
| 43 kCFCompareCaseInsensitive)) |
| 44 return true; |
| 45 } |
| 46 } |
| 47 return false; |
| 48 } |
| 22 | 49 |
| 23 // In SecureProtocols, each SSL version is represented by a bit: | 50 inline bool SSLVersionIsEnabled(CFStringRef key, bool default_value) { |
| 24 // SSL 2.0: 0x08 | 51 Boolean exists_and_valid; |
| 25 // SSL 3.0: 0x20 | 52 Boolean rv = CFPreferencesGetAppBooleanValue(key, |
| 26 // TLS 1.0: 0x80 | 53 kCFPreferencesCurrentApplication, |
| 27 // The bits are OR'ed to form the DWORD value. So 0xa0 means SSL 3.0 and | 54 &exists_and_valid); |
| 28 // TLS 1.0. | 55 if (!exists_and_valid) |
| 29 enum { | 56 return default_value; |
| 30 SSL2 = 0x08, | 57 return rv; |
| 31 SSL3 = 0x20, | 58 } |
| 32 TLS1 = 0x80 | |
| 33 }; | |
| 34 | 59 |
| 35 // If CertificateRevocation or SecureProtocols is missing, IE uses a default | 60 } // namespace |
| 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 | 61 |
| 43 SSLConfigServiceWin::SSLConfigServiceWin() : ever_updated_(false) { | 62 SSLConfigServiceMac::SSLConfigServiceMac() : ever_updated_(false) { |
| 44 // We defer retrieving the settings until the first call to GetSSLConfig, to | 63 // 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. | 64 // avoid an expensive call on the UI thread, which could affect startup time. |
| 46 } | 65 } |
| 47 | 66 |
| 48 SSLConfigServiceWin::SSLConfigServiceWin(TimeTicks now) : ever_updated_(false) { | 67 SSLConfigServiceMac::SSLConfigServiceMac(TimeTicks now) : ever_updated_(false) { |
| 49 UpdateConfig(now); | 68 UpdateConfig(now); |
| 50 } | 69 } |
| 51 | 70 |
| 52 void SSLConfigServiceWin::GetSSLConfigAt(SSLConfig* config, TimeTicks now) { | 71 void SSLConfigServiceMac::GetSSLConfigAt(SSLConfig* config, TimeTicks now) { |
| 53 if (!ever_updated_ || | 72 if (!ever_updated_ || |
| 54 now - config_time_ > TimeDelta::FromSeconds(kConfigUpdateInterval)) | 73 now - config_time_ > TimeDelta::FromSeconds(kConfigUpdateInterval)) |
| 55 UpdateConfig(now); | 74 UpdateConfig(now); |
| 56 *config = config_info_; | 75 *config = config_info_; |
| 57 } | 76 } |
| 58 | 77 |
| 59 // static | 78 // static |
| 60 bool SSLConfigServiceWin::GetSSLConfigNow(SSLConfig* config) { | 79 bool SSLConfigServiceMac::GetSSLConfigNow(SSLConfig* config) { |
| 61 RegKey internet_settings; | 80 // Our own revocation checking flag is a binary value, but Mac OS X uses |
| 62 if (!internet_settings.Open(HKEY_CURRENT_USER, kInternetSettingsSubKeyName, | 81 // several shades of revocation checking: |
| 63 KEY_READ)) | 82 // - None (i.e., disabled, the default) |
| 64 return false; | 83 // - BestAttempt |
| 84 // - RequireIfPresent |
| 85 // - RequireForall |
| 86 // Mac OS X also breaks down revocation check for both CRLs and OCSP. We |
| 87 // set our revocation flag if the system-wide settings for either OCSP |
| 88 // or CRLs is anything other than None. |
| 89 config->rev_checking_enabled = (RevocationStyleIsEnabled(kOCSPStyleKey) || |
| 90 RevocationStyleIsEnabled(kCRLStyleKey)); |
| 65 | 91 |
| 66 DWORD revocation; | 92 config->ssl2_enabled = SSLVersionIsEnabled(kSSL2EnabledKey, |
| 67 if (!internet_settings.ReadValueDW(kRevocationValueName, &revocation)) | 93 kSSL2EnabledDefaultValue); |
| 68 revocation = REVOCATION_DEFAULT; | 94 config->ssl3_enabled = SSLVersionIsEnabled(kSSL3EnabledKey, |
| 69 | 95 kSSL3EnabledDefaultValue); |
| 70 DWORD protocols; | 96 config->tls1_enabled = SSLVersionIsEnabled(kTLS1EnabledKey, |
| 71 if (!internet_settings.ReadValueDW(kProtocolsValueName, &protocols)) | 97 kTLS1EnabledDefaultValue); |
| 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 | 98 |
| 79 return true; | 99 return true; |
| 80 } | 100 } |
| 81 | 101 |
| 82 // static | 102 // static |
| 83 void SSLConfigServiceWin::SetRevCheckingEnabled(bool enabled) { | 103 void SSLConfigServiceMac::SetSSL2Enabled(bool enabled) { |
| 84 DWORD value = enabled; | 104 CFPreferencesSetAppValue(kSSL2EnabledKey, |
| 85 RegKey internet_settings(HKEY_CURRENT_USER, kInternetSettingsSubKeyName, | 105 enabled ? kCFBooleanTrue : kCFBooleanFalse, |
| 86 KEY_WRITE); | 106 kCFPreferencesCurrentApplication); |
| 87 internet_settings.WriteValue(kRevocationValueName, value); | 107 CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication); |
| 88 // TODO(mattm): We should call UpdateConfig after updating settings, but these | |
| 89 // methods are static. | |
| 90 } | 108 } |
| 91 | 109 |
| 92 // static | 110 // static |
| 93 void SSLConfigServiceWin::SetSSL2Enabled(bool enabled) { | 111 void SSLConfigServiceMac::SetSSL3Enabled(bool enabled) { |
| 94 RegKey internet_settings(HKEY_CURRENT_USER, kInternetSettingsSubKeyName, | 112 CFPreferencesSetAppValue(kSSL3EnabledKey, |
| 95 KEY_READ | KEY_WRITE); | 113 enabled ? kCFBooleanTrue : kCFBooleanFalse, |
| 96 DWORD value; | 114 kCFPreferencesCurrentApplication); |
| 97 if (!internet_settings.ReadValueDW(kProtocolsValueName, &value)) | 115 CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication); |
| 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 } | 116 } |
| 107 | 117 |
| 108 void SSLConfigServiceWin::UpdateConfig(TimeTicks now) { | 118 // static |
| 119 void SSLConfigServiceMac::SetTLS1Enabled(bool enabled) { |
| 120 CFPreferencesSetAppValue(kTLS1EnabledKey, |
| 121 enabled ? kCFBooleanTrue : kCFBooleanFalse, |
| 122 kCFPreferencesCurrentApplication); |
| 123 CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication); |
| 124 } |
| 125 |
| 126 // static |
| 127 void SSLConfigServiceMac::SetRevCheckingEnabled(bool enabled) { |
| 128 // This method is provided for use by the unit tests. These settings |
| 129 // are normally changed via the Keychain Access application's preferences |
| 130 // dialog. |
| 131 CFPreferencesSetValue(kOCSPStyleKey, |
| 132 enabled ? kBestAttemptRevocationValue : kNoneRevocationValue, |
| 133 kRevocationPreferencesIdentifier, kCFPreferencesCurrentUser, |
| 134 kCFPreferencesAnyHost); |
| 135 CFPreferencesSetValue(kCRLStyleKey, |
| 136 enabled ? kBestAttemptRevocationValue : kNoneRevocationValue, |
| 137 kRevocationPreferencesIdentifier, kCFPreferencesCurrentUser, |
| 138 kCFPreferencesAnyHost); |
| 139 } |
| 140 |
| 141 void SSLConfigServiceMac::UpdateConfig(TimeTicks now) { |
| 109 GetSSLConfigNow(&config_info_); | 142 GetSSLConfigNow(&config_info_); |
| 110 config_time_ = now; | 143 config_time_ = now; |
| 111 ever_updated_ = true; | 144 ever_updated_ = true; |
| 112 } | 145 } |
| 113 | 146 |
| 114 } // namespace net | 147 } // namespace net |
| OLD | NEW |