blob: 0d1cfe8bb77d19be3e033dfc386f6e11ba4ab9b1 [file] [log] [blame]
[email protected]09581d12012-02-27 05:12:471// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]3b073b22009-01-16 03:29:035#include "chrome/browser/ssl/ssl_error_info.h"
initial.commit09911bf2008-07-26 23:55:296
[email protected]09581d12012-02-27 05:12:477#include "base/i18n/time_formatting.h"
[email protected]e309f312013-06-07 21:50:088#include "base/strings/utf_string_conversions.h"
initial.commit09911bf2008-07-26 23:55:299#include "chrome/common/time_format.h"
[email protected]b59c6cf02012-03-12 20:51:4210#include "content/public/browser/cert_store.h"
[email protected]34ac8f32009-02-22 23:03:2711#include "googleurl/src/gurl.h"
12#include "grit/chromium_strings.h"
13#include "grit/generated_resources.h"
[email protected]68b65022012-08-18 01:58:4214#include "net/base/escape.h"
initial.commit09911bf2008-07-26 23:55:2915#include "net/base/net_errors.h"
[email protected]6e7845ae2013-03-29 21:48:1116#include "net/cert/cert_status_flags.h"
[email protected]536fd0b2013-03-14 17:41:5717#include "net/ssl/ssl_info.h"
[email protected]c051a1b2011-01-21 23:30:1718#include "ui/base/l10n/l10n_util.h"
initial.commit09911bf2008-07-26 23:55:2919
[email protected]42197a22010-12-28 23:29:4220SSLErrorInfo::SSLErrorInfo(const string16& title,
21 const string16& details,
22 const string16& short_description,
23 const std::vector<string16>& extra_info)
initial.commit09911bf2008-07-26 23:55:2924 : title_(title),
25 details_(details),
26 short_description_(short_description),
27 extra_information_(extra_info) {
28}
29
30// static
31SSLErrorInfo SSLErrorInfo::CreateError(ErrorType error_type,
[email protected]8ac1a752008-07-31 19:40:3732 net::X509Certificate* cert,
initial.commit09911bf2008-07-26 23:55:2933 const GURL& request_url) {
[email protected]42197a22010-12-28 23:29:4234 string16 title, details, short_description;
35 std::vector<string16> extra_info;
initial.commit09911bf2008-07-26 23:55:2936 switch (error_type) {
37 case CERT_COMMON_NAME_INVALID: {
[email protected]42197a22010-12-28 23:29:4238 title =
39 l10n_util::GetStringUTF16(IDS_CERT_ERROR_COMMON_NAME_INVALID_TITLE);
initial.commit09911bf2008-07-26 23:55:2940 // If the certificate contains multiple DNS names, we choose the most
41 // representative one -- either the DNS name that's also in the subject
42 // field, or the first one. If this heuristic turns out to be
43 // inadequate, we can consider choosing the DNS name that is the
44 // "closest match" to the host name in the request URL, or listing all
45 // the DNS names with an HTML <ul>.
46 std::vector<std::string> dns_names;
47 cert->GetDNSNames(&dns_names);
48 DCHECK(!dns_names.empty());
49 size_t i = 0;
50 for (; i < dns_names.size(); ++i) {
51 if (dns_names[i] == cert->subject().common_name)
52 break;
53 }
54 if (i == dns_names.size())
55 i = 0;
56 details =
[email protected]42197a22010-12-28 23:29:4257 l10n_util::GetStringFUTF16(IDS_CERT_ERROR_COMMON_NAME_INVALID_DETAILS,
58 UTF8ToUTF16(request_url.host()),
[email protected]68b65022012-08-18 01:58:4259 net::EscapeForHTML(
60 UTF8ToUTF16(dns_names[i])),
[email protected]42197a22010-12-28 23:29:4261 UTF8ToUTF16(request_url.host()));
62 short_description = l10n_util::GetStringUTF16(
63 IDS_CERT_ERROR_COMMON_NAME_INVALID_DESCRIPTION);
initial.commit09911bf2008-07-26 23:55:2964 extra_info.push_back(
[email protected]42197a22010-12-28 23:29:4265 l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
initial.commit09911bf2008-07-26 23:55:2966 extra_info.push_back(
[email protected]42197a22010-12-28 23:29:4267 l10n_util::GetStringFUTF16(
initial.commit09911bf2008-07-26 23:55:2968 IDS_CERT_ERROR_COMMON_NAME_INVALID_EXTRA_INFO_2,
[email protected]68b65022012-08-18 01:58:4269 net::EscapeForHTML(UTF8ToUTF16(cert->subject().common_name)),
[email protected]42197a22010-12-28 23:29:4270 UTF8ToUTF16(request_url.host())));
initial.commit09911bf2008-07-26 23:55:2971 break;
72 }
73 case CERT_DATE_INVALID:
74 extra_info.push_back(
[email protected]42197a22010-12-28 23:29:4275 l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
initial.commit09911bf2008-07-26 23:55:2976 if (cert->HasExpired()) {
[email protected]42197a22010-12-28 23:29:4277 title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXPIRED_TITLE);
[email protected]09581d12012-02-27 05:12:4778 details = l10n_util::GetStringFUTF16(
79 IDS_CERT_ERROR_EXPIRED_DETAILS,
80 UTF8ToUTF16(request_url.host()),
81 UTF8ToUTF16(request_url.host()),
82 base::TimeFormatFriendlyDateAndTime(base::Time::Now()));
initial.commit09911bf2008-07-26 23:55:2983 short_description =
[email protected]42197a22010-12-28 23:29:4284 l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXPIRED_DESCRIPTION);
85 extra_info.push_back(l10n_util::GetStringUTF16(
86 IDS_CERT_ERROR_EXPIRED_DETAILS_EXTRA_INFO_2));
initial.commit09911bf2008-07-26 23:55:2987 } else {
88 // Then it must be not yet valid. We don't check that it is not yet
89 // valid as there is still a very unlikely chance that the cert might
90 // have become valid since the error occurred.
[email protected]42197a22010-12-28 23:29:4291 title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_NOT_YET_VALID_TITLE);
92 details = l10n_util::GetStringFUTF16(
93 IDS_CERT_ERROR_NOT_YET_VALID_DETAILS,
94 UTF8ToUTF16(request_url.host()),
[email protected]09581d12012-02-27 05:12:4795 UTF8ToUTF16(request_url.host()),
96 base::TimeFormatFriendlyDateAndTime(base::Time::Now()));
initial.commit09911bf2008-07-26 23:55:2997 short_description =
[email protected]42197a22010-12-28 23:29:4298 l10n_util::GetStringUTF16(IDS_CERT_ERROR_NOT_YET_VALID_DESCRIPTION);
initial.commit09911bf2008-07-26 23:55:2999 extra_info.push_back(
[email protected]42197a22010-12-28 23:29:42100 l10n_util::GetStringUTF16(
initial.commit09911bf2008-07-26 23:55:29101 IDS_CERT_ERROR_NOT_YET_VALID_DETAILS_EXTRA_INFO_2));
102 }
103 break;
104 case CERT_AUTHORITY_INVALID:
[email protected]42197a22010-12-28 23:29:42105 title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_AUTHORITY_INVALID_TITLE);
106 details = l10n_util::GetStringFUTF16(
107 IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS,
108 UTF8ToUTF16(request_url.host()));
109 short_description = l10n_util::GetStringUTF16(
110 IDS_CERT_ERROR_AUTHORITY_INVALID_DESCRIPTION);
initial.commit09911bf2008-07-26 23:55:29111 extra_info.push_back(
[email protected]42197a22010-12-28 23:29:42112 l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
113 extra_info.push_back(l10n_util::GetStringFUTF16(
114 IDS_CERT_ERROR_AUTHORITY_INVALID_EXTRA_INFO_2,
115 UTF8ToUTF16(request_url.host()),
116 UTF8ToUTF16(request_url.host())));
[email protected]b9c23c12013-05-15 02:09:20117#if !defined(OS_IOS)
118 // The third paragraph advises users to install a private trust anchor,
119 // but that is not possible in Chrome for iOS at this time.
[email protected]42197a22010-12-28 23:29:42120 extra_info.push_back(l10n_util::GetStringUTF16(
121 IDS_CERT_ERROR_AUTHORITY_INVALID_EXTRA_INFO_3));
[email protected]b9c23c12013-05-15 02:09:20122#endif
initial.commit09911bf2008-07-26 23:55:29123 break;
124 case CERT_CONTAINS_ERRORS:
[email protected]42197a22010-12-28 23:29:42125 title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_CONTAINS_ERRORS_TITLE);
126 details = l10n_util::GetStringFUTF16(
127 IDS_CERT_ERROR_CONTAINS_ERRORS_DETAILS,
128 UTF8ToUTF16(request_url.host()));
initial.commit09911bf2008-07-26 23:55:29129 short_description =
[email protected]42197a22010-12-28 23:29:42130 l10n_util::GetStringUTF16(IDS_CERT_ERROR_CONTAINS_ERRORS_DESCRIPTION);
initial.commit09911bf2008-07-26 23:55:29131 extra_info.push_back(
[email protected]42197a22010-12-28 23:29:42132 l10n_util::GetStringFUTF16(IDS_CERT_ERROR_EXTRA_INFO_1,
133 UTF8ToUTF16(request_url.host())));
134 extra_info.push_back(l10n_util::GetStringUTF16(
135 IDS_CERT_ERROR_CONTAINS_ERRORS_EXTRA_INFO_2));
initial.commit09911bf2008-07-26 23:55:29136 break;
137 case CERT_NO_REVOCATION_MECHANISM:
[email protected]42197a22010-12-28 23:29:42138 title = l10n_util::GetStringUTF16(
139 IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_TITLE);
140 details = l10n_util::GetStringUTF16(
141 IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DETAILS);
142 short_description = l10n_util::GetStringUTF16(
initial.commit09911bf2008-07-26 23:55:29143 IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DESCRIPTION);
144 break;
145 case CERT_UNABLE_TO_CHECK_REVOCATION:
[email protected]42197a22010-12-28 23:29:42146 title = l10n_util::GetStringUTF16(
147 IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_TITLE);
148 details = l10n_util::GetStringUTF16(
initial.commit09911bf2008-07-26 23:55:29149 IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DETAILS);
[email protected]42197a22010-12-28 23:29:42150 short_description = l10n_util::GetStringUTF16(
initial.commit09911bf2008-07-26 23:55:29151 IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DESCRIPTION);
152 break;
153 case CERT_REVOKED:
[email protected]42197a22010-12-28 23:29:42154 title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_REVOKED_CERT_TITLE);
155 details = l10n_util::GetStringFUTF16(IDS_CERT_ERROR_REVOKED_CERT_DETAILS,
156 UTF8ToUTF16(request_url.host()));
initial.commit09911bf2008-07-26 23:55:29157 short_description =
[email protected]42197a22010-12-28 23:29:42158 l10n_util::GetStringUTF16(IDS_CERT_ERROR_REVOKED_CERT_DESCRIPTION);
initial.commit09911bf2008-07-26 23:55:29159 extra_info.push_back(
[email protected]42197a22010-12-28 23:29:42160 l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
initial.commit09911bf2008-07-26 23:55:29161 extra_info.push_back(
[email protected]42197a22010-12-28 23:29:42162 l10n_util::GetStringUTF16(IDS_CERT_ERROR_REVOKED_CERT_EXTRA_INFO_2));
initial.commit09911bf2008-07-26 23:55:29163 break;
164 case CERT_INVALID:
[email protected]42197a22010-12-28 23:29:42165 title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_INVALID_CERT_TITLE);
[email protected]eb8a06d2011-03-04 04:40:38166 details = l10n_util::GetStringFUTF16(
167 IDS_CERT_ERROR_INVALID_CERT_DETAILS,
168 UTF8ToUTF16(request_url.host()));
initial.commit09911bf2008-07-26 23:55:29169 short_description =
[email protected]42197a22010-12-28 23:29:42170 l10n_util::GetStringUTF16(IDS_CERT_ERROR_INVALID_CERT_DESCRIPTION);
[email protected]eb8a06d2011-03-04 04:40:38171 extra_info.push_back(
172 l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
173 extra_info.push_back(l10n_util::GetStringUTF16(
174 IDS_CERT_ERROR_INVALID_CERT_EXTRA_INFO_2));
initial.commit09911bf2008-07-26 23:55:29175 break;
[email protected]0374b292009-08-14 23:49:19176 case CERT_WEAK_SIGNATURE_ALGORITHM:
[email protected]42197a22010-12-28 23:29:42177 title = l10n_util::GetStringUTF16(
178 IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_TITLE);
179 details = l10n_util::GetStringFUTF16(
[email protected]0374b292009-08-14 23:49:19180 IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DETAILS,
[email protected]42197a22010-12-28 23:29:42181 UTF8ToUTF16(request_url.host()));
182 short_description = l10n_util::GetStringUTF16(
[email protected]0374b292009-08-14 23:49:19183 IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DESCRIPTION);
184 extra_info.push_back(
[email protected]42197a22010-12-28 23:29:42185 l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
[email protected]0374b292009-08-14 23:49:19186 extra_info.push_back(
[email protected]42197a22010-12-28 23:29:42187 l10n_util::GetStringUTF16(
[email protected]0374b292009-08-14 23:49:19188 IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_EXTRA_INFO_2));
189 break;
[email protected]aaa20bde2011-12-16 23:27:35190 case CERT_WEAK_KEY:
191 title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_WEAK_KEY_TITLE);
192 details = l10n_util::GetStringFUTF16(
193 IDS_CERT_ERROR_WEAK_KEY_DETAILS, UTF8ToUTF16(request_url.host()));
194 short_description = l10n_util::GetStringUTF16(
195 IDS_CERT_ERROR_WEAK_KEY_DESCRIPTION);
196 extra_info.push_back(
197 l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
198 extra_info.push_back(
199 l10n_util::GetStringUTF16(
200 IDS_CERT_ERROR_WEAK_KEY_EXTRA_INFO_2));
201 break;
initial.commit09911bf2008-07-26 23:55:29202 case UNKNOWN:
[email protected]42197a22010-12-28 23:29:42203 title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_UNKNOWN_ERROR_TITLE);
204 details = l10n_util::GetStringUTF16(IDS_CERT_ERROR_UNKNOWN_ERROR_DETAILS);
initial.commit09911bf2008-07-26 23:55:29205 short_description =
[email protected]42197a22010-12-28 23:29:42206 l10n_util::GetStringUTF16(IDS_CERT_ERROR_UNKNOWN_ERROR_DESCRIPTION);
initial.commit09911bf2008-07-26 23:55:29207 break;
208 default:
209 NOTREACHED();
210 }
211 return SSLErrorInfo(title, details, short_description, extra_info);
212}
213
214SSLErrorInfo::~SSLErrorInfo() {
215}
216
217// static
218SSLErrorInfo::ErrorType SSLErrorInfo::NetErrorToErrorType(int net_error) {
219 switch (net_error) {
220 case net::ERR_CERT_COMMON_NAME_INVALID:
221 return CERT_COMMON_NAME_INVALID;
222 case net::ERR_CERT_DATE_INVALID:
223 return CERT_DATE_INVALID;
224 case net::ERR_CERT_AUTHORITY_INVALID:
225 return CERT_AUTHORITY_INVALID;
226 case net::ERR_CERT_CONTAINS_ERRORS:
227 return CERT_CONTAINS_ERRORS;
228 case net::ERR_CERT_NO_REVOCATION_MECHANISM:
229 return CERT_NO_REVOCATION_MECHANISM;
230 case net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION:
231 return CERT_UNABLE_TO_CHECK_REVOCATION;
232 case net::ERR_CERT_REVOKED:
233 return CERT_REVOKED;
234 case net::ERR_CERT_INVALID:
235 return CERT_INVALID;
[email protected]0374b292009-08-14 23:49:19236 case net::ERR_CERT_WEAK_SIGNATURE_ALGORITHM:
237 return CERT_WEAK_SIGNATURE_ALGORITHM;
[email protected]aaa20bde2011-12-16 23:27:35238 case net::ERR_CERT_WEAK_KEY:
239 return CERT_WEAK_KEY;
initial.commit09911bf2008-07-26 23:55:29240 default:
241 NOTREACHED();
242 return UNKNOWN;
243 }
244}
245
246// static
247int SSLErrorInfo::GetErrorsForCertStatus(int cert_id,
[email protected]70d66502011-09-23 00:55:08248 net::CertStatus cert_status,
initial.commit09911bf2008-07-26 23:55:29249 const GURL& url,
250 std::vector<SSLErrorInfo>* errors) {
[email protected]70d66502011-09-23 00:55:08251 const net::CertStatus kErrorFlags[] = {
initial.commit09911bf2008-07-26 23:55:29252 net::CERT_STATUS_COMMON_NAME_INVALID,
253 net::CERT_STATUS_DATE_INVALID,
254 net::CERT_STATUS_AUTHORITY_INVALID,
255 net::CERT_STATUS_NO_REVOCATION_MECHANISM,
256 net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION,
257 net::CERT_STATUS_REVOKED,
[email protected]0374b292009-08-14 23:49:19258 net::CERT_STATUS_INVALID,
[email protected]aaa20bde2011-12-16 23:27:35259 net::CERT_STATUS_WEAK_SIGNATURE_ALGORITHM,
260 net::CERT_STATUS_WEAK_KEY
initial.commit09911bf2008-07-26 23:55:29261 };
262
263 const ErrorType kErrorTypes[] = {
264 CERT_COMMON_NAME_INVALID,
265 CERT_DATE_INVALID,
266 CERT_AUTHORITY_INVALID,
267 CERT_NO_REVOCATION_MECHANISM,
268 CERT_UNABLE_TO_CHECK_REVOCATION,
269 CERT_REVOKED,
[email protected]0374b292009-08-14 23:49:19270 CERT_INVALID,
[email protected]aaa20bde2011-12-16 23:27:35271 CERT_WEAK_SIGNATURE_ALGORITHM,
272 CERT_WEAK_KEY
initial.commit09911bf2008-07-26 23:55:29273 };
274 DCHECK(arraysize(kErrorFlags) == arraysize(kErrorTypes));
275
[email protected]8ac1a752008-07-31 19:40:37276 scoped_refptr<net::X509Certificate> cert = NULL;
initial.commit09911bf2008-07-26 23:55:29277 int count = 0;
[email protected]85e0f1f2008-12-17 18:30:28278 for (size_t i = 0; i < arraysize(kErrorFlags); ++i) {
initial.commit09911bf2008-07-26 23:55:29279 if (cert_status & kErrorFlags[i]) {
280 count++;
281 if (!cert.get()) {
[email protected]b59c6cf02012-03-12 20:51:42282 bool r = content::CertStore::GetInstance()->RetrieveCert(
283 cert_id, &cert);
initial.commit09911bf2008-07-26 23:55:29284 DCHECK(r);
285 }
286 if (errors)
[email protected]39790b7f2013-06-03 00:10:59287 errors->push_back(
288 SSLErrorInfo::CreateError(kErrorTypes[i], cert.get(), url));
initial.commit09911bf2008-07-26 23:55:29289 }
290 }
291 return count;
292}