1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ssl/ssl_error_info.h"
7 #include "base/utf_string_conversions.h"
8 #include "chrome/common/time_format.h"
9 #include "content/browser/cert_store.h"
10 #include "googleurl/src/gurl.h"
11 #include "grit/chromium_strings.h"
12 #include "grit/generated_resources.h"
13 #include "net/base/cert_status_flags.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/ssl_info.h"
16 #include "ui/base/l10n/l10n_util.h"
18 SSLErrorInfo::SSLErrorInfo(const string16
& title
,
19 const string16
& details
,
20 const string16
& short_description
,
21 const std::vector
<string16
>& extra_info
)
24 short_description_(short_description
),
25 extra_information_(extra_info
) {
29 SSLErrorInfo
SSLErrorInfo::CreateError(ErrorType error_type
,
30 net::X509Certificate
* cert
,
31 const GURL
& request_url
) {
32 string16 title
, details
, short_description
;
33 std::vector
<string16
> extra_info
;
35 case CERT_COMMON_NAME_INVALID
: {
37 l10n_util::GetStringUTF16(IDS_CERT_ERROR_COMMON_NAME_INVALID_TITLE
);
38 // If the certificate contains multiple DNS names, we choose the most
39 // representative one -- either the DNS name that's also in the subject
40 // field, or the first one. If this heuristic turns out to be
41 // inadequate, we can consider choosing the DNS name that is the
42 // "closest match" to the host name in the request URL, or listing all
43 // the DNS names with an HTML <ul>.
44 std::vector
<std::string
> dns_names
;
45 cert
->GetDNSNames(&dns_names
);
46 DCHECK(!dns_names
.empty());
48 for (; i
< dns_names
.size(); ++i
) {
49 if (dns_names
[i
] == cert
->subject().common_name
)
52 if (i
== dns_names
.size())
55 l10n_util::GetStringFUTF16(IDS_CERT_ERROR_COMMON_NAME_INVALID_DETAILS
,
56 UTF8ToUTF16(request_url
.host()),
57 UTF8ToUTF16(dns_names
[i
]),
58 UTF8ToUTF16(request_url
.host()));
59 short_description
= l10n_util::GetStringUTF16(
60 IDS_CERT_ERROR_COMMON_NAME_INVALID_DESCRIPTION
);
62 l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1
));
64 l10n_util::GetStringFUTF16(
65 IDS_CERT_ERROR_COMMON_NAME_INVALID_EXTRA_INFO_2
,
66 UTF8ToUTF16(cert
->subject().common_name
),
67 UTF8ToUTF16(request_url
.host())));
70 case CERT_DATE_INVALID
:
72 l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1
));
73 if (cert
->HasExpired()) {
74 title
= l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXPIRED_TITLE
);
75 details
= l10n_util::GetStringFUTF16(IDS_CERT_ERROR_EXPIRED_DETAILS
,
76 UTF8ToUTF16(request_url
.host()),
77 UTF8ToUTF16(request_url
.host()));
79 l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXPIRED_DESCRIPTION
);
80 extra_info
.push_back(l10n_util::GetStringUTF16(
81 IDS_CERT_ERROR_EXPIRED_DETAILS_EXTRA_INFO_2
));
83 // Then it must be not yet valid. We don't check that it is not yet
84 // valid as there is still a very unlikely chance that the cert might
85 // have become valid since the error occurred.
86 title
= l10n_util::GetStringUTF16(IDS_CERT_ERROR_NOT_YET_VALID_TITLE
);
87 details
= l10n_util::GetStringFUTF16(
88 IDS_CERT_ERROR_NOT_YET_VALID_DETAILS
,
89 UTF8ToUTF16(request_url
.host()),
90 UTF8ToUTF16(request_url
.host()));
92 l10n_util::GetStringUTF16(IDS_CERT_ERROR_NOT_YET_VALID_DESCRIPTION
);
94 l10n_util::GetStringUTF16(
95 IDS_CERT_ERROR_NOT_YET_VALID_DETAILS_EXTRA_INFO_2
));
98 case CERT_AUTHORITY_INVALID
:
99 title
= l10n_util::GetStringUTF16(IDS_CERT_ERROR_AUTHORITY_INVALID_TITLE
);
100 details
= l10n_util::GetStringFUTF16(
101 IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS
,
102 UTF8ToUTF16(request_url
.host()));
103 short_description
= l10n_util::GetStringUTF16(
104 IDS_CERT_ERROR_AUTHORITY_INVALID_DESCRIPTION
);
105 extra_info
.push_back(
106 l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1
));
107 extra_info
.push_back(l10n_util::GetStringFUTF16(
108 IDS_CERT_ERROR_AUTHORITY_INVALID_EXTRA_INFO_2
,
109 UTF8ToUTF16(request_url
.host()),
110 UTF8ToUTF16(request_url
.host())));
111 extra_info
.push_back(l10n_util::GetStringUTF16(
112 IDS_CERT_ERROR_AUTHORITY_INVALID_EXTRA_INFO_3
));
114 case CERT_CONTAINS_ERRORS
:
115 title
= l10n_util::GetStringUTF16(IDS_CERT_ERROR_CONTAINS_ERRORS_TITLE
);
116 details
= l10n_util::GetStringFUTF16(
117 IDS_CERT_ERROR_CONTAINS_ERRORS_DETAILS
,
118 UTF8ToUTF16(request_url
.host()));
120 l10n_util::GetStringUTF16(IDS_CERT_ERROR_CONTAINS_ERRORS_DESCRIPTION
);
121 extra_info
.push_back(
122 l10n_util::GetStringFUTF16(IDS_CERT_ERROR_EXTRA_INFO_1
,
123 UTF8ToUTF16(request_url
.host())));
124 extra_info
.push_back(l10n_util::GetStringUTF16(
125 IDS_CERT_ERROR_CONTAINS_ERRORS_EXTRA_INFO_2
));
127 case CERT_NO_REVOCATION_MECHANISM
:
128 title
= l10n_util::GetStringUTF16(
129 IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_TITLE
);
130 details
= l10n_util::GetStringUTF16(
131 IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DETAILS
);
132 short_description
= l10n_util::GetStringUTF16(
133 IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DESCRIPTION
);
135 case CERT_UNABLE_TO_CHECK_REVOCATION
:
136 title
= l10n_util::GetStringUTF16(
137 IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_TITLE
);
138 details
= l10n_util::GetStringUTF16(
139 IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DETAILS
);
140 short_description
= l10n_util::GetStringUTF16(
141 IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DESCRIPTION
);
144 title
= l10n_util::GetStringUTF16(IDS_CERT_ERROR_REVOKED_CERT_TITLE
);
145 details
= l10n_util::GetStringFUTF16(IDS_CERT_ERROR_REVOKED_CERT_DETAILS
,
146 UTF8ToUTF16(request_url
.host()));
148 l10n_util::GetStringUTF16(IDS_CERT_ERROR_REVOKED_CERT_DESCRIPTION
);
149 extra_info
.push_back(
150 l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1
));
151 extra_info
.push_back(
152 l10n_util::GetStringUTF16(IDS_CERT_ERROR_REVOKED_CERT_EXTRA_INFO_2
));
155 title
= l10n_util::GetStringUTF16(IDS_CERT_ERROR_INVALID_CERT_TITLE
);
156 details
= l10n_util::GetStringFUTF16(
157 IDS_CERT_ERROR_INVALID_CERT_DETAILS
,
158 UTF8ToUTF16(request_url
.host()));
160 l10n_util::GetStringUTF16(IDS_CERT_ERROR_INVALID_CERT_DESCRIPTION
);
161 extra_info
.push_back(
162 l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1
));
163 extra_info
.push_back(l10n_util::GetStringUTF16(
164 IDS_CERT_ERROR_INVALID_CERT_EXTRA_INFO_2
));
166 case CERT_WEAK_SIGNATURE_ALGORITHM
:
167 title
= l10n_util::GetStringUTF16(
168 IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_TITLE
);
169 details
= l10n_util::GetStringFUTF16(
170 IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DETAILS
,
171 UTF8ToUTF16(request_url
.host()));
172 short_description
= l10n_util::GetStringUTF16(
173 IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DESCRIPTION
);
174 extra_info
.push_back(
175 l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1
));
176 extra_info
.push_back(
177 l10n_util::GetStringUTF16(
178 IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_EXTRA_INFO_2
));
181 title
= l10n_util::GetStringUTF16(IDS_CERT_ERROR_WEAK_KEY_TITLE
);
182 details
= l10n_util::GetStringFUTF16(
183 IDS_CERT_ERROR_WEAK_KEY_DETAILS
, UTF8ToUTF16(request_url
.host()));
184 short_description
= l10n_util::GetStringUTF16(
185 IDS_CERT_ERROR_WEAK_KEY_DESCRIPTION
);
186 extra_info
.push_back(
187 l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1
));
188 extra_info
.push_back(
189 l10n_util::GetStringUTF16(
190 IDS_CERT_ERROR_WEAK_KEY_EXTRA_INFO_2
));
192 case CERT_NOT_IN_DNS
:
193 title
= l10n_util::GetStringUTF16(IDS_CERT_ERROR_NOT_IN_DNS_TITLE
);
194 details
= l10n_util::GetStringUTF16(IDS_CERT_ERROR_NOT_IN_DNS_DETAILS
);
195 short_description
= l10n_util::GetStringUTF16(
196 IDS_CERT_ERROR_NOT_IN_DNS_DESCRIPTION
);
197 extra_info
.push_back(
198 l10n_util::GetStringUTF16(IDS_CERT_ERROR_NOT_IN_DNS_EXTRA_INFO
));
201 title
= l10n_util::GetStringUTF16(IDS_CERT_ERROR_UNKNOWN_ERROR_TITLE
);
202 details
= l10n_util::GetStringUTF16(IDS_CERT_ERROR_UNKNOWN_ERROR_DETAILS
);
204 l10n_util::GetStringUTF16(IDS_CERT_ERROR_UNKNOWN_ERROR_DESCRIPTION
);
209 return SSLErrorInfo(title
, details
, short_description
, extra_info
);
212 SSLErrorInfo::~SSLErrorInfo() {
216 SSLErrorInfo::ErrorType
SSLErrorInfo::NetErrorToErrorType(int net_error
) {
218 case net::ERR_CERT_COMMON_NAME_INVALID
:
219 return CERT_COMMON_NAME_INVALID
;
220 case net::ERR_CERT_DATE_INVALID
:
221 return CERT_DATE_INVALID
;
222 case net::ERR_CERT_AUTHORITY_INVALID
:
223 return CERT_AUTHORITY_INVALID
;
224 case net::ERR_CERT_CONTAINS_ERRORS
:
225 return CERT_CONTAINS_ERRORS
;
226 case net::ERR_CERT_NO_REVOCATION_MECHANISM
:
227 return CERT_NO_REVOCATION_MECHANISM
;
228 case net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION
:
229 return CERT_UNABLE_TO_CHECK_REVOCATION
;
230 case net::ERR_CERT_REVOKED
:
232 case net::ERR_CERT_INVALID
:
234 case net::ERR_CERT_WEAK_SIGNATURE_ALGORITHM
:
235 return CERT_WEAK_SIGNATURE_ALGORITHM
;
236 case net::ERR_CERT_WEAK_KEY
:
237 return CERT_WEAK_KEY
;
238 case net::ERR_CERT_NOT_IN_DNS
:
239 return CERT_NOT_IN_DNS
;
247 int SSLErrorInfo::GetErrorsForCertStatus(int cert_id
,
248 net::CertStatus cert_status
,
250 std::vector
<SSLErrorInfo
>* errors
) {
251 const net::CertStatus kErrorFlags
[] = {
252 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
,
258 net::CERT_STATUS_INVALID
,
259 net::CERT_STATUS_WEAK_SIGNATURE_ALGORITHM
,
260 net::CERT_STATUS_WEAK_KEY
263 const ErrorType kErrorTypes
[] = {
264 CERT_COMMON_NAME_INVALID
,
266 CERT_AUTHORITY_INVALID
,
267 CERT_NO_REVOCATION_MECHANISM
,
268 CERT_UNABLE_TO_CHECK_REVOCATION
,
271 CERT_WEAK_SIGNATURE_ALGORITHM
,
274 DCHECK(arraysize(kErrorFlags
) == arraysize(kErrorTypes
));
276 scoped_refptr
<net::X509Certificate
> cert
= NULL
;
278 for (size_t i
= 0; i
< arraysize(kErrorFlags
); ++i
) {
279 if (cert_status
& kErrorFlags
[i
]) {
282 bool r
= CertStore::GetInstance()->RetrieveCert(cert_id
, &cert
);
286 errors
->push_back(SSLErrorInfo::CreateError(kErrorTypes
[i
], cert
, url
));