Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(585)

Side by Side Diff: ios/web/net/crw_cert_verification_controller.mm

Issue 1322193003: WKWebView(iOS9): correctly update SSL status for current navigation item (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@reland_cert_verification
Patch Set: Updated comment Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/logging.h" 7 #include "base/logging.h"
8 #include "base/mac/bind_objc_block.h" 8 #include "base/mac/bind_objc_block.h"
9 #import "base/memory/ref_counted.h" 9 #import "base/memory/ref_counted.h"
10 #import "base/memory/scoped_ptr.h" 10 #import "base/memory/scoped_ptr.h"
11 #include "base/strings/sys_string_conversions.h" 11 #include "base/strings/sys_string_conversions.h"
12 #include "base/threading/worker_pool.h"
12 #include "ios/web/net/cert_verifier_block_adapter.h" 13 #include "ios/web/net/cert_verifier_block_adapter.h"
13 #include "ios/web/public/browser_state.h" 14 #include "ios/web/public/browser_state.h"
14 #include "ios/web/public/web_thread.h" 15 #include "ios/web/public/web_thread.h"
16 #import "ios/web/web_state/wk_web_view_security_util.h"
15 #include "net/cert/cert_verify_result.h" 17 #include "net/cert/cert_verify_result.h"
16 #include "net/ssl/ssl_config_service.h" 18 #include "net/ssl/ssl_config_service.h"
17 #include "net/url_request/url_request_context.h" 19 #include "net/url_request/url_request_context.h"
18 #include "net/url_request/url_request_context_getter.h" 20 #include "net/url_request/url_request_context_getter.h"
19 21
20 namespace { 22 namespace {
21 23
22 // This class takes ownership of block and releases it on UI thread, even if 24 // This class takes ownership of block and releases it on UI thread, even if
23 // |BlockHolder| is destructed on a background thread. 25 // |BlockHolder| is destructed on a background thread.
24 template <class T> 26 template <class T>
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 // URLRequestContextGetter for obtaining net layer objects. 68 // URLRequestContextGetter for obtaining net layer objects.
67 net::URLRequestContextGetter* _contextGetter; 69 net::URLRequestContextGetter* _contextGetter;
68 } 70 }
69 71
70 // Cert verification flags. Must be used on IO Thread. 72 // Cert verification flags. Must be used on IO Thread.
71 @property(nonatomic, readonly) int certVerifyFlags; 73 @property(nonatomic, readonly) int certVerifyFlags;
72 74
73 // Creates _certVerifier object on IO thread. 75 // Creates _certVerifier object on IO thread.
74 - (void)createCertVerifier; 76 - (void)createCertVerifier;
75 77
76 // Verifies the given |cert| for the given |host| and calls |completionHandler| 78 // Verifies the given |cert| for the given |host| using |net::CertVerifier| and
77 // on completion. |completionHandler| cannot be null and will be called 79 // calls |completionHandler| on completion. This method can be called on any
78 // synchronously or asynchronously on IO thread. 80 // thread. |completionHandler| cannot be null and will be called asynchronously
81 // on IO thread.
79 - (void)verifyCert:(const scoped_refptr<net::X509Certificate>&)cert 82 - (void)verifyCert:(const scoped_refptr<net::X509Certificate>&)cert
80 forHost:(NSString*)host 83 forHost:(NSString*)host
81 completionHandler:(void (^)(net::CertVerifyResult, int))completionHandler; 84 completionHandler:(void (^)(net::CertVerifyResult, int))completionHandler;
82 85
86 // Verifies the given |trust| using SecTrustRef API. |completionHandler| cannot
87 // be null and will be either called asynchronously on Worker thread or
88 // synchronously on current thread if the worker task can't start (in this
89 // case |dispatched| argument will be NO).
90 - (void)verifyTrust:(base::ScopedCFTypeRef<SecTrustRef>)trust
91 completionHandler:(void (^)(SecTrustResultType, BOOL dispatched))handler;
92
83 @end 93 @end
84 94
85 @implementation CRWCertVerificationController 95 @implementation CRWCertVerificationController
86 96
87 #pragma mark - Superclass 97 #pragma mark - Superclass
88 98
89 - (void)dealloc { 99 - (void)dealloc {
90 DCHECK(!_certVerifier); 100 DCHECK(!_certVerifier);
91 [super dealloc]; 101 [super dealloc];
92 } 102 }
(...skipping 12 matching lines...) Expand all
105 if (self) { 115 if (self) {
106 _contextGetter = browserState->GetRequestContext(); 116 _contextGetter = browserState->GetRequestContext();
107 DCHECK(_contextGetter); 117 DCHECK(_contextGetter);
108 [self createCertVerifier]; 118 [self createCertVerifier];
109 } 119 }
110 return self; 120 return self;
111 } 121 }
112 122
113 - (void)decidePolicyForCert:(const scoped_refptr<net::X509Certificate>&)cert 123 - (void)decidePolicyForCert:(const scoped_refptr<net::X509Certificate>&)cert
114 host:(NSString*)host 124 host:(NSString*)host
115 completionHandler:(web::PolicyDecisionHandler)handler { 125 completionHandler:(web::PolicyDecisionHandler)completionHandler {
116 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); 126 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
117 // completionHandler of |verifyCert:forHost:completionHandler:| is called on 127 // completionHandler of |verifyCert:forHost:completionHandler:| is called on
118 // IO thread and then bounces back to UI thread. As a result all objects 128 // IO thread and then bounces back to UI thread. As a result all objects
119 // captured by completionHandler may be released on either UI or IO thread. 129 // captured by completionHandler may be released on either UI or IO thread.
120 // Since |handler| can potentially capture multiple thread unsafe objects 130 // Since |completionHandler| can potentially capture multiple thread unsafe
121 // (like Web Controller) |handler| itself should never be released on 131 // objects (like Web Controller) |completionHandler| itself should never be
122 // background thread and |BlockHolder| ensures that. 132 // released on background thread and |BlockHolder| ensures that.
123 __block scoped_refptr<BlockHolder<web::PolicyDecisionHandler>> handlerHolder( 133 __block scoped_refptr<BlockHolder<web::PolicyDecisionHandler>> handlerHolder(
124 new BlockHolder<web::PolicyDecisionHandler>(handler)); 134 new BlockHolder<web::PolicyDecisionHandler>(completionHandler));
125 [self verifyCert:cert 135 [self verifyCert:cert
126 forHost:host 136 forHost:host
127 completionHandler:^(net::CertVerifyResult result, int error) { 137 completionHandler:^(net::CertVerifyResult result, int error) {
128 web::CertAcceptPolicy policy = 138 web::CertAcceptPolicy policy =
129 web::CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR; 139 web::CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR;
130 if (error == net::OK) { 140 if (error == net::OK) {
131 policy = web::CERT_ACCEPT_POLICY_ALLOW; 141 policy = web::CERT_ACCEPT_POLICY_ALLOW;
132 } else if (net::IsCertStatusError(result.cert_status)) { 142 } else if (net::IsCertStatusError(result.cert_status)) {
133 policy = net::IsCertStatusMinorError(result.cert_status) 143 policy = net::IsCertStatusMinorError(result.cert_status)
134 ? web::CERT_ACCEPT_POLICY_ALLOW 144 ? web::CERT_ACCEPT_POLICY_ALLOW
135 : web::CERT_ACCEPT_POLICY_RECOVERABLE_ERROR; 145 : web::CERT_ACCEPT_POLICY_RECOVERABLE_ERROR;
136 } 146 }
137 147
138 dispatch_async(dispatch_get_main_queue(), ^{ 148 dispatch_async(dispatch_get_main_queue(), ^{
139 handlerHolder->call(policy, result.cert_status); 149 handlerHolder->call(policy, result.cert_status);
140 }); 150 });
141 }]; 151 }];
142 } 152 }
143 153
154 - (void)querySSLStatusForTrust:(base::ScopedCFTypeRef<SecTrustRef>)trust
155 host:(NSString*)host
156 completionHandler:(web::StatusQueryHandler)completionHandler {
157 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
158
159 // The completion handlers of |verifyCert:forHost:completionHandler:| and
160 // |verifyTrust:completionHandler:| will be deallocated on background thread.
161 // |completionHandler| itself should never be released on background thread
162 // and |BlockHolder| ensures that.
163 __block scoped_refptr<BlockHolder<web::StatusQueryHandler>> handlerHolder(
164 new BlockHolder<web::StatusQueryHandler>(completionHandler));
165 [self verifyTrust:trust
166 completionHandler:^(SecTrustResultType trustResult, BOOL dispatched) {
167 if (!dispatched) {
168 // CertVerification task did not start.
169 dispatch_async(dispatch_get_main_queue(), ^{
170 handlerHolder->call(web::SECURITY_STYLE_UNKNOWN, net::CertStatus());
171 });
172 return;
173 }
174
175 web::SecurityStyle securityStyle =
176 web::GetSecurityStyleFromTrustResult(trustResult);
177 if (securityStyle == web::SECURITY_STYLE_AUTHENTICATED) {
178 // SecTrust API considers this cert as valid.
179 dispatch_async(dispatch_get_main_queue(), ^{
180 handlerHolder->call(securityStyle, net::CertStatus());
181 });
182 return;
183 }
184
185 // Retrieve the net::CertStatus for invalid certificates to determine
186 // the rejection reason, it is possible that rejection reason could not
187 // be determined and |cert_status| will be empty.
188 // TODO(eugenebut): Add UMA for CertVerifier and SecTrust verification
189 // mismatch (crbug.com/535699).
190 scoped_refptr<net::X509Certificate> cert(
191 web::CreateCertFromTrust(trust));
192 [self verifyCert:cert
193 forHost:host
194 completionHandler:^(net::CertVerifyResult certVerifierResult, int) {
195 dispatch_async(dispatch_get_main_queue(), ^{
196 handlerHolder->call(securityStyle,
197 certVerifierResult.cert_status);
198 });
199 }];
200 }];
201 }
202
144 - (void)shutDown { 203 - (void)shutDown {
145 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); 204 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
146 web::WebThread::PostTask(web::WebThread::IO, FROM_HERE, base::BindBlock(^{ 205 web::WebThread::PostTask(web::WebThread::IO, FROM_HERE, base::BindBlock(^{
147 // This block captures |self| delaying its deallocation and causing dealloc 206 // This block captures |self| delaying its deallocation and causing dealloc
148 // to happen on either IO or UI thread (which is fine for this class). 207 // to happen on either IO or UI thread (which is fine for this class).
149 _certVerifier.reset(); 208 _certVerifier.reset();
150 })); 209 }));
151 } 210 }
152 211
153 #pragma mark - Private 212 #pragma mark - Private
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 249
191 web::CertVerifierBlockAdapter::Params params( 250 web::CertVerifierBlockAdapter::Params params(
192 blockCert.Pass(), base::SysNSStringToUTF8(host)); 251 blockCert.Pass(), base::SysNSStringToUTF8(host));
193 params.flags = self.certVerifyFlags; 252 params.flags = self.certVerifyFlags;
194 params.crl_set = net::SSLConfigService::GetCRLSet(); 253 params.crl_set = net::SSLConfigService::GetCRLSet();
195 // OCSP response is not provided by iOS API. 254 // OCSP response is not provided by iOS API.
196 _certVerifier->Verify(params, completionHandler); 255 _certVerifier->Verify(params, completionHandler);
197 })); 256 }));
198 } 257 }
199 258
259 - (void)verifyTrust:(base::ScopedCFTypeRef<SecTrustRef>)trust
260 completionHandler:(void (^)(SecTrustResultType, BOOL))completionHandler {
261 DCHECK(completionHandler);
262 // SecTrustEvaluate performs trust evaluation synchronously, possibly making
263 // network requests. The UI thread should not be blocked by that operation.
264 bool dispatched = base::WorkerPool::PostTask(FROM_HERE, base::BindBlock(^{
265 SecTrustResultType trustResult = kSecTrustResultInvalid;
266 if (SecTrustEvaluate(trust.get(), &trustResult) != errSecSuccess) {
267 trustResult = kSecTrustResultInvalid;
268 }
269 completionHandler(trustResult, YES);
270 }), false /* task_is_slow */);
271
272 if (!dispatched) {
273 completionHandler(kSecTrustResultInvalid, NO);
274 }
275 }
276
200 @end 277 @end
OLDNEW
« no previous file with comments | « ios/web/net/crw_cert_verification_controller.h ('k') | ios/web/net/crw_cert_verification_controller_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698