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 | |
485 } // namespace | 437 } // namespace |
486 | 438 |
487 void X509Certificate::Initialize() { | 439 void X509Certificate::Initialize() { |
488 std::wstring subject_info; | 440 std::wstring subject_info; |
489 std::wstring issuer_info; | 441 std::wstring issuer_info; |
490 DWORD name_size; | 442 DWORD name_size; |
491 DCHECK(cert_handle_); | 443 DCHECK(cert_handle_); |
492 name_size = CertNameToStr(cert_handle_->dwCertEncodingType, | 444 name_size = CertNameToStr(cert_handle_->dwCertEncodingType, |
493 &cert_handle_->pCertInfo->Subject, | 445 &cert_handle_->pCertInfo->Subject, |
494 CERT_X500_NAME_STR | CERT_NAME_STR_CRLF_FLAG, | 446 CERT_X500_NAME_STR | CERT_NAME_STR_CRLF_FLAG, |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
794 NULL, // the cert won't be persisted in any cert store | 746 NULL, // the cert won't be persisted in any cert store |
795 X509_ASN_ENCODING, | 747 X509_ASN_ENCODING, |
796 reinterpret_cast<const BYTE*>(data), length, | 748 reinterpret_cast<const BYTE*>(data), length, |
797 CERT_STORE_ADD_USE_EXISTING, | 749 CERT_STORE_ADD_USE_EXISTING, |
798 &cert_handle)) | 750 &cert_handle)) |
799 return NULL; | 751 return NULL; |
800 | 752 |
801 return cert_handle; | 753 return cert_handle; |
802 } | 754 } |
803 | 755 |
804 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( | |
805 const char* data, int length, Format format) { | |
806 OSCertHandles results; | |
807 switch (format) { | |
808 case FORMAT_DER: { | |
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 | |
825 | 756 |
826 // static | 757 // static |
827 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( | 758 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( |
828 OSCertHandle cert_handle) { | 759 OSCertHandle cert_handle) { |
829 return CertDuplicateCertificateContext(cert_handle); | 760 return CertDuplicateCertificateContext(cert_handle); |
830 } | 761 } |
831 | 762 |
832 // static | 763 // static |
833 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { | 764 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { |
834 CertFreeCertificateContext(cert_handle); | 765 CertFreeCertificateContext(cert_handle); |
(...skipping 10 matching lines...) Expand all Loading... |
845 DWORD sha1_size = sizeof(sha1.data); | 776 DWORD sha1_size = sizeof(sha1.data); |
846 rv = CryptHashCertificate(NULL, CALG_SHA1, 0, cert->pbCertEncoded, | 777 rv = CryptHashCertificate(NULL, CALG_SHA1, 0, cert->pbCertEncoded, |
847 cert->cbCertEncoded, sha1.data, &sha1_size); | 778 cert->cbCertEncoded, sha1.data, &sha1_size); |
848 DCHECK(rv && sha1_size == sizeof(sha1.data)); | 779 DCHECK(rv && sha1_size == sizeof(sha1.data)); |
849 if (!rv) | 780 if (!rv) |
850 memset(sha1.data, 0, sizeof(sha1.data)); | 781 memset(sha1.data, 0, sizeof(sha1.data)); |
851 return sha1; | 782 return sha1; |
852 } | 783 } |
853 | 784 |
854 } // namespace net | 785 } // namespace net |
OLD | NEW |