blob: 00b04422e20a601fdbba398c18c7dca63f3f9bdd [file] [log] [blame]
Avi Drissman8ba1bad2022-09-13 19:22:361// Copyright 2015 The Chromium Authors
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
felt2493b4452015-09-17 20:33:595#include "components/ssl_errors/error_info.h"
initial.commit09911bf2008-07-26 23:55:296
avif57136c12015-12-25 23:27:457#include <stddef.h>
8
Arthur Sonzogni6718b702025-01-09 10:49:109#include <array>
10
jshin8b581d82015-08-07 10:11:0911#include "base/i18n/message_formatter.h"
Hans Wennborg5bafbb92020-06-18 09:13:5712#include "base/notreached.h"
Ryan Hamilton7f3bd3d2022-04-23 00:07:3913#include "base/strings/escape.h"
[email protected]e309f312013-06-07 21:50:0814#include "base/strings/utf_string_conversions.h"
thakisfe8fa0a2017-02-23 19:46:3615#include "components/strings/grit/components_strings.h"
initial.commit09911bf2008-07-26 23:55:2916#include "net/base/net_errors.h"
[email protected]6e7845ae2013-03-29 21:48:1117#include "net/cert/cert_status_flags.h"
[email protected]536fd0b2013-03-14 17:41:5718#include "net/ssl/ssl_info.h"
[email protected]c051a1b2011-01-21 23:30:1719#include "ui/base/l10n/l10n_util.h"
[email protected]761fa4702013-07-02 15:25:1520#include "url/gurl.h"
initial.commit09911bf2008-07-26 23:55:2921
[email protected]f911df52013-12-24 23:24:2322using base::UTF8ToUTF16;
23
felt2493b4452015-09-17 20:33:5924namespace ssl_errors {
25
Jan Wilken Dörriefa241ba2021-03-11 17:57:0126ErrorInfo::ErrorInfo(const std::u16string& details,
27 const std::u16string& short_description)
felt2493b4452015-09-17 20:33:5928 : details_(details), short_description_(short_description) {}
initial.commit09911bf2008-07-26 23:55:2929
30// static
felt2493b4452015-09-17 20:33:5931ErrorInfo ErrorInfo::CreateError(ErrorType error_type,
32 net::X509Certificate* cert,
33 const GURL& request_url) {
Jan Wilken Dörriefa241ba2021-03-11 17:57:0134 std::u16string details, short_description;
initial.commit09911bf2008-07-26 23:55:2935 switch (error_type) {
36 case CERT_COMMON_NAME_INVALID: {
initial.commit09911bf2008-07-26 23:55:2937 std::vector<std::string> dns_names;
elawrencec7484f52017-04-05 21:46:4238 cert->GetSubjectAltName(&dns_names, nullptr);
39
initial.commit09911bf2008-07-26 23:55:2940 size_t i = 0;
elawrencec7484f52017-04-05 21:46:4241 if (dns_names.empty()) {
42 // The certificate had no DNS names, display an explanatory string.
elawrence71bba342017-05-17 16:19:4343 details = l10n_util::GetStringFUTF16(
44 IDS_CERT_ERROR_NO_SUBJECT_ALTERNATIVE_NAMES_DETAILS,
45 UTF8ToUTF16(request_url.host()));
elawrencec7484f52017-04-05 21:46:4246 } else {
47 // If the certificate contains multiple DNS names, we choose the most
48 // representative one -- either the DNS name that's also in the subject
49 // field, or the first one. If this heuristic turns out to be
50 // inadequate, we can consider choosing the DNS name that is the
51 // "closest match" to the host name in the request URL, or listing all
52 // the DNS names with an HTML <ul>.
53 for (; i < dns_names.size(); ++i) {
54 if (dns_names[i] == cert->subject().common_name)
55 break;
56 }
57 if (i == dns_names.size())
58 i = 0;
elawrence71bba342017-05-17 16:19:4359
60 details = l10n_util::GetStringFUTF16(
61 IDS_CERT_ERROR_COMMON_NAME_INVALID_DETAILS,
62 UTF8ToUTF16(request_url.host()),
Ryan Hamilton7f3bd3d2022-04-23 00:07:3963 base::EscapeForHTML(UTF8ToUTF16(dns_names[i])));
initial.commit09911bf2008-07-26 23:55:2964 }
elawrencec7484f52017-04-05 21:46:4265
[email protected]42197a22010-12-28 23:29:4266 short_description = l10n_util::GetStringUTF16(
67 IDS_CERT_ERROR_COMMON_NAME_INVALID_DESCRIPTION);
initial.commit09911bf2008-07-26 23:55:2968 break;
69 }
70 case CERT_DATE_INVALID:
initial.commit09911bf2008-07-26 23:55:2971 if (cert->HasExpired()) {
fahl0757a442015-04-24 01:43:0972 // Make sure to round up to the smallest integer value not less than
73 // the expiration value (https://crbug.com/476758).
74 int expiration_value =
75 (base::Time::Now() - cert->valid_expiry()).InDays() + 1;
jshin8b581d82015-08-07 10:11:0976 details = base::i18n::MessageFormatter::FormatWithNumberedArgs(
77 l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXPIRED_DETAILS),
78 request_url.host(), expiration_value, base::Time::Now());
initial.commit09911bf2008-07-26 23:55:2979 short_description =
[email protected]42197a22010-12-28 23:29:4280 l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXPIRED_DESCRIPTION);
[email protected]1511b0d2014-08-19 04:02:1081 } else if (base::Time::Now() < cert->valid_start()) {
jshin8b581d82015-08-07 10:11:0982 details = base::i18n::MessageFormatter::FormatWithNumberedArgs(
83 l10n_util::GetStringUTF16(IDS_CERT_ERROR_NOT_YET_VALID_DETAILS),
84 request_url.host(),
85 (cert->valid_start() - base::Time::Now()).InDays());
initial.commit09911bf2008-07-26 23:55:2986 short_description =
[email protected]42197a22010-12-28 23:29:4287 l10n_util::GetStringUTF16(IDS_CERT_ERROR_NOT_YET_VALID_DESCRIPTION);
[email protected]1511b0d2014-08-19 04:02:1088 } else {
89 // Two possibilities: (1) an intermediate or root certificate has
90 // expired, or (2) the certificate has become valid since the error
fahl9d6f4e942015-04-21 03:38:0891 // occurred. Both are probably rare cases. To avoid giving the wrong
92 // date, remove the information.
[email protected]1511b0d2014-08-19 04:02:1093 details = l10n_util::GetStringFUTF16(
fahl9d6f4e942015-04-21 03:38:0894 IDS_CERT_ERROR_NOT_VALID_AT_THIS_TIME_DETAILS,
95 UTF8ToUTF16(request_url.host()));
96 short_description = l10n_util::GetStringUTF16(
97 IDS_CERT_ERROR_NOT_VALID_AT_THIS_TIME_DESCRIPTION);
initial.commit09911bf2008-07-26 23:55:2998 }
99 break;
Ryan Sleevi54fe7662019-11-21 01:31:58100 case CERT_KNOWN_INTERCEPTION_BLOCKED:
initial.commit09911bf2008-07-26 23:55:29101 case CERT_AUTHORITY_INVALID:
Carlos IL9f2a0252025-02-25 22:23:48102 case CERT_SELF_SIGNED_LOCAL_NETWORK:
felt2493b4452015-09-17 20:33:59103 details =
104 l10n_util::GetStringFUTF16(IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS,
105 UTF8ToUTF16(request_url.host()));
[email protected]42197a22010-12-28 23:29:42106 short_description = l10n_util::GetStringUTF16(
107 IDS_CERT_ERROR_AUTHORITY_INVALID_DESCRIPTION);
initial.commit09911bf2008-07-26 23:55:29108 break;
109 case CERT_CONTAINS_ERRORS:
felt2493b4452015-09-17 20:33:59110 details =
111 l10n_util::GetStringFUTF16(IDS_CERT_ERROR_CONTAINS_ERRORS_DETAILS,
112 UTF8ToUTF16(request_url.host()));
initial.commit09911bf2008-07-26 23:55:29113 short_description =
[email protected]42197a22010-12-28 23:29:42114 l10n_util::GetStringUTF16(IDS_CERT_ERROR_CONTAINS_ERRORS_DESCRIPTION);
initial.commit09911bf2008-07-26 23:55:29115 break;
116 case CERT_NO_REVOCATION_MECHANISM:
Matt Mueller936511442019-09-03 18:15:12117 details = l10n_util::GetStringFUTF16(
118 IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DETAILS,
119 UTF8ToUTF16(request_url.host()));
[email protected]42197a22010-12-28 23:29:42120 short_description = l10n_util::GetStringUTF16(
initial.commit09911bf2008-07-26 23:55:29121 IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DESCRIPTION);
122 break;
initial.commit09911bf2008-07-26 23:55:29123 case CERT_REVOKED:
[email protected]42197a22010-12-28 23:29:42124 details = l10n_util::GetStringFUTF16(IDS_CERT_ERROR_REVOKED_CERT_DETAILS,
125 UTF8ToUTF16(request_url.host()));
initial.commit09911bf2008-07-26 23:55:29126 short_description =
[email protected]42197a22010-12-28 23:29:42127 l10n_util::GetStringUTF16(IDS_CERT_ERROR_REVOKED_CERT_DESCRIPTION);
initial.commit09911bf2008-07-26 23:55:29128 break;
129 case CERT_INVALID:
felt2493b4452015-09-17 20:33:59130 details = l10n_util::GetStringFUTF16(IDS_CERT_ERROR_INVALID_CERT_DETAILS,
131 UTF8ToUTF16(request_url.host()));
initial.commit09911bf2008-07-26 23:55:29132 short_description =
[email protected]42197a22010-12-28 23:29:42133 l10n_util::GetStringUTF16(IDS_CERT_ERROR_INVALID_CERT_DESCRIPTION);
initial.commit09911bf2008-07-26 23:55:29134 break;
[email protected]0374b292009-08-14 23:49:19135 case CERT_WEAK_SIGNATURE_ALGORITHM:
[email protected]42197a22010-12-28 23:29:42136 details = l10n_util::GetStringFUTF16(
[email protected]0374b292009-08-14 23:49:19137 IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DETAILS,
[email protected]42197a22010-12-28 23:29:42138 UTF8ToUTF16(request_url.host()));
139 short_description = l10n_util::GetStringUTF16(
[email protected]0374b292009-08-14 23:49:19140 IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DESCRIPTION);
[email protected]0374b292009-08-14 23:49:19141 break;
[email protected]aaa20bde2011-12-16 23:27:35142 case CERT_WEAK_KEY:
felt2493b4452015-09-17 20:33:59143 details = l10n_util::GetStringFUTF16(IDS_CERT_ERROR_WEAK_KEY_DETAILS,
144 UTF8ToUTF16(request_url.host()));
145 short_description =
146 l10n_util::GetStringUTF16(IDS_CERT_ERROR_WEAK_KEY_DESCRIPTION);
[email protected]aaa20bde2011-12-16 23:27:35147 break;
[email protected]f5a393db2013-12-16 18:41:01148 case CERT_NAME_CONSTRAINT_VIOLATION:
[email protected]f5a393db2013-12-16 18:41:01149 details = l10n_util::GetStringFUTF16(
150 IDS_CERT_ERROR_NAME_CONSTRAINT_VIOLATION_DETAILS,
151 UTF8ToUTF16(request_url.host()));
152 short_description = l10n_util::GetStringUTF16(
153 IDS_CERT_ERROR_NAME_CONSTRAINT_VIOLATION_DESCRIPTION);
154 break;
palmer4867d6cc2015-01-28 23:05:09155 case CERT_VALIDITY_TOO_LONG:
156 details =
157 l10n_util::GetStringFUTF16(IDS_CERT_ERROR_VALIDITY_TOO_LONG_DETAILS,
158 UTF8ToUTF16(request_url.host()));
159 short_description = l10n_util::GetStringUTF16(
160 IDS_CERT_ERROR_VALIDITY_TOO_LONG_DESCRIPTION);
161 break;
[email protected]6061c142013-10-21 15:13:34162 case CERT_PINNED_KEY_MISSING:
[email protected]6061c142013-10-21 15:13:34163 details = l10n_util::GetStringUTF16(
felt2493b4452015-09-17 20:33:59164 IDS_CERT_ERROR_SUMMARY_PINNING_FAILURE_DETAILS);
[email protected]6061c142013-10-21 15:13:34165 short_description = l10n_util::GetStringUTF16(
felt2493b4452015-09-17 20:33:59166 IDS_CERT_ERROR_SUMMARY_PINNING_FAILURE_DESCRIPTION);
rsleevi4f8012722014-09-30 01:28:01167 break;
feltf752492a2015-09-14 16:17:35168 case CERT_UNABLE_TO_CHECK_REVOCATION:
Matt Mueller936511442019-09-03 18:15:12169 details = l10n_util::GetStringFUTF16(
170 IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DETAILS,
171 UTF8ToUTF16(request_url.host()));
feltf752492a2015-09-14 16:17:35172 short_description = l10n_util::GetStringUTF16(
173 IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DESCRIPTION);
174 break;
rsleevi41b34612016-06-30 00:18:25175 case CERTIFICATE_TRANSPARENCY_REQUIRED:
176 details = l10n_util::GetStringUTF16(
177 IDS_CERT_ERROR_CERTIFICATE_TRANSPARENCY_REQUIRED_DETAILS);
178 short_description = l10n_util::GetStringUTF16(
179 IDS_CERT_ERROR_CERTIFICATE_TRANSPARENCY_REQUIRED_DESCRIPTION);
180 break;
Emily Stark25f01b82024-04-19 00:04:50181 case CERT_NON_UNIQUE_NAME:
182 details =
183 l10n_util::GetStringFUTF16(IDS_CERT_ERROR_NON_UNIQUE_NAME_DETAILS,
184 UTF8ToUTF16(request_url.host()));
185 short_description =
186 l10n_util::GetStringUTF16(IDS_CERT_ERROR_NON_UNIQUE_NAME_DESCRIPTION);
187 break;
initial.commit09911bf2008-07-26 23:55:29188 case UNKNOWN:
[email protected]42197a22010-12-28 23:29:42189 details = l10n_util::GetStringUTF16(IDS_CERT_ERROR_UNKNOWN_ERROR_DETAILS);
initial.commit09911bf2008-07-26 23:55:29190 short_description =
[email protected]42197a22010-12-28 23:29:42191 l10n_util::GetStringUTF16(IDS_CERT_ERROR_UNKNOWN_ERROR_DESCRIPTION);
initial.commit09911bf2008-07-26 23:55:29192 break;
193 default:
Peter Boström77d21352024-11-13 22:26:11194 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29195 }
felt2493b4452015-09-17 20:33:59196 return ErrorInfo(details, short_description);
initial.commit09911bf2008-07-26 23:55:29197}
198
Sorin Jianuaa967bc2024-10-09 04:44:37199ErrorInfo::~ErrorInfo() = default;
initial.commit09911bf2008-07-26 23:55:29200
201// static
felt2493b4452015-09-17 20:33:59202ErrorInfo::ErrorType ErrorInfo::NetErrorToErrorType(int net_error) {
initial.commit09911bf2008-07-26 23:55:29203 switch (net_error) {
204 case net::ERR_CERT_COMMON_NAME_INVALID:
205 return CERT_COMMON_NAME_INVALID;
206 case net::ERR_CERT_DATE_INVALID:
207 return CERT_DATE_INVALID;
208 case net::ERR_CERT_AUTHORITY_INVALID:
209 return CERT_AUTHORITY_INVALID;
210 case net::ERR_CERT_CONTAINS_ERRORS:
211 return CERT_CONTAINS_ERRORS;
212 case net::ERR_CERT_NO_REVOCATION_MECHANISM:
213 return CERT_NO_REVOCATION_MECHANISM;
214 case net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION:
215 return CERT_UNABLE_TO_CHECK_REVOCATION;
216 case net::ERR_CERT_REVOKED:
217 return CERT_REVOKED;
218 case net::ERR_CERT_INVALID:
219 return CERT_INVALID;
[email protected]0374b292009-08-14 23:49:19220 case net::ERR_CERT_WEAK_SIGNATURE_ALGORITHM:
221 return CERT_WEAK_SIGNATURE_ALGORITHM;
Emily Stark25f01b82024-04-19 00:04:50222 case net::ERR_CERT_NON_UNIQUE_NAME:
223 return CERT_NON_UNIQUE_NAME;
[email protected]aaa20bde2011-12-16 23:27:35224 case net::ERR_CERT_WEAK_KEY:
225 return CERT_WEAK_KEY;
[email protected]f5a393db2013-12-16 18:41:01226 case net::ERR_CERT_NAME_CONSTRAINT_VIOLATION:
227 return CERT_NAME_CONSTRAINT_VIOLATION;
palmer4867d6cc2015-01-28 23:05:09228 case net::ERR_CERT_VALIDITY_TOO_LONG:
229 return CERT_VALIDITY_TOO_LONG;
[email protected]6061c142013-10-21 15:13:34230 case net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN:
231 return CERT_PINNED_KEY_MISSING;
rsleevi41b34612016-06-30 00:18:25232 case net::ERR_CERTIFICATE_TRANSPARENCY_REQUIRED:
233 return CERTIFICATE_TRANSPARENCY_REQUIRED;
Ryan Sleevi54fe7662019-11-21 01:31:58234 case net::ERR_CERT_KNOWN_INTERCEPTION_BLOCKED:
235 return CERT_KNOWN_INTERCEPTION_BLOCKED;
Carlos IL9f2a0252025-02-25 22:23:48236 case net::ERR_CERT_SELF_SIGNED_LOCAL_NETWORK:
237 return CERT_SELF_SIGNED_LOCAL_NETWORK;
initial.commit09911bf2008-07-26 23:55:29238 default:
Peter Boström77d21352024-11-13 22:26:11239 NOTREACHED();
felt2493b4452015-09-17 20:33:59240 }
initial.commit09911bf2008-07-26 23:55:29241}
242
243// static
felt2493b4452015-09-17 20:33:59244void ErrorInfo::GetErrorsForCertStatus(
245 const scoped_refptr<net::X509Certificate>& cert,
246 net::CertStatus cert_status,
247 const GURL& url,
248 std::vector<ErrorInfo>* errors) {
Arthur Sonzogni6718b702025-01-09 10:49:10249 const auto kErrorFlags = std::to_array<net::CertStatus>({
palmer4867d6cc2015-01-28 23:05:09250 net::CERT_STATUS_COMMON_NAME_INVALID,
251 net::CERT_STATUS_DATE_INVALID,
252 net::CERT_STATUS_AUTHORITY_INVALID,
253 net::CERT_STATUS_NO_REVOCATION_MECHANISM,
254 net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION,
255 net::CERT_STATUS_REVOKED,
256 net::CERT_STATUS_INVALID,
257 net::CERT_STATUS_WEAK_SIGNATURE_ALGORITHM,
Emily Stark25f01b82024-04-19 00:04:50258 net::CERT_STATUS_NON_UNIQUE_NAME,
palmer4867d6cc2015-01-28 23:05:09259 net::CERT_STATUS_WEAK_KEY,
260 net::CERT_STATUS_NAME_CONSTRAINT_VIOLATION,
261 net::CERT_STATUS_VALIDITY_TOO_LONG,
rsleevi41b34612016-06-30 00:18:25262 net::CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED,
Ryan Sleevi54fe7662019-11-21 01:31:58263 net::CERT_STATUS_KNOWN_INTERCEPTION_BLOCKED,
Arthur Sonzogni6718b702025-01-09 10:49:10264 });
initial.commit09911bf2008-07-26 23:55:29265
Arthur Sonzogni6718b702025-01-09 10:49:10266 const auto kErrorTypes = std::to_array<ErrorType>({
palmer4867d6cc2015-01-28 23:05:09267 CERT_COMMON_NAME_INVALID,
268 CERT_DATE_INVALID,
269 CERT_AUTHORITY_INVALID,
270 CERT_NO_REVOCATION_MECHANISM,
271 CERT_UNABLE_TO_CHECK_REVOCATION,
272 CERT_REVOKED,
273 CERT_INVALID,
274 CERT_WEAK_SIGNATURE_ALGORITHM,
Emily Stark25f01b82024-04-19 00:04:50275 CERT_NON_UNIQUE_NAME,
palmer4867d6cc2015-01-28 23:05:09276 CERT_WEAK_KEY,
277 CERT_NAME_CONSTRAINT_VIOLATION,
278 CERT_VALIDITY_TOO_LONG,
rsleevi41b34612016-06-30 00:18:25279 CERTIFICATE_TRANSPARENCY_REQUIRED,
Ryan Sleevi54fe7662019-11-21 01:31:58280 CERT_KNOWN_INTERCEPTION_BLOCKED,
Arthur Sonzogni6718b702025-01-09 10:49:10281 });
Daniel Cheng7b7aaecc2022-02-26 17:57:25282 DCHECK(std::size(kErrorFlags) == std::size(kErrorTypes));
initial.commit09911bf2008-07-26 23:55:29283
Daniel Cheng7b7aaecc2022-02-26 17:57:25284 for (size_t i = 0; i < std::size(kErrorFlags); ++i) {
felt2493b4452015-09-17 20:33:59285 if ((cert_status & kErrorFlags[i]) && errors) {
286 errors->push_back(
287 ErrorInfo::CreateError(kErrorTypes[i], cert.get(), url));
initial.commit09911bf2008-07-26 23:55:29288 }
289 }
initial.commit09911bf2008-07-26 23:55:29290}
felt2493b4452015-09-17 20:33:59291
292} // namespace ssl_errors