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 if (errSecSuccess != SecTrustEvaluate(trust.get(), &trustResult)) { | |
stuartmorgan
2015/09/10 22:26:18
Chromium style prefers the 'variable == constant'
Eugene But (OOO till 7-30)
2015/09/14 23:20:30
Acknowledged.
| |
161 trustResult = kSecTrustResultInvalid; | |
stuartmorgan
2015/09/10 22:26:17
This looks redundant; can STE modify the out param
Eugene But (OOO till 7-30)
2015/09/14 23:20:30
Not according to this code: http://opensource.appl
| |
162 } | |
163 | |
164 dispatch_async(dispatch_get_main_queue(), ^{ | |
165 handlerHolder->call(web::GetSecurityStyleFromTrustResult(trustResult), | |
166 certVerifierResult.cert_status); | |
167 }); | |
168 }]; | |
169 } | |
170 | |
138 - (void)shutDown { | 171 - (void)shutDown { |
139 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 172 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
140 web::WebThread::PostTask(web::WebThread::IO, FROM_HERE, base::BindBlock(^{ | 173 web::WebThread::PostTask(web::WebThread::IO, FROM_HERE, base::BindBlock(^{ |
141 // This block captures |self| delaying its deallocation and causing dealloc | 174 // 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). | 175 // to happen on either IO or UI thread (which is fine for this class). |
143 _certVerifier.reset(); | 176 _certVerifier.reset(); |
144 })); | 177 })); |
145 } | 178 } |
146 | 179 |
147 #pragma mark - Private | 180 #pragma mark - Private |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
185 web::CertVerifierBlockAdapter::Params params( | 218 web::CertVerifierBlockAdapter::Params params( |
186 blockCert.Pass(), base::SysNSStringToUTF8(host)); | 219 blockCert.Pass(), base::SysNSStringToUTF8(host)); |
187 params.flags = self.certVerifyFlags; | 220 params.flags = self.certVerifyFlags; |
188 params.crl_set = net::SSLConfigService::GetCRLSet(); | 221 params.crl_set = net::SSLConfigService::GetCRLSet(); |
189 // OCSP response is not provided by iOS API. | 222 // OCSP response is not provided by iOS API. |
190 _certVerifier->Verify(params, completionHandler); | 223 _certVerifier->Verify(params, completionHandler); |
191 })); | 224 })); |
192 } | 225 } |
193 | 226 |
194 @end | 227 @end |
OLD | NEW |