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

Side by Side Diff: net/cert/x509_certificate_openssl_ios.cc

Issue 1810153002: Adding iOS OpenSSL Implementation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Simplifying logic for first iteration. Created 4 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 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 #include "net/cert/x509_certificate.h" 5 #include "net/cert/x509_certificate.h"
6 6
7 #include <openssl/asn1.h> 7 #include <CommonCrypto/CommonDigest.h>
8 #include <openssl/bytestring.h> 8 #include <Security/Security.h>
9 #include <openssl/crypto.h> 9
10 #include <openssl/obj_mac.h>
11 #include <openssl/pem.h>
12 #include <openssl/sha.h>
13 #include <openssl/ssl.h>
14 #include <openssl/x509v3.h> 10 #include <openssl/x509v3.h>
davidben 2016/03/21 19:46:47 I think this also needs an <openssl/x509.h>
svaldez 2016/03/21 20:23:52 Done.
15 11
16 #include "base/macros.h" 12 #include "base/mac/scoped_cftyperef.h"
17 #include "base/memory/singleton.h"
18 #include "base/numerics/safe_conversions.h"
19 #include "base/pickle.h" 13 #include "base/pickle.h"
20 #include "base/sha1.h"
21 #include "base/strings/string_number_conversions.h"
22 #include "base/strings/string_piece.h" 14 #include "base/strings/string_piece.h"
23 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
24 #include "crypto/openssl_util.h" 16 #include "crypto/openssl_util.h"
25 #include "crypto/scoped_openssl_types.h" 17 #include "crypto/scoped_openssl_types.h"
26 #include "net/base/ip_address_number.h" 18 #include "net/base/ip_address_number.h"
27 #include "net/base/net_errors.h"
28 #include "net/cert/x509_util_openssl.h" 19 #include "net/cert/x509_util_openssl.h"
20 #include "net/ssl/openssl_ssl_util.h"
29 21
30 #if defined(OS_ANDROID) 22 using base::ScopedCFTypeRef;
31 #include "base/logging.h"
32 #include "net/android/network_library.h"
33 #endif
34 23
35 namespace net { 24 namespace net {
36 25
37 namespace { 26 namespace {
38 27
39 using ScopedGENERAL_NAMES = 28 using ScopedGENERAL_NAMES =
40 crypto::ScopedOpenSSL<GENERAL_NAMES, GENERAL_NAMES_free>; 29 crypto::ScopedOpenSSL<GENERAL_NAMES, GENERAL_NAMES_free>;
41 30
31 // Returns true if a given |cert_handle| is actually a valid X.509 certificate
32 // handle.
33 //
34 // SecCertificateCreateFromData() does not always force the immediate parsing of
35 // the certificate, and as such, may return a SecCertificateRef for an
36 // invalid/unparsable certificate. Force parsing to occur to ensure that the
37 // SecCertificateRef is correct. On later versions where
38 // SecCertificateCreateFromData() immediately parses, rather than lazily, this
39 // call is cheap, as the subject is cached.
40 bool IsValidOSCertHandle(SecCertificateRef cert_handle) {
41 ScopedCFTypeRef<CFStringRef> sanity_check(
42 SecCertificateCopySubjectSummary(cert_handle));
43 return sanity_check != NULL;
44 }
45
42 void CreateOSCertHandlesFromPKCS7Bytes( 46 void CreateOSCertHandlesFromPKCS7Bytes(
43 const char* data, 47 const char* data,
44 size_t length, 48 size_t length,
45 X509Certificate::OSCertHandles* handles) { 49 X509Certificate::OSCertHandles* handles) {
46 crypto::EnsureOpenSSLInit(); 50 crypto::EnsureOpenSSLInit();
47 crypto::OpenSSLErrStackTracer err_cleaner(FROM_HERE); 51 crypto::OpenSSLErrStackTracer err_cleaner(FROM_HERE);
48 52
49 CBS der_data; 53 CBS der_data;
50 CBS_init(&der_data, reinterpret_cast<const uint8_t*>(data), length); 54 CBS_init(&der_data, reinterpret_cast<const uint8_t*>(data), length);
51 STACK_OF(X509)* certs = sk_X509_new_null(); 55 STACK_OF(X509)* certs = sk_X509_new_null();
52 56
53 if (PKCS7_get_certificates(certs, &der_data)) { 57 if (PKCS7_get_certificates(certs, &der_data)) {
davidben 2016/03/21 19:46:47 [Hrm. I really should get you a non-crypto/x509 ve
svaldez 2016/03/21 20:23:52 Acknowledged.
54 for (size_t i = 0; i < sk_X509_num(certs); ++i) { 58 for (size_t i = 0; i < sk_X509_num(certs); ++i) {
55 X509* x509_cert = 59 X509* x509_cert = sk_X509_value(certs, i);
56 X509Certificate::DupOSCertHandle(sk_X509_value(certs, i)); 60 base::StringPiece der;
57 handles->push_back(x509_cert); 61 if (!x509_util::GetDER(x509_cert, &der))
62 return;
63 handles->push_back(X509Certificate::CreateOSCertHandleFromBytes(
64 der.data(), der.length()));
58 } 65 }
59 } 66 }
60 sk_X509_pop_free(certs, X509_free); 67 sk_X509_pop_free(certs, X509_free);
61 } 68 }
62 69
63 void ParsePrincipalValues(X509_NAME* name, 70 void ParsePrincipalValues(X509_NAME* name,
64 int nid, 71 int nid,
65 std::vector<std::string>* fields) { 72 std::vector<std::string>* fields) {
66 for (int index = -1; 73 for (int index = -1;
67 (index = X509_NAME_get_index_by_NID(name, nid, index)) != -1;) { 74 (index = X509_NAME_get_index_by_NID(name, nid, index)) != -1;) {
68 std::string field; 75 std::string field;
69 if (!x509_util::ParsePrincipalValueByIndex(name, index, &field)) 76 if (!x509_util::ParsePrincipalValueByIndex(name, index, &field))
70 break; 77 break;
71 fields->push_back(field); 78 fields->push_back(field);
72 } 79 }
73 } 80 }
74 81
75 void ParsePrincipal(X509Certificate::OSCertHandle cert, 82 void ParsePrincipal(X509Certificate::OSCertHandle os_cert,
76 X509_NAME* x509_name, 83 X509_NAME* x509_name,
77 CertPrincipal* principal) { 84 CertPrincipal* principal) {
78 if (!x509_name) 85 if (!x509_name)
79 return; 86 return;
80 87
81 ParsePrincipalValues(x509_name, NID_streetAddress, 88 ParsePrincipalValues(x509_name, NID_streetAddress,
82 &principal->street_addresses); 89 &principal->street_addresses);
83 ParsePrincipalValues(x509_name, NID_organizationName, 90 ParsePrincipalValues(x509_name, NID_organizationName,
84 &principal->organization_names); 91 &principal->organization_names);
85 ParsePrincipalValues(x509_name, NID_organizationalUnitName, 92 ParsePrincipalValues(x509_name, NID_organizationalUnitName,
86 &principal->organization_unit_names); 93 &principal->organization_unit_names);
87 ParsePrincipalValues(x509_name, NID_domainComponent, 94 ParsePrincipalValues(x509_name, NID_domainComponent,
88 &principal->domain_components); 95 &principal->domain_components);
89 96
90 x509_util::ParsePrincipalValueByNID(x509_name, NID_commonName, 97 x509_util::ParsePrincipalValueByNID(x509_name, NID_commonName,
91 &principal->common_name); 98 &principal->common_name);
92 x509_util::ParsePrincipalValueByNID(x509_name, NID_localityName, 99 x509_util::ParsePrincipalValueByNID(x509_name, NID_localityName,
93 &principal->locality_name); 100 &principal->locality_name);
94 x509_util::ParsePrincipalValueByNID(x509_name, NID_stateOrProvinceName, 101 x509_util::ParsePrincipalValueByNID(x509_name, NID_stateOrProvinceName,
95 &principal->state_or_province_name); 102 &principal->state_or_province_name);
96 x509_util::ParsePrincipalValueByNID(x509_name, NID_countryName, 103 x509_util::ParsePrincipalValueByNID(x509_name, NID_countryName,
97 &principal->country_name); 104 &principal->country_name);
98 } 105 }
99 106
100 void ParseSubjectAltName(X509Certificate::OSCertHandle cert, 107 void ParseSubjectAltName(X509Certificate::OSCertHandle os_cert,
101 std::vector<std::string>* dns_names, 108 std::vector<std::string>* dns_names,
102 std::vector<std::string>* ip_addresses) { 109 std::vector<std::string>* ip_addresses) {
103 DCHECK(dns_names || ip_addresses); 110 DCHECK(dns_names || ip_addresses);
104 int index = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1); 111 ScopedX509 cert = OSCertHandleToOpenSSL(os_cert);
davidben 2016/03/21 19:46:47 Check for errors here. iOS and OpenSSL may have di
svaldez 2016/03/21 20:23:52 Done.
105 X509_EXTENSION* alt_name_ext = X509_get_ext(cert, index); 112 int index = X509_get_ext_by_NID(cert.get(), NID_subject_alt_name, -1);
113 X509_EXTENSION* alt_name_ext = X509_get_ext(cert.get(), index);
106 if (!alt_name_ext) 114 if (!alt_name_ext)
107 return; 115 return;
108 116
109 ScopedGENERAL_NAMES alt_names( 117 ScopedGENERAL_NAMES alt_names(
110 reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext))); 118 reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext)));
111 if (!alt_names.get()) 119 if (!alt_names.get())
112 return; 120 return;
113 121
114 for (size_t i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) { 122 for (size_t i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) {
115 const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i); 123 const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i);
(...skipping 16 matching lines...) Expand all
132 // net mask hence 8 or 32 bytes. Logging to help diagnose any mixup. 140 // net mask hence 8 or 32 bytes. Logging to help diagnose any mixup.
133 LOG(WARNING) << "Bad sized IP Address in cert: " << ip_addr_len; 141 LOG(WARNING) << "Bad sized IP Address in cert: " << ip_addr_len;
134 continue; 142 continue;
135 } 143 }
136 ip_addresses->push_back( 144 ip_addresses->push_back(
137 std::string(reinterpret_cast<const char*>(ip_addr), ip_addr_len)); 145 std::string(reinterpret_cast<const char*>(ip_addr), ip_addr_len));
138 } 146 }
139 } 147 }
140 } 148 }
141 149
142 class X509InitSingleton {
143 public:
144 static X509InitSingleton* GetInstance() {
145 // We allow the X509 store to leak, because it is used from a non-joinable
146 // worker that is not stopped on shutdown, hence may still be using
147 // OpenSSL library after the AtExit runner has completed.
148 return base::Singleton<X509InitSingleton, base::LeakySingletonTraits<
149 X509InitSingleton>>::get();
150 }
151 X509_STORE* store() const { return store_.get(); }
152
153 void ResetCertStore() {
154 store_.reset(X509_STORE_new());
155 DCHECK(store_.get());
156 X509_STORE_set_default_paths(store_.get());
157 // TODO(joth): Enable CRL (see X509_STORE_set_flags(X509_V_FLAG_CRL_CHECK)).
158 }
159
160 private:
161 friend struct base::DefaultSingletonTraits<X509InitSingleton>;
162 X509InitSingleton() {
163 crypto::EnsureOpenSSLInit();
164 ResetCertStore();
165 }
166
167 crypto::ScopedOpenSSL<X509_STORE, X509_STORE_free> store_;
168
169 DISALLOW_COPY_AND_ASSIGN(X509InitSingleton);
170 };
171
172 // Used to free a list of X509_NAMEs and the objects it points to. 150 // Used to free a list of X509_NAMEs and the objects it points to.
173 void sk_X509_NAME_free_all(STACK_OF(X509_NAME)* sk) { 151 void sk_X509_NAME_free_all(STACK_OF(X509_NAME) * sk) {
174 sk_X509_NAME_pop_free(sk, X509_NAME_free); 152 sk_X509_NAME_pop_free(sk, X509_NAME_free);
175 } 153 }
176 154
177 } // namespace 155 } // namespace
178 156
179 // static 157 // static
180 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( 158 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle(
181 OSCertHandle cert_handle) { 159 OSCertHandle handle) {
182 DCHECK(cert_handle); 160 if (!handle)
183 return X509_up_ref(cert_handle); 161 return NULL;
162 return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle)));
184 } 163 }
185 164
186 // static 165 // static
187 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { 166 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
188 // Decrement the ref-count for the cert and, if all references are gone, 167 if (cert_handle)
189 // free the memory and any application-specific data associated with the 168 CFRelease(cert_handle);
190 // certificate.
191 X509_free(cert_handle);
192 } 169 }
193 170
194 void X509Certificate::Initialize() { 171 void X509Certificate::Initialize() {
195 crypto::EnsureOpenSSLInit(); 172 crypto::EnsureOpenSSLInit();
196 fingerprint_ = CalculateFingerprint(cert_handle_); 173 fingerprint_ = CalculateFingerprint(cert_handle_);
197 ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_); 174 ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_);
198 175 ScopedX509 x509_cert = OSCertHandleToOpenSSL(cert_handle_);
199 ASN1_INTEGER* serial_num = X509_get_serialNumber(cert_handle_); 176 ASN1_INTEGER* serial_num = X509_get_serialNumber(x509_cert.get());
200 if (serial_num) { 177 if (serial_num) {
201 // ASN1_INTEGERS represent the decoded number, in a format internal to 178 // ASN1_INTEGERS represent the decoded number, in a format internal to
202 // OpenSSL. Most notably, this may have leading zeroes stripped off for 179 // OpenSSL. Most notably, this may have leading zeroes stripped off for
203 // numbers whose first byte is >= 0x80. Thus, it is necessary to 180 // numbers whose first byte is >= 0x80. Thus, it is necessary to
204 // re-encoded the integer back into DER, which is what the interface 181 // re-encoded the integer back into DER, which is what the interface
205 // of X509Certificate exposes, to ensure callers get the proper (DER) 182 // of X509Certificate exposes, to ensure callers get the proper (DER)
206 // value. 183 // value.
207 int bytes_required = i2c_ASN1_INTEGER(serial_num, NULL); 184 int bytes_required = i2c_ASN1_INTEGER(serial_num, NULL);
208 unsigned char* buffer = reinterpret_cast<unsigned char*>( 185 unsigned char* buffer = reinterpret_cast<unsigned char*>(
209 base::WriteInto(&serial_number_, bytes_required + 1)); 186 base::WriteInto(&serial_number_, bytes_required + 1));
210 int bytes_written = i2c_ASN1_INTEGER(serial_num, &buffer); 187 int bytes_written = i2c_ASN1_INTEGER(serial_num, &buffer);
211 DCHECK_EQ(static_cast<size_t>(bytes_written), serial_number_.size()); 188 DCHECK_EQ(static_cast<size_t>(bytes_written), serial_number_.size());
212 } 189 }
213 190
214 ParsePrincipal(cert_handle_, X509_get_subject_name(cert_handle_), &subject_); 191 ParsePrincipal(cert_handle_, X509_get_subject_name(x509_cert.get()),
215 ParsePrincipal(cert_handle_, X509_get_issuer_name(cert_handle_), &issuer_); 192 &subject_);
216 x509_util::ParseDate(X509_get_notBefore(cert_handle_), &valid_start_); 193 ParsePrincipal(cert_handle_, X509_get_issuer_name(x509_cert.get()), &issuer_);
217 x509_util::ParseDate(X509_get_notAfter(cert_handle_), &valid_expiry_); 194 x509_util::ParseDate(X509_get_notBefore(x509_cert.get()), &valid_start_);
218 } 195 x509_util::ParseDate(X509_get_notAfter(x509_cert.get()), &valid_expiry_);
219
220 // static
221 void X509Certificate::ResetCertStore() {
222 X509InitSingleton::GetInstance()->ResetCertStore();
223 } 196 }
224 197
225 // static 198 // static
226 SHA1HashValue X509Certificate::CalculateFingerprint(OSCertHandle cert) { 199 SHA1HashValue X509Certificate::CalculateFingerprint(OSCertHandle cert) {
227 SHA1HashValue sha1; 200 SHA1HashValue sha1;
228 unsigned int sha1_size = static_cast<unsigned int>(sizeof(sha1.data)); 201 memset(sha1.data, 0, sizeof(sha1.data));
229 int ret = X509_digest(cert, EVP_sha1(), sha1.data, &sha1_size); 202
230 CHECK(ret); 203 ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert));
231 CHECK_EQ(sha1_size, sizeof(sha1.data)); 204 if (!cert_data)
205 return sha1;
206 DCHECK(CFDataGetBytePtr(cert_data));
207 DCHECK_NE(0, CFDataGetLength(cert_data));
208 CC_SHA1(CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data), sha1.data);
209
232 return sha1; 210 return sha1;
233 } 211 }
234 212
235 // static 213 // static
236 SHA256HashValue X509Certificate::CalculateFingerprint256(OSCertHandle cert) { 214 SHA256HashValue X509Certificate::CalculateFingerprint256(OSCertHandle cert) {
237 SHA256HashValue sha256; 215 SHA256HashValue sha256;
238 unsigned int sha256_size = static_cast<unsigned int>(sizeof(sha256.data)); 216 memset(sha256.data, 0, sizeof(sha256.data));
239 int ret = X509_digest(cert, EVP_sha256(), sha256.data, &sha256_size); 217
240 CHECK(ret); 218 ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert));
241 CHECK_EQ(sha256_size, sizeof(sha256.data)); 219 if (!cert_data)
220 return sha256;
221 DCHECK(CFDataGetBytePtr(cert_data));
222 DCHECK_NE(0, CFDataGetLength(cert_data));
223 CC_SHA256(CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data),
224 sha256.data);
225
242 return sha256; 226 return sha256;
243 } 227 }
244 228
245 // static 229 // static
246 SHA1HashValue X509Certificate::CalculateCAFingerprint( 230 SHA1HashValue X509Certificate::CalculateCAFingerprint(
247 const OSCertHandles& intermediates) { 231 const OSCertHandles& intermediates) {
248 SHA1HashValue sha1; 232 SHA1HashValue sha1;
249 memset(sha1.data, 0, sizeof(sha1.data)); 233 memset(sha1.data, 0, sizeof(sha1.data));
250 234
251 SHA_CTX sha1_ctx; 235 CC_SHA1_CTX sha1_ctx;
252 SHA1_Init(&sha1_ctx); 236 CC_SHA1_Init(&sha1_ctx);
253 base::StringPiece der;
254 for (size_t i = 0; i < intermediates.size(); ++i) { 237 for (size_t i = 0; i < intermediates.size(); ++i) {
255 if (!x509_util::GetDER(intermediates[i], &der)) 238 ScopedCFTypeRef<CFDataRef> cert_data(
239 SecCertificateCopyData(intermediates[i]));
240 if (!cert_data)
256 return sha1; 241 return sha1;
257 SHA1_Update(&sha1_ctx, der.data(), der.length()); 242 CC_SHA1_Update(&sha1_ctx, CFDataGetBytePtr(cert_data),
243 CFDataGetLength(cert_data));
258 } 244 }
259 SHA1_Final(sha1.data, &sha1_ctx); 245 CC_SHA1_Final(sha1.data, &sha1_ctx);
260
261 return sha1; 246 return sha1;
262 } 247 }
263 248
264 // static 249 // static
265 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( 250 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
266 const char* data, 251 const char* data,
267 size_t length) { 252 size_t length) {
268 crypto::EnsureOpenSSLInit(); 253 ScopedCFTypeRef<CFDataRef> cert_data(CFDataCreateWithBytesNoCopy(
269 const unsigned char* d2i_data = 254 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data),
270 reinterpret_cast<const unsigned char*>(data); 255 base::checked_cast<CFIndex>(length), kCFAllocatorNull));
271 // Don't cache this data for x509_util::GetDER as this wire format 256 if (!cert_data)
272 // may be not be identical from the i2d_X509 roundtrip. 257 return nullptr;
273 X509* cert = d2i_X509(NULL, &d2i_data, base::checked_cast<long>(length)); 258 OSCertHandle cert_handle = SecCertificateCreateWithData(NULL, cert_data);
274 return cert; 259 if (!cert_handle)
260 return nullptr;
261 if (!IsValidOSCertHandle(cert_handle)) {
262 CFRelease(cert_handle);
263 return nullptr;
264 }
265 return cert_handle;
275 } 266 }
276 267
277 // static 268 // static
278 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( 269 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
279 const char* data, 270 const char* data,
280 size_t length, 271 size_t length,
281 Format format) { 272 Format format) {
282 OSCertHandles results; 273 OSCertHandles results;
283 274
284 switch (format) { 275 switch (format) {
285 case FORMAT_SINGLE_CERTIFICATE: { 276 case FORMAT_SINGLE_CERTIFICATE: {
286 OSCertHandle handle = CreateOSCertHandleFromBytes(data, length); 277 OSCertHandle handle =
278 X509Certificate::CreateOSCertHandleFromBytes(data, length);
287 if (handle) 279 if (handle)
288 results.push_back(handle); 280 results.push_back(handle);
289 break; 281 break;
290 } 282 }
291 case FORMAT_PKCS7: { 283 case FORMAT_PKCS7: {
292 CreateOSCertHandlesFromPKCS7Bytes(data, length, &results); 284 CreateOSCertHandlesFromPKCS7Bytes(data, length, &results);
293 break; 285 break;
294 } 286 }
295 default: { 287 default: {
296 NOTREACHED() << "Certificate format " << format << " unimplemented"; 288 NOTREACHED() << "Certificate format " << format << " unimplemented";
297 break; 289 break;
298 } 290 }
299 } 291 }
300 292
301 return results; 293 return results;
302 } 294 }
303 295
304 void X509Certificate::GetSubjectAltName( 296 void X509Certificate::GetSubjectAltName(
305 std::vector<std::string>* dns_names, 297 std::vector<std::string>* dns_names,
306 std::vector<std::string>* ip_addrs) const { 298 std::vector<std::string>* ip_addrs) const {
307 if (dns_names) 299 if (dns_names)
308 dns_names->clear(); 300 dns_names->clear();
309 if (ip_addrs) 301 if (ip_addrs)
310 ip_addrs->clear(); 302 ip_addrs->clear();
311 303
312 ParseSubjectAltName(cert_handle_, dns_names, ip_addrs); 304 ParseSubjectAltName(cert_handle_, dns_names, ip_addrs);
313 } 305 }
314 306
315 // static 307 // static
316 X509_STORE* X509Certificate::cert_store() {
317 return X509InitSingleton::GetInstance()->store();
318 }
319
320 // static
321 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, 308 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle,
322 std::string* encoded) { 309 std::string* encoded) {
323 base::StringPiece der; 310 base::StringPiece der;
324 if (!cert_handle || !x509_util::GetDER(cert_handle, &der)) 311 if (!cert_handle)
325 return false; 312 return false;
326 encoded->assign(der.data(), der.length()); 313 ScopedCFTypeRef<CFDataRef> der_data(SecCertificateCopyData(cert_handle));
314 if (!der_data)
315 return false;
316 encoded->assign(reinterpret_cast<const char*>(CFDataGetBytePtr(der_data)),
317 CFDataGetLength(der_data));
327 return true; 318 return true;
328 } 319 }
329 320
330 // static 321 // static
331 bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a, 322 bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a,
332 X509Certificate::OSCertHandle b) { 323 X509Certificate::OSCertHandle b) {
333 DCHECK(a && b); 324 DCHECK(a && b);
334 if (a == b) 325 if (a == b)
335 return true; 326 return true;
336 327 if (CFEqual(a, b))
337 // X509_cmp only checks the fingerprint, but we want to compare the whole 328 return true;
338 // DER data. Encoding it from OSCertHandle is an expensive operation, so we 329 ScopedCFTypeRef<CFDataRef> a_data(SecCertificateCopyData(a));
339 // cache the DER (if not already cached via X509_set_ex_data). 330 ScopedCFTypeRef<CFDataRef> b_data(SecCertificateCopyData(b));
340 base::StringPiece der_a, der_b; 331 return a_data && b_data &&
341 332 CFDataGetLength(a_data) == CFDataGetLength(b_data) &&
342 return x509_util::GetDER(a, &der_a) && 333 memcmp(CFDataGetBytePtr(a_data), CFDataGetBytePtr(b_data),
343 x509_util::GetDER(b, &der_b) && 334 CFDataGetLength(a_data)) == 0;
344 der_a == der_b;
345 } 335 }
346 336
347 // static 337 // static
348 X509Certificate::OSCertHandle X509Certificate::ReadOSCertHandleFromPickle( 338 X509Certificate::OSCertHandle X509Certificate::ReadOSCertHandleFromPickle(
349 base::PickleIterator* pickle_iter) { 339 base::PickleIterator* pickle_iter) {
350 const char* data; 340 const char* data;
351 int length; 341 int length;
352 if (!pickle_iter->ReadData(&data, &length)) 342 if (!pickle_iter->ReadData(&data, &length))
353 return NULL; 343 return NULL;
354 344
355 return CreateOSCertHandleFromBytes(data, length); 345 return X509Certificate::CreateOSCertHandleFromBytes(data, length);
356 } 346 }
357 347
358 // static 348 // static
359 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, 349 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle,
360 base::Pickle* pickle) { 350 base::Pickle* pickle) {
361 base::StringPiece der; 351 ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert_handle));
362 if (!x509_util::GetDER(cert_handle, &der)) 352 if (!cert_data)
363 return false; 353 return false;
364 354
365 return pickle->WriteData(der.data(), der.length()); 355 return pickle->WriteData(
356 reinterpret_cast<const char*>(CFDataGetBytePtr(cert_data)),
357 CFDataGetLength(cert_data));
366 } 358 }
367 359
368 // static 360 // static
369 void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle, 361 void X509Certificate::GetPublicKeyInfo(OSCertHandle os_cert,
370 size_t* size_bits, 362 size_t* size_bits,
371 PublicKeyType* type) { 363 PublicKeyType* type) {
davidben 2016/03/21 19:46:47 I'm really puzzled why this can't be done from App
svaldez 2016/03/21 20:23:52 Because its iOS?
372 *type = kPublicKeyTypeUnknown; 364 *type = kPublicKeyTypeUnknown;
373 *size_bits = 0; 365 *size_bits = 0;
374 366 ScopedX509 cert = OSCertHandleToOpenSSL(os_cert);
375 crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert_handle)); 367 crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert.get()));
376 if (!scoped_key.get()) 368 if (!scoped_key.get())
377 return; 369 return;
378 370
379 CHECK(scoped_key.get()); 371 CHECK(scoped_key.get());
380 EVP_PKEY* key = scoped_key.get(); 372 EVP_PKEY* key = scoped_key.get();
381 373
382 switch (key->type) { 374 switch (key->type) {
383 case EVP_PKEY_RSA: 375 case EVP_PKEY_RSA:
384 *type = kPublicKeyTypeRSA; 376 *type = kPublicKeyTypeRSA;
385 *size_bits = EVP_PKEY_size(key) * 8; 377 *size_bits = EVP_PKEY_size(key) * 8;
davidben 2016/03/21 19:46:47 I believe all of these want to be EVP_PKEY_bits(ke
svaldez 2016/03/21 20:23:52 Done.
386 break; 378 break;
387 case EVP_PKEY_DSA: 379 case EVP_PKEY_DSA:
388 *type = kPublicKeyTypeDSA; 380 *type = kPublicKeyTypeDSA;
389 *size_bits = EVP_PKEY_size(key) * 8; 381 *size_bits = EVP_PKEY_size(key) * 8;
390 break; 382 break;
391 case EVP_PKEY_EC: 383 case EVP_PKEY_EC:
392 *type = kPublicKeyTypeECDSA; 384 *type = kPublicKeyTypeECDSA;
393 *size_bits = EVP_PKEY_bits(key); 385 *size_bits = EVP_PKEY_bits(key);
394 break; 386 break;
395 case EVP_PKEY_DH: 387 case EVP_PKEY_DH:
396 *type = kPublicKeyTypeDH; 388 *type = kPublicKeyTypeDH;
397 *size_bits = EVP_PKEY_size(key) * 8; 389 *size_bits = EVP_PKEY_size(key) * 8;
398 break; 390 break;
399 } 391 }
400 } 392 }
401 393
394 bool X509Certificate::SupportsSSLClientAuth() const {
395 return false;
396 }
397
398 CFMutableArrayRef X509Certificate::CreateOSCertChainForCert() const {
399 CFMutableArrayRef cert_list =
400 CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
401 if (!cert_list)
402 return NULL;
403
404 CFArrayAppendValue(cert_list, os_cert_handle());
405 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i)
406 CFArrayAppendValue(cert_list, intermediate_ca_certs_[i]);
407
408 return cert_list;
409 }
410
402 bool X509Certificate::IsIssuedByEncoded( 411 bool X509Certificate::IsIssuedByEncoded(
403 const std::vector<std::string>& valid_issuers) { 412 const std::vector<std::string>& valid_issuers) {
404 if (valid_issuers.empty()) 413 if (valid_issuers.empty())
405 return false; 414 return false;
406 415
407 // Convert to a temporary list of X509_NAME objects. 416 // Convert to a temporary list of X509_NAME objects.
408 // It will own the objects it points to. 417 // It will own the objects it points to.
409 crypto::ScopedOpenSSL<STACK_OF(X509_NAME), sk_X509_NAME_free_all> 418 crypto::ScopedOpenSSL<STACK_OF(X509_NAME), sk_X509_NAME_free_all>
410 issuer_names(sk_X509_NAME_new_null()); 419 issuer_names(sk_X509_NAME_new_null());
411 if (!issuer_names.get()) 420 if (!issuer_names.get())
412 return false; 421 return false;
413 422
414 for (std::vector<std::string>::const_iterator it = valid_issuers.begin(); 423 for (std::vector<std::string>::const_iterator it = valid_issuers.begin();
415 it != valid_issuers.end(); ++it) { 424 it != valid_issuers.end(); ++it) {
416 const unsigned char* p = 425 const unsigned char* p = reinterpret_cast<const unsigned char*>(it->data());
417 reinterpret_cast<const unsigned char*>(it->data());
418 long len = static_cast<long>(it->length()); 426 long len = static_cast<long>(it->length());
419 X509_NAME* ca_name = d2i_X509_NAME(NULL, &p, len); 427 X509_NAME* ca_name = d2i_X509_NAME(NULL, &p, len);
420 if (ca_name == NULL) 428 if (ca_name == NULL)
421 return false; 429 return false;
422 sk_X509_NAME_push(issuer_names.get(), ca_name); 430 sk_X509_NAME_push(issuer_names.get(), ca_name);
423 } 431 }
424 432
425 // Create a temporary list of X509_NAME objects corresponding 433 // Create a temporary list of X509_NAME objects corresponding
426 // to the certificate chain. It doesn't own the object it points to. 434 // to the certificate chain. It doesn't own the object it points to.
427 std::vector<X509_NAME*> cert_names; 435 std::vector<X509_NAME*> cert_names;
428 X509_NAME* issuer = X509_get_issuer_name(cert_handle_); 436 ScopedX509 x509_cert = OSCertHandleToOpenSSL(cert_handle_);
437 X509_NAME* issuer = X509_get_issuer_name(x509_cert.get());
429 if (issuer == NULL) 438 if (issuer == NULL)
430 return false; 439 return false;
431 440
432 cert_names.push_back(issuer); 441 cert_names.push_back(issuer);
433 for (OSCertHandles::iterator it = intermediate_ca_certs_.begin(); 442 for (OSCertHandles::iterator it = intermediate_ca_certs_.begin();
434 it != intermediate_ca_certs_.end(); ++it) { 443 it != intermediate_ca_certs_.end(); ++it) {
435 issuer = X509_get_issuer_name(*it); 444 ScopedX509 intermediate_cert = OSCertHandleToOpenSSL(*it);
445 issuer = X509_get_issuer_name(intermediate_cert.get());
436 if (issuer == NULL) 446 if (issuer == NULL)
437 return false; 447 return false;
438 cert_names.push_back(issuer); 448 cert_names.push_back(issuer);
439 } 449 }
440 450
441 // and 'cert_names'. 451 // and 'cert_names'.
442 for (size_t n = 0; n < cert_names.size(); ++n) { 452 for (size_t n = 0; n < cert_names.size(); ++n) {
443 for (size_t m = 0; m < sk_X509_NAME_num(issuer_names.get()); ++m) { 453 for (size_t m = 0; m < sk_X509_NAME_num(issuer_names.get()); ++m) {
444 X509_NAME* issuer = sk_X509_NAME_value(issuer_names.get(), m); 454 X509_NAME* issuer = sk_X509_NAME_value(issuer_names.get(), m);
445 if (X509_NAME_cmp(issuer, cert_names[n]) == 0) { 455 if (X509_NAME_cmp(issuer, cert_names[n]) == 0) {
446 return true; 456 return true;
447 } 457 }
448 } 458 }
449 } 459 }
450 460
451 return false; 461 return false;
452 } 462 }
453 463
454 // static 464 // static
455 bool X509Certificate::IsSelfSigned(OSCertHandle cert_handle) { 465 bool X509Certificate::IsSelfSigned(OSCertHandle os_cert) {
456 crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert_handle)); 466 ScopedX509 cert = OSCertHandleToOpenSSL(os_cert);
467 crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert.get()));
457 if (!scoped_key) 468 if (!scoped_key)
458 return false; 469 return false;
459 470
460 // NOTE: X509_verify() returns 1 in case of success, 0 or -1 on error. 471 // NOTE: X509_verify() returns 1 in case of success, 0 or -1 on error.
461 return X509_verify(cert_handle, scoped_key.get()) == 1; 472 return X509_verify(cert.get(), scoped_key.get()) == 1;
462 } 473 }
463 474
464 } // namespace net 475 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698