Index: ios/web/net/crw_cert_verification_controller.mm |
diff --git a/ios/web/net/crw_cert_verification_controller.mm b/ios/web/net/crw_cert_verification_controller.mm |
index b8dba8fa106811aa2c53aeffbe5539587ea8f301..731be24c30f2f353f1d306cdeff6ffcf623f1613 100644 |
--- a/ios/web/net/crw_cert_verification_controller.mm |
+++ b/ios/web/net/crw_cert_verification_controller.mm |
@@ -11,6 +11,7 @@ |
#include "ios/web/net/cert_verifier_block_adapter.h" |
#include "ios/web/public/browser_state.h" |
#include "ios/web/public/web_thread.h" |
+#import "ios/web/web_state/wk_web_view_security_util.h" |
#include "net/cert/cert_verify_result.h" |
#include "net/ssl/ssl_config_service.h" |
#include "net/url_request/url_request_context.h" |
@@ -106,16 +107,16 @@ class BlockHolder : public base::RefCountedThreadSafe<BlockHolder<T>> { |
- (void)decidePolicyForCert:(const scoped_refptr<net::X509Certificate>&)cert |
host:(NSString*)host |
- completionHandler:(web::PolicyDecisionHandler)handler { |
+ completionHandler:(web::PolicyDecisionHandler)completionHandler { |
DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
// completionHandler of |verifyCert:forHost:completionHandler:| is called on |
// IO thread and then bounces back to UI thread. As a result all objects |
// captured by completionHandler may be released on either UI or IO thread. |
- // Since |handler| can potentially capture multiple thread unsafe objects |
- // (like Web Controller) |handler| itself should never be released on |
- // background thread and |BlockHolder| ensures that. |
+ // Since |completionHandler| can potentially capture multiple thread unsafe |
+ // objects (like Web Controller) |completionHandler| itself should never be |
+ // released on background thread and |BlockHolder| ensures that. |
__block scoped_refptr<BlockHolder<web::PolicyDecisionHandler>> handlerHolder( |
- new BlockHolder<web::PolicyDecisionHandler>(handler)); |
+ new BlockHolder<web::PolicyDecisionHandler>(completionHandler)); |
[self verifyCert:cert |
forHost:host |
completionHandler:^(net::CertVerifyResult result, int error) { |
@@ -135,6 +136,45 @@ class BlockHolder : public base::RefCountedThreadSafe<BlockHolder<T>> { |
}]; |
} |
+- (void)querySSLStatusForCertChain:(NSArray*)certChain |
+ host:(NSString*)host |
+ completionHandler:(web::StatusQueryHandler)completionHandler { |
+ DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
+ DCHECK(certChain.count); |
+ |
+ // Completion handler of |verifyCert:forHost:completionHandler:| will be |
+ // deallocated on IO thread. |completionHandler| itself should never be |
+ // released on background thread and |BlockHolder| ensures that. |
+ __block scoped_refptr<BlockHolder<web::StatusQueryHandler>> handlerHolder( |
+ new BlockHolder<web::StatusQueryHandler>(completionHandler)); |
+ scoped_refptr<net::X509Certificate> cert(web::CreateCertFromChain(certChain)); |
+ // Knowing net::CertStatus is necessary even for valid certs in order to |
+ // support SHA-1 deprecation. |
Ryan Sleevi
2015/09/19 12:45:38
I'm not sure what is meant to be accomplished by t
Eugene But (OOO till 7-30)
2015/09/21 17:23:39
What I was trying to say with this comment is that
Ryan Sleevi
2015/09/21 17:39:04
I still think this comment is a bit shaky on the l
Eugene But (OOO till 7-30)
2015/09/21 21:05:01
Done.
|
+ [self verifyCert:cert |
+ forHost:host |
+ completionHandler:^(net::CertVerifyResult certVerifierResult, int) { |
+ base::ScopedCFTypeRef<SecTrustRef> trust( |
+ web::CreateServerTrustFromChain(certChain, host)); |
+ |
+ SecTrustResultType trustResult = kSecTrustResultInvalid; |
+ SecTrustEvaluate(trust.get(), &trustResult); |
Ryan Sleevi
2015/09/19 12:45:37
BUG: You need to check the result code here.
DESI
Eugene But (OOO till 7-30)
2015/09/21 17:23:39
Initially I wrote code like this:
if (errSecSucce
Ryan Sleevi
2015/09/21 17:39:04
I appreciate the explanation, but the rationale fo
Ryan Sleevi
2015/09/21 17:39:04
Woah, you're calling this on the IO thread? That's
Eugene But (OOO till 7-30)
2015/09/21 21:05:01
Bounced to WorkerThread.
Eugene But (OOO till 7-30)
2015/09/21 21:05:01
Done.
|
+ |
+ // For certs, which considered valid by Sec Trust API, discard all |
+ // error bits from net::CertStatus. This will leave cert in a valid |
+ // state, but will keep important information, like SHA-1 presence. |
Ryan Sleevi
2015/09/19 12:45:38
If there are error bits, we won't necessarily have
Eugene But (OOO till 7-30)
2015/09/21 17:23:39
So if SecTrust thinks that cert is valid, but cert
Ryan Sleevi
2015/09/21 17:39:04
This is another comment that appears confusing, es
Eugene But (OOO till 7-30)
2015/09/21 21:05:01
Done.
|
+ web::SecurityStyle security_style = |
+ web::GetSecurityStyleFromTrustResult(trustResult); |
+ net::CertStatus cert_status = certVerifierResult.cert_status; |
+ if (security_style == web::SECURITY_STYLE_AUTHENTICATED) { |
+ cert_status &= net::CERT_STATUS_NON_ERROR_STATUSES; |
Ryan Sleevi
2015/09/19 12:45:38
cert_status &= ~CERT_STATUS_ALL_ERRORS;
Eugene But (OOO till 7-30)
2015/09/21 17:23:40
Done.
|
+ } |
+ |
+ dispatch_async(dispatch_get_main_queue(), ^{ |
+ handlerHolder->call(security_style, cert_status); |
+ }); |
+ }]; |
+} |
+ |
- (void)shutDown { |
DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
web::WebThread::PostTask(web::WebThread::IO, FROM_HERE, base::BindBlock(^{ |