diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-12 14:49:04 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-12 14:49:04 +0000 |
commit | fc7de49e356bc0b2961170713583904a6c248a55 (patch) | |
tree | 1a16482939a64abc14dc4a483da7f2785b49c327 | |
parent | 0ced842a26fcc6bd9be368786fcff7c6428f4a05 (diff) | |
download | chromium_src-fc7de49e356bc0b2961170713583904a6c248a55.zip chromium_src-fc7de49e356bc0b2961170713583904a6c248a55.tar.gz chromium_src-fc7de49e356bc0b2961170713583904a6c248a55.tar.bz2 |
Plumb SSL connection information into the PageInfo model.
This plumbs two bits of information into the PageInfo model (the dialog
which results from clicking on the padlock icon): whether or not we
performed SSLv3 fallback and whether or not the server supported the
renegotiation extension.
It doesn't actually do anything with this information yet (except to add
histograms of them), pending future CLs.
BUG=none
TEST=none
http://codereview.chromium.org/2943001/show
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52079 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/renderer_host/resource_dispatcher_host.cc | 16 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_manager.cc | 17 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_manager.h | 6 | ||||
-rw-r--r-- | chrome/browser/tab_contents/navigation_entry.cc | 1 | ||||
-rw-r--r-- | chrome/browser/tab_contents/navigation_entry.h | 8 | ||||
-rw-r--r-- | chrome/browser/tab_contents/provisional_load_details.cc | 4 | ||||
-rw-r--r-- | chrome/browser/tab_contents/provisional_load_details.h | 3 | ||||
-rw-r--r-- | chrome/browser/tab_contents/render_view_context_menu.cc | 6 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents.cc | 5 | ||||
-rw-r--r-- | net/base/ssl_config_service.h | 5 | ||||
-rw-r--r-- | net/base/ssl_connection_status_flags.h | 31 | ||||
-rw-r--r-- | net/base/ssl_info.h | 9 | ||||
-rw-r--r-- | net/http/http_network_transaction.cc | 5 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_mac.cc | 4 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_nss.cc | 15 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_win.cc | 6 |
16 files changed, 119 insertions, 22 deletions
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc index 2d1e7fc..253c5ba 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host.cc +++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc @@ -1038,14 +1038,16 @@ bool ResourceDispatcherHost::CompleteResponseStarted(URLRequest* request) { CertStore::GetSharedInstance()->StoreCert(request->ssl_info().cert, info->child_id()); response->response_head.security_info = - SSLManager::SerializeSecurityInfo(cert_id, - request->ssl_info().cert_status, - request->ssl_info().security_bits); + SSLManager::SerializeSecurityInfo( + cert_id, request->ssl_info().cert_status, + request->ssl_info().security_bits, + request->ssl_info().connection_status); } else { // We should not have any SSL state. DCHECK(!request->ssl_info().cert_status && (request->ssl_info().security_bits == -1 || - request->ssl_info().security_bits == 0)); + request->ssl_info().security_bits == 0) && + !request->ssl_info().connection_status); } NotifyResponseStarted(request, info->child_id()); @@ -1375,9 +1377,9 @@ void ResourceDispatcherHost::OnResponseCompleted(URLRequest* request) { if (ssl_info.cert != NULL) { int cert_id = CertStore::GetSharedInstance()->StoreCert(ssl_info.cert, info->child_id()); - security_info = SSLManager::SerializeSecurityInfo(cert_id, - ssl_info.cert_status, - ssl_info.security_bits); + security_info = SSLManager::SerializeSecurityInfo( + cert_id, ssl_info.cert_status, ssl_info.security_bits, + ssl_info.connection_status); } if (info->resource_handler()->OnResponseCompleted(info->request_id(), diff --git a/chrome/browser/ssl/ssl_manager.cc b/chrome/browser/ssl/ssl_manager.cc index dbff09e..d328d6e 100644 --- a/chrome/browser/ssl/ssl_manager.cc +++ b/chrome/browser/ssl/ssl_manager.cc @@ -59,11 +59,13 @@ void SSLManager::NotifySSLInternalStateChanged() { // static std::string SSLManager::SerializeSecurityInfo(int cert_id, int cert_status, - int security_bits) { + int security_bits, + int ssl_connection_status) { Pickle pickle; pickle.WriteInt(cert_id); pickle.WriteInt(cert_status); pickle.WriteInt(security_bits); + pickle.WriteInt(ssl_connection_status); return std::string(static_cast<const char*>(pickle.data()), pickle.size()); } @@ -71,13 +73,15 @@ std::string SSLManager::SerializeSecurityInfo(int cert_id, bool SSLManager::DeserializeSecurityInfo(const std::string& state, int* cert_id, int* cert_status, - int* security_bits) { + int* security_bits, + int* ssl_connection_status) { DCHECK(cert_id && cert_status && security_bits); if (state.empty()) { // No SSL used. *cert_id = 0; *cert_status = 0; *security_bits = -1; + *ssl_connection_status = 0; return false; } @@ -85,7 +89,8 @@ bool SSLManager::DeserializeSecurityInfo(const std::string& state, void * iter = NULL; return pickle.ReadInt(&iter, cert_id) && pickle.ReadInt(&iter, cert_status) && - pickle.ReadInt(&iter, security_bits); + pickle.ReadInt(&iter, security_bits) && + pickle.ReadInt(&iter, ssl_connection_status); } // static @@ -134,11 +139,12 @@ void SSLManager::DidCommitProvisionalLoad( if (details->is_main_frame) { if (entry) { // Decode the security details. - int ssl_cert_id, ssl_cert_status, ssl_security_bits; + int ssl_cert_id, ssl_cert_status, ssl_security_bits, ssl_connection_status; DeserializeSecurityInfo(details->serialized_security_info, &ssl_cert_id, &ssl_cert_status, - &ssl_security_bits); + &ssl_security_bits, + &ssl_connection_status); // We may not have an entry if this is a navigation to an initial blank // page. Reset the SSL information and add the new data we have. @@ -146,6 +152,7 @@ void SSLManager::DidCommitProvisionalLoad( entry->ssl().set_cert_id(ssl_cert_id); entry->ssl().set_cert_status(ssl_cert_status); entry->ssl().set_security_bits(ssl_security_bits); + entry->ssl().set_connection_status(ssl_connection_status); } backend_.ShowPendingMessages(); } diff --git a/chrome/browser/ssl/ssl_manager.h b/chrome/browser/ssl/ssl_manager.h index 7ee110e..e9916b3 100644 --- a/chrome/browser/ssl/ssl_manager.h +++ b/chrome/browser/ssl/ssl_manager.h @@ -56,11 +56,13 @@ class SSLManager : public NotificationObserver { // Convenience methods for serializing/deserializing the security info. static std::string SerializeSecurityInfo(int cert_id, int cert_status, - int security_bits); + int security_bits, + int connection_status); static bool DeserializeSecurityInfo(const std::string& state, int* cert_id, int* cert_status, - int* security_bits); + int* security_bits, + int* connection_status); // Returns "<organization_name> [<country>]". static std::wstring GetEVCertName(const net::X509Certificate& cert); diff --git a/chrome/browser/tab_contents/navigation_entry.cc b/chrome/browser/tab_contents/navigation_entry.cc index 4ce5bda..0fb4777 100644 --- a/chrome/browser/tab_contents/navigation_entry.cc +++ b/chrome/browser/tab_contents/navigation_entry.cc @@ -29,6 +29,7 @@ NavigationEntry::SSLStatus::SSLStatus() cert_id_(0), cert_status_(0), security_bits_(-1), + connection_status_(0), content_status_(NORMAL_CONTENT) { } diff --git a/chrome/browser/tab_contents/navigation_entry.h b/chrome/browser/tab_contents/navigation_entry.h index 1faee15..341ebeb 100644 --- a/chrome/browser/tab_contents/navigation_entry.h +++ b/chrome/browser/tab_contents/navigation_entry.h @@ -102,6 +102,13 @@ class NavigationEntry { return (content_status_ & RAN_INSECURE_CONTENT) != 0; } + void set_connection_status(int connection_status) { + connection_status_ = connection_status; + } + int connection_status() const { + return connection_status_; + } + // Raw accessors for all the content status flags. This contains a // combination of any of the ContentStatusFlags defined above. It is used // by some tests for checking and for certain copying. Use the per-status @@ -119,6 +126,7 @@ class NavigationEntry { int cert_id_; int cert_status_; int security_bits_; + int connection_status_; int content_status_; // Copy and assignment is explicitly allowed for this class. diff --git a/chrome/browser/tab_contents/provisional_load_details.cc b/chrome/browser/tab_contents/provisional_load_details.cc index f144d0a..3bea977 100644 --- a/chrome/browser/tab_contents/provisional_load_details.cc +++ b/chrome/browser/tab_contents/provisional_load_details.cc @@ -19,9 +19,11 @@ ProvisionalLoadDetails::ProvisionalLoadDetails(bool is_main_frame, ssl_cert_id_(0), ssl_cert_status_(0), ssl_security_bits_(-1), + ssl_connection_status_(0), is_content_filtered_(is_content_filtered) { SSLManager::DeserializeSecurityInfo(security_info, &ssl_cert_id_, &ssl_cert_status_, - &ssl_security_bits_); + &ssl_security_bits_, + &ssl_connection_status_); } diff --git a/chrome/browser/tab_contents/provisional_load_details.h b/chrome/browser/tab_contents/provisional_load_details.h index ce4f5da..4f6abad 100644 --- a/chrome/browser/tab_contents/provisional_load_details.h +++ b/chrome/browser/tab_contents/provisional_load_details.h @@ -43,6 +43,8 @@ class ProvisionalLoadDetails { int ssl_security_bits() const { return ssl_security_bits_; } + int ssl_connection_status() const { return ssl_connection_status_; } + bool is_content_filtered() const { return is_content_filtered_; } private: @@ -53,6 +55,7 @@ class ProvisionalLoadDetails { int ssl_cert_id_; int ssl_cert_status_; int ssl_security_bits_; + int ssl_connection_status_; bool is_content_filtered_; DISALLOW_COPY_AND_ASSIGN(ProvisionalLoadDetails); diff --git a/chrome/browser/tab_contents/render_view_context_menu.cc b/chrome/browser/tab_contents/render_view_context_menu.cc index 101d43f..c912965 100644 --- a/chrome/browser/tab_contents/render_view_context_menu.cc +++ b/chrome/browser/tab_contents/render_view_context_menu.cc @@ -1169,14 +1169,16 @@ void RenderViewContextMenu::ExecuteCommand(int id) { // Deserialize the SSL info. NavigationEntry::SSLStatus ssl; if (!params_.security_info.empty()) { - int cert_id, cert_status, security_bits; + int cert_id, cert_status, security_bits, connection_status; SSLManager::DeserializeSecurityInfo(params_.security_info, &cert_id, &cert_status, - &security_bits); + &security_bits, + &connection_status); ssl.set_cert_id(cert_id); ssl.set_cert_status(cert_status); ssl.set_security_bits(security_bits); + ssl.set_connection_status(connection_status); } source_tab_contents_->ShowPageInfo(params_.frame_url, ssl, false); // Don't show the history. diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index f0dd1d5..963ed7b 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -2032,10 +2032,11 @@ void TabContents::DidLoadResourceFromMemoryCache( const std::string& main_frame_origin, const std::string& security_info) { // Send out a notification that we loaded a resource from our memory cache. - int cert_id = 0, cert_status = 0, security_bits = 0; + int cert_id = 0, cert_status = 0, security_bits = 0, connection_status = 0; SSLManager::DeserializeSecurityInfo(security_info, &cert_id, &cert_status, - &security_bits); + &security_bits, + &connection_status); LoadFromMemoryCacheDetails details(url, frame_origin, main_frame_origin, GetRenderProcessHost()->id(), cert_id, cert_status); diff --git a/net/base/ssl_config_service.h b/net/base/ssl_config_service.h index d195039..3f0f479 100644 --- a/net/base/ssl_config_service.h +++ b/net/base/ssl_config_service.h @@ -18,7 +18,8 @@ struct SSLConfig { // Default to SSL 2.0 off, SSL 3.0 on, and TLS 1.0 on. SSLConfig() : rev_checking_enabled(true), ssl2_enabled(false), ssl3_enabled(true), - tls1_enabled(true), send_client_cert(false), verify_ev_cert(false) { + tls1_enabled(true), ssl3_fallback(false), send_client_cert(false), + verify_ev_cert(false) { } bool rev_checking_enabled; // True if server certificate revocation @@ -26,6 +27,8 @@ struct SSLConfig { bool ssl2_enabled; // True if SSL 2.0 is enabled. bool ssl3_enabled; // True if SSL 3.0 is enabled. bool tls1_enabled; // True if TLS 1.0 is enabled. + bool ssl3_fallback; // True if we are falling back to SSL 3.0 (one still + // needs to clear tls1_enabled). // TODO(wtc): move the following members to a new SSLParams structure. They // are not SSL configuration settings. diff --git a/net/base/ssl_connection_status_flags.h b/net/base/ssl_connection_status_flags.h new file mode 100644 index 0000000..2618f57 --- /dev/null +++ b/net/base/ssl_connection_status_flags.h @@ -0,0 +1,31 @@ +// Copyright (c) 2010 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. + +#ifndef NET_BASE_SSL_CONNECTION_STATUS_FLAGS_H_ +#define NET_BASE_SSL_CONNECTION_STATUS_FLAGS_H_ + +namespace net { + +// Status flags for SSLInfo::connection_status. +enum { + // The lower 16 bits are reserved for the TLS ciphersuite id. + SSL_CONNECTION_CIPHERSUITE_SHIFT = 0, + SSL_CONNECTION_CIPHERSUITE_MASK = 0xffff, + + // The next two bits are reserved for the compression used. + SSL_CONNECTION_COMPRESSION_SHIFT = 16, + SSL_CONNECTION_COMPRESSION_MASK = 3, + + // We fell back to SSLv3 for this connection. + SSL_CONNECTION_SSL3_FALLBACK = 1 << 18, + // The server doesn't support the renegotiation_info extension. + SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION = 1 << 19, + + // 1 << 31 (the sign bit) is reserved so that the SSL connection status will + // never be negative. +}; + +} // namespace net + +#endif // NET_BASE_SSL_CONNECTION_STATUS_FLAGS_H_ diff --git a/net/base/ssl_info.h b/net/base/ssl_info.h index 3fe0ce4..280b497 100644 --- a/net/base/ssl_info.h +++ b/net/base/ssl_info.h @@ -16,12 +16,13 @@ namespace net { // This is really a struct. All members are public. class SSLInfo { public: - SSLInfo() : cert_status(0), security_bits(-1) { } + SSLInfo() : cert_status(0), security_bits(-1), connection_status(0) { } void Reset() { cert = NULL; - security_bits = -1; cert_status = 0; + security_bits = -1; + connection_status = 0; } bool is_valid() const { return cert != NULL; } @@ -43,6 +44,10 @@ class SSLInfo { // 0 means the connection is not encrypted. // -1 means the security strength is unknown. int security_bits; + + // Bitmask of information about the SSL connection itself. See + // ssl_connection_status_flags.h for values. + int connection_status; }; } // namespace net diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index fed8af8..1d58863 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -22,6 +22,7 @@ #include "net/base/net_errors.h" #include "net/base/net_util.h" #include "net/base/ssl_cert_request_info.h" +#include "net/base/ssl_connection_status_flags.h" #include "net/base/upload_data_stream.h" #include "net/http/http_auth.h" #include "net/http/http_auth_handler.h" @@ -1084,9 +1085,13 @@ int HttpNetworkTransaction::DoSSLConnect() { if (ContainsKey(*g_tls_intolerant_servers, GetHostAndPort(request_->url))) { LOG(WARNING) << "Falling back to SSLv3 because host is TLS intolerant: " << GetHostAndPort(request_->url); + ssl_config_.ssl3_fallback = true; ssl_config_.tls1_enabled = false; } + UMA_HISTOGRAM_ENUMERATION("Net.ConnectionUsedSSLv3Fallback", + (int) ssl_config_.ssl3_fallback, 2); + if (request_->load_flags & LOAD_VERIFY_EV_CERT) ssl_config_.verify_ev_cert = true; diff --git a/net/socket/ssl_client_socket_mac.cc b/net/socket/ssl_client_socket_mac.cc index f1d2278..325df61 100644 --- a/net/socket/ssl_client_socket_mac.cc +++ b/net/socket/ssl_client_socket_mac.cc @@ -18,6 +18,7 @@ #include "net/base/net_errors.h" #include "net/base/net_log.h" #include "net/base/ssl_cert_request_info.h" +#include "net/base/ssl_connection_status_flags.h" #include "net/base/ssl_info.h" // Welcome to Mac SSL. We've been waiting for you. @@ -652,6 +653,9 @@ void SSLClientSocketMac::GetSSLInfo(SSLInfo* ssl_info) { OSStatus status = SSLGetNegotiatedCipher(ssl_context_, &suite); if (!status) ssl_info->security_bits = KeySizeOfCipherSuite(suite); + + if (ssl_config_.ssl3_fallback) + ssl_info->connection_status |= SSL_CONNECTION_SSL3_FALLBACK; } void SSLClientSocketMac::GetSSLCertRequestInfo( diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc index 285499e..5226c56 100644 --- a/net/socket/ssl_client_socket_nss.cc +++ b/net/socket/ssl_client_socket_nss.cc @@ -60,6 +60,7 @@ #include <pk11pub.h> #include "base/compiler_specific.h" +#include "base/histogram.h" #include "base/logging.h" #include "base/nss_util.h" #include "base/singleton.h" @@ -70,6 +71,7 @@ #include "net/base/net_log.h" #include "net/base/net_errors.h" #include "net/base/ssl_cert_request_info.h" +#include "net/base/ssl_connection_status_flags.h" #include "net/base/ssl_info.h" #include "net/base/sys_addrinfo.h" #include "net/ocsp/nss_ocsp.h" @@ -789,6 +791,19 @@ void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) { DCHECK(server_cert_ != NULL); ssl_info->cert = server_cert_; + PRBool peer_supports_renego_ext; + ok = SSL_HandshakeNegotiatedExtension(nss_fd_, ssl_renegotiation_info_xtn, + &peer_supports_renego_ext); + if (ok == SECSuccess) { + if (!peer_supports_renego_ext) + ssl_info->connection_status |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION; + UMA_HISTOGRAM_ENUMERATION("Net.RenegotiationExtensionSupported", + (int)peer_supports_renego_ext, 2); + } + + if (ssl_config_.ssl3_fallback) + ssl_info->connection_status |= SSL_CONNECTION_SSL3_FALLBACK; + LeaveFunction(""); } diff --git a/net/socket/ssl_client_socket_win.cc b/net/socket/ssl_client_socket_win.cc index a0da5f4..9a4be48 100644 --- a/net/socket/ssl_client_socket_win.cc +++ b/net/socket/ssl_client_socket_win.cc @@ -17,6 +17,7 @@ #include "net/base/net_log.h" #include "net/base/net_errors.h" #include "net/base/ssl_cert_request_info.h" +#include "net/base/ssl_connection_status_flags.h" #include "net/base/ssl_info.h" #pragma comment(lib, "secur32.lib") @@ -335,6 +336,8 @@ SSLClientSocketWin::~SSLClientSocketWin() { } void SSLClientSocketWin::GetSSLInfo(SSLInfo* ssl_info) { + ssl_info->Reset(); + if (!server_cert_) return; @@ -349,6 +352,9 @@ void SSLClientSocketWin::GetSSLInfo(SSLInfo* ssl_info) { // normalized. ssl_info->security_bits = connection_info.dwCipherStrength; } + + if (ssl_config_.ssl3_fallback) + ssl_info->connection_status |= SSL_CONNECTION_SSL3_FALLBACK; } void SSLClientSocketWin::GetSSLCertRequestInfo( |