From 0374b299997a8bd265a7f79cc06f79e7892a0ac7 Mon Sep 17 00:00:00 2001 From: "wtc@chromium.org" Date: Fri, 14 Aug 2009 23:49:19 +0000 Subject: Add new certificate error code ERR_CERT_WEAK_SIGNATURE_ALGORITHM and certificate status flag CERT_STATUS_WEAK_SIGNATURE_ALGORITHM. Note that I didn't add new load flag LOAD_IGNORE_CERT_WEAK_SIGNATURE_ALGORITHM. Allow users to accept MD2 certificates as certificates signed using a weak signature algorithm. MD4 certificates are still treated as invalid certificates. R=jar,jcampan BUG=http://crbug.com/18725 TEST=none Review URL: http://codereview.chromium.org/165504 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23497 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/app/generated_resources.grd | 13 +++++++++++++ chrome/browser/ssl/ssl_error_info.cc | 22 ++++++++++++++++++++-- chrome/browser/ssl/ssl_error_info.h | 11 ++++++----- chrome/browser/ssl/ssl_policy.cc | 3 ++- chrome/common/security_filter_peer.cc | 1 + net/base/cert_status_flags.cc | 4 ++++ net/base/cert_status_flags.h | 1 + net/base/net_error_list.h | 6 +++++- net/base/x509_certificate_win.cc | 8 ++++++-- 9 files changed, 58 insertions(+), 11 deletions(-) diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index e2026c3..62860a8 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -1927,6 +1927,19 @@ each locale. --> Server's certificate is invalid + + The site's security certificate is signed using a weak signature algorithm! + + + You attempted to reach <strong>$1paypal.com</strong>, but the server presented a certificate signed using a weak signature algorithm. This means that the security credentials the server presented could have been forged, and the server may not be the server you expected (you may be communicating with an attacker). You should not proceed. + + + In this case, the server certificate or an intermediate CA certificate presented to your browser is signed using a weak signature algorithm such as RSA-MD2. Recent research by computer scientists showed the signature algorithm is weaker than previously believed, and the signature algorithm is rarely used by trustworthy websites today. This certificate could have been forged. You should not proceed past this point. + + + Server's certificate is signed using a weak signature algorithm + + Unknown server certificate error diff --git a/chrome/browser/ssl/ssl_error_info.cc b/chrome/browser/ssl/ssl_error_info.cc index d47529a..fd54bd4 100644 --- a/chrome/browser/ssl/ssl_error_info.cc +++ b/chrome/browser/ssl/ssl_error_info.cc @@ -153,6 +153,20 @@ SSLErrorInfo SSLErrorInfo::CreateError(ErrorType error_type, short_description = l10n_util::GetString(IDS_CERT_ERROR_INVALID_CERT_DESCRIPTION); break; + case CERT_WEAK_SIGNATURE_ALGORITHM: + title = + l10n_util::GetString(IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_TITLE); + details = l10n_util::GetStringF( + IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DETAILS, + UTF8ToWide(request_url.host())); + short_description = l10n_util::GetString( + IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DESCRIPTION); + extra_info.push_back( + l10n_util::GetString(IDS_CERT_ERROR_EXTRA_INFO_1)); + extra_info.push_back( + l10n_util::GetString( + IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_EXTRA_INFO_2)); + break; case MIXED_CONTENTS: title = l10n_util::GetString(IDS_SSL_MIXED_CONTENT_TITLE); details = l10n_util::GetString(IDS_SSL_MIXED_CONTENT_DETAILS); @@ -199,6 +213,8 @@ SSLErrorInfo::ErrorType SSLErrorInfo::NetErrorToErrorType(int net_error) { return CERT_REVOKED; case net::ERR_CERT_INVALID: return CERT_INVALID; + case net::ERR_CERT_WEAK_SIGNATURE_ALGORITHM: + return CERT_WEAK_SIGNATURE_ALGORITHM; default: NOTREACHED(); return UNKNOWN; @@ -217,7 +233,8 @@ int SSLErrorInfo::GetErrorsForCertStatus(int cert_id, net::CERT_STATUS_NO_REVOCATION_MECHANISM, net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION, net::CERT_STATUS_REVOKED, - net::CERT_STATUS_INVALID + net::CERT_STATUS_INVALID, + net::CERT_STATUS_WEAK_SIGNATURE_ALGORITHM }; const ErrorType kErrorTypes[] = { @@ -227,7 +244,8 @@ int SSLErrorInfo::GetErrorsForCertStatus(int cert_id, CERT_NO_REVOCATION_MECHANISM, CERT_UNABLE_TO_CHECK_REVOCATION, CERT_REVOKED, - CERT_INVALID + CERT_INVALID, + CERT_WEAK_SIGNATURE_ALGORITHM }; DCHECK(arraysize(kErrorFlags) == arraysize(kErrorTypes)); diff --git a/chrome/browser/ssl/ssl_error_info.h b/chrome/browser/ssl/ssl_error_info.h index d11fc0d..c3f9b63 100644 --- a/chrome/browser/ssl/ssl_error_info.h +++ b/chrome/browser/ssl/ssl_error_info.h @@ -1,9 +1,9 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-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. -#ifndef CHROME_BROWSER_SSL_ERROR_INFO_H__ -#define CHROME_BROWSER_SSL_ERROR_INFO_H__ +#ifndef CHROME_BROWSER_SSL_SSL_ERROR_INFO_H_ +#define CHROME_BROWSER_SSL_SSL_ERROR_INFO_H_ #include #include @@ -27,6 +27,7 @@ class SSLErrorInfo { CERT_UNABLE_TO_CHECK_REVOCATION, CERT_REVOKED, CERT_INVALID, + CERT_WEAK_SIGNATURE_ALGORITHM, MIXED_CONTENTS, UNSAFE_CONTENTS, UNKNOWN @@ -64,7 +65,7 @@ class SSLErrorInfo { return extra_information_; } -private: + private: SSLErrorInfo(const std::wstring& title, const std::wstring& details, const std::wstring& short_description, @@ -78,4 +79,4 @@ private: std::vector extra_information_; }; -#endif // CHROME_BROWSER_SSL_ERROR_INFO_H__ +#endif // CHROME_BROWSER_SSL_SSL_ERROR_INFO_H_ diff --git a/chrome/browser/ssl/ssl_policy.cc b/chrome/browser/ssl/ssl_policy.cc index 4efad66..cbef647 100644 --- a/chrome/browser/ssl/ssl_policy.cc +++ b/chrome/browser/ssl/ssl_policy.cc @@ -84,10 +84,11 @@ void SSLPolicy::OnCertError(SSLCertErrorHandler* handler) { // For now we handle the DENIED as the UNKNOWN, which means a blocking // page is shown to the user every time he comes back to the page. - switch(handler->cert_error()) { + switch (handler->cert_error()) { case net::ERR_CERT_COMMON_NAME_INVALID: case net::ERR_CERT_DATE_INVALID: case net::ERR_CERT_AUTHORITY_INVALID: + case net::ERR_CERT_WEAK_SIGNATURE_ALGORITHM: OnOverridableCertError(handler); break; case net::ERR_CERT_NO_REVOCATION_MECHANISM: diff --git a/chrome/common/security_filter_peer.cc b/chrome/common/security_filter_peer.cc index 5369199..79256e7 100644 --- a/chrome/common/security_filter_peer.cc +++ b/chrome/common/security_filter_peer.cc @@ -75,6 +75,7 @@ SecurityFilterPeer* case net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION: case net::ERR_CERT_REVOKED: case net::ERR_CERT_INVALID: + case net::ERR_CERT_WEAK_SIGNATURE_ALGORITHM: case net::ERR_INSECURE_RESPONSE: if (ResourceType::IsFrame(resource_type)) return CreateSecurityFilterPeerForFrame(peer, os_error); diff --git a/net/base/cert_status_flags.cc b/net/base/cert_status_flags.cc index a0ddc13..7cf4b3e 100644 --- a/net/base/cert_status_flags.cc +++ b/net/base/cert_status_flags.cc @@ -31,6 +31,8 @@ int MapNetErrorToCertStatus(int error) { // Falls through. case ERR_CERT_INVALID: return CERT_STATUS_INVALID; + case ERR_CERT_WEAK_SIGNATURE_ALGORITHM: + return CERT_STATUS_WEAK_SIGNATURE_ALGORITHM; default: return 0; } @@ -51,6 +53,8 @@ int MapCertStatusToNetError(int cert_status) { return ERR_CERT_AUTHORITY_INVALID; if (cert_status & CERT_STATUS_COMMON_NAME_INVALID) return ERR_CERT_COMMON_NAME_INVALID; + if (cert_status & CERT_STATUS_WEAK_SIGNATURE_ALGORITHM) + return ERR_CERT_WEAK_SIGNATURE_ALGORITHM; if (cert_status & CERT_STATUS_DATE_INVALID) return ERR_CERT_DATE_INVALID; diff --git a/net/base/cert_status_flags.h b/net/base/cert_status_flags.h index 0b84be6..e4f07bb 100644 --- a/net/base/cert_status_flags.h +++ b/net/base/cert_status_flags.h @@ -19,6 +19,7 @@ enum { CERT_STATUS_UNABLE_TO_CHECK_REVOCATION = 1 << 5, CERT_STATUS_REVOKED = 1 << 6, CERT_STATUS_INVALID = 1 << 7, + CERT_STATUS_WEAK_SIGNATURE_ALGORITHM = 1 << 8, // Bits 16 to 30 are for non-error statuses. CERT_STATUS_IS_EV = 1 << 16, diff --git a/net/base/net_error_list.h b/net/base/net_error_list.h index cd9ba06..c750295 100644 --- a/net/base/net_error_list.h +++ b/net/base/net_error_list.h @@ -194,13 +194,17 @@ NET_ERROR(CERT_REVOKED, -206) // NET_ERROR(CERT_INVALID, -207) +// The server responded with a certificate that is signed using a weak +// signature algorithm. +NET_ERROR(CERT_WEAK_SIGNATURE_ALGORITHM, -208) + // Add new certificate error codes here. // // Update the value of CERT_END whenever you add a new certificate error // code. // The value immediately past the last certificate error code. -NET_ERROR(CERT_END, -208) +NET_ERROR(CERT_END, -209) // The URL is invalid. NET_ERROR(INVALID_URL, -300) diff --git a/net/base/x509_certificate_win.cc b/net/base/x509_certificate_win.cc index 9fe5e9f..a16c3b2 100644 --- a/net/base/x509_certificate_win.cc +++ b/net/base/x509_certificate_win.cc @@ -471,10 +471,14 @@ int X509Certificate::Verify(const std::string& hostname, verify_result->cert_status |= MapCertChainErrorStatusToCertStatus( chain_context->TrustStatus.dwErrorStatus); - // Treat certificate signatures using weak signature algorithms as invalid. - if (verify_result->has_md2 || verify_result->has_md4) + // Treat certificates signed using broken signature algorithms as invalid. + if (verify_result->has_md4) verify_result->cert_status |= CERT_STATUS_INVALID; + // Flag certificates signed using weak signature algorithms. + if (verify_result->has_md2) + verify_result->cert_status |= CERT_STATUS_WEAK_SIGNATURE_ALGORITHM; + std::wstring wstr_hostname = ASCIIToWide(hostname); SSL_EXTRA_CERT_CHAIN_POLICY_PARA extra_policy_para; -- cgit v1.1