OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/pickle.h" | 8 #include "base/pickle.h" |
9 #include "base/string_tokenizer.h" | 9 #include "base/string_tokenizer.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 &principal->common_name, &principal->locality_name, | 427 &principal->common_name, &principal->locality_name, |
428 &principal->state_or_province_name, &principal->country_name }; | 428 &principal->state_or_province_name, &principal->country_name }; |
429 for (int i = 0; i < arraysize(single_value_lists); ++i) { | 429 for (int i = 0; i < arraysize(single_value_lists); ++i) { |
430 int length = static_cast<int>(single_value_lists[i]->size()); | 430 int length = static_cast<int>(single_value_lists[i]->size()); |
431 DCHECK(single_value_lists[i]->size() <= 1); | 431 DCHECK(single_value_lists[i]->size() <= 1); |
432 if (single_value_lists[i]->size() > 0) | 432 if (single_value_lists[i]->size() > 0) |
433 *(single_values[i]) = (*(single_value_lists[i]))[0]; | 433 *(single_values[i]) = (*(single_value_lists[i]))[0]; |
434 } | 434 } |
435 } | 435 } |
436 | 436 |
| 437 void AddCertsFromStore(HCERTSTORE store, |
| 438 X509Certificate::OSCertHandles* results) { |
| 439 PCCERT_CONTEXT cert = NULL; |
| 440 |
| 441 while ((cert = CertEnumCertificatesInStore(store, cert)) != NULL) { |
| 442 PCCERT_CONTEXT to_add = NULL; |
| 443 if (CertAddCertificateContextToStore( |
| 444 NULL, // The cert won't be persisted in any cert store. This breaks |
| 445 // any association the context currently has to |store|, which |
| 446 // allows us, the caller, to safely close |store| without |
| 447 // releasing the cert handles. |
| 448 cert, |
| 449 CERT_STORE_ADD_USE_EXISTING, |
| 450 &to_add) && to_add != NULL) { |
| 451 // When processing stores generated from PKCS#7/PKCS#12 files, it |
| 452 // appears that the order returned is the inverse of the order that it |
| 453 // appeared in the file. |
| 454 // TODO(rsleevi): Ensure this order is consistent across all Win |
| 455 // versions |
| 456 results->insert(results->begin(), to_add); |
| 457 } |
| 458 } |
| 459 } |
| 460 |
| 461 X509Certificate::OSCertHandles ParsePKCS7(const char* data, size_t length) { |
| 462 X509Certificate::OSCertHandles results; |
| 463 CERT_BLOB data_blob; |
| 464 data_blob.cbData = length; |
| 465 data_blob.pbData = reinterpret_cast<BYTE*>(const_cast<char*>(data)); |
| 466 |
| 467 HCERTSTORE out_store = NULL; |
| 468 |
| 469 DWORD expected_types = CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED | |
| 470 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED | |
| 471 CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED; |
| 472 |
| 473 if (!CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &data_blob, expected_types, |
| 474 CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL, NULL, |
| 475 &out_store, NULL, NULL) || out_store == NULL) { |
| 476 return results; |
| 477 } |
| 478 |
| 479 AddCertsFromStore(out_store, &results); |
| 480 CertCloseStore(out_store, CERT_CLOSE_STORE_CHECK_FLAG); |
| 481 |
| 482 return results; |
| 483 } |
| 484 |
437 } // namespace | 485 } // namespace |
438 | 486 |
439 void X509Certificate::Initialize() { | 487 void X509Certificate::Initialize() { |
440 std::wstring subject_info; | 488 std::wstring subject_info; |
441 std::wstring issuer_info; | 489 std::wstring issuer_info; |
442 DWORD name_size; | 490 DWORD name_size; |
443 DCHECK(cert_handle_); | 491 DCHECK(cert_handle_); |
444 name_size = CertNameToStr(cert_handle_->dwCertEncodingType, | 492 name_size = CertNameToStr(cert_handle_->dwCertEncodingType, |
445 &cert_handle_->pCertInfo->Subject, | 493 &cert_handle_->pCertInfo->Subject, |
446 CERT_X500_NAME_STR | CERT_NAME_STR_CRLF_FLAG, | 494 CERT_X500_NAME_STR | CERT_NAME_STR_CRLF_FLAG, |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 NULL, // the cert won't be persisted in any cert store | 794 NULL, // the cert won't be persisted in any cert store |
747 X509_ASN_ENCODING, | 795 X509_ASN_ENCODING, |
748 reinterpret_cast<const BYTE*>(data), length, | 796 reinterpret_cast<const BYTE*>(data), length, |
749 CERT_STORE_ADD_USE_EXISTING, | 797 CERT_STORE_ADD_USE_EXISTING, |
750 &cert_handle)) | 798 &cert_handle)) |
751 return NULL; | 799 return NULL; |
752 | 800 |
753 return cert_handle; | 801 return cert_handle; |
754 } | 802 } |
755 | 803 |
| 804 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( |
| 805 const char* data, int length, Format format) { |
| 806 OSCertHandles results; |
| 807 switch (format) { |
| 808 case FORMAT_SINGLE_CERTIFICATE: { |
| 809 OSCertHandle handle = CreateOSCertHandleFromBytes(data, length); |
| 810 if (handle != NULL) |
| 811 results.push_back(handle); |
| 812 break; |
| 813 } |
| 814 case FORMAT_PKCS7: |
| 815 results = ParsePKCS7(data, length); |
| 816 break; |
| 817 default: |
| 818 NOTREACHED() << "Certificate format " << format << " unimplemented"; |
| 819 break; |
| 820 } |
| 821 |
| 822 return results; |
| 823 } |
| 824 |
756 | 825 |
757 // static | 826 // static |
758 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( | 827 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( |
759 OSCertHandle cert_handle) { | 828 OSCertHandle cert_handle) { |
760 return CertDuplicateCertificateContext(cert_handle); | 829 return CertDuplicateCertificateContext(cert_handle); |
761 } | 830 } |
762 | 831 |
763 // static | 832 // static |
764 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { | 833 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { |
765 CertFreeCertificateContext(cert_handle); | 834 CertFreeCertificateContext(cert_handle); |
(...skipping 10 matching lines...) Expand all Loading... |
776 DWORD sha1_size = sizeof(sha1.data); | 845 DWORD sha1_size = sizeof(sha1.data); |
777 rv = CryptHashCertificate(NULL, CALG_SHA1, 0, cert->pbCertEncoded, | 846 rv = CryptHashCertificate(NULL, CALG_SHA1, 0, cert->pbCertEncoded, |
778 cert->cbCertEncoded, sha1.data, &sha1_size); | 847 cert->cbCertEncoded, sha1.data, &sha1_size); |
779 DCHECK(rv && sha1_size == sizeof(sha1.data)); | 848 DCHECK(rv && sha1_size == sizeof(sha1.data)); |
780 if (!rv) | 849 if (!rv) |
781 memset(sha1.data, 0, sizeof(sha1.data)); | 850 memset(sha1.data, 0, sizeof(sha1.data)); |
782 return sha1; | 851 return sha1; |
783 } | 852 } |
784 | 853 |
785 } // namespace net | 854 } // namespace net |
OLD | NEW |