diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-01 16:22:27 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-01 16:22:27 +0000 |
commit | 30bd4e355cc33a44a3f8a17a935807b062e57089 (patch) | |
tree | 2388711ae1441fc2008efce7787d83a76f7e2c49 | |
parent | e0cd5d03d07b1354beb04414ef5d69869c4c037f (diff) | |
download | chromium_src-30bd4e355cc33a44a3f8a17a935807b062e57089.zip chromium_src-30bd4e355cc33a44a3f8a17a935807b062e57089.tar.gz chromium_src-30bd4e355cc33a44a3f8a17a935807b062e57089.tar.bz2 |
Detect Kaspersky SSL MITM and give a helpful error message.
BUG=86208
TEST=Install Kaspersky Internet security and configure SSL MITM. Navigate to an HTTPS page. Check that the error message is helpful and not generic.
Review URL: http://codereview.chromium.org/7275027
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@91298 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/app/generated_resources.grd | 16 | ||||
-rw-r--r-- | chrome/renderer/localized_error.cc | 12 | ||||
-rw-r--r-- | net/base/net_error_list.h | 10 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_nss.cc | 67 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_nss.h | 3 |
5 files changed, 77 insertions, 31 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 3b70c0d..439711a 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -6369,6 +6369,9 @@ Keep your key file in a safe place. You will need it to create new versions of y <message name="IDS_ERRORPAGES_HEADING_ESET_ANTI_VIRUS_SSL_INTERCEPTION" desc="Heading of the error page when we detect that ESET anti-virus is running and intercepting our HTTPS connections. 'ESET' is a product name and may be best left untranslated."> Cannot make secure connection because of ESET anti-virus </message> + <message name="IDS_ERRORPAGES_HEADING_KASPERSKY_ANTI_VIRUS_SSL_INTERCEPTION" desc="Heading of the error page when we detect that Kaspersky anti-virus is running and intercepting our HTTPS connections. 'Kaspersky' is a product name and may be best left untranslated."> + Cannot make secure connection because of Kaspersky anti-virus + </message> <message name="IDS_ERRORPAGES_SUMMARY_NOT_AVAILABLE" desc="Summary in the error page when we can't connect to a site."> The webpage at <ph name="URL"><strong jscontent="failedUrl"></strong></ph> might be temporarily down or it may have moved permanently to a new web address. </message> @@ -6534,6 +6537,19 @@ Keep your key file in a safe place. You will need it to create new versions of y instructions. </message> + <message name="IDS_ERRORPAGES_SUMMARY_KASPERSKY_ANTI_VIRUS_SSL_INTERCEPTION" desc="Summary in the error page when we detect that Kaspersky anti-virus is running and intercepting our HTTPS connections. 'Kaspersky' is a product name and may be best left untranslated. 'Learn more' should be the contents of IDS_LEARN_MORE."> + <ph name="PRODUCT_NAME"><span jscontent="productName"></span><ex>Google Chrome</ex></ph> + has detected that a Kaspersky product is intercepting secure connections. + This is typically not a security issue as the Kaspersky software is + usually running on the same computer. However, due to an intolerance + to specific aspects of + <ph name="PRODUCT_NAME"><span jscontent="productName"></span><ex>Google Chrome</ex></ph>'s + secure connections, Kaspersky products have to be configured to not + perform this interception. Click the 'Learn more' link for + instructions which guide you to the configuration option that should be + disabled. + </message> + <message name="IDS_ERRORPAGES_SUMMARY_NETNANNY_SSL_INTERCEPTION" desc="Summary in the error page when we detect that NetNanny is running and intercepting our HTTPS connections. 'NetNanny' is a product name and may be best left untranslated. 'Learn more' should be the contents of IDS_LEARN_MORE."> <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> has detected that NetNanny is intercepting secure connections. This is typically diff --git a/chrome/renderer/localized_error.cc b/chrome/renderer/localized_error.cc index 3476505..c6bdbaa 100644 --- a/chrome/renderer/localized_error.cc +++ b/chrome/renderer/localized_error.cc @@ -34,6 +34,8 @@ static const char kWeakDHKeyLearnMoreUrl[] = "http://sites.google.com/a/chromium.org/dev/err_ssl_weak_server_ephemeral_dh_key"; static const char kESETLearnMoreUrl[] = "http://kb.eset.com/esetkb/index?page=content&id=SOLN2588"; +static const char kKasperskyLearnMoreUrl[] = + "http://support.kaspersky.com/kav2012/settings/options?print=true&qid=208284701"; enum NAV_SUGGESTIONS { SUGGEST_NONE = 0, @@ -215,6 +217,13 @@ const LocalizedErrorMap net_error_options[] = { IDS_ERRORPAGES_DETAILS_SSL_PROTOCOL_ERROR, SUGGEST_LEARNMORE, }, + {net::ERR_KASPERSKY_ANTI_VIRUS_SSL_INTERCEPTION, + IDS_ERRORPAGES_TITLE_LOAD_FAILED, + IDS_ERRORPAGES_HEADING_KASPERSKY_ANTI_VIRUS_SSL_INTERCEPTION, + IDS_ERRORPAGES_SUMMARY_KASPERSKY_ANTI_VIRUS_SSL_INTERCEPTION, + IDS_ERRORPAGES_DETAILS_SSL_PROTOCOL_ERROR, + SUGGEST_LEARNMORE, + }, {net::ERR_TEMPORARILY_THROTTLED, IDS_ERRORPAGES_TITLE_ACCESS_DENIED, IDS_ERRORPAGES_HEADING_ACCESS_DENIED, @@ -548,6 +557,9 @@ void LocalizedError::GetStrings(const WebKit::WebURLError& error, case net::ERR_ESET_ANTI_VIRUS_SSL_INTERCEPTION: learn_more_url = GURL(kESETLearnMoreUrl); break; + case net::ERR_KASPERSKY_ANTI_VIRUS_SSL_INTERCEPTION: + learn_more_url = GURL(kKasperskyLearnMoreUrl); + break; default: break; } diff --git a/net/base/net_error_list.h b/net/base/net_error_list.h index ef44b46..cfde9d8 100644 --- a/net/base/net_error_list.h +++ b/net/base/net_error_list.h @@ -187,6 +187,7 @@ NET_ERROR(MANDATORY_PROXY_CONFIGURATION_FAILED, -131) // We detected an ESET product intercepting our HTTPS connections. Since these // products are False Start intolerant, we return this error so that we can // give the user a helpful error message rather than have the connection hang. +// See also: KASPERSKY_ANTI_VIRUS_SSL_INTERCEPTION NET_ERROR(ESET_ANTI_VIRUS_SSL_INTERCEPTION, -132) // We've hit the max socket limit for the socket pool while preconnecting. We @@ -231,6 +232,13 @@ NET_ERROR(SSL_CLIENT_AUTH_SIGNATURE_FAILED, -141) // which exceeds size threshold). NET_ERROR(MSG_TOO_BIG, -142) +// We detected a Kaspersky product intercepting our HTTPS connections. This +// interacts badly with our SSL stack for unknown reasons (disabling False +// Start doesn't help). We return this error so that we can give the user a +// helpful error message rather than have the connection hang. +// See also: ESET_ANTI_VIRUS_SSL_INTERCEPTION +NET_ERROR(KASPERSKY_ANTI_VIRUS_SSL_INTERCEPTION, -143) + // Connection was aborted for switching to another ptotocol. // WebSocket abort SocketStream connection when alternate protocol is found. NET_ERROR(PROTOCOL_SWITCHED, -146) @@ -238,7 +246,7 @@ NET_ERROR(PROTOCOL_SWITCHED, -146) // Returned when attempting to bind an address that is already in use. NET_ERROR(ADDRESS_IN_USE, -147) -// NOTE: error codes 143-145 are available, please use those before adding +// NOTE: error codes 144-145 are available, please use those before adding // 148. // Certificate error codes diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc index 44a87fb..41bd5cc0 100644 --- a/net/socket/ssl_client_socket_nss.cc +++ b/net/socket/ssl_client_socket_nss.cc @@ -451,6 +451,7 @@ SSLClientSocketNSS::SSLClientSocketNSS(ClientSocketHandle* transport_socket, handshake_callback_called_(false), completed_handshake_(false), eset_mitm_detected_(false), + kaspersky_mitm_detected_(false), predicted_cert_chain_correct_(false), next_handshake_state_(STATE_NONE), nss_fd_(NULL), @@ -644,6 +645,7 @@ void SSLClientSocketNSS::Disconnect() { ssl_connection_status_ = 0; completed_handshake_ = false; eset_mitm_detected_ = false; + kaspersky_mitm_detected_ = false; start_cert_verification_time_ = base::TimeTicks(); predicted_cert_chain_correct_ = false; nss_bufs_ = NULL; @@ -1391,6 +1393,8 @@ int SSLClientSocketNSS::DoHandshake() { if (handshake_callback_called_) { if (eset_mitm_detected_) { net_error = ERR_ESET_ANTI_VIRUS_SSL_INTERCEPTION; + } else if (kaspersky_mitm_detected_) { + net_error = ERR_KASPERSKY_ANTI_VIRUS_SSL_INTERCEPTION; } else { // We need to see if the predicted certificate chain (in // |ssl_host_info_->state().certs) matches the actual certificate chain @@ -1873,39 +1877,42 @@ SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg, SECStatus rv = SSL_OptionGet(socket, SSL_ENABLE_FALSE_START, &false_start); DCHECK_EQ(SECSuccess, rv); - if (false_start) { - SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); - - // ESET anti-virus is capable of intercepting HTTPS connections on Windows. - // However, it is False Start intolerant and causes the connections to hang - // forever. We detect ESET by the issuer of the leaf certificate and set a - // flag to return a specific error, giving the user instructions for - // reconfiguring ESET. - CERTCertificate* cert = SSL_PeerCertificate(that->nss_fd_); - if (cert) { - char* common_name = CERT_GetCommonName(&cert->issuer); - if (common_name) { - if (strcmp(common_name, "ESET_RootSslCert") == 0) - that->eset_mitm_detected_ = true; - if (strcmp(common_name, - "ContentWatch Root Certificate Authority") == 0) { - // This is NetNanny. NetNanny are updating their product so we - // silently disable False Start for now. - rv = SSL_OptionSet(socket, SSL_ENABLE_FALSE_START, PR_FALSE); - DCHECK_EQ(SECSuccess, rv); - false_start = 0; - } - PORT_Free(common_name); + SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); + CERTCertificate* cert = SSL_PeerCertificate(that->nss_fd_); + if (cert) { + char* common_name = CERT_GetCommonName(&cert->issuer); + if (common_name) { + if (false_start && strcmp(common_name, "ESET_RootSslCert") == 0) + // ESET anti-virus is capable of intercepting HTTPS connections on + // Windows. However, it is False Start intolerant and causes the + // connections to hang forever. We detect ESET by the issuer of the + // leaf certificate and set a flag to return a specific error, giving + // the user instructions for reconfiguring ESET. + that->eset_mitm_detected_ = true; + if (strcmp(common_name, + "Kaspersky Anti-Virus personal root certificate") == 0) { + // Kaspersky has an unknown intolerance to our HTTPS handshakes and so + // we detect and give a more helpful error message. + that->kaspersky_mitm_detected_ = true; + } + if (false_start && + strcmp(common_name, "ContentWatch Root Certificate Authority") == 0) { + // This is NetNanny. NetNanny are updating their product so we + // silently disable False Start for now. + rv = SSL_OptionSet(socket, SSL_ENABLE_FALSE_START, PR_FALSE); + DCHECK_EQ(SECSuccess, rv); + false_start = 0; } - CERT_DestroyCertificate(cert); + PORT_Free(common_name); } + CERT_DestroyCertificate(cert); + } - if (false_start && !that->handshake_callback_called_) { - that->corked_ = true; - that->uncork_timer_.Start( - base::TimeDelta::FromMilliseconds(kCorkTimeoutMs), - that, &SSLClientSocketNSS::UncorkAfterTimeout); - } + if (false_start && !that->handshake_callback_called_) { + that->corked_ = true; + that->uncork_timer_.Start( + base::TimeDelta::FromMilliseconds(kCorkTimeoutMs), + that, &SSLClientSocketNSS::UncorkAfterTimeout); } #endif diff --git a/net/socket/ssl_client_socket_nss.h b/net/socket/ssl_client_socket_nss.h index 7d2f7cf..8573b48 100644 --- a/net/socket/ssl_client_socket_nss.h +++ b/net/socket/ssl_client_socket_nss.h @@ -223,6 +223,9 @@ class SSLClientSocketNSS : public SSLClientSocket { // True iff we believe that the user has an ESET product intercepting our // HTTPS connections. bool eset_mitm_detected_; + // True iff we believe that the user has a Kaspersky product intercepting our + // HTTPS connections. + bool kaspersky_mitm_detected_; // True iff |ssl_host_info_| contained a predicted certificate chain and // that we found the prediction to be correct. |