Index: net/base/ssl_config_service_mac.cc |
=================================================================== |
--- net/base/ssl_config_service_mac.cc (revision 24911) |
+++ net/base/ssl_config_service_mac.cc (working copy) |
@@ -1,55 +1,74 @@ |
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
+// Copyright (c) 2009 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 "net/base/ssl_config_service_mac.h" |
-#include "base/registry.h" |
+#include <CoreFoundation/CoreFoundation.h> |
+#include "base/scoped_cftyperef.h" |
+ |
using base::TimeDelta; |
using base::TimeTicks; |
namespace net { |
+namespace { |
+ |
static const int kConfigUpdateInterval = 10; // seconds |
-static const wchar_t kInternetSettingsSubKeyName[] = |
- L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"; |
+static const bool kSSL2EnabledDefaultValue = false; |
+static const bool kSSL3EnabledDefaultValue = true; |
+static const bool kTLS1EnabledDefaultValue = true; |
-static const wchar_t kRevocationValueName[] = L"CertificateRevocation"; |
+static CFStringRef kRevocationPreferencesIdentifier = |
+ CFSTR("com.apple.security.revocation"); |
+static CFStringRef kOCSPStyleKey = CFSTR("OCSPStyle"); |
+static CFStringRef kCRLStyleKey = CFSTR("CRLStyle"); |
+static CFStringRef kNoneRevocationValue = CFSTR("None"); |
+static CFStringRef kBestAttemptRevocationValue = CFSTR("BestAttempt"); |
+static CFStringRef kSSL2EnabledKey = CFSTR("org.chromium.ssl.ssl2"); |
+static CFStringRef kSSL3EnabledKey = CFSTR("org.chromium.ssl.ssl3"); |
+static CFStringRef kTLS1EnabledKey = CFSTR("org.chromium.ssl.tls1"); |
-static const wchar_t kProtocolsValueName[] = L"SecureProtocols"; |
+bool RevocationStyleIsEnabled(CFStringRef key) { |
+ CFPropertyListRef plist_ref = CFPreferencesCopyValue(kOCSPStyleKey, |
+ kRevocationPreferencesIdentifier, kCFPreferencesCurrentUser, |
+ kCFPreferencesAnyHost); |
+ if (plist_ref) { |
+ scoped_cftyperef<CFPropertyListRef> scoped_plist_ref(plist_ref); |
+ if (CFGetTypeID(plist_ref) == CFStringGetTypeID()) { |
+ CFStringRef style = reinterpret_cast<CFStringRef>(plist_ref); |
+ if (CFStringCompare(kNoneRevocationValue, style, |
+ kCFCompareCaseInsensitive)) |
+ return true; |
+ } |
+ } |
+ return false; |
+} |
-// 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 |
-}; |
+inline bool SSLVersionIsEnabled(CFStringRef key, bool default_value) { |
+ Boolean exists_and_valid; |
+ Boolean rv = CFPreferencesGetAppBooleanValue(key, |
+ kCFPreferencesCurrentApplication, |
+ &exists_and_valid); |
+ if (!exists_and_valid) |
+ return default_value; |
+ return rv; |
+} |
-// 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 |
-}; |
+} // namespace |
-SSLConfigServiceWin::SSLConfigServiceWin() : ever_updated_(false) { |
+SSLConfigServiceMac::SSLConfigServiceMac() : 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) { |
+SSLConfigServiceMac::SSLConfigServiceMac(TimeTicks now) : ever_updated_(false) { |
UpdateConfig(now); |
} |
-void SSLConfigServiceWin::GetSSLConfigAt(SSLConfig* config, TimeTicks now) { |
+void SSLConfigServiceMac::GetSSLConfigAt(SSLConfig* config, TimeTicks now) { |
if (!ever_updated_ || |
now - config_time_ > TimeDelta::FromSeconds(kConfigUpdateInterval)) |
UpdateConfig(now); |
@@ -57,55 +76,69 @@ |
} |
// static |
-bool SSLConfigServiceWin::GetSSLConfigNow(SSLConfig* config) { |
- RegKey internet_settings; |
- if (!internet_settings.Open(HKEY_CURRENT_USER, kInternetSettingsSubKeyName, |
- KEY_READ)) |
- return false; |
+bool SSLConfigServiceMac::GetSSLConfigNow(SSLConfig* config) { |
+ // Our own revocation checking flag is a binary value, but Mac OS X uses |
+ // several shades of revocation checking: |
+ // - None (i.e., disabled, the default) |
+ // - BestAttempt |
+ // - RequireIfPresent |
+ // - RequireForall |
+ // Mac OS X also breaks down revocation check for both CRLs and OCSP. We |
+ // set our revocation flag if the system-wide settings for either OCSP |
+ // or CRLs is anything other than None. |
+ config->rev_checking_enabled = (RevocationStyleIsEnabled(kOCSPStyleKey) || |
+ RevocationStyleIsEnabled(kCRLStyleKey)); |
- DWORD revocation; |
- if (!internet_settings.ReadValueDW(kRevocationValueName, &revocation)) |
- revocation = REVOCATION_DEFAULT; |
+ config->ssl2_enabled = SSLVersionIsEnabled(kSSL2EnabledKey, |
+ kSSL2EnabledDefaultValue); |
+ config->ssl3_enabled = SSLVersionIsEnabled(kSSL3EnabledKey, |
+ kSSL3EnabledDefaultValue); |
+ config->tls1_enabled = SSLVersionIsEnabled(kTLS1EnabledKey, |
+ kTLS1EnabledDefaultValue); |
- DWORD protocols; |
- if (!internet_settings.ReadValueDW(kProtocolsValueName, &protocols)) |
- protocols = PROTOCOLS_DEFAULT; |
+ return true; |
+} |
- config->rev_checking_enabled = (revocation != 0); |
- config->ssl2_enabled = ((protocols & SSL2) != 0); |
- config->ssl3_enabled = ((protocols & SSL3) != 0); |
- config->tls1_enabled = ((protocols & TLS1) != 0); |
+// static |
+void SSLConfigServiceMac::SetSSL2Enabled(bool enabled) { |
+ CFPreferencesSetAppValue(kSSL2EnabledKey, |
+ enabled ? kCFBooleanTrue : kCFBooleanFalse, |
+ kCFPreferencesCurrentApplication); |
+ CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication); |
+} |
- return true; |
+// static |
+void SSLConfigServiceMac::SetSSL3Enabled(bool enabled) { |
+ CFPreferencesSetAppValue(kSSL3EnabledKey, |
+ enabled ? kCFBooleanTrue : kCFBooleanFalse, |
+ kCFPreferencesCurrentApplication); |
+ CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication); |
} |
// 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. |
+void SSLConfigServiceMac::SetTLS1Enabled(bool enabled) { |
+ CFPreferencesSetAppValue(kTLS1EnabledKey, |
+ enabled ? kCFBooleanTrue : kCFBooleanFalse, |
+ kCFPreferencesCurrentApplication); |
+ CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication); |
} |
// 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 SSLConfigServiceMac::SetRevCheckingEnabled(bool enabled) { |
+ // This method is provided for use by the unit tests. These settings |
+ // are normally changed via the Keychain Access application's preferences |
+ // dialog. |
+ CFPreferencesSetValue(kOCSPStyleKey, |
+ enabled ? kBestAttemptRevocationValue : kNoneRevocationValue, |
+ kRevocationPreferencesIdentifier, kCFPreferencesCurrentUser, |
+ kCFPreferencesAnyHost); |
+ CFPreferencesSetValue(kCRLStyleKey, |
+ enabled ? kBestAttemptRevocationValue : kNoneRevocationValue, |
+ kRevocationPreferencesIdentifier, kCFPreferencesCurrentUser, |
+ kCFPreferencesAnyHost); |
} |
-void SSLConfigServiceWin::UpdateConfig(TimeTicks now) { |
+void SSLConfigServiceMac::UpdateConfig(TimeTicks now) { |
GetSSLConfigNow(&config_info_); |
config_time_ = now; |
ever_updated_ = true; |