OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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 #import "ios/web/web_state/ui/crw_web_controller.h" | 5 #import "ios/web/web_state/ui/crw_web_controller.h" |
6 | 6 |
7 #import <WebKit/WebKit.h> | 7 #import <WebKit/WebKit.h> |
8 | 8 |
9 #import <objc/runtime.h> | 9 #import <objc/runtime.h> |
10 #include <stddef.h> | 10 #include <stddef.h> |
(...skipping 4488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4499 [_delegate webControllerDidUpdateSSLStatusForCurrentNavigationItem:self]; | 4499 [_delegate webControllerDidUpdateSSLStatusForCurrentNavigationItem:self]; |
4500 } | 4500 } |
4501 } | 4501 } |
4502 | 4502 |
4503 - (void)handleSSLCertError:(NSError*)error { | 4503 - (void)handleSSLCertError:(NSError*)error { |
4504 CHECK(web::IsWKWebViewSSLCertError(error)); | 4504 CHECK(web::IsWKWebViewSSLCertError(error)); |
4505 | 4505 |
4506 net::SSLInfo info; | 4506 net::SSLInfo info; |
4507 web::GetSSLInfoFromWKWebViewSSLCertError(error, &info); | 4507 web::GetSSLInfoFromWKWebViewSSLCertError(error, &info); |
4508 | 4508 |
4509 // TODO(crbug.com/602298): Remove |status| variable, once |presentSSLError:| | |
4510 // callback is dropped. | |
4511 web::SSLStatus status; | |
4512 status.security_style = web::SECURITY_STYLE_AUTHENTICATION_BROKEN; | |
4513 status.cert_status = info.cert_status; | |
4514 if (!info.cert) { | 4509 if (!info.cert) { |
4515 // |info.cert| can be null if certChain in NSError is empty or can not be | 4510 // |info.cert| can be null if certChain in NSError is empty or can not be |
4516 // parsed, in this case do not ask delegate if error should be allowed, it | 4511 // parsed, in this case do not ask delegate if error should be allowed, it |
4517 // should not be. | 4512 // should not be. |
4518 [self handleLoadError:error inMainFrame:YES]; | 4513 [self handleLoadError:error inMainFrame:YES]; |
4519 return; | 4514 return; |
4520 } | 4515 } |
4521 | 4516 |
4522 status.cert_id = web::CertStore::GetInstance()->StoreCert(info.cert.get(), | 4517 web::CertStore::GetInstance()->StoreCert(info.cert.get(), self.certGroupID); |
4523 self.certGroupID); | |
4524 | 4518 |
4525 // Retrieve verification results from _certVerificationErrors cache to avoid | 4519 // Retrieve verification results from _certVerificationErrors cache to avoid |
4526 // unnecessary recalculations. Verification results are cached for the leaf | 4520 // unnecessary recalculations. Verification results are cached for the leaf |
4527 // cert, because the cert chain in |didReceiveAuthenticationChallenge:| is | 4521 // cert, because the cert chain in |didReceiveAuthenticationChallenge:| is |
4528 // the OS constructed chain, while |chain| is the chain from the server. | 4522 // the OS constructed chain, while |chain| is the chain from the server. |
4529 NSArray* chain = error.userInfo[web::kNSErrorPeerCertificateChainKey]; | 4523 NSArray* chain = error.userInfo[web::kNSErrorPeerCertificateChainKey]; |
4530 NSURL* requestURL = error.userInfo[web::kNSErrorFailingURLKey]; | 4524 NSURL* requestURL = error.userInfo[web::kNSErrorFailingURLKey]; |
4531 NSString* host = [requestURL host]; | 4525 NSString* host = [requestURL host]; |
4532 scoped_refptr<net::X509Certificate> leafCert; | 4526 scoped_refptr<net::X509Certificate> leafCert; |
4533 BOOL recoverable = NO; | 4527 BOOL recoverable = NO; |
4534 if (chain.count && host.length) { | 4528 if (chain.count && host.length) { |
4535 // The complete cert chain may not be available, so the leaf cert is used | 4529 // The complete cert chain may not be available, so the leaf cert is used |
4536 // as a key to retrieve _certVerificationErrors, as well as for storing the | 4530 // as a key to retrieve _certVerificationErrors, as well as for storing the |
4537 // cert decision. | 4531 // cert decision. |
4538 leafCert = web::CreateCertFromChain(@[ chain.firstObject ]); | 4532 leafCert = web::CreateCertFromChain(@[ chain.firstObject ]); |
4539 if (leafCert) { | 4533 if (leafCert) { |
4540 auto error = _certVerificationErrors->Get( | 4534 auto error = _certVerificationErrors->Get( |
4541 {leafCert, base::SysNSStringToUTF8(host)}); | 4535 {leafCert, base::SysNSStringToUTF8(host)}); |
4542 bool cacheHit = error != _certVerificationErrors->end(); | 4536 bool cacheHit = error != _certVerificationErrors->end(); |
4543 if (cacheHit) { | 4537 if (cacheHit) { |
4544 recoverable = error->second.is_recoverable; | 4538 recoverable = error->second.is_recoverable; |
4545 status.cert_status = error->second.status; | |
4546 info.cert_status = error->second.status; | 4539 info.cert_status = error->second.status; |
4547 } | 4540 } |
4548 UMA_HISTOGRAM_BOOLEAN("WebController.CertVerificationErrorsCacheHit", | 4541 UMA_HISTOGRAM_BOOLEAN("WebController.CertVerificationErrorsCacheHit", |
4549 cacheHit); | 4542 cacheHit); |
4550 } | 4543 } |
4551 } | 4544 } |
4552 | 4545 |
4553 // Present SSL interstitial and inform everyone that the load is cancelled. | 4546 // Ask web client if this cert error should be allowed. |
4554 void (^proceedBlock)() = ^{ | 4547 web::GetWebClient()->AllowCertificateError( |
4555 DCHECK(recoverable); | 4548 self.webState, net::MapCertStatusToNetError(info.cert_status), info, |
4556 // The interstitial will be removed during reload. | 4549 net::GURLWithNSURL(requestURL), recoverable, |
4557 [_certVerificationController allowCert:leafCert | 4550 base::BindBlock(^(bool proceed) { |
4558 forHost:host | 4551 if (proceed) { |
4559 status:status.cert_status]; | 4552 DCHECK(recoverable); |
4560 [self loadCurrentURL]; | 4553 [_certVerificationController allowCert:leafCert |
4561 }; | 4554 forHost:host |
4562 // TODO(crbug.com/602298): Remove SSL error API from CRWWebDelegate. | 4555 status:info.cert_status]; |
4563 if ([self.delegate respondsToSelector:@selector(presentSSLError: | 4556 [self loadCurrentURL]; |
4564 forSSLStatus: | 4557 } |
4565 recoverable: | 4558 })); |
4566 callback:)]) { | |
4567 [self.delegate presentSSLError:info | |
4568 forSSLStatus:status | |
4569 recoverable:recoverable | |
4570 callback:^(BOOL proceed) { | |
4571 if (proceed) | |
4572 proceedBlock(); | |
4573 }]; | |
4574 } else { | |
4575 web::GetWebClient()->AllowCertificateError( | |
4576 self.webState, net::MapCertStatusToNetError(info.cert_status), info, | |
4577 net::GURLWithNSURL(requestURL), recoverable, | |
4578 base::BindBlock(^(bool proceed) { | |
4579 if (proceed) | |
4580 proceedBlock(); | |
4581 })); | |
4582 } | |
4583 | 4559 |
4584 [self didUpdateSSLStatusForCurrentNavigationItem]; | 4560 [self didUpdateSSLStatusForCurrentNavigationItem]; |
4585 [self loadCancelled]; | 4561 [self loadCancelled]; |
4586 } | 4562 } |
4587 | 4563 |
4588 - (void)ensureWebViewCreated { | 4564 - (void)ensureWebViewCreated { |
4589 WKWebViewConfiguration* config = | 4565 WKWebViewConfiguration* config = |
4590 [self webViewConfigurationProvider].GetWebViewConfiguration(); | 4566 [self webViewConfigurationProvider].GetWebViewConfiguration(); |
4591 [self ensureWebViewCreatedWithConfiguration:config]; | 4567 [self ensureWebViewCreatedWithConfiguration:config]; |
4592 } | 4568 } |
(...skipping 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5662 } | 5638 } |
5663 | 5639 |
5664 return web::WEB_VIEW_DOCUMENT_TYPE_GENERIC; | 5640 return web::WEB_VIEW_DOCUMENT_TYPE_GENERIC; |
5665 } | 5641 } |
5666 | 5642 |
5667 - (NSString*)refererFromNavigationAction:(WKNavigationAction*)action { | 5643 - (NSString*)refererFromNavigationAction:(WKNavigationAction*)action { |
5668 return [action.request valueForHTTPHeaderField:@"Referer"]; | 5644 return [action.request valueForHTTPHeaderField:@"Referer"]; |
5669 } | 5645 } |
5670 | 5646 |
5671 @end | 5647 @end |
OLD | NEW |