| 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/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 "base/threading/worker_pool.h" |
| 13 #include "ios/web/net/cert_verifier_block_adapter.h" | 13 #include "ios/web/net/cert_verifier_block_adapter.h" |
| 14 #include "ios/web/public/browser_state.h" | 14 #include "ios/web/public/browser_state.h" |
| 15 #include "ios/web/public/certificate_policy_cache.h" |
| 15 #include "ios/web/public/web_thread.h" | 16 #include "ios/web/public/web_thread.h" |
| 16 #import "ios/web/web_state/wk_web_view_security_util.h" | 17 #import "ios/web/web_state/wk_web_view_security_util.h" |
| 17 #include "net/cert/cert_verify_result.h" | 18 #include "net/cert/cert_verify_result.h" |
| 18 #include "net/ssl/ssl_config_service.h" | 19 #include "net/ssl/ssl_config_service.h" |
| 19 #include "net/url_request/url_request_context.h" | 20 #include "net/url_request/url_request_context.h" |
| 20 #include "net/url_request/url_request_context_getter.h" | 21 #include "net/url_request/url_request_context_getter.h" |
| 21 | 22 |
| 22 namespace { | 23 namespace { |
| 23 | 24 |
| 24 // This class takes ownership of block and releases it on UI thread, even if | 25 // This class takes ownership of block and releases it on UI thread, even if |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 | 61 |
| 61 } // namespace | 62 } // namespace |
| 62 | 63 |
| 63 @interface CRWCertVerificationController () { | 64 @interface CRWCertVerificationController () { |
| 64 // Cert verification object which wraps |net::CertVerifier|. Must be created, | 65 // Cert verification object which wraps |net::CertVerifier|. Must be created, |
| 65 // used and destroyed on IO Thread. | 66 // used and destroyed on IO Thread. |
| 66 scoped_ptr<web::CertVerifierBlockAdapter> _certVerifier; | 67 scoped_ptr<web::CertVerifierBlockAdapter> _certVerifier; |
| 67 | 68 |
| 68 // URLRequestContextGetter for obtaining net layer objects. | 69 // URLRequestContextGetter for obtaining net layer objects. |
| 69 net::URLRequestContextGetter* _contextGetter; | 70 net::URLRequestContextGetter* _contextGetter; |
| 71 |
| 72 // Used to remember user exceptions to invalid certs. |
| 73 scoped_refptr<web::CertificatePolicyCache> _certPolicyCache; |
| 70 } | 74 } |
| 71 | 75 |
| 72 // Cert verification flags. Must be used on IO Thread. | 76 // Cert verification flags. Must be used on IO Thread. |
| 73 @property(nonatomic, readonly) int certVerifyFlags; | 77 @property(nonatomic, readonly) int certVerifyFlags; |
| 74 | 78 |
| 75 // Creates _certVerifier object on IO thread. | 79 // Creates _certVerifier object on IO thread. |
| 76 - (void)createCertVerifier; | 80 - (void)createCertVerifier; |
| 77 | 81 |
| 78 // Verifies the given |cert| for the given |host| using |net::CertVerifier| and | 82 // Verifies the given |cert| for the given |host| using |net::CertVerifier| and |
| 79 // calls |completionHandler| on completion. This method can be called on any | 83 // calls |completionHandler| on completion. This method can be called on any |
| 80 // thread. |completionHandler| cannot be null and will be called asynchronously | 84 // thread. |completionHandler| cannot be null and will be called asynchronously |
| 81 // on IO thread. | 85 // on IO thread or synchronously on current thread if IO task can't start (in |
| 86 // this case |dispatched| argument will be NO). |
| 82 - (void)verifyCert:(const scoped_refptr<net::X509Certificate>&)cert | 87 - (void)verifyCert:(const scoped_refptr<net::X509Certificate>&)cert |
| 83 forHost:(NSString*)host | 88 forHost:(NSString*)host |
| 84 completionHandler:(void (^)(net::CertVerifyResult, int))completionHandler; | 89 completionHandler:(void (^)(net::CertVerifyResult, BOOL dispatched))handler; |
| 85 | 90 |
| 86 // Verifies the given |trust| using SecTrustRef API. |completionHandler| cannot | 91 // Verifies the given |trust| using SecTrustRef API. |completionHandler| cannot |
| 87 // be null and will be either called asynchronously on Worker thread or | 92 // 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 | 93 // synchronously on current thread if the worker task can't start (in this |
| 89 // case |dispatched| argument will be NO). | 94 // case |dispatched| argument will be NO). |
| 90 - (void)verifyTrust:(base::ScopedCFTypeRef<SecTrustRef>)trust | 95 - (void)verifyTrust:(base::ScopedCFTypeRef<SecTrustRef>)trust |
| 91 completionHandler:(void (^)(SecTrustResultType, BOOL dispatched))handler; | 96 completionHandler:(void (^)(SecTrustResultType, BOOL dispatched))handler; |
| 92 | 97 |
| 98 // Returns cert accept policy for the given SecTrust result. |trustResult| must |
| 99 // not be for a valid cert. Must be called on IO thread. |
| 100 - (web::CertAcceptPolicy) |
| 101 loadPolicyForBadTrustResult:(SecTrustResultType)trustResult |
| 102 certVerifierResult:(net::CertVerifyResult)certVerifierResult |
| 103 serverTrust:(SecTrustRef)trust |
| 104 host:(NSString*)host; |
| 105 |
| 93 @end | 106 @end |
| 94 | 107 |
| 95 @implementation CRWCertVerificationController | 108 @implementation CRWCertVerificationController |
| 96 | 109 |
| 97 #pragma mark - Superclass | 110 #pragma mark - Superclass |
| 98 | 111 |
| 99 - (void)dealloc { | 112 - (void)dealloc { |
| 100 DCHECK(!_certVerifier); | 113 DCHECK(!_certVerifier); |
| 101 [super dealloc]; | 114 [super dealloc]; |
| 102 } | 115 } |
| 103 | 116 |
| 104 #pragma mark - Public | 117 #pragma mark - Public |
| 105 | 118 |
| 106 - (instancetype)init { | 119 - (instancetype)init { |
| 107 NOTREACHED(); | 120 NOTREACHED(); |
| 108 return nil; | 121 return nil; |
| 109 } | 122 } |
| 110 | 123 |
| 111 - (instancetype)initWithBrowserState:(web::BrowserState*)browserState { | 124 - (instancetype)initWithBrowserState:(web::BrowserState*)browserState { |
| 112 DCHECK(browserState); | 125 DCHECK(browserState); |
| 113 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 126 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
| 114 self = [super init]; | 127 self = [super init]; |
| 115 if (self) { | 128 if (self) { |
| 116 _contextGetter = browserState->GetRequestContext(); | 129 _contextGetter = browserState->GetRequestContext(); |
| 117 DCHECK(_contextGetter); | 130 DCHECK(_contextGetter); |
| 131 _certPolicyCache = |
| 132 web::BrowserState::GetCertificatePolicyCache(browserState); |
| 133 |
| 118 [self createCertVerifier]; | 134 [self createCertVerifier]; |
| 119 } | 135 } |
| 120 return self; | 136 return self; |
| 121 } | 137 } |
| 122 | 138 |
| 123 - (void)decidePolicyForCert:(const scoped_refptr<net::X509Certificate>&)cert | 139 - (void)decideLoadPolicyForTrust:(base::ScopedCFTypeRef<SecTrustRef>)trust |
| 124 host:(NSString*)host | 140 host:(NSString*)host |
| 125 completionHandler:(web::PolicyDecisionHandler)completionHandler { | 141 completionHandler:(web::PolicyDecisionHandler)completionHandler { |
| 126 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 142 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
| 127 // completionHandler of |verifyCert:forHost:completionHandler:| is called on | 143 // completionHandler of |verifyCert:forHost:completionHandler:| is called on |
| 128 // IO thread and then bounces back to UI thread. As a result all objects | 144 // IO thread and then bounces back to UI thread. As a result all objects |
| 129 // captured by completionHandler may be released on either UI or IO thread. | 145 // captured by completionHandler may be released on either UI or IO thread. |
| 130 // Since |completionHandler| can potentially capture multiple thread unsafe | 146 // Since |completionHandler| can potentially capture multiple thread unsafe |
| 131 // objects (like Web Controller) |completionHandler| itself should never be | 147 // objects (like Web Controller) |completionHandler| itself should never be |
| 132 // released on background thread and |BlockHolder| ensures that. | 148 // released on background thread and |BlockHolder| ensures that. |
| 133 __block scoped_refptr<BlockHolder<web::PolicyDecisionHandler>> handlerHolder( | 149 __block scoped_refptr<BlockHolder<web::PolicyDecisionHandler>> handlerHolder( |
| 134 new BlockHolder<web::PolicyDecisionHandler>(completionHandler)); | 150 new BlockHolder<web::PolicyDecisionHandler>(completionHandler)); |
| 135 [self verifyCert:cert | 151 [self verifyTrust:trust |
| 136 forHost:host | 152 completionHandler:^(SecTrustResultType trustResult, BOOL dispatched) { |
| 137 completionHandler:^(net::CertVerifyResult result, int error) { | 153 if (!dispatched) { |
| 138 web::CertAcceptPolicy policy = | 154 // Cert verification task did not start. |
| 139 web::CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR; | 155 dispatch_async(dispatch_get_main_queue(), ^{ |
| 140 if (error == net::OK) { | 156 handlerHolder->call(web::CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR, |
| 141 policy = web::CERT_ACCEPT_POLICY_ALLOW; | 157 net::CertStatus()); |
| 142 } else if (net::IsCertStatusError(result.cert_status)) { | 158 }); |
| 143 policy = net::IsCertStatusMinorError(result.cert_status) | 159 return; |
| 144 ? web::CERT_ACCEPT_POLICY_ALLOW | |
| 145 : web::CERT_ACCEPT_POLICY_RECOVERABLE_ERROR; | |
| 146 } | 160 } |
| 147 | 161 |
| 148 dispatch_async(dispatch_get_main_queue(), ^{ | 162 if (web::GetSecurityStyleFromTrustResult(trustResult) == |
| 149 handlerHolder->call(policy, result.cert_status); | 163 web::SECURITY_STYLE_AUTHENTICATED) { |
| 150 }); | 164 // SecTrust API considers this cert as valid. |
| 165 dispatch_async(dispatch_get_main_queue(), ^{ |
| 166 handlerHolder->call(web::CERT_ACCEPT_POLICY_ALLOW, |
| 167 net::CertStatus()); |
| 168 }); |
| 169 return; |
| 170 } |
| 171 |
| 172 // SecTrust API considers this cert as invalid. Check the reason and |
| 173 // whether or not user has decided to proceed with this bad cert. |
| 174 scoped_refptr<net::X509Certificate> cert( |
| 175 web::CreateCertFromTrust(trust)); |
| 176 [self verifyCert:cert |
| 177 forHost:host |
| 178 completionHandler:^(net::CertVerifyResult certVerifierResult, |
| 179 BOOL dispatched) { |
| 180 if (!dispatched) { |
| 181 // Cert verification task did not start. |
| 182 dispatch_async(dispatch_get_main_queue(), ^{ |
| 183 handlerHolder->call( |
| 184 web::CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR, |
| 185 net::CertStatus()); |
| 186 }); |
| 187 return; |
| 188 } |
| 189 |
| 190 web::CertAcceptPolicy policy = |
| 191 [self loadPolicyForBadTrustResult:trustResult |
| 192 certVerifierResult:certVerifierResult |
| 193 serverTrust:trust.get() |
| 194 host:host]; |
| 195 |
| 196 dispatch_async(dispatch_get_main_queue(), ^{ |
| 197 handlerHolder->call(policy, certVerifierResult.cert_status); |
| 198 }); |
| 199 }]; |
| 151 }]; | 200 }]; |
| 152 } | 201 } |
| 153 | 202 |
| 154 - (void)querySSLStatusForTrust:(base::ScopedCFTypeRef<SecTrustRef>)trust | 203 - (void)querySSLStatusForTrust:(base::ScopedCFTypeRef<SecTrustRef>)trust |
| 155 host:(NSString*)host | 204 host:(NSString*)host |
| 156 completionHandler:(web::StatusQueryHandler)completionHandler { | 205 completionHandler:(web::StatusQueryHandler)completionHandler { |
| 157 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 206 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
| 158 | 207 |
| 159 // The completion handlers of |verifyCert:forHost:completionHandler:| and | 208 // The completion handlers of |verifyCert:forHost:completionHandler:| and |
| 160 // |verifyTrust:completionHandler:| will be deallocated on background thread. | 209 // |verifyTrust:completionHandler:| will be deallocated on background thread. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 184 | 233 |
| 185 // Retrieve the net::CertStatus for invalid certificates to determine | 234 // Retrieve the net::CertStatus for invalid certificates to determine |
| 186 // the rejection reason, it is possible that rejection reason could not | 235 // the rejection reason, it is possible that rejection reason could not |
| 187 // be determined and |cert_status| will be empty. | 236 // be determined and |cert_status| will be empty. |
| 188 // TODO(eugenebut): Add UMA for CertVerifier and SecTrust verification | 237 // TODO(eugenebut): Add UMA for CertVerifier and SecTrust verification |
| 189 // mismatch (crbug.com/535699). | 238 // mismatch (crbug.com/535699). |
| 190 scoped_refptr<net::X509Certificate> cert( | 239 scoped_refptr<net::X509Certificate> cert( |
| 191 web::CreateCertFromTrust(trust)); | 240 web::CreateCertFromTrust(trust)); |
| 192 [self verifyCert:cert | 241 [self verifyCert:cert |
| 193 forHost:host | 242 forHost:host |
| 194 completionHandler:^(net::CertVerifyResult certVerifierResult, int) { | 243 completionHandler:^(net::CertVerifyResult certVerifierResult, |
| 244 BOOL) { |
| 195 dispatch_async(dispatch_get_main_queue(), ^{ | 245 dispatch_async(dispatch_get_main_queue(), ^{ |
| 196 handlerHolder->call(securityStyle, | 246 handlerHolder->call(securityStyle, |
| 197 certVerifierResult.cert_status); | 247 certVerifierResult.cert_status); |
| 198 }); | 248 }); |
| 199 }]; | 249 }]; |
| 200 }]; | 250 }]; |
| 201 } | 251 } |
| 202 | 252 |
| 253 - (void)allowCert:(scoped_refptr<net::X509Certificate>)cert |
| 254 forHost:(NSString*)host |
| 255 status:(net::CertStatus)status { |
| 256 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
| 257 // Store user decisions with the leaf cert, ignoring any intermediates. |
| 258 // This is because WKWebView returns the verified certificate chain in |
| 259 // |webView:didReceiveAuthenticationChallenge:completionHandler:|, |
| 260 // but the server-supplied chain in |
| 261 // |webView:didFailProvisionalNavigation:withError:|. |
| 262 if (!cert->GetIntermediateCertificates().empty()) { |
| 263 cert = net::X509Certificate::CreateFromHandle( |
| 264 cert->os_cert_handle(), net::X509Certificate::OSCertHandles()); |
| 265 } |
| 266 DCHECK(cert->GetIntermediateCertificates().empty()); |
| 267 web::WebThread::PostTask(web::WebThread::IO, FROM_HERE, base::BindBlock(^{ |
| 268 _certPolicyCache->AllowCertForHost( |
| 269 cert.get(), base::SysNSStringToUTF8(host), status); |
| 270 })); |
| 271 } |
| 272 |
| 203 - (void)shutDown { | 273 - (void)shutDown { |
| 204 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 274 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
| 205 web::WebThread::PostTask(web::WebThread::IO, FROM_HERE, base::BindBlock(^{ | 275 web::WebThread::PostTask(web::WebThread::IO, FROM_HERE, base::BindBlock(^{ |
| 206 // This block captures |self| delaying its deallocation and causing dealloc | 276 // This block captures |self| delaying its deallocation and causing dealloc |
| 207 // to happen on either IO or UI thread (which is fine for this class). | 277 // to happen on either IO or UI thread (which is fine for this class). |
| 208 _certVerifier.reset(); | 278 _certVerifier.reset(); |
| 209 })); | 279 })); |
| 210 } | 280 } |
| 211 | 281 |
| 212 #pragma mark - Private | 282 #pragma mark - Private |
| (...skipping 15 matching lines...) Expand all Loading... |
| 228 - (void)createCertVerifier { | 298 - (void)createCertVerifier { |
| 229 web::WebThread::PostTask(web::WebThread::IO, FROM_HERE, base::BindBlock(^{ | 299 web::WebThread::PostTask(web::WebThread::IO, FROM_HERE, base::BindBlock(^{ |
| 230 net::URLRequestContext* context = _contextGetter->GetURLRequestContext(); | 300 net::URLRequestContext* context = _contextGetter->GetURLRequestContext(); |
| 231 _certVerifier.reset(new web::CertVerifierBlockAdapter( | 301 _certVerifier.reset(new web::CertVerifierBlockAdapter( |
| 232 context->cert_verifier(), context->net_log())); | 302 context->cert_verifier(), context->net_log())); |
| 233 })); | 303 })); |
| 234 } | 304 } |
| 235 | 305 |
| 236 - (void)verifyCert:(const scoped_refptr<net::X509Certificate>&)cert | 306 - (void)verifyCert:(const scoped_refptr<net::X509Certificate>&)cert |
| 237 forHost:(NSString*)host | 307 forHost:(NSString*)host |
| 238 completionHandler:(void (^)(net::CertVerifyResult, int))completionHandler { | 308 completionHandler:(void (^)(net::CertVerifyResult, BOOL))completionHandler { |
| 239 DCHECK(completionHandler); | 309 DCHECK(completionHandler); |
| 240 __block scoped_refptr<net::X509Certificate> blockCert = cert; | 310 __block scoped_refptr<net::X509Certificate> blockCert = cert; |
| 241 web::WebThread::PostTask( | 311 bool dispatched = web::WebThread::PostTask( |
| 242 web::WebThread::IO, FROM_HERE, base::BindBlock(^{ | 312 web::WebThread::IO, FROM_HERE, base::BindBlock(^{ |
| 243 // WeakNSObject does not work across different threads, hence this block | 313 // WeakNSObject does not work across different threads, hence this block |
| 244 // retains self. | 314 // retains self. |
| 245 if (!_certVerifier) { | 315 if (!_certVerifier) { |
| 246 completionHandler(net::CertVerifyResult(), net::ERR_FAILED); | 316 completionHandler(net::CertVerifyResult(), net::ERR_FAILED); |
| 247 return; | 317 return; |
| 248 } | 318 } |
| 249 | 319 |
| 250 web::CertVerifierBlockAdapter::Params params( | 320 web::CertVerifierBlockAdapter::Params params( |
| 251 blockCert.Pass(), base::SysNSStringToUTF8(host)); | 321 blockCert.Pass(), base::SysNSStringToUTF8(host)); |
| 252 params.flags = self.certVerifyFlags; | 322 params.flags = self.certVerifyFlags; |
| 253 params.crl_set = net::SSLConfigService::GetCRLSet(); | 323 params.crl_set = net::SSLConfigService::GetCRLSet(); |
| 254 // OCSP response is not provided by iOS API. | 324 // OCSP response is not provided by iOS API. |
| 255 _certVerifier->Verify(params, completionHandler); | 325 _certVerifier->Verify(params, ^(net::CertVerifyResult result, int) { |
| 326 completionHandler(result, YES); |
| 327 }); |
| 256 })); | 328 })); |
| 329 |
| 330 if (!dispatched) { |
| 331 completionHandler(net::CertVerifyResult(), NO); |
| 332 } |
| 257 } | 333 } |
| 258 | 334 |
| 259 - (void)verifyTrust:(base::ScopedCFTypeRef<SecTrustRef>)trust | 335 - (void)verifyTrust:(base::ScopedCFTypeRef<SecTrustRef>)trust |
| 260 completionHandler:(void (^)(SecTrustResultType, BOOL))completionHandler { | 336 completionHandler:(void (^)(SecTrustResultType, BOOL))completionHandler { |
| 261 DCHECK(completionHandler); | 337 DCHECK(completionHandler); |
| 262 // SecTrustEvaluate performs trust evaluation synchronously, possibly making | 338 // SecTrustEvaluate performs trust evaluation synchronously, possibly making |
| 263 // network requests. The UI thread should not be blocked by that operation. | 339 // network requests. The UI thread should not be blocked by that operation. |
| 264 bool dispatched = base::WorkerPool::PostTask(FROM_HERE, base::BindBlock(^{ | 340 bool dispatched = base::WorkerPool::PostTask(FROM_HERE, base::BindBlock(^{ |
| 265 SecTrustResultType trustResult = kSecTrustResultInvalid; | 341 SecTrustResultType trustResult = kSecTrustResultInvalid; |
| 266 if (SecTrustEvaluate(trust.get(), &trustResult) != errSecSuccess) { | 342 if (SecTrustEvaluate(trust.get(), &trustResult) != errSecSuccess) { |
| 267 trustResult = kSecTrustResultInvalid; | 343 trustResult = kSecTrustResultInvalid; |
| 268 } | 344 } |
| 269 completionHandler(trustResult, YES); | 345 completionHandler(trustResult, YES); |
| 270 }), false /* task_is_slow */); | 346 }), false /* task_is_slow */); |
| 271 | 347 |
| 272 if (!dispatched) { | 348 if (!dispatched) { |
| 273 completionHandler(kSecTrustResultInvalid, NO); | 349 completionHandler(kSecTrustResultInvalid, NO); |
| 274 } | 350 } |
| 275 } | 351 } |
| 276 | 352 |
| 353 - (web::CertAcceptPolicy) |
| 354 loadPolicyForBadTrustResult:(SecTrustResultType)trustResult |
| 355 certVerifierResult:(net::CertVerifyResult)certVerifierResult |
| 356 serverTrust:(SecTrustRef)trust |
| 357 host:(NSString*)host { |
| 358 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::IO); |
| 359 DCHECK_NE(web::SECURITY_STYLE_AUTHENTICATED, |
| 360 web::GetSecurityStyleFromTrustResult(trustResult)); |
| 361 |
| 362 if (trustResult != kSecTrustResultRecoverableTrustFailure || |
| 363 SecTrustGetCertificateCount(trust) == 0) { |
| 364 // Trust result is not recoverable or leaf cert is missing. |
| 365 return web::CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR; |
| 366 } |
| 367 |
| 368 // Check if user has decided to proceed with this bad cert. |
| 369 scoped_refptr<net::X509Certificate> leafCert = |
| 370 net::X509Certificate::CreateFromHandle( |
| 371 SecTrustGetCertificateAtIndex(trust, 0), |
| 372 net::X509Certificate::OSCertHandles()); |
| 373 |
| 374 web::CertPolicy::Judgment judgment = _certPolicyCache->QueryPolicy( |
| 375 leafCert.get(), base::SysNSStringToUTF8(host), |
| 376 certVerifierResult.cert_status); |
| 377 |
| 378 return (judgment == web::CertPolicy::ALLOWED) |
| 379 ? web::CERT_ACCEPT_POLICY_RECOVERABLE_ERROR_ACCEPTED_BY_USER |
| 380 : web::CERT_ACCEPT_POLICY_RECOVERABLE_ERROR_UNDECIDED_BY_USER; |
| 381 } |
| 382 |
| 277 @end | 383 @end |
| OLD | NEW |