OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 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. | |
4 | |
5 #include "chrome/browser/website_settings_model.h" | |
6 | |
7 #include <string> | |
8 #include <vector> | |
9 | |
10 #include "base/string_number_conversions.h" | |
11 #include "base/utf_string_conversions.h" | |
12 #include "chrome/browser/profiles/profile.h" | |
13 #include "chrome/browser/ssl/ssl_error_info.h" | |
14 #include "content/browser/cert_store.h" | |
15 #include "content/browser/ssl/ssl_manager.h" | |
16 #include "content/public/common/ssl_status.h" | |
17 #include "content/public/common/url_constants.h" | |
18 #include "grit/chromium_strings.h" | |
19 #include "grit/generated_resources.h" | |
20 #include "grit/theme_resources.h" | |
21 #include "net/base/cert_status_flags.h" | |
22 #include "net/base/ssl_cipher_suite_names.h" | |
23 #include "net/base/ssl_connection_status_flags.h" | |
24 #include "net/base/x509_certificate.h" | |
25 #include "ui/base/l10n/l10n_util.h" | |
26 #include "ui/base/resource/resource_bundle.h" | |
27 | |
28 WebsiteSettingsModel::WebsiteSettingsModel(Profile* profile, | |
29 const GURL& url, | |
30 const content::SSLStatus& ssl) | |
31 : site_identity_status_(SITE_IDENTITY_STATUS_NA), | |
32 site_connection_status_(SITE_CONNECTION_STATUS_NA) { | |
33 Init(profile, url, ssl); | |
34 // After initialization there must be a status about the a site's connection | |
wtc
2012/02/15 02:14:29
Typo: the a
Nit: this sentence sounds a little aw
markusheintz_
2012/02/15 19:04:18
Done. Thanks a lot for correcting this.
| |
35 // and it's identity available. | |
36 DCHECK_NE(site_identity_status_, SITE_IDENTITY_STATUS_NA); | |
37 DCHECK_NE(site_connection_status_, SITE_CONNECTION_STATUS_NA); | |
38 } | |
39 | |
40 WebsiteSettingsModel::~WebsiteSettingsModel() { | |
41 } | |
42 | |
43 WebsiteSettingsModel::SiteConnectionStatus | |
44 WebsiteSettingsModel::site_connection_status() const { | |
45 return site_connection_status_; | |
46 } | |
47 | |
48 WebsiteSettingsModel::SiteIdentityStatus | |
49 WebsiteSettingsModel::site_identity_status() const { | |
50 return site_identity_status_; | |
51 } | |
52 | |
53 string16 WebsiteSettingsModel::site_connection_details() const { | |
54 return site_connection_details_; | |
55 } | |
56 | |
57 string16 WebsiteSettingsModel::site_identity_details() const { | |
58 return site_identity_details_; | |
59 } | |
60 | |
61 string16 WebsiteSettingsModel::organization_name() const { | |
wtc
2012/02/15 02:14:29
Nit: why don't you define these five getters in th
markusheintz_
2012/02/15 19:04:18
True. I changed this.
The getters were not define
| |
62 return organization_name_; | |
63 } | |
64 | |
65 void WebsiteSettingsModel::Init(Profile* profile, | |
66 const GURL& url, | |
67 const content::SSLStatus& ssl) { | |
68 if (url.SchemeIs(chrome::kChromeUIScheme)) { | |
69 site_identity_status_ = SITE_IDENTITY_STATUS_INTERNAL_PAGE; | |
70 site_identity_details_ = | |
71 l10n_util::GetStringUTF16(IDS_PAGE_INFO_INTERNAL_PAGE); | |
72 site_connection_status_ = SITE_CONNECTION_STATUS_INTERNAL_PAGE; | |
73 return; | |
74 } | |
75 | |
76 scoped_refptr<net::X509Certificate> cert; | |
77 | |
78 // Identity section. | |
79 string16 subject_name(UTF8ToUTF16(url.host())); | |
80 bool empty_subject_name = false; | |
81 if (subject_name.empty()) { | |
82 subject_name.assign( | |
83 l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY)); | |
84 empty_subject_name = true; | |
85 } | |
86 | |
87 if (ssl.cert_id && | |
88 CertStore::GetInstance()->RetrieveCert(ssl.cert_id, &cert) && | |
89 (!net::IsCertStatusError(ssl.cert_status) || | |
90 net::IsCertStatusMinorError(ssl.cert_status))) { | |
91 // There are no major errors. Check for minor errors. | |
92 if (net::IsCertStatusMinorError(ssl.cert_status)) { | |
93 site_identity_status_ = SITE_IDENTITY_STATUS_CERT_NOT_VERIFIED; | |
94 string16 issuer_name(UTF8ToUTF16(cert->issuer().GetDisplayName())); | |
95 if (issuer_name.empty()) { | |
96 issuer_name.assign(l10n_util::GetStringUTF16( | |
97 IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY)); | |
98 } | |
99 site_identity_details_.assign(l10n_util::GetStringFUTF16( | |
100 IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY, issuer_name)); | |
101 | |
102 site_identity_details_ += ASCIIToUTF16("\n\n"); | |
103 if (ssl.cert_status & net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION) { | |
104 site_identity_details_ += l10n_util::GetStringUTF16( | |
105 IDS_PAGE_INFO_SECURITY_TAB_UNABLE_TO_CHECK_REVOCATION); | |
106 } else if (ssl.cert_status & net::CERT_STATUS_NO_REVOCATION_MECHANISM) { | |
107 site_identity_details_ += l10n_util::GetStringUTF16( | |
108 IDS_PAGE_INFO_SECURITY_TAB_NO_REVOCATION_MECHANISM); | |
109 } else { | |
110 NOTREACHED() << "Need to specify string for this warning"; | |
111 } | |
112 } else if (ssl.cert_status & net::CERT_STATUS_IS_EV) { | |
113 // EV HTTPS page. | |
114 site_identity_status_ = SITE_IDENTITY_STATUS_EV_CERT; | |
115 DCHECK(!cert->subject().organization_names.empty()); | |
116 organization_name_ = UTF8ToUTF16(cert->subject().organization_names[0]); | |
117 // An EV Cert is required to have a city (localityName) and country but | |
118 // state is "if any". | |
119 DCHECK(!cert->subject().locality_name.empty()); | |
120 DCHECK(!cert->subject().country_name.empty()); | |
121 string16 locality; | |
122 if (!cert->subject().state_or_province_name.empty()) { | |
123 locality = l10n_util::GetStringFUTF16( | |
124 IDS_PAGEINFO_ADDRESS, | |
125 UTF8ToUTF16(cert->subject().locality_name), | |
126 UTF8ToUTF16(cert->subject().state_or_province_name), | |
127 UTF8ToUTF16(cert->subject().country_name)); | |
128 } else { | |
129 locality = l10n_util::GetStringFUTF16( | |
130 IDS_PAGEINFO_PARTIAL_ADDRESS, | |
131 UTF8ToUTF16(cert->subject().locality_name), | |
132 UTF8ToUTF16(cert->subject().country_name)); | |
133 } | |
134 DCHECK(!cert->subject().organization_names.empty()); | |
135 site_identity_details_.assign(l10n_util::GetStringFUTF16( | |
136 IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_EV, | |
137 UTF8ToUTF16(cert->subject().organization_names[0]), | |
138 locality, | |
139 UTF8ToUTF16(cert->issuer().GetDisplayName()))); | |
140 } else if (ssl.cert_status & net::CERT_STATUS_IS_DNSSEC) { | |
141 // DNSSEC authenticated page. | |
142 site_identity_status_ = SITE_IDENTITY_STATUS_DNSSEC_CERT; | |
143 site_identity_details_.assign(l10n_util::GetStringFUTF16( | |
144 IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY, UTF8ToUTF16("DNSSEC"))); | |
145 } else { | |
146 // Non-EV OK HTTPS page. | |
147 site_identity_status_ = SITE_IDENTITY_STATUS_CERT; | |
148 string16 issuer_name(UTF8ToUTF16(cert->issuer().GetDisplayName())); | |
149 if (issuer_name.empty()) { | |
150 issuer_name.assign(l10n_util::GetStringUTF16( | |
151 IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY)); | |
152 } | |
153 site_identity_details_.assign(l10n_util::GetStringFUTF16( | |
154 IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY, issuer_name)); | |
155 } | |
156 } else { | |
157 // HTTP or HTTPS with errors (not warnings). | |
158 site_identity_details_.assign(l10n_util::GetStringUTF16( | |
159 IDS_PAGE_INFO_SECURITY_TAB_INSECURE_IDENTITY)); | |
160 if (ssl.security_style == content::SECURITY_STYLE_UNAUTHENTICATED) | |
161 site_identity_status_ = SITE_IDENTITY_STATUS_NO_CERT; | |
162 else | |
163 site_identity_status_ = SITE_IDENTITY_STATUS_ERROR; | |
164 | |
165 const string16 bullet = UTF8ToUTF16("\n • "); | |
166 std::vector<SSLErrorInfo> errors; | |
167 SSLErrorInfo::GetErrorsForCertStatus(ssl.cert_id, ssl.cert_status, | |
168 url, &errors); | |
169 for (size_t i = 0; i < errors.size(); ++i) { | |
170 site_identity_details_ += bullet; | |
171 site_identity_details_ += errors[i].short_description(); | |
172 } | |
173 | |
174 if (ssl.cert_status & net::CERT_STATUS_NON_UNIQUE_NAME) { | |
175 site_identity_details_ += ASCIIToUTF16("\n\n"); | |
176 site_identity_details_ += l10n_util::GetStringUTF16( | |
177 IDS_PAGE_INFO_SECURITY_TAB_NON_UNIQUE_NAME); | |
178 } | |
179 } | |
180 | |
181 // Site Connection | |
182 // We consider anything less than 80 bits encryption to be weak encryption. | |
183 // TODO(wtc): Bug 1198735: report mixed/unsafe content for unencrypted and | |
184 // weakly encrypted connections. | |
185 site_connection_status_ = SITE_CONNECTION_STATUS_NA; | |
186 | |
187 if (!ssl.cert_id) { | |
188 // Not HTTPS. | |
189 DCHECK_EQ(ssl.security_style, content::SECURITY_STYLE_UNAUTHENTICATED); | |
190 if (ssl.security_style == content::SECURITY_STYLE_UNAUTHENTICATED) | |
191 site_connection_status_ = SITE_CONNECTION_STATUS_UNENCRYPTED; | |
192 else | |
193 site_connection_status_ = SITE_CONNECTION_STATUS_ENCRYPTED_ERROR; | |
194 | |
195 site_connection_details_.assign(l10n_util::GetStringFUTF16( | |
196 IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT, | |
197 subject_name)); | |
198 } else if (ssl.security_bits < 0) { | |
199 // Security strength is unknown. Say nothing. | |
200 site_connection_status_ = SITE_CONNECTION_STATUS_ENCRYPTED_ERROR; | |
201 } else if (ssl.security_bits == 0) { | |
202 DCHECK_NE(ssl.security_style, content::SECURITY_STYLE_UNAUTHENTICATED); | |
203 site_connection_status_ = SITE_CONNECTION_STATUS_ENCRYPTED_ERROR; | |
204 site_connection_details_.assign(l10n_util::GetStringFUTF16( | |
205 IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT, | |
206 subject_name)); | |
207 } else if (ssl.security_bits < 80) { | |
208 site_connection_status_ = SITE_CONNECTION_STATUS_ENCRYPTED_ERROR; | |
209 site_connection_details_.assign(l10n_util::GetStringFUTF16( | |
210 IDS_PAGE_INFO_SECURITY_TAB_WEAK_ENCRYPTION_CONNECTION_TEXT, | |
211 subject_name)); | |
212 } else { | |
213 site_connection_status_ = SITE_CONNECTION_STATUS_ENCRYPTED; | |
214 site_connection_details_.assign(l10n_util::GetStringFUTF16( | |
215 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_CONNECTION_TEXT, | |
216 subject_name, | |
217 base::IntToString16(ssl.security_bits))); | |
218 if (ssl.content_status) { | |
219 bool ran_insecure_content = | |
220 !!(ssl.content_status & content::SSLStatus::RAN_INSECURE_CONTENT); | |
221 site_connection_status_ = ran_insecure_content ? | |
222 SITE_CONNECTION_STATUS_ENCRYPTED_ERROR | |
223 : SITE_CONNECTION_STATUS_MIXED_CONTENT; | |
224 site_connection_details_.assign(l10n_util::GetStringFUTF16( | |
225 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK, | |
226 site_connection_details_, | |
227 l10n_util::GetStringUTF16(ran_insecure_content ? | |
228 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_ERROR : | |
229 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_WARNING))); | |
230 } | |
231 } | |
232 | |
233 uint16 cipher_suite = | |
234 net::SSLConnectionStatusToCipherSuite(ssl.connection_status); | |
235 if (ssl.security_bits > 0 && cipher_suite) { | |
236 int ssl_version = | |
237 net::SSLConnectionStatusToVersion(ssl.connection_status); | |
238 const char* ssl_version_str; | |
239 net::SSLVersionToString(&ssl_version_str, ssl_version); | |
240 site_connection_details_ += ASCIIToUTF16("\n\n"); | |
241 site_connection_details_ += l10n_util::GetStringFUTF16( | |
242 IDS_PAGE_INFO_SECURITY_TAB_SSL_VERSION, | |
243 ASCIIToUTF16(ssl_version_str)); | |
244 | |
245 bool did_fallback = (ssl.connection_status & | |
246 net::SSL_CONNECTION_SSL3_FALLBACK) != 0; | |
247 bool no_renegotiation = | |
248 (ssl.connection_status & | |
249 net::SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION) != 0; | |
250 const char *key_exchange, *cipher, *mac; | |
251 net::SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, cipher_suite); | |
252 | |
253 site_connection_details_ += ASCIIToUTF16("\n\n"); | |
254 site_connection_details_ += l10n_util::GetStringFUTF16( | |
255 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTION_DETAILS, | |
256 ASCIIToUTF16(cipher), ASCIIToUTF16(mac), ASCIIToUTF16(key_exchange)); | |
257 | |
258 site_connection_details_ += ASCIIToUTF16("\n\n"); | |
259 uint8 compression_id = | |
260 net::SSLConnectionStatusToCompression(ssl.connection_status); | |
261 if (compression_id) { | |
262 const char* compression; | |
263 net::SSLCompressionToString(&compression, compression_id); | |
264 site_connection_details_ += l10n_util::GetStringFUTF16( | |
265 IDS_PAGE_INFO_SECURITY_TAB_COMPRESSION_DETAILS, | |
266 ASCIIToUTF16(compression)); | |
267 } else { | |
268 site_connection_details_ += l10n_util::GetStringUTF16( | |
269 IDS_PAGE_INFO_SECURITY_TAB_NO_COMPRESSION); | |
270 } | |
271 | |
272 if (did_fallback) { | |
273 // For now, only SSLv3 fallback will trigger a warning icon. | |
274 if (site_connection_status_ < SITE_CONNECTION_STATUS_MIXED_CONTENT) | |
275 site_connection_status_ = SITE_CONNECTION_STATUS_MIXED_CONTENT; | |
276 site_connection_details_ += ASCIIToUTF16("\n\n"); | |
277 site_connection_details_ += l10n_util::GetStringUTF16( | |
278 IDS_PAGE_INFO_SECURITY_TAB_FALLBACK_MESSAGE); | |
279 } | |
280 if (no_renegotiation) { | |
281 site_connection_details_ += ASCIIToUTF16("\n\n"); | |
282 site_connection_details_ += l10n_util::GetStringUTF16( | |
283 IDS_PAGE_INFO_SECURITY_TAB_RENEGOTIATION_MESSAGE); | |
284 } | |
285 } | |
286 } | |
OLD | NEW |