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

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

Issue 2151693008: [ios] Use -[WKWebView serverTrust] instead of certificateChain on iOS 10. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Self review Created 4 years, 5 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
« no previous file with comments | « ios/web/net/crw_ssl_status_updater.h ('k') | ios/web/net/crw_ssl_status_updater_unittest.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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_ssl_status_updater.h" 5 #import "ios/web/net/crw_ssl_status_updater.h"
6 6
7 #import "base/ios/weak_nsobject.h" 7 #import "base/ios/weak_nsobject.h"
8 #import "base/mac/scoped_nsobject.h" 8 #import "base/mac/scoped_nsobject.h"
9 #import "base/strings/sys_string_conversions.h" 9 #import "base/strings/sys_string_conversions.h"
10 #include "ios/web/public/cert_store.h" 10 #include "ios/web/public/cert_store.h"
11 #import "ios/web/public/navigation_item.h" 11 #import "ios/web/public/navigation_item.h"
12 #import "ios/web/public/navigation_manager.h" 12 #import "ios/web/public/navigation_manager.h"
13 #include "ios/web/public/ssl_status.h" 13 #include "ios/web/public/ssl_status.h"
14 #import "ios/web/web_state/wk_web_view_security_util.h" 14 #import "ios/web/web_state/wk_web_view_security_util.h"
15 #include "net/cert/x509_certificate.h" 15 #include "net/cert/x509_certificate.h"
16 #include "url/gurl.h" 16 #include "url/gurl.h"
17 17
18 using base::ScopedCFTypeRef;
18 using net::CertStatus; 19 using net::CertStatus;
19 using web::SecurityStyle; 20 using web::SecurityStyle;
20 21
21 @interface CRWSSLStatusUpdater () { 22 @interface CRWSSLStatusUpdater () {
22 // DataSource for CRWSSLStatusUpdater. 23 // DataSource for CRWSSLStatusUpdater.
23 base::WeakNSProtocol<id<CRWSSLStatusUpdaterDataSource>> _dataSource; 24 base::WeakNSProtocol<id<CRWSSLStatusUpdaterDataSource>> _dataSource;
24 // Backs up property of the same name. 25 // Backs up property of the same name.
25 base::WeakNSProtocol<id<CRWSSLStatusUpdaterDelegate>> _delegate; 26 base::WeakNSProtocol<id<CRWSSLStatusUpdaterDelegate>> _delegate;
26 } 27 }
27 28
28 // Unowned pointer to web::NavigationManager. 29 // Unowned pointer to web::NavigationManager.
29 @property(nonatomic, readonly) web::NavigationManager* navigationManager; 30 @property(nonatomic, readonly) web::NavigationManager* navigationManager;
30 31
31 // Identifier used for storing and retrieving certificates. 32 // Identifier used for storing and retrieving certificates.
32 @property(nonatomic, readonly) int certGroupID; 33 @property(nonatomic, readonly) int certGroupID;
33 34
34 // Updates |security_style| and |cert_status| for the NavigationItem with ID 35 // Updates |security_style| and |cert_status| for the NavigationItem with ID
35 // |navigationItemID|, if URL and certificate chain still match |host| and 36 // |navigationItemID|, if URL and certificate chain still match |host| and
36 // |certChain|. 37 // |certChain|.
37 - (void)updateSSLStatusForNavigationItemWithID:(int)navigationItemID 38 - (void)updateSSLStatusForItemWithID:(int)navigationItemID
38 certChain:(NSArray*)chain 39 trust:(ScopedCFTypeRef<SecTrustRef>)trust
39 host:(NSString*)host 40 host:(NSString*)host
40 withSecurityStyle:(SecurityStyle)style 41 withSecurityStyle:(SecurityStyle)style
41 certStatus:(CertStatus)certStatus; 42 certStatus:(CertStatus)certStatus;
42 43
43 // Asynchronously obtains SSL status from given |certChain| and |host| and 44 // Asynchronously obtains SSL status from given |secTrust| and |host| and
44 // updates current navigation item. Before scheduling update changes SSLStatus' 45 // updates current navigation item. Before scheduling update changes SSLStatus'
45 // cert_status and security_style to default. 46 // cert_status and security_style to default.
46 - (void)scheduleSSLStatusUpdateUsingCertChain:(NSArray*)chain 47 - (void)scheduleSSLStatusUpdateUsingTrust:(ScopedCFTypeRef<SecTrustRef>)trust
47 host:(NSString*)host; 48 host:(NSString*)host;
48 49
49 // Notifies delegate about SSLStatus change. 50 // Notifies delegate about SSLStatus change.
50 - (void)didChangeSSLStatusForNavigationItem:(web::NavigationItem*)navItem; 51 - (void)didChangeSSLStatusForNavigationItem:(web::NavigationItem*)navItem;
51 52
52 @end 53 @end
53 54
54 @implementation CRWSSLStatusUpdater 55 @implementation CRWSSLStatusUpdater
55 @synthesize navigationManager = _navigationManager; 56 @synthesize navigationManager = _navigationManager;
56 @synthesize certGroupID = _certGroupID; 57 @synthesize certGroupID = _certGroupID;
57 58
(...skipping 16 matching lines...) Expand all
74 - (id<CRWSSLStatusUpdaterDelegate>)delegate { 75 - (id<CRWSSLStatusUpdaterDelegate>)delegate {
75 return _delegate.get(); 76 return _delegate.get();
76 } 77 }
77 78
78 - (void)setDelegate:(id<CRWSSLStatusUpdaterDelegate>)delegate { 79 - (void)setDelegate:(id<CRWSSLStatusUpdaterDelegate>)delegate {
79 _delegate.reset(delegate); 80 _delegate.reset(delegate);
80 } 81 }
81 82
82 - (void)updateSSLStatusForNavigationItem:(web::NavigationItem*)item 83 - (void)updateSSLStatusForNavigationItem:(web::NavigationItem*)item
83 withCertHost:(NSString*)host 84 withCertHost:(NSString*)host
84 certChain:(NSArray*)chain 85 trust:(ScopedCFTypeRef<SecTrustRef>)trust
85 hasOnlySecureContent:(BOOL)hasOnlySecureContent { 86 hasOnlySecureContent:(BOOL)hasOnlySecureContent {
86 web::SSLStatus previousSSLStatus = item->GetSSL(); 87 web::SSLStatus previousSSLStatus = item->GetSSL();
87 88
88 // Starting from iOS9 WKWebView blocks active mixed content, so if 89 // Starting from iOS9 WKWebView blocks active mixed content, so if
89 // |hasOnlySecureContent| returns NO it means passive content. 90 // |hasOnlySecureContent| returns NO it means passive content.
90 item->GetSSL().content_status = 91 item->GetSSL().content_status =
91 hasOnlySecureContent ? web::SSLStatus::NORMAL_CONTENT 92 hasOnlySecureContent ? web::SSLStatus::NORMAL_CONTENT
92 : web::SSLStatus::DISPLAYED_INSECURE_CONTENT; 93 : web::SSLStatus::DISPLAYED_INSECURE_CONTENT;
93 94
94 // Try updating SSLStatus for current NavigationItem asynchronously. 95 // Try updating SSLStatus for current NavigationItem asynchronously.
95 scoped_refptr<net::X509Certificate> cert; 96 scoped_refptr<net::X509Certificate> cert;
96 if (item->GetURL().SchemeIsCryptographic()) { 97 if (item->GetURL().SchemeIsCryptographic()) {
97 cert = web::CreateCertFromChain(chain); 98 cert = web::CreateCertFromTrust(trust);
98 if (cert) { 99 if (cert) {
99 int oldCertID = item->GetSSL().cert_id; 100 int oldCertID = item->GetSSL().cert_id;
100 std::string oldHost = item->GetSSL().cert_status_host; 101 std::string oldHost = item->GetSSL().cert_status_host;
101 item->GetSSL().cert_id = web::CertStore::GetInstance()->StoreCert( 102 item->GetSSL().cert_id = web::CertStore::GetInstance()->StoreCert(
102 cert.get(), self.certGroupID); 103 cert.get(), self.certGroupID);
103 item->GetSSL().cert_status_host = base::SysNSStringToUTF8(host); 104 item->GetSSL().cert_status_host = base::SysNSStringToUTF8(host);
104 // Only recompute the SSLStatus information if the certificate or host has 105 // Only recompute the SSLStatus information if the certificate or host has
105 // since changed. Host can be changed in case of redirect. 106 // since changed. Host can be changed in case of redirect.
106 if (oldCertID != item->GetSSL().cert_id || 107 if (oldCertID != item->GetSSL().cert_id ||
107 oldHost != item->GetSSL().cert_status_host) { 108 oldHost != item->GetSSL().cert_status_host) {
108 // Real SSL status is unknown, reset cert status and security style. 109 // Real SSL status is unknown, reset cert status and security style.
109 // They will be asynchronously updated in 110 // They will be asynchronously updated in
110 // |scheduleSSLStatusUpdateUsingCertChain|. 111 // |scheduleSSLStatusUpdateUsingTrust:host:|.
111 item->GetSSL().cert_status = CertStatus(); 112 item->GetSSL().cert_status = CertStatus();
112 item->GetSSL().security_style = web::SECURITY_STYLE_UNKNOWN; 113 item->GetSSL().security_style = web::SECURITY_STYLE_UNKNOWN;
113 114
114 [self scheduleSSLStatusUpdateUsingCertChain:chain host:host]; 115 [self scheduleSSLStatusUpdateUsingTrust:std::move(trust) host:host];
115 } 116 }
116 } 117 }
117 } 118 }
118 119
119 if (!cert) { 120 if (!cert) {
120 item->GetSSL().cert_id = 0; 121 item->GetSSL().cert_id = 0;
121 if (!item->GetURL().SchemeIsCryptographic()) { 122 if (!item->GetURL().SchemeIsCryptographic()) {
122 // HTTP or other non-secure connection. 123 // HTTP or other non-secure connection.
123 item->GetSSL().security_style = web::SECURITY_STYLE_UNAUTHENTICATED; 124 item->GetSSL().security_style = web::SECURITY_STYLE_UNAUTHENTICATED;
124 } else { 125 } else {
125 // HTTPS, no certificate (this use-case has not been observed). 126 // HTTPS, no certificate (this use-case has not been observed).
126 item->GetSSL().security_style = web::SECURITY_STYLE_UNKNOWN; 127 item->GetSSL().security_style = web::SECURITY_STYLE_UNKNOWN;
127 } 128 }
128 } 129 }
129 130
130 if (!previousSSLStatus.Equals(item->GetSSL())) { 131 if (!previousSSLStatus.Equals(item->GetSSL())) {
131 [self didChangeSSLStatusForNavigationItem:item]; 132 [self didChangeSSLStatusForNavigationItem:item];
132 } 133 }
133 } 134 }
134 135
135 #pragma mark - Private 136 #pragma mark - Private
136 137
137 - (void)updateSSLStatusForNavigationItemWithID:(int)navigationItemID 138 - (void)updateSSLStatusForItemWithID:(int)navigationItemID
138 certChain:(NSArray*)chain 139 trust:(ScopedCFTypeRef<SecTrustRef>)trust
139 host:(NSString*)host 140 host:(NSString*)host
140 withSecurityStyle:(SecurityStyle)style 141 withSecurityStyle:(SecurityStyle)style
141 certStatus:(CertStatus)certStatus { 142 certStatus:(CertStatus)certStatus {
142 // The searched item almost always be the last one, so walk backward rather 143 // The searched item almost always be the last one, so walk backward rather
143 // than forward. 144 // than forward.
144 for (int i = _navigationManager->GetItemCount() - 1; 0 <= i; i--) { 145 for (int i = _navigationManager->GetItemCount() - 1; 0 <= i; i--) {
145 web::NavigationItem* item = _navigationManager->GetItemAtIndex(i); 146 web::NavigationItem* item = _navigationManager->GetItemAtIndex(i);
146 if (item->GetUniqueID() != navigationItemID) 147 if (item->GetUniqueID() != navigationItemID)
147 continue; 148 continue;
148 149
149 // NavigationItem's UniqueID is preserved even after redirects, so 150 // NavigationItem's UniqueID is preserved even after redirects, so
150 // checking that cert and URL match is necessary. 151 // checking that cert and URL match is necessary.
151 scoped_refptr<net::X509Certificate> cert(web::CreateCertFromChain(chain)); 152 scoped_refptr<net::X509Certificate> cert(web::CreateCertFromTrust(trust));
152 int certID = 153 int certID =
153 web::CertStore::GetInstance()->StoreCert(cert.get(), self.certGroupID); 154 web::CertStore::GetInstance()->StoreCert(cert.get(), self.certGroupID);
154 std::string GURLHost = base::SysNSStringToUTF8(host); 155 std::string GURLHost = base::SysNSStringToUTF8(host);
155 web::SSLStatus& SSLStatus = item->GetSSL(); 156 web::SSLStatus& SSLStatus = item->GetSSL();
156 if (item->GetURL().SchemeIsCryptographic() && SSLStatus.cert_id == certID && 157 if (item->GetURL().SchemeIsCryptographic() && SSLStatus.cert_id == certID &&
157 item->GetURL().host() == GURLHost) { 158 item->GetURL().host() == GURLHost) {
158 web::SSLStatus previousSSLStatus = item->GetSSL(); 159 web::SSLStatus previousSSLStatus = item->GetSSL();
159 SSLStatus.cert_status = certStatus; 160 SSLStatus.cert_status = certStatus;
160 SSLStatus.security_style = style; 161 SSLStatus.security_style = style;
161 if (!previousSSLStatus.Equals(SSLStatus)) { 162 if (!previousSSLStatus.Equals(SSLStatus)) {
162 [self didChangeSSLStatusForNavigationItem:item]; 163 [self didChangeSSLStatusForNavigationItem:item];
163 } 164 }
164 } 165 }
165 return; 166 return;
166 } 167 }
167 } 168 }
168 169
169 - (void)scheduleSSLStatusUpdateUsingCertChain:(NSArray*)chain 170 - (void)scheduleSSLStatusUpdateUsingTrust:(ScopedCFTypeRef<SecTrustRef>)trust
170 host:(NSString*)host { 171 host:(NSString*)host {
171 // Use Navigation Item's unique ID to locate requested item after 172 // Use Navigation Item's unique ID to locate requested item after
172 // obtaining cert status asynchronously. 173 // obtaining cert status asynchronously.
173 int itemID = _navigationManager->GetLastCommittedItem()->GetUniqueID(); 174 int itemID = _navigationManager->GetLastCommittedItem()->GetUniqueID();
174 175
175 DCHECK(_dataSource); 176 DCHECK(_dataSource);
176 base::WeakNSObject<CRWSSLStatusUpdater> weakSelf(self); 177 base::WeakNSObject<CRWSSLStatusUpdater> weakSelf(self);
177 [_dataSource SSLStatusUpdater:self 178 [_dataSource SSLStatusUpdater:self
178 querySSLStatusForCertChain:chain 179 querySSLStatusForTrust:trust
179 host:host 180 host:host
180 completionHandler:^(SecurityStyle style, CertStatus certStatus) { 181 completionHandler:^(SecurityStyle style, CertStatus certStatus) {
181 [weakSelf updateSSLStatusForNavigationItemWithID:itemID 182 [weakSelf updateSSLStatusForItemWithID:itemID
182 certChain:chain 183 trust:std::move(trust)
183 host:host 184 host:host
184 withSecurityStyle:style 185 withSecurityStyle:style
185 certStatus:certStatus]; 186 certStatus:certStatus];
186 }]; 187 }];
187 } 188 }
188 189
189 - (void)didChangeSSLStatusForNavigationItem:(web::NavigationItem*)navItem { 190 - (void)didChangeSSLStatusForNavigationItem:(web::NavigationItem*)navItem {
190 if ([_delegate respondsToSelector: 191 if ([_delegate respondsToSelector:
191 @selector(SSLStatusUpdater:didChangeSSLStatusForNavigationItem:)]) { 192 @selector(SSLStatusUpdater:didChangeSSLStatusForNavigationItem:)]) {
192 [_delegate SSLStatusUpdater:self 193 [_delegate SSLStatusUpdater:self
193 didChangeSSLStatusForNavigationItem:navItem]; 194 didChangeSSLStatusForNavigationItem:navItem];
194 } 195 }
195 } 196 }
196 197
197 @end 198 @end
OLDNEW
« no previous file with comments | « ios/web/net/crw_ssl_status_updater.h ('k') | ios/web/net/crw_ssl_status_updater_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698