Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ios/chrome/browser/ui/omnibox/page_info_model.h" | 5 #include "ios/chrome/browser/ui/omnibox/page_info_model.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 50 SECTION_INFO_INTERNAL_PAGE, BUTTON_RELOAD)); | 50 SECTION_INFO_INTERNAL_PAGE, BUTTON_RELOAD)); |
| 51 } else { | 51 } else { |
| 52 sections_.push_back( | 52 sections_.push_back( |
| 53 SectionInfo(ICON_STATE_INTERNAL_PAGE, base::string16(), | 53 SectionInfo(ICON_STATE_INTERNAL_PAGE, base::string16(), |
| 54 l10n_util::GetStringUTF16(IDS_PAGE_INFO_INTERNAL_PAGE), | 54 l10n_util::GetStringUTF16(IDS_PAGE_INFO_INTERNAL_PAGE), |
| 55 SECTION_INFO_INTERNAL_PAGE, BUTTON_NONE)); | 55 SECTION_INFO_INTERNAL_PAGE, BUTTON_NONE)); |
| 56 } | 56 } |
| 57 return; | 57 return; |
| 58 } | 58 } |
| 59 | 59 |
| 60 SectionStateIcon icon_id = ICON_STATE_OK; | 60 base::string16 hostname(base::UTF8ToUTF16(url.host())); |
| 61 base::string16 headline; | 61 if (hostname.empty()) { |
| 62 base::string16 description; | 62 hostname.clear(); |
|
rohitrao (ping after 24h)
2017/01/19 01:26:08
What does clear()ing an empty string do?
lgarron
2017/01/19 21:26:20
Ah, uh, nothing? :-P
This is vestigial now, so I'v
| |
| 63 | |
| 64 // Identity section. | |
| 65 base::string16 subject_name(base::UTF8ToUTF16(url.host())); | |
| 66 bool empty_subject_name = false; | |
| 67 if (subject_name.empty()) { | |
| 68 subject_name.assign( | |
| 69 l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY)); | |
| 70 empty_subject_name = true; | |
| 71 } | 63 } |
| 72 | 64 |
| 73 bool is_cert_present = !!ssl.certificate; | 65 base::string16 summary; |
| 74 bool is_major_cert_error = net::IsCertStatusError(ssl.cert_status) && | 66 base::string16 details; |
| 75 !net::IsCertStatusMinorError(ssl.cert_status); | 67 base::string16 certificate_details; |
| 76 | 68 |
| 77 // It is possible to have |SECURITY_STYLE_AUTHENTICATION_BROKEN| and non-error | 69 // Summary and detais. |
|
rohitrao (ping after 24h)
2017/01/19 01:26:08
Typo: details.
lgarron
2017/01/19 21:26:20
Fixed.
| |
| 78 // |cert_status| for WKWebView because |security_style| and |cert_status| are | 70 SectionStateIcon icon_id = ICON_NONE; |
| 79 // calculated using different API, which may lead to different cert | 71 if (!ssl.certificate) { |
| 80 // verification results. | 72 // Not HTTPS. |
| 81 if (is_cert_present && !is_major_cert_error && | 73 icon_id = ICON_STATE_INFO; |
| 82 ssl.security_style != web::SECURITY_STYLE_AUTHENTICATION_BROKEN) { | 74 summary.assign(l10n_util::GetStringUTF16(IDS_PAGEINFO_NOT_SECURE_SUMMARY)); |
| 83 // There are no major errors. Check for minor errors. | 75 details.assign(l10n_util::GetStringUTF16(IDS_PAGEINFO_NOT_SECURE_DETAILS)); |
| 84 if (net::IsCertStatusMinorError(ssl.cert_status)) { | 76 } else { |
|
rohitrao (ping after 24h)
2017/01/19 01:26:08
There are a lot of nested if/else statements, and
lgarron
2017/01/19 21:26:20
Added.
| |
| 77 // It is possible to have |SECURITY_STYLE_AUTHENTICATION_BROKEN| and | |
| 78 // non-error | |
| 79 // |cert_status| for WKWebView because |security_style| and |cert_status| | |
| 80 // are | |
| 81 // calculated using different API, which may lead to different cert | |
| 82 // verification results. | |
| 83 if (net::IsCertStatusError(ssl.cert_status) || | |
| 84 ssl.security_style == web::SECURITY_STYLE_AUTHENTICATION_BROKEN) { | |
| 85 icon_id = ICON_STATE_ERROR; | |
| 86 DCHECK(!net::IsCertStatusMinorError(ssl.cert_status)); | |
| 87 summary.assign( | |
| 88 l10n_util::GetStringUTF16(IDS_PAGEINFO_NOT_SECURE_SUMMARY)); | |
| 89 details.assign( | |
| 90 l10n_util::GetStringUTF16(IDS_PAGEINFO_NOT_SECURE_DETAILS)); | |
| 91 | |
| 92 certificate_details.assign(l10n_util::GetStringUTF16( | |
| 93 IDS_PAGE_INFO_SECURITY_TAB_INSECURE_IDENTITY)); | |
| 94 const base::string16 bullet = base::UTF8ToUTF16("\n • "); | |
| 95 std::vector<ssl_errors::ErrorInfo> errors; | |
| 96 ssl_errors::ErrorInfo::GetErrorsForCertStatus( | |
| 97 ssl.certificate, ssl.cert_status, url, &errors); | |
| 98 for (size_t i = 0; i < errors.size(); ++i) { | |
| 99 certificate_details += bullet; | |
| 100 certificate_details += errors[i].short_description(); | |
| 101 } | |
| 102 } else { | |
| 85 base::string16 issuer_name( | 103 base::string16 issuer_name( |
| 86 base::UTF8ToUTF16(ssl.certificate->issuer().GetDisplayName())); | 104 base::UTF8ToUTF16(ssl.certificate->issuer().GetDisplayName())); |
| 87 if (issuer_name.empty()) { | 105 if (!issuer_name.empty()) { |
| 88 issuer_name.assign(l10n_util::GetStringUTF16( | 106 certificate_details.assign(l10n_util::GetStringFUTF16( |
| 89 IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY)); | 107 IDS_IOS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY, issuer_name)); |
| 90 } | 108 } |
| 91 description.assign(l10n_util::GetStringFUTF16( | 109 if (ssl.content_status == web::SSLStatus::DISPLAYED_INSECURE_CONTENT) { |
| 92 IDS_IOS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY, issuer_name)); | 110 // For WKWebView security_bits flag is always -1, and description is |
| 111 // empty because ciphersuite is unknown. On iOS9 WKWebView blocks active | |
| 112 // mixed content, so warning should be about page look, not about page | |
| 113 // behavior. | |
| 114 icon_id = ICON_STATE_INFO; | |
| 115 summary.assign( | |
| 116 l10n_util::GetStringUTF16(IDS_PAGEINFO_MIXED_CONTENT_SUMMARY)); | |
| 117 details.assign( | |
| 118 l10n_util::GetStringUTF16(IDS_PAGEINFO_MIXED_CONTENT_DETAILS)); | |
| 119 } else { | |
| 120 icon_id = ICON_STATE_OK; | |
| 121 summary.assign(l10n_util::GetStringUTF16(IDS_PAGEINFO_SECURE_SUMMARY)); | |
| 122 details.assign(l10n_util::GetStringUTF16(IDS_PAGEINFO_SECURE_DETAILS)); | |
| 93 | 123 |
| 94 description += base::ASCIIToUTF16("\n\n"); | 124 DCHECK(!(ssl.cert_status & net::CERT_STATUS_IS_EV)) |
| 95 if (ssl.cert_status & net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION) { | 125 << "Extended Validation should be disabled"; |
| 96 description += l10n_util::GetStringUTF16( | |
| 97 IDS_PAGE_INFO_SECURITY_TAB_UNABLE_TO_CHECK_REVOCATION); | |
| 98 } else if (ssl.cert_status & net::CERT_STATUS_NO_REVOCATION_MECHANISM) { | |
| 99 description += l10n_util::GetStringUTF16( | |
| 100 IDS_PAGE_INFO_SECURITY_TAB_NO_REVOCATION_MECHANISM); | |
| 101 } else { | |
| 102 NOTREACHED() << "Need to specify string for this warning"; | |
| 103 } | 126 } |
| 104 icon_id = ICON_STATE_INFO; | |
| 105 } else { | |
| 106 // OK HTTPS page. | |
| 107 DCHECK(!(ssl.cert_status & net::CERT_STATUS_IS_EV)) | |
| 108 << "Extended Validation should be disabled"; | |
| 109 if (empty_subject_name) | |
| 110 headline.clear(); // Don't display any title. | |
| 111 else | |
| 112 headline.assign(subject_name); | |
| 113 base::string16 issuer_name( | |
| 114 base::UTF8ToUTF16(ssl.certificate->issuer().GetDisplayName())); | |
| 115 if (issuer_name.empty()) { | |
| 116 issuer_name.assign(l10n_util::GetStringUTF16( | |
| 117 IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY)); | |
| 118 } | |
| 119 description.assign(l10n_util::GetStringFUTF16( | |
| 120 IDS_IOS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY, issuer_name)); | |
| 121 } | |
| 122 if (ssl.cert_status & net::CERT_STATUS_SHA1_SIGNATURE_PRESENT) { | |
| 123 icon_id = ICON_STATE_INFO; | |
| 124 description += | |
| 125 base::UTF8ToUTF16("\n\n") + | |
| 126 l10n_util::GetStringUTF16( | |
| 127 IDS_PAGE_INFO_SECURITY_TAB_DEPRECATED_SIGNATURE_ALGORITHM); | |
| 128 } | |
| 129 } else { | |
| 130 // HTTP or HTTPS with errors (not warnings). | |
| 131 description.assign(l10n_util::GetStringUTF16( | |
| 132 IDS_PAGE_INFO_SECURITY_TAB_INSECURE_IDENTITY)); | |
| 133 icon_id = ssl.security_style == web::SECURITY_STYLE_UNAUTHENTICATED | |
| 134 ? ICON_STATE_INFO | |
| 135 : ICON_STATE_ERROR; | |
| 136 | |
| 137 const base::string16 bullet = base::UTF8ToUTF16("\n • "); | |
| 138 std::vector<ssl_errors::ErrorInfo> errors; | |
| 139 ssl_errors::ErrorInfo::GetErrorsForCertStatus( | |
| 140 ssl.certificate, ssl.cert_status, url, &errors); | |
| 141 for (size_t i = 0; i < errors.size(); ++i) { | |
| 142 description += bullet; | |
| 143 description += errors[i].short_description(); | |
| 144 } | |
| 145 | |
| 146 if (ssl.cert_status & net::CERT_STATUS_NON_UNIQUE_NAME) { | |
| 147 description += base::ASCIIToUTF16("\n\n"); | |
| 148 description += | |
| 149 l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_NON_UNIQUE_NAME); | |
| 150 } | |
| 151 } | |
| 152 sections_.push_back(SectionInfo(icon_id, headline, description, | |
| 153 SECTION_INFO_IDENTITY, | |
| 154 BUTTON_SHOW_SECURITY_HELP)); | |
| 155 | |
| 156 // Connection section. | |
| 157 icon_id = ICON_STATE_OK; | |
| 158 headline.clear(); | |
| 159 description.clear(); | |
| 160 if (!ssl.certificate) { | |
| 161 // Not HTTPS. | |
| 162 icon_id = ssl.security_style == web::SECURITY_STYLE_UNAUTHENTICATED | |
| 163 ? ICON_STATE_INFO | |
| 164 : ICON_STATE_ERROR; | |
| 165 description.assign( | |
| 166 l10n_util::GetStringUTF16(IDS_PAGEINFO_NOT_SECURE_SUMMARY)); | |
| 167 description += base::ASCIIToUTF16("\n\n"); | |
| 168 description += l10n_util::GetStringUTF16(IDS_PAGEINFO_NOT_SECURE_DETAILS); | |
| 169 } else if (ssl.security_bits < 0) { | |
| 170 if (ssl.content_status == web::SSLStatus::DISPLAYED_INSECURE_CONTENT) { | |
| 171 DCHECK(description.empty()); | |
| 172 // For WKWebView security_bits flag is always -1, and description is empty | |
| 173 // because ciphersuite is unknown. On iOS9 WKWebView blocks active | |
| 174 // mixed content, so warning should be about page look, not about page | |
| 175 // behavior. | |
| 176 icon_id = ICON_NONE; | |
| 177 description.assign(l10n_util::GetStringUTF16( | |
| 178 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_WARNING)); | |
| 179 } else { | |
| 180 // Security strength is unknown. Say nothing. | |
| 181 icon_id = ICON_STATE_ERROR; | |
| 182 } | |
| 183 } else if (ssl.security_bits == 0) { | |
| 184 DCHECK_NE(ssl.security_style, web::SECURITY_STYLE_UNAUTHENTICATED); | |
| 185 icon_id = ICON_STATE_ERROR; | |
| 186 description.assign(l10n_util::GetStringFUTF16( | |
| 187 IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT, | |
| 188 subject_name)); | |
| 189 } else { | |
| 190 if (net::SSLConnectionStatusToVersion(ssl.connection_status) >= | |
| 191 net::SSL_CONNECTION_VERSION_TLS1_2 && | |
| 192 (net::OBSOLETE_SSL_NONE == | |
| 193 net::ObsoleteSSLStatus( | |
| 194 net::SSLConnectionStatusToCipherSuite(ssl.connection_status)))) { | |
| 195 description.assign(l10n_util::GetStringFUTF16( | |
| 196 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_CONNECTION_TEXT, subject_name)); | |
| 197 } else { | |
| 198 description.assign(l10n_util::GetStringFUTF16( | |
| 199 IDS_PAGE_INFO_SECURITY_TAB_WEAK_ENCRYPTION_CONNECTION_TEXT, | |
| 200 subject_name)); | |
| 201 } | |
| 202 if (ssl.content_status) { | |
| 203 bool ran_insecure_content = false; // Always false on iOS. | |
| 204 icon_id = ran_insecure_content ? ICON_STATE_ERROR : ICON_NONE; | |
| 205 description.assign(l10n_util::GetStringFUTF16( | |
| 206 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK, description, | |
| 207 l10n_util::GetStringUTF16( | |
| 208 ran_insecure_content | |
| 209 ? IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_ERROR | |
| 210 : IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_WARNIN G))); | |
| 211 } | 127 } |
| 212 } | 128 } |
| 213 | 129 |
| 214 uint16_t cipher_suite = | 130 base::string16 description; |
| 215 net::SSLConnectionStatusToCipherSuite(ssl.connection_status); | 131 base::string16 spacer = base::UTF8ToUTF16("\n\n"); |
| 216 if (ssl.security_bits > 0 && cipher_suite) { | |
| 217 int ssl_version = net::SSLConnectionStatusToVersion(ssl.connection_status); | |
| 218 const char* ssl_version_str; | |
| 219 net::SSLVersionToString(&ssl_version_str, ssl_version); | |
| 220 description += base::ASCIIToUTF16("\n\n"); | |
| 221 description += | |
| 222 l10n_util::GetStringFUTF16(IDS_PAGE_INFO_SECURITY_TAB_SSL_VERSION, | |
| 223 base::ASCIIToUTF16(ssl_version_str)); | |
| 224 | 132 |
| 225 bool no_renegotiation = | 133 description.assign(summary); |
| 226 (ssl.connection_status & | 134 description += spacer; |
| 227 net::SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION) != 0; | 135 description += details; |
| 228 const char *key_exchange, *cipher, *mac; | |
| 229 bool is_aead; | |
| 230 bool is_tls13; | |
| 231 net::SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, | |
| 232 &is_tls13, cipher_suite); | |
| 233 | 136 |
| 234 description += base::ASCIIToUTF16("\n\n"); | 137 if (!certificate_details.empty()) { |
| 235 if (is_aead) { | 138 description += spacer; |
| 236 description += l10n_util::GetStringFUTF16( | 139 description += certificate_details; |
| 237 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTION_DETAILS_AEAD, | |
| 238 base::ASCIIToUTF16(cipher), base::ASCIIToUTF16(key_exchange)); | |
| 239 } else { | |
| 240 description += l10n_util::GetStringFUTF16( | |
| 241 IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTION_DETAILS, | |
| 242 base::ASCIIToUTF16(cipher), base::ASCIIToUTF16(mac), | |
| 243 base::ASCIIToUTF16(key_exchange)); | |
| 244 } | |
| 245 | |
| 246 if (no_renegotiation) { | |
| 247 description += base::ASCIIToUTF16("\n\n"); | |
| 248 description += l10n_util::GetStringUTF16( | |
| 249 IDS_PAGE_INFO_SECURITY_TAB_RENEGOTIATION_MESSAGE); | |
| 250 } | |
| 251 } | 140 } |
| 252 | 141 |
| 253 if (!description.empty()) { | 142 sections_.push_back(SectionInfo(icon_id, hostname, description, |
| 254 sections_.push_back(SectionInfo(icon_id, headline, description, | 143 SECTION_INFO_CONNECTION, |
| 255 SECTION_INFO_CONNECTION, | 144 BUTTON_SHOW_SECURITY_HELP)); |
| 256 BUTTON_SHOW_SECURITY_HELP)); | |
| 257 } | |
| 258 | |
| 259 if (ssl.certificate) { | |
| 260 certificate_label_ = | |
| 261 l10n_util::GetStringUTF16(IDS_PAGEINFO_CERT_INFO_BUTTON); | |
| 262 } | |
| 263 } | 145 } |
| 264 | 146 |
| 265 PageInfoModel::~PageInfoModel() {} | 147 PageInfoModel::~PageInfoModel() {} |
| 266 | 148 |
| 267 int PageInfoModel::GetSectionCount() { | 149 int PageInfoModel::GetSectionCount() { |
| 268 return sections_.size(); | 150 return sections_.size(); |
| 269 } | 151 } |
| 270 | 152 |
| 271 PageInfoModel::SectionInfo PageInfoModel::GetSectionInfo(int index) { | 153 PageInfoModel::SectionInfo PageInfoModel::GetSectionInfo(int index) { |
| 272 DCHECK(index < static_cast<int>(sections_.size())); | 154 DCHECK(index < static_cast<int>(sections_.size())); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 288 case ICON_STATE_OFFLINE_PAGE: | 170 case ICON_STATE_OFFLINE_PAGE: |
| 289 return &rb.GetNativeImageNamed(IDR_IOS_OMNIBOX_OFFLINE); | 171 return &rb.GetNativeImageNamed(IDR_IOS_OMNIBOX_OFFLINE); |
| 290 } | 172 } |
| 291 } | 173 } |
| 292 | 174 |
| 293 base::string16 PageInfoModel::GetCertificateLabel() const { | 175 base::string16 PageInfoModel::GetCertificateLabel() const { |
| 294 return certificate_label_; | 176 return certificate_label_; |
| 295 } | 177 } |
| 296 | 178 |
| 297 PageInfoModel::PageInfoModel() : observer_(NULL) {} | 179 PageInfoModel::PageInfoModel() : observer_(NULL) {} |
| OLD | NEW |