Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/base/x509_certificate.h" | 5 #include "net/base/x509_certificate.h" |
| 6 | 6 |
| 7 #include <openssl/asn1.h> | 7 #include <openssl/asn1.h> |
| 8 #include <openssl/crypto.h> | 8 #include <openssl/crypto.h> |
| 9 #include <openssl/obj_mac.h> | 9 #include <openssl/obj_mac.h> |
| 10 #include <openssl/pem.h> | 10 #include <openssl/pem.h> |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 226 if (data_length <= 0 || !data) | 226 if (data_length <= 0 || !data) |
| 227 return false; | 227 return false; |
| 228 internal_cache = SetDERCache(cert, x509_der_cache_index, data, data_length); | 228 internal_cache = SetDERCache(cert, x509_der_cache_index, data, data_length); |
| 229 if (!internal_cache) | 229 if (!internal_cache) |
| 230 return false; | 230 return false; |
| 231 } | 231 } |
| 232 *der_cache = *internal_cache; | 232 *der_cache = *internal_cache; |
| 233 return true; | 233 return true; |
| 234 } | 234 } |
| 235 | 235 |
| 236 // Used to free a list of X509_NAMEs without touching its objts. | |
| 237 // sk_X509_NAME_free is a macro and can't be used as function | |
| 238 // template parameter. | |
| 239 void sk_X509_NAME_free_list(STACK_OF(X509_NAME)* sk) { | |
| 240 sk_X509_NAME_free(sk); | |
| 241 } | |
| 242 | |
| 243 // Used to free a list of X509_NAMEs and the objects it points to. | |
| 244 void sk_X509_NAME_free_all(STACK_OF(X509_NAME)* sk) { | |
| 245 sk_X509_NAME_pop_free(sk, X509_NAME_free); | |
| 246 } | |
| 247 | |
| 236 } // namespace | 248 } // namespace |
| 237 | 249 |
| 238 // static | 250 // static |
| 239 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( | 251 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( |
| 240 OSCertHandle cert_handle) { | 252 OSCertHandle cert_handle) { |
| 241 DCHECK(cert_handle); | 253 DCHECK(cert_handle); |
| 242 // Using X509_dup causes the entire certificate to be reparsed. This | 254 // Using X509_dup causes the entire certificate to be reparsed. This |
| 243 // conversion, besides being non-trivial, drops any associated | 255 // conversion, besides being non-trivial, drops any associated |
| 244 // application-specific data set by X509_set_ex_data. Using CRYPTO_add | 256 // application-specific data set by X509_set_ex_data. Using CRYPTO_add |
| 245 // just bumps up the ref-count for the cert, without causing any allocations | 257 // just bumps up the ref-count for the cert, without causing any allocations |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 464 *type = kPublicKeyTypeECDSA; | 476 *type = kPublicKeyTypeECDSA; |
| 465 *size_bits = EVP_PKEY_size(key); | 477 *size_bits = EVP_PKEY_size(key); |
| 466 break; | 478 break; |
| 467 case EVP_PKEY_DH: | 479 case EVP_PKEY_DH: |
| 468 *type = kPublicKeyTypeDH; | 480 *type = kPublicKeyTypeDH; |
| 469 *size_bits = EVP_PKEY_size(key) * 8; | 481 *size_bits = EVP_PKEY_size(key) * 8; |
| 470 break; | 482 break; |
| 471 } | 483 } |
| 472 } | 484 } |
| 473 | 485 |
| 486 bool X509Certificate::IsIssuedByEncoded( | |
| 487 const std::vector<std::string>& valid_issuers) { | |
| 488 if (valid_issuers.empty()) | |
| 489 return false; | |
| 490 | |
| 491 // Convert to a temporary list of X509_NAME objects. | |
| 492 // It will own the objects it points to. | |
| 493 crypto::ScopedOpenSSL<STACK_OF(X509_NAME), sk_X509_NAME_free_all> | |
| 494 issuer_names(sk_X509_NAME_new_null()); | |
| 495 if (!issuer_names.get()) | |
| 496 return false; | |
| 497 | |
| 498 for (std::vector<std::string>::const_iterator it = valid_issuers.begin(); | |
| 499 it != valid_issuers.end(); ++it) { | |
| 500 const unsigned char* p = | |
| 501 reinterpret_cast<const unsigned char*>(it->data()); | |
| 502 long len = static_cast<long>(it->length()); | |
| 503 X509_NAME* ca_name = d2i_X509_NAME(NULL, &p, len); | |
| 504 if (ca_name == NULL) | |
| 505 return false; | |
| 506 sk_X509_NAME_push(issuer_names.get(), ca_name); | |
| 507 } | |
| 508 | |
| 509 // Create a temporary list of X509_NAME objects corresponding | |
| 510 // to the certificate chain. It doesn't own the object it points to. | |
| 511 crypto::ScopedOpenSSL<STACK_OF(X509_NAME), sk_X509_NAME_free_list> | |
| 512 cert_names(sk_X509_NAME_new_null()); | |
| 513 if (!cert_names.get()) | |
| 514 return false; | |
| 515 | |
| 516 X509_NAME* issuer = X509_get_issuer_name(cert_handle_); | |
| 517 if (issuer == NULL) | |
| 518 return false; | |
| 519 | |
| 520 sk_X509_NAME_push(cert_names.get(), issuer); | |
| 521 for (OSCertHandles::iterator it = intermediate_ca_certs_.begin(); | |
| 522 it != intermediate_ca_certs_.end(); ++it) { | |
| 523 issuer = X509_get_subject_name(*it); | |
|
Ryan Sleevi
2012/12/13 19:49:05
BUG: See previous comments re: subject vs issuer
digit1
2012/12/14 17:54:33
Done.
| |
| 524 if (issuer == NULL) | |
| 525 return false; | |
| 526 sk_X509_NAME_push(cert_names.get(), issuer); | |
| 527 } | |
| 528 | |
| 529 // and 'cert_names'. | |
|
Ryan Sleevi
2012/12/13 19:49:05
Not sure this comment really makes sense. Is it a
digit1
2012/12/14 17:54:33
Yes, it's a left-over, I've removed it.
| |
| 530 X509_NAME* issued_by = NULL; | |
| 531 for (int n = 0; n < sk_X509_NAME_num(cert_names.get()); ++n) { | |
| 532 X509_NAME* cert_name = sk_X509_NAME_value(cert_names.get(), n); | |
| 533 for (int m = 0; m < sk_X509_NAME_num(issuer_names.get()); ++m) { | |
| 534 X509_NAME* issuer = sk_X509_NAME_value(issuer_names.get(), m); | |
| 535 if (X509_NAME_cmp(issuer, cert_name) == 0) { | |
| 536 issued_by = cert_name; | |
| 537 break; | |
|
Ryan Sleevi
2012/12/13 19:49:05
This breaks the inner loop but keeps spinning the
digit1
2012/12/14 17:54:33
Doh. Thanks for this.
| |
| 538 } | |
| 539 } | |
| 540 } | |
| 541 | |
| 542 return (issued_by != NULL); | |
| 543 } | |
| 544 | |
| 474 } // namespace net | 545 } // namespace net |
| OLD | NEW |