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 |