blob: 34a074bac8d8be4cd5ac0a23cf3f4c157024d7d0 [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 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.
initial.commit09911bf2008-07-26 23:55:294
5#include "chrome/browser/ssl_error_info.h"
6
7#include "base/string_util.h"
8#include "chrome/browser/cert_store.h"
9#include "chrome/common/l10n_util.h"
10#include "chrome/common/resource_bundle.h"
11#include "chrome/common/time_format.h"
12#include "net/base/cert_status_flags.h"
13#include "net/base/net_errors.h"
14#include "net/base/ssl_info.h"
[email protected]46072d42008-07-28 14:49:3515#include "googleurl/src/gurl.h"
16
initial.commit09911bf2008-07-26 23:55:2917#include "generated_resources.h"
18
19SSLErrorInfo::SSLErrorInfo(const std::wstring& title,
20 const std::wstring& details,
21 const std::wstring& short_description,
22 const std::vector<std::wstring>& extra_info)
23 : title_(title),
24 details_(details),
25 short_description_(short_description),
26 extra_information_(extra_info) {
27}
28
29// static
30SSLErrorInfo SSLErrorInfo::CreateError(ErrorType error_type,
[email protected]8ac1a752008-07-31 19:40:3731 net::X509Certificate* cert,
initial.commit09911bf2008-07-26 23:55:2932 const GURL& request_url) {
33 std::wstring title, details, short_description;
34 std::vector<std::wstring> extra_info;
35 switch (error_type) {
36 case CERT_COMMON_NAME_INVALID: {
37 title = l10n_util::GetString(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());
47 size_t i = 0;
48 for (; i < dns_names.size(); ++i) {
49 if (dns_names[i] == cert->subject().common_name)
50 break;
51 }
52 if (i == dns_names.size())
53 i = 0;
54 details =
55 l10n_util::GetStringF(IDS_CERT_ERROR_COMMON_NAME_INVALID_DETAILS,
56 UTF8ToWide(request_url.host()),
57 UTF8ToWide(dns_names[i]),
58 UTF8ToWide(request_url.host()));
59 short_description =
60 l10n_util::GetString(IDS_CERT_ERROR_COMMON_NAME_INVALID_DESCRIPTION);
61 extra_info.push_back(
62 l10n_util::GetString(IDS_CERT_ERROR_EXTRA_INFO_1));
63 extra_info.push_back(
64 l10n_util::GetStringF(
65 IDS_CERT_ERROR_COMMON_NAME_INVALID_EXTRA_INFO_2,
66 UTF8ToWide(cert->subject().common_name),
67 UTF8ToWide(request_url.host())));
68 break;
69 }
70 case CERT_DATE_INVALID:
71 extra_info.push_back(
72 l10n_util::GetString(IDS_CERT_ERROR_EXTRA_INFO_1));
73 if (cert->HasExpired()) {
74 title = l10n_util::GetString(IDS_CERT_ERROR_EXPIRED_TITLE);
75 details = l10n_util::GetStringF(IDS_CERT_ERROR_EXPIRED_DETAILS,
76 UTF8ToWide(request_url.host()),
77 UTF8ToWide(request_url.host()));
78 short_description =
79 l10n_util::GetString(IDS_CERT_ERROR_EXPIRED_DESCRIPTION);
80 extra_info.push_back(
81 l10n_util::GetString(IDS_CERT_ERROR_EXPIRED_DETAILS_EXTRA_INFO_2));
82 } else {
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::GetString(IDS_CERT_ERROR_NOT_YET_VALID_TITLE);
87 details = l10n_util::GetStringF(IDS_CERT_ERROR_NOT_YET_VALID_DETAILS,
88 UTF8ToWide(request_url.host()),
89 UTF8ToWide(request_url.host()));
90 short_description =
91 l10n_util::GetString(IDS_CERT_ERROR_NOT_YET_VALID_DESCRIPTION);
92 extra_info.push_back(
93 l10n_util::GetString(
94 IDS_CERT_ERROR_NOT_YET_VALID_DETAILS_EXTRA_INFO_2));
95 }
96 break;
97 case CERT_AUTHORITY_INVALID:
98 title = l10n_util::GetString(IDS_CERT_ERROR_AUTHORITY_INVALID_TITLE);
99 details = l10n_util::GetStringF(IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS,
100 UTF8ToWide(request_url.host()));
101 short_description =
102 l10n_util::GetString(IDS_CERT_ERROR_AUTHORITY_INVALID_DESCRIPTION);
103 extra_info.push_back(
104 l10n_util::GetString(IDS_CERT_ERROR_EXTRA_INFO_1));
105 extra_info.push_back(
106 l10n_util::GetStringF(IDS_CERT_ERROR_AUTHORITY_INVALID_EXTRA_INFO_2,
107 UTF8ToWide(request_url.host()),
108 UTF8ToWide(request_url.host())));
109 extra_info.push_back(
110 l10n_util::GetString(IDS_CERT_ERROR_AUTHORITY_INVALID_EXTRA_INFO_3));
111 break;
112 case CERT_CONTAINS_ERRORS:
113 title = l10n_util::GetString(IDS_CERT_ERROR_CONTAINS_ERRORS_TITLE);
114 details = l10n_util::GetStringF(IDS_CERT_ERROR_CONTAINS_ERRORS_DETAILS,
115 UTF8ToWide(request_url.host()));
116 short_description =
117 l10n_util::GetString(IDS_CERT_ERROR_CONTAINS_ERRORS_DESCRIPTION);
118 extra_info.push_back(
119 l10n_util::GetStringF(IDS_CERT_ERROR_EXTRA_INFO_1,
120 UTF8ToWide(request_url.host())));
121 extra_info.push_back(
122 l10n_util::GetString(IDS_CERT_ERROR_CONTAINS_ERRORS_EXTRA_INFO_2));
123 break;
124 case CERT_NO_REVOCATION_MECHANISM:
125 title =
126 l10n_util::GetString(IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_TITLE);
127 details =
128 l10n_util::GetString(IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DETAILS);
129 short_description = l10n_util::GetString(
130 IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DESCRIPTION);
131 break;
132 case CERT_UNABLE_TO_CHECK_REVOCATION:
133 title =
134 l10n_util::GetString(IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_TITLE);
135 details = l10n_util::GetString(
136 IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DETAILS);
137 short_description = l10n_util::GetString(
138 IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DESCRIPTION);
139 break;
140 case CERT_REVOKED:
141 title = l10n_util::GetString(IDS_CERT_ERROR_REVOKED_CERT_TITLE);
142 details = l10n_util::GetStringF(IDS_CERT_ERROR_REVOKED_CERT_DETAILS,
143 UTF8ToWide(request_url.host()));
144 short_description =
145 l10n_util::GetString(IDS_CERT_ERROR_REVOKED_CERT_DESCRIPTION);
146 extra_info.push_back(
147 l10n_util::GetString(IDS_CERT_ERROR_EXTRA_INFO_1));
148 extra_info.push_back(
149 l10n_util::GetString(IDS_CERT_ERROR_REVOKED_CERT_EXTRA_INFO_2));
150 break;
151 case CERT_INVALID:
152 title = l10n_util::GetString(IDS_CERT_ERROR_INVALID_CERT_TITLE);
153 details = l10n_util::GetString(IDS_CERT_ERROR_INVALID_CERT_DETAILS);
154 short_description =
155 l10n_util::GetString(IDS_CERT_ERROR_INVALID_CERT_DESCRIPTION);
156 break;
157 case MIXED_CONTENTS:
158 title = l10n_util::GetString(IDS_SSL_MIXED_CONTENT_TITLE);
159 details = l10n_util::GetString(IDS_SSL_MIXED_CONTENT_DETAILS);
160 short_description =
161 l10n_util::GetString(IDS_SSL_MIXED_CONTENT_DESCRIPTION);
162 break;
163 case UNSAFE_CONTENTS:
164 title = l10n_util::GetString(IDS_SSL_UNSAFE_CONTENT_TITLE);
165 details = l10n_util::GetString(IDS_SSL_UNSAFE_CONTENT_DETAILS);
166 short_description =
167 l10n_util::GetString(IDS_SSL_UNSAFE_CONTENT_DESCRIPTION);
168 break;
169 case UNKNOWN:
170 title = l10n_util::GetString(IDS_CERT_ERROR_UNKNOWN_ERROR_TITLE);
171 details = l10n_util::GetString(IDS_CERT_ERROR_UNKNOWN_ERROR_DETAILS);
172 short_description =
173 l10n_util::GetString(IDS_CERT_ERROR_UNKNOWN_ERROR_DESCRIPTION);
174 break;
175 default:
176 NOTREACHED();
177 }
178 return SSLErrorInfo(title, details, short_description, extra_info);
179}
180
181SSLErrorInfo::~SSLErrorInfo() {
182}
183
184// static
185SSLErrorInfo::ErrorType SSLErrorInfo::NetErrorToErrorType(int net_error) {
186 switch (net_error) {
187 case net::ERR_CERT_COMMON_NAME_INVALID:
188 return CERT_COMMON_NAME_INVALID;
189 case net::ERR_CERT_DATE_INVALID:
190 return CERT_DATE_INVALID;
191 case net::ERR_CERT_AUTHORITY_INVALID:
192 return CERT_AUTHORITY_INVALID;
193 case net::ERR_CERT_CONTAINS_ERRORS:
194 return CERT_CONTAINS_ERRORS;
195 case net::ERR_CERT_NO_REVOCATION_MECHANISM:
196 return CERT_NO_REVOCATION_MECHANISM;
197 case net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION:
198 return CERT_UNABLE_TO_CHECK_REVOCATION;
199 case net::ERR_CERT_REVOKED:
200 return CERT_REVOKED;
201 case net::ERR_CERT_INVALID:
202 return CERT_INVALID;
203 default:
204 NOTREACHED();
205 return UNKNOWN;
206 }
207}
208
209// static
210int SSLErrorInfo::GetErrorsForCertStatus(int cert_id,
211 int cert_status,
212 const GURL& url,
213 std::vector<SSLErrorInfo>* errors) {
214 const int kErrorFlags[] = {
215 net::CERT_STATUS_COMMON_NAME_INVALID,
216 net::CERT_STATUS_DATE_INVALID,
217 net::CERT_STATUS_AUTHORITY_INVALID,
218 net::CERT_STATUS_NO_REVOCATION_MECHANISM,
219 net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION,
220 net::CERT_STATUS_REVOKED,
221 net::CERT_STATUS_INVALID
222 };
223
224 const ErrorType kErrorTypes[] = {
225 CERT_COMMON_NAME_INVALID,
226 CERT_DATE_INVALID,
227 CERT_AUTHORITY_INVALID,
228 CERT_NO_REVOCATION_MECHANISM,
229 CERT_UNABLE_TO_CHECK_REVOCATION,
230 CERT_REVOKED,
231 CERT_INVALID
232 };
233 DCHECK(arraysize(kErrorFlags) == arraysize(kErrorTypes));
234
[email protected]8ac1a752008-07-31 19:40:37235 scoped_refptr<net::X509Certificate> cert = NULL;
initial.commit09911bf2008-07-26 23:55:29236 int count = 0;
237 for (int i = 0; i < arraysize(kErrorFlags); ++i) {
238 if (cert_status & kErrorFlags[i]) {
239 count++;
240 if (!cert.get()) {
241 bool r = CertStore::GetSharedInstance()->RetrieveCert(cert_id, &cert);
242 DCHECK(r);
243 }
244 if (errors)
245 errors->push_back(SSLErrorInfo::CreateError(kErrorTypes[i], cert, url));
246 }
247 }
248 return count;
249}
license.botbf09a502008-08-24 00:55:55250