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

Side by Side Diff: ios/web/navigation/crw_session_certificate_policy_manager.mm

Issue 1028603004: Upstream ios/web/navigation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ios-testing
Patch Set: Rebase and resync Created 5 years, 9 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
(Empty)
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import "ios/web/navigation/crw_session_certificate_policy_manager.h"
6
7 #include <map>
8 #include <set>
9
10 #include "base/bind.h"
11 #include "base/location.h"
12 #include "base/logging.h"
13 #include "base/strings/sys_string_conversions.h"
14 #include "ios/web/public/certificate_policy_cache.h"
15 #include "ios/web/public/web_thread.h"
16 #include "net/cert/x509_certificate.h"
17
18 // Break if we detect that CertStatus values changed, because we persist them on
19 // disk and thus require them to be consistent.
20 COMPILE_ASSERT(net::CERT_STATUS_ALL_ERRORS == 0xFFFF,
21 cert_status_value_changed);
22 COMPILE_ASSERT(net::CERT_STATUS_COMMON_NAME_INVALID == 1 << 0,
23 cert_status_value_changed);
24 COMPILE_ASSERT(net::CERT_STATUS_DATE_INVALID == 1 << 1,
25 cert_status_value_changed);
26 COMPILE_ASSERT(net::CERT_STATUS_AUTHORITY_INVALID == 1 << 2,
27 cert_status_value_changed);
28 COMPILE_ASSERT(net::CERT_STATUS_NO_REVOCATION_MECHANISM == 1 << 4,
29 cert_status_value_changed);
30 COMPILE_ASSERT(net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION == 1 << 5,
31 cert_status_value_changed);
32 COMPILE_ASSERT(net::CERT_STATUS_REVOKED == 1 << 6,
33 cert_status_value_changed);
34 COMPILE_ASSERT(net::CERT_STATUS_INVALID == 1 << 7,
35 cert_status_value_changed);
36 COMPILE_ASSERT(net::CERT_STATUS_WEAK_SIGNATURE_ALGORITHM == 1 << 8,
37 cert_status_value_changed);
38 COMPILE_ASSERT(net::CERT_STATUS_NON_UNIQUE_NAME == 1 << 10,
39 cert_status_value_changed);
40 COMPILE_ASSERT(net::CERT_STATUS_WEAK_KEY == 1 << 11,
41 cert_status_value_changed);
42 COMPILE_ASSERT(net::CERT_STATUS_IS_EV == 1 << 16,
43 cert_status_value_changed);
44 COMPILE_ASSERT(net::CERT_STATUS_REV_CHECKING_ENABLED == 1 << 17,
45 cert_status_value_changed);
46
47 namespace {
48
49 NSString* const kAllowedCertificatesKey = @"allowedCertificates";
50
51 struct AllowedCertificate {
52 scoped_refptr<net::X509Certificate> certificate;
53 std::string host;
54 };
55
56 class LessThan {
57 public:
58 bool operator() (const AllowedCertificate& lhs,
59 const AllowedCertificate& rhs) const {
60 if (lhs.host != rhs.host)
61 return lhs.host < rhs.host;
62 return certificateCompare_(lhs.certificate, rhs.certificate);
63 }
64 private:
65 net::X509Certificate::LessThan certificateCompare_;
66 };
67
68 typedef std::map<AllowedCertificate, net::CertStatus, LessThan>
69 AllowedCertificates;
70
71 NSData* CertificateToNSData(net::X509Certificate* certificate) {
72 std::string s;
73 bool success =
74 net::X509Certificate::GetDEREncoded(certificate->os_cert_handle(), &s);
75 DCHECK(success);
76 return [NSData dataWithBytes:s.c_str() length:s.length()];
77 }
78
79 net::X509Certificate* NSDataToCertificate(NSData* data) {
80 return net::X509Certificate::CreateFromBytes((const char *)[data bytes],
81 [data length]);
82 }
83
84 void AddToCertificatePolicyCache(
85 scoped_refptr<web::CertificatePolicyCache> policy_cache,
86 AllowedCertificates certs) {
87 DCHECK(policy_cache);
88 AllowedCertificates::iterator it;
89 for (it = certs.begin(); it != certs.end(); ++it) {
90 policy_cache->AllowCertForHost(
91 it->first.certificate.get(), it->first.host, it->second);
92 }
93 }
94
95 } // namespace
96
97 @implementation CRWSessionCertificatePolicyManager {
98 @private
99 AllowedCertificates allowed_;
100 }
101
102 - (void)registerAllowedCertificate:(net::X509Certificate*)certificate
103 forHost:(const std::string&)host
104 status:(net::CertStatus)status {
105 DCHECK([NSThread isMainThread]);
106 DCHECK(certificate);
107 AllowedCertificate allowedCertificate = {certificate, host};
108 allowed_[allowedCertificate] = status;
109 }
110
111 - (void)clearCertificates {
112 DCHECK([NSThread isMainThread]);
113 allowed_.clear();
114 }
115
116 - (void)updateCertificatePolicyCache:
117 (const scoped_refptr<web::CertificatePolicyCache>&)cache {
118 DCHECK([NSThread isMainThread]);
119 DCHECK(cache);
120 // Make a copy of allowed_ and access the policy cache from the IOThread.
121 web::WebThread::PostTask(
122 web::WebThread::IO, FROM_HERE,
123 base::Bind(&AddToCertificatePolicyCache, cache, allowed_));
124 }
125
126 #pragma mark -
127 #pragma mark NSCoding and NSCopying methods
128
129 - (id)initWithCoder:(NSCoder*)aDecoder {
130 DCHECK([NSThread isMainThread]);
131 self = [super init];
132 if (self) {
133 NSMutableSet* allowed = [aDecoder
134 decodeObjectForKey:kAllowedCertificatesKey];
135 for (NSArray* fields in allowed) {
136 if ([fields count] == 2) {
137 DVLOG(2) << "Dropping cached certificate policy (old format).";
138 continue;
139 } else if ([fields count] != 3) {
140 NOTREACHED();
141 continue;
142 }
143 net::X509Certificate* c = NSDataToCertificate([fields objectAtIndex:0]);
144 std::string host = base::SysNSStringToUTF8([fields objectAtIndex:1]);
145 net::CertStatus status = (net::CertStatus)[[fields objectAtIndex:2]
146 unsignedIntegerValue];
147 [self registerAllowedCertificate:c forHost:host status:status];
148 }
149 }
150 return self;
151 }
152
153 - (void)encodeWithCoder:(NSCoder*)aCoder {
154 if (allowed_.size() == 0)
155 return;
156
157 // Simple serialization of the set. If a same certificate is duplicated in the
158 // set (for a different host), the serialization will be duplicated as well.
159 NSMutableSet* allowedToEncode = [NSMutableSet set];
160 AllowedCertificates::iterator it;
161 for (it = allowed_.begin(); it != allowed_.end(); ++it) {
162 NSData* c = CertificateToNSData(it->first.certificate.get());
163 NSString* h = base::SysUTF8ToNSString(it->first.host);
164 DCHECK(c);
165 DCHECK(h);
166 if (!c || !h)
167 continue;
168 const NSUInteger status = (NSUInteger)it->second;
169 NSArray* fields = [NSArray arrayWithObjects:c, h, @(status), nil];
170 [allowedToEncode addObject:fields];
171 }
172 [aCoder encodeObject:allowedToEncode forKey:kAllowedCertificatesKey];
173 }
174
175 - (id)copyWithZone:(NSZone*)zone {
176 DCHECK([NSThread isMainThread]);
177 CRWSessionCertificatePolicyManager* copy = [[[self class] alloc] init];
178 copy->allowed_ = allowed_;
179 return copy;
180 }
181
182 @end
OLDNEW
« no previous file with comments | « ios/web/navigation/crw_session_certificate_policy_manager.h ('k') | ios/web/navigation/crw_session_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698