| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/net/crw_cert_verification_controller.h" | 5 #import "ios/web/net/crw_cert_verification_controller.h" |
| 6 | 6 |
| 7 #include "base/mac/bind_objc_block.h" | 7 #include "base/mac/bind_objc_block.h" |
| 8 #import "base/memory/ref_counted.h" | 8 #import "base/memory/ref_counted.h" |
| 9 #import "base/memory/scoped_ptr.h" | 9 #import "base/memory/scoped_ptr.h" |
| 10 #include "base/strings/sys_string_conversions.h" | 10 #include "base/strings/sys_string_conversions.h" |
| 11 #include "ios/web/net/cert_verifier_block_adapter.h" | 11 #include "ios/web/net/cert_verifier_block_adapter.h" |
| 12 #include "ios/web/public/browser_state.h" | 12 #include "ios/web/public/browser_state.h" |
| 13 #include "ios/web/public/web_thread.h" | 13 #include "ios/web/public/web_thread.h" |
| 14 #import "ios/web/web_state/wk_web_view_security_util.h" |
| 14 #include "net/cert/cert_verify_result.h" | 15 #include "net/cert/cert_verify_result.h" |
| 15 #include "net/ssl/ssl_config_service.h" | 16 #include "net/ssl/ssl_config_service.h" |
| 16 #include "net/url_request/url_request_context.h" | 17 #include "net/url_request/url_request_context.h" |
| 17 #include "net/url_request/url_request_context_getter.h" | 18 #include "net/url_request/url_request_context_getter.h" |
| 18 | 19 |
| 19 namespace { | 20 namespace { |
| 20 | 21 |
| 21 // This class takes ownership of block and releases it on UI thread, even if | 22 // This class takes ownership of block and releases it on UI thread, even if |
| 22 // |BlockHolder| is destructed on a background thread. | 23 // |BlockHolder| is destructed on a background thread. |
| 23 template <class T> | 24 template <class T> |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 if (self) { | 100 if (self) { |
| 100 _contextGetter = browserState->GetRequestContext(); | 101 _contextGetter = browserState->GetRequestContext(); |
| 101 DCHECK(_contextGetter); | 102 DCHECK(_contextGetter); |
| 102 [self createCertVerifier]; | 103 [self createCertVerifier]; |
| 103 } | 104 } |
| 104 return self; | 105 return self; |
| 105 } | 106 } |
| 106 | 107 |
| 107 - (void)decidePolicyForCert:(const scoped_refptr<net::X509Certificate>&)cert | 108 - (void)decidePolicyForCert:(const scoped_refptr<net::X509Certificate>&)cert |
| 108 host:(NSString*)host | 109 host:(NSString*)host |
| 109 completionHandler:(web::PolicyDecisionHandler)handler { | 110 completionHandler:(web::PolicyDecisionHandler)completionHandler { |
| 110 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 111 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
| 111 // completionHandler of |verifyCert:forHost:completionHandler:| is called on | 112 // completionHandler of |verifyCert:forHost:completionHandler:| is called on |
| 112 // IO thread and then bounces back to UI thread. As a result all objects | 113 // IO thread and then bounces back to UI thread. As a result all objects |
| 113 // captured by completionHandler may be released on either UI or IO thread. | 114 // captured by completionHandler may be released on either UI or IO thread. |
| 114 // Since |handler| can potentially capture multiple thread unsafe objects | 115 // Since |completionHandler| can potentially capture multiple thread unsafe |
| 115 // (like Web Controller) |handler| itself should never be released on | 116 // objects (like Web Controller) |completionHandler| itself should never be |
| 116 // background thread and |BlockHolder| ensures that. | 117 // released on background thread and |BlockHolder| ensures that. |
| 117 __block scoped_refptr<BlockHolder<web::PolicyDecisionHandler>> handlerHolder( | 118 __block scoped_refptr<BlockHolder<web::PolicyDecisionHandler>> handlerHolder( |
| 118 new BlockHolder<web::PolicyDecisionHandler>(handler)); | 119 new BlockHolder<web::PolicyDecisionHandler>(completionHandler)); |
| 119 [self verifyCert:cert | 120 [self verifyCert:cert |
| 120 forHost:host | 121 forHost:host |
| 121 completionHandler:^(net::CertVerifyResult result, int error) { | 122 completionHandler:^(net::CertVerifyResult result, int error) { |
| 122 web::CertAcceptPolicy policy = | 123 web::CertAcceptPolicy policy = |
| 123 web::CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR; | 124 web::CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR; |
| 124 if (error == net::OK) { | 125 if (error == net::OK) { |
| 125 policy = web::CERT_ACCEPT_POLICY_ALLOW; | 126 policy = web::CERT_ACCEPT_POLICY_ALLOW; |
| 126 } else if (net::IsCertStatusError(result.cert_status)) { | 127 } else if (net::IsCertStatusError(result.cert_status)) { |
| 127 policy = net::IsCertStatusMinorError(result.cert_status) | 128 policy = net::IsCertStatusMinorError(result.cert_status) |
| 128 ? web::CERT_ACCEPT_POLICY_ALLOW | 129 ? web::CERT_ACCEPT_POLICY_ALLOW |
| 129 : web::CERT_ACCEPT_POLICY_RECOVERABLE_ERROR; | 130 : web::CERT_ACCEPT_POLICY_RECOVERABLE_ERROR; |
| 130 } | 131 } |
| 131 | 132 |
| 132 dispatch_async(dispatch_get_main_queue(), ^{ | 133 dispatch_async(dispatch_get_main_queue(), ^{ |
| 133 handlerHolder->call(policy, result.cert_status); | 134 handlerHolder->call(policy, result.cert_status); |
| 134 }); | 135 }); |
| 135 }]; | 136 }]; |
| 136 } | 137 } |
| 137 | 138 |
| 139 - (void)querySSLStatusForCertChain:(NSArray*)certChain |
| 140 host:(NSString*)host |
| 141 completionHandler:(web::StatusQueryHandler)completionHandler { |
| 142 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
| 143 DCHECK(certChain.count); |
| 144 |
| 145 // Completion handler of |verifyCert:forHost:completionHandler:| will be |
| 146 // deallocated on IO thread. |completionHandler| itself should never be |
| 147 // released on background thread and |BlockHolder| ensures that. |
| 148 __block scoped_refptr<BlockHolder<web::StatusQueryHandler>> handlerHolder( |
| 149 new BlockHolder<web::StatusQueryHandler>(completionHandler)); |
| 150 scoped_refptr<net::X509Certificate> cert(web::CreateCertFromChain(certChain)); |
| 151 // Knowing net::CertStatus is necessry even for valid certs in order to |
| 152 // support SHA-1 deprecation. |
| 153 [self verifyCert:cert |
| 154 forHost:host |
| 155 completionHandler:^(net::CertVerifyResult certVerifierResult, int) { |
| 156 base::ScopedCFTypeRef<SecTrustRef> trust( |
| 157 web::CreateServerTrustFromChain(certChain, host)); |
| 158 |
| 159 SecTrustResultType trustResult = kSecTrustResultInvalid; |
| 160 SecTrustEvaluate(trust.get(), &trustResult); |
| 161 |
| 162 dispatch_async(dispatch_get_main_queue(), ^{ |
| 163 handlerHolder->call(web::GetSecurityStyleFromTrustResult(trustResult), |
| 164 certVerifierResult.cert_status); |
| 165 }); |
| 166 }]; |
| 167 } |
| 168 |
| 138 - (void)shutDown { | 169 - (void)shutDown { |
| 139 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 170 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
| 140 web::WebThread::PostTask(web::WebThread::IO, FROM_HERE, base::BindBlock(^{ | 171 web::WebThread::PostTask(web::WebThread::IO, FROM_HERE, base::BindBlock(^{ |
| 141 // This block captures |self| delaying its deallocation and causing dealloc | 172 // This block captures |self| delaying its deallocation and causing dealloc |
| 142 // to happen on either IO or UI thread (which is fine for this class). | 173 // to happen on either IO or UI thread (which is fine for this class). |
| 143 _certVerifier.reset(); | 174 _certVerifier.reset(); |
| 144 })); | 175 })); |
| 145 } | 176 } |
| 146 | 177 |
| 147 #pragma mark - Private | 178 #pragma mark - Private |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 web::CertVerifierBlockAdapter::Params params( | 216 web::CertVerifierBlockAdapter::Params params( |
| 186 blockCert.Pass(), base::SysNSStringToUTF8(host)); | 217 blockCert.Pass(), base::SysNSStringToUTF8(host)); |
| 187 params.flags = self.certVerifyFlags; | 218 params.flags = self.certVerifyFlags; |
| 188 params.crl_set = net::SSLConfigService::GetCRLSet(); | 219 params.crl_set = net::SSLConfigService::GetCRLSet(); |
| 189 // OCSP response is not provided by iOS API. | 220 // OCSP response is not provided by iOS API. |
| 190 _certVerifier->Verify(params, completionHandler); | 221 _certVerifier->Verify(params, completionHandler); |
| 191 })); | 222 })); |
| 192 } | 223 } |
| 193 | 224 |
| 194 @end | 225 @end |
| OLD | NEW |