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

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

Issue 2400033005: Use BoringSSL scopers in //net. (Closed)
Patch Set: avoid some unnecessary refcount-bumping Created 4 years, 2 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) 2016 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 <CommonCrypto/CommonDigest.h> 7 #include <CommonCrypto/CommonDigest.h>
8 #include <Security/Security.h> 8 #include <Security/Security.h>
9 9
10 #include <openssl/x509.h> 10 #include <openssl/x509.h>
11 #include <openssl/x509v3.h> 11 #include <openssl/x509v3.h>
12 12
13 #include "base/mac/scoped_cftyperef.h" 13 #include "base/mac/scoped_cftyperef.h"
14 #include "base/pickle.h" 14 #include "base/pickle.h"
15 #include "base/strings/string_piece.h" 15 #include "base/strings/string_piece.h"
16 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "crypto/openssl_util.h" 17 #include "crypto/openssl_util.h"
18 #include "crypto/scoped_openssl_types.h"
19 #include "net/base/ip_address.h" 18 #include "net/base/ip_address.h"
20 #include "net/cert/x509_util_openssl.h" 19 #include "net/cert/x509_util_openssl.h"
21 #include "net/ssl/openssl_ssl_util.h" 20 #include "net/ssl/openssl_ssl_util.h"
22 21
23 using base::ScopedCFTypeRef; 22 using base::ScopedCFTypeRef;
24 23
25 namespace net { 24 namespace net {
26 25
27 namespace { 26 namespace {
28 27
29 using ScopedGENERAL_NAMES =
30 crypto::ScopedOpenSSL<GENERAL_NAMES, GENERAL_NAMES_free>;
31
32 // Returns true if a given |cert_handle| is actually a valid X.509 certificate 28 // Returns true if a given |cert_handle| is actually a valid X.509 certificate
33 // handle. 29 // handle.
34 // 30 //
35 // SecCertificateCreateFromData() does not always force the immediate parsing of 31 // SecCertificateCreateFromData() does not always force the immediate parsing of
36 // the certificate, and as such, may return a SecCertificateRef for an 32 // the certificate, and as such, may return a SecCertificateRef for an
37 // invalid/unparsable certificate. Force parsing to occur to ensure that the 33 // invalid/unparsable certificate. Force parsing to occur to ensure that the
38 // SecCertificateRef is correct. On later versions where 34 // SecCertificateRef is correct. On later versions where
39 // SecCertificateCreateFromData() immediately parses, rather than lazily, this 35 // SecCertificateCreateFromData() immediately parses, rather than lazily, this
40 // call is cheap, as the subject is cached. 36 // call is cheap, as the subject is cached.
41 bool IsValidOSCertHandle(SecCertificateRef cert_handle) { 37 bool IsValidOSCertHandle(SecCertificateRef cert_handle) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 x509_util::ParsePrincipalValueByNID(x509_name, NID_stateOrProvinceName, 98 x509_util::ParsePrincipalValueByNID(x509_name, NID_stateOrProvinceName,
103 &principal->state_or_province_name); 99 &principal->state_or_province_name);
104 x509_util::ParsePrincipalValueByNID(x509_name, NID_countryName, 100 x509_util::ParsePrincipalValueByNID(x509_name, NID_countryName,
105 &principal->country_name); 101 &principal->country_name);
106 } 102 }
107 103
108 void ParseSubjectAltName(X509Certificate::OSCertHandle os_cert, 104 void ParseSubjectAltName(X509Certificate::OSCertHandle os_cert,
109 std::vector<std::string>* dns_names, 105 std::vector<std::string>* dns_names,
110 std::vector<std::string>* ip_addresses) { 106 std::vector<std::string>* ip_addresses) {
111 DCHECK(dns_names || ip_addresses); 107 DCHECK(dns_names || ip_addresses);
112 ScopedX509 cert = OSCertHandleToOpenSSL(os_cert); 108 bssl::UniquePtr<X509> cert = OSCertHandleToOpenSSL(os_cert);
113 if (!cert.get()) 109 if (!cert.get())
114 return; 110 return;
115 int index = X509_get_ext_by_NID(cert.get(), NID_subject_alt_name, -1); 111 int index = X509_get_ext_by_NID(cert.get(), NID_subject_alt_name, -1);
116 X509_EXTENSION* alt_name_ext = X509_get_ext(cert.get(), index); 112 X509_EXTENSION* alt_name_ext = X509_get_ext(cert.get(), index);
117 if (!alt_name_ext) 113 if (!alt_name_ext)
118 return; 114 return;
119 115
120 ScopedGENERAL_NAMES alt_names( 116 bssl::UniquePtr<GENERAL_NAMES> alt_names(
121 reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext))); 117 reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext)));
122 if (!alt_names.get()) 118 if (!alt_names.get())
123 return; 119 return;
124 120
125 for (size_t i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) { 121 for (size_t i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) {
126 const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i); 122 const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i);
127 if (name->type == GEN_DNS && dns_names) { 123 if (name->type == GEN_DNS && dns_names) {
128 const unsigned char* dns_name = ASN1_STRING_data(name->d.dNSName); 124 const unsigned char* dns_name = ASN1_STRING_data(name->d.dNSName);
129 if (!dns_name) 125 if (!dns_name)
130 continue; 126 continue;
(...skipping 12 matching lines...) Expand all
143 // net mask hence 8 or 32 bytes. Logging to help diagnose any mixup. 139 // net mask hence 8 or 32 bytes. Logging to help diagnose any mixup.
144 LOG(WARNING) << "Bad sized IP Address in cert: " << ip_addr_len; 140 LOG(WARNING) << "Bad sized IP Address in cert: " << ip_addr_len;
145 continue; 141 continue;
146 } 142 }
147 ip_addresses->push_back( 143 ip_addresses->push_back(
148 std::string(reinterpret_cast<const char*>(ip_addr), ip_addr_len)); 144 std::string(reinterpret_cast<const char*>(ip_addr), ip_addr_len));
149 } 145 }
150 } 146 }
151 } 147 }
152 148
153 // Used to free a list of X509_NAMEs and the objects it points to.
154 void sk_X509_NAME_free_all(STACK_OF(X509_NAME) * sk) {
155 sk_X509_NAME_pop_free(sk, X509_NAME_free);
156 }
157
158 } // namespace 149 } // namespace
159 150
160 // static 151 // static
161 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( 152 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle(
162 OSCertHandle handle) { 153 OSCertHandle handle) {
163 if (!handle) 154 if (!handle)
164 return nullptr; 155 return nullptr;
165 return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle))); 156 return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle)));
166 } 157 }
167 158
168 // static 159 // static
169 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { 160 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
170 if (cert_handle) 161 if (cert_handle)
171 CFRelease(cert_handle); 162 CFRelease(cert_handle);
172 } 163 }
173 164
174 void X509Certificate::Initialize() { 165 void X509Certificate::Initialize() {
175 crypto::EnsureOpenSSLInit(); 166 crypto::EnsureOpenSSLInit();
176 ScopedX509 x509_cert = OSCertHandleToOpenSSL(cert_handle_); 167 bssl::UniquePtr<X509> x509_cert = OSCertHandleToOpenSSL(cert_handle_);
177 if (!x509_cert) 168 if (!x509_cert)
178 return; 169 return;
179 ASN1_INTEGER* serial_num = X509_get_serialNumber(x509_cert.get()); 170 ASN1_INTEGER* serial_num = X509_get_serialNumber(x509_cert.get());
180 if (serial_num) { 171 if (serial_num) {
181 // ASN1_INTEGERS represent the decoded number, in a format internal to 172 // ASN1_INTEGERS represent the decoded number, in a format internal to
182 // OpenSSL. Most notably, this may have leading zeroes stripped off for 173 // OpenSSL. Most notably, this may have leading zeroes stripped off for
183 // numbers whose first byte is >= 0x80. Thus, it is necessary to 174 // numbers whose first byte is >= 0x80. Thus, it is necessary to
184 // re-encoded the integer back into DER, which is what the interface 175 // re-encoded the integer back into DER, which is what the interface
185 // of X509Certificate exposes, to ensure callers get the proper (DER) 176 // of X509Certificate exposes, to ensure callers get the proper (DER)
186 // value. 177 // value.
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 reinterpret_cast<const char*>(CFDataGetBytePtr(cert_data)), 326 reinterpret_cast<const char*>(CFDataGetBytePtr(cert_data)),
336 CFDataGetLength(cert_data)); 327 CFDataGetLength(cert_data));
337 } 328 }
338 329
339 // static 330 // static
340 void X509Certificate::GetPublicKeyInfo(OSCertHandle os_cert, 331 void X509Certificate::GetPublicKeyInfo(OSCertHandle os_cert,
341 size_t* size_bits, 332 size_t* size_bits,
342 PublicKeyType* type) { 333 PublicKeyType* type) {
343 *type = kPublicKeyTypeUnknown; 334 *type = kPublicKeyTypeUnknown;
344 *size_bits = 0; 335 *size_bits = 0;
345 ScopedX509 cert = OSCertHandleToOpenSSL(os_cert); 336 bssl::UniquePtr<X509> cert = OSCertHandleToOpenSSL(os_cert);
346 if (!cert) 337 if (!cert)
347 return; 338 return;
348 crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert.get())); 339 bssl::UniquePtr<EVP_PKEY> scoped_key(X509_get_pubkey(cert.get()));
349 if (!scoped_key) 340 if (!scoped_key)
350 return; 341 return;
351 342
352 EVP_PKEY* key = scoped_key.get(); 343 EVP_PKEY* key = scoped_key.get();
353 344
354 switch (key->type) { 345 switch (key->type) {
355 case EVP_PKEY_RSA: 346 case EVP_PKEY_RSA:
356 *type = kPublicKeyTypeRSA; 347 *type = kPublicKeyTypeRSA;
357 break; 348 break;
358 case EVP_PKEY_DSA: 349 case EVP_PKEY_DSA:
(...skipping 26 matching lines...) Expand all
385 return cert_list; 376 return cert_list;
386 } 377 }
387 378
388 bool X509Certificate::IsIssuedByEncoded( 379 bool X509Certificate::IsIssuedByEncoded(
389 const std::vector<std::string>& valid_issuers) { 380 const std::vector<std::string>& valid_issuers) {
390 if (valid_issuers.empty()) 381 if (valid_issuers.empty())
391 return false; 382 return false;
392 383
393 // Convert to a temporary list of X509_NAME objects. 384 // Convert to a temporary list of X509_NAME objects.
394 // It will own the objects it points to. 385 // It will own the objects it points to.
395 crypto::ScopedOpenSSL<STACK_OF(X509_NAME), sk_X509_NAME_free_all> 386 bssl::UniquePtr<STACK_OF(X509_NAME)> issuer_names(sk_X509_NAME_new_null());
eroman 2016/10/10 22:45:55 The STACK_OF() stuff is kind of inscrutable to me.
davidben 2016/10/10 23:24:40 Fake C templates. :-) You can basically pretend it
396 issuer_names(sk_X509_NAME_new_null());
397 if (!issuer_names) 387 if (!issuer_names)
398 return false; 388 return false;
399 389
400 for (std::vector<std::string>::const_iterator it = valid_issuers.begin(); 390 for (std::vector<std::string>::const_iterator it = valid_issuers.begin();
401 it != valid_issuers.end(); ++it) { 391 it != valid_issuers.end(); ++it) {
402 const unsigned char* p = reinterpret_cast<const unsigned char*>(it->data()); 392 const unsigned char* p = reinterpret_cast<const unsigned char*>(it->data());
403 long len = static_cast<long>(it->length()); 393 long len = static_cast<long>(it->length());
404 X509_NAME* ca_name = d2i_X509_NAME(nullptr, &p, len); 394 X509_NAME* ca_name = d2i_X509_NAME(nullptr, &p, len);
405 if (ca_name == nullptr) 395 if (ca_name == nullptr)
406 return false; 396 return false;
407 sk_X509_NAME_push(issuer_names.get(), ca_name); 397 sk_X509_NAME_push(issuer_names.get(), ca_name);
408 } 398 }
409 399
410 ScopedX509 x509_cert = OSCertHandleToOpenSSL(cert_handle_); 400 bssl::UniquePtr<X509> x509_cert = OSCertHandleToOpenSSL(cert_handle_);
411 if (!x509_cert) 401 if (!x509_cert)
412 return false; 402 return false;
413 X509_NAME* cert_issuer = X509_get_issuer_name(x509_cert.get()); 403 X509_NAME* cert_issuer = X509_get_issuer_name(x509_cert.get());
414 if (cert_issuer == nullptr) 404 if (cert_issuer == nullptr)
415 return false; 405 return false;
416 406
417 for (size_t m = 0; m < sk_X509_NAME_num(issuer_names.get()); ++m) { 407 for (size_t m = 0; m < sk_X509_NAME_num(issuer_names.get()); ++m) {
418 X509_NAME* issuer = sk_X509_NAME_value(issuer_names.get(), m); 408 X509_NAME* issuer = sk_X509_NAME_value(issuer_names.get(), m);
419 if (X509_NAME_cmp(issuer, cert_issuer) == 0) { 409 if (X509_NAME_cmp(issuer, cert_issuer) == 0) {
420 return true; 410 return true;
421 } 411 }
422 } 412 }
423 413
424 for (OSCertHandles::iterator it = intermediate_ca_certs_.begin(); 414 for (OSCertHandles::iterator it = intermediate_ca_certs_.begin();
425 it != intermediate_ca_certs_.end(); ++it) { 415 it != intermediate_ca_certs_.end(); ++it) {
426 ScopedX509 intermediate_cert = OSCertHandleToOpenSSL(*it); 416 bssl::UniquePtr<X509> intermediate_cert = OSCertHandleToOpenSSL(*it);
427 if (!intermediate_cert) 417 if (!intermediate_cert)
428 return false; 418 return false;
429 cert_issuer = X509_get_issuer_name(intermediate_cert.get()); 419 cert_issuer = X509_get_issuer_name(intermediate_cert.get());
430 if (cert_issuer == nullptr) 420 if (cert_issuer == nullptr)
431 return false; 421 return false;
432 422
433 for (size_t m = 0; m < sk_X509_NAME_num(issuer_names.get()); ++m) { 423 for (size_t m = 0; m < sk_X509_NAME_num(issuer_names.get()); ++m) {
434 X509_NAME* issuer = sk_X509_NAME_value(issuer_names.get(), m); 424 X509_NAME* issuer = sk_X509_NAME_value(issuer_names.get(), m);
435 if (X509_NAME_cmp(issuer, cert_issuer) == 0) { 425 if (X509_NAME_cmp(issuer, cert_issuer) == 0) {
436 return true; 426 return true;
437 } 427 }
438 } 428 }
439 } 429 }
440 430
441 return false; 431 return false;
442 } 432 }
443 433
444 // static 434 // static
445 bool X509Certificate::IsSelfSigned(OSCertHandle os_cert) { 435 bool X509Certificate::IsSelfSigned(OSCertHandle os_cert) {
446 ScopedX509 cert = OSCertHandleToOpenSSL(os_cert); 436 bssl::UniquePtr<X509> cert = OSCertHandleToOpenSSL(os_cert);
447 if (!cert) 437 if (!cert)
448 return false; 438 return false;
449 crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert.get())); 439 bssl::UniquePtr<EVP_PKEY> scoped_key(X509_get_pubkey(cert.get()));
450 if (!scoped_key) 440 if (!scoped_key)
451 return false; 441 return false;
452 if (!X509_verify(cert.get(), scoped_key.get())) 442 if (!X509_verify(cert.get(), scoped_key.get()))
453 return false; 443 return false;
454 return X509_check_issued(cert.get(), cert.get()) == X509_V_OK; 444 return X509_check_issued(cert.get(), cert.get()) == X509_V_OK;
455 } 445 }
456 446
457 } // namespace net 447 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698