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 |