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 X509Certificate::OSCertHandle HandleFromBytes(const BYTE* data, DWORD length) { |
| 438 X509Certificate::OSCertHandle cert_handle = NULL; |
| 439 |
| 440 if (!CertAddEncodedCertificateToStore( |
| 441 NULL, // the cert won't be persisted in any cert store |
| 442 X509_ASN_ENCODING, |
| 443 reinterpret_cast<const BYTE*>(data), length, |
| 444 CERT_STORE_ADD_USE_EXISTING, |
| 445 &cert_handle)) |
| 446 return NULL; |
| 447 |
| 448 return cert_handle; |
| 449 } |
| 450 |
| 451 void AddCertsFromStore(HCERTSTORE store, |
| 452 X509Certificate::OSCertHandles* results) { |
| 453 PCCERT_CONTEXT cur_cert = NULL; |
| 454 |
| 455 while ((cur_cert = CertEnumCertificatesInStore(store, cur_cert)) != NULL) { |
| 456 PCCERT_CONTEXT to_add = NULL; |
| 457 if (CertAddCertificateContextToStore( |
| 458 NULL, // The cert won't be persisted in any cert store. This breaks |
| 459 // any association the context currently has to |store|, which |
| 460 // allows us the caller to safely close |store| without |
| 461 // releasing the cert handles. |
| 462 cur_cert, |
| 463 CERT_STORE_ADD_USE_EXISTING, |
| 464 &to_add) && to_add != NULL) { |
| 465 // When processing stores generated from PKCS#7/PKCS#12 files, it |
| 466 // appears that the order returned is the inverse of the order that it |
| 467 // appeared in the file. |
| 468 // TODO(rsleevi): Ensure this order is consistent across all flavours of |
| 469 // Windows. |
| 470 results->insert(results->begin(), to_add); |
| 471 } |
| 472 } |
| 473 } |
| 474 |
| 475 X509Certificate::OSCertHandles ParsePKCS7(const char* data, size_t length) { |
| 476 X509Certificate::OSCertHandles results; |
| 477 CERT_BLOB data_blob; |
| 478 data_blob.cbData = length; |
| 479 data_blob.pbData = reinterpret_cast<BYTE*>(const_cast<char*>(data)); |
| 480 |
| 481 HCERTSTORE out_store = NULL; |
| 482 |
| 483 DWORD expected_types = CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED | |
| 484 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED | |
| 485 CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED; |
| 486 |
| 487 if (!CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &data_blob, expected_types, |
| 488 CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL, NULL, |
| 489 &out_store, NULL, NULL) || out_store == NULL) { |
| 490 return results; |
| 491 } |
| 492 |
| 493 AddCertsFromStore(out_store, &results); |
| 494 CertCloseStore(out_store, CERT_CLOSE_STORE_CHECK_FLAG); |
| 495 |
| 496 return results; |
| 497 } |
| 498 |
| 499 X509Certificate::OSCertHandles ParseNetscapeSequence(const char* data, |
| 500 size_t length) { |
| 501 X509Certificate::OSCertHandles results; |
| 502 CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY* certs = NULL; |
| 503 DWORD certs_size = 0; |
| 504 |
| 505 CRYPT_DECODE_PARA decode_para; |
| 506 decode_para.cbSize = sizeof(decode_para); |
| 507 decode_para.pfnAlloc = MyCryptAlloc; |
| 508 decode_para.pfnFree = MyCryptFree; |
| 509 |
| 510 DWORD size = 0; |
| 511 BOOL rv = CryptDecodeObjectEx( |
| 512 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, |
| 513 PKCS_CONTENT_INFO_SEQUENCE_OF_ANY, |
| 514 reinterpret_cast<const BYTE*>(data), length, |
| 515 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, |
| 516 &decode_para, &certs, &certs_size); |
| 517 if (rv) { |
| 518 scoped_ptr_malloc<CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY> scoped_certs(certs); |
| 519 for (DWORD i = 0; i < certs->cValue; ++i) { |
| 520 X509Certificate::OSCertHandle handle = |
| 521 HandleFromBytes(certs->rgValue[i].pbData, certs->rgValue[i].cbData); |
| 522 if (handle) |
| 523 results.push_back(handle); |
| 524 } |
| 525 } |
| 526 |
| 527 return results; |
| 528 } |
| 529 |
437 } // namespace | 530 } // namespace |
438 | 531 |
439 void X509Certificate::Initialize() { | 532 void X509Certificate::Initialize() { |
440 std::wstring subject_info; | 533 std::wstring subject_info; |
441 std::wstring issuer_info; | 534 std::wstring issuer_info; |
442 DWORD name_size; | 535 DWORD name_size; |
443 DCHECK(cert_handle_); | 536 DCHECK(cert_handle_); |
444 name_size = CertNameToStr(cert_handle_->dwCertEncodingType, | 537 name_size = CertNameToStr(cert_handle_->dwCertEncodingType, |
445 &cert_handle_->pCertInfo->Subject, | 538 &cert_handle_->pCertInfo->Subject, |
446 CERT_X500_NAME_STR | CERT_NAME_STR_CRLF_FLAG, | 539 CERT_X500_NAME_STR | CERT_NAME_STR_CRLF_FLAG, |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 scoped_ptr_malloc<CERT_POLICIES_INFO> policies_info; | 823 scoped_ptr_malloc<CERT_POLICIES_INFO> policies_info; |
731 GetCertPoliciesInfo(end_cert, &policies_info); | 824 GetCertPoliciesInfo(end_cert, &policies_info); |
732 if (!policies_info.get()) | 825 if (!policies_info.get()) |
733 return false; | 826 return false; |
734 | 827 |
735 return ContainsPolicy(policies_info.get(), ev_policy_oid); | 828 return ContainsPolicy(policies_info.get(), ev_policy_oid); |
736 } | 829 } |
737 | 830 |
738 // static | 831 // static |
739 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( | 832 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( |
740 const char* data, int length) { | 833 const char* data, size_t length) { |
741 OSCertHandle cert_handle = NULL; | 834 return HandleFromBytes(reinterpret_cast<const BYTE*>(data), length); |
742 if (!CertAddEncodedCertificateToStore( | 835 } |
743 NULL, // the cert won't be persisted in any cert store | |
744 X509_ASN_ENCODING, | |
745 reinterpret_cast<const BYTE*>(data), length, | |
746 CERT_STORE_ADD_USE_EXISTING, | |
747 &cert_handle)) | |
748 return NULL; | |
749 | 836 |
750 return cert_handle; | 837 // static |
| 838 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( |
| 839 const char *data, size_t length, CertificateFormat format) { |
| 840 OSCertHandles results; |
| 841 switch (format) { |
| 842 case FORMAT_DER: |
| 843 { |
| 844 OSCertHandle handle = CreateOSCertHandleFromBytes(data, length); |
| 845 if (handle != NULL) |
| 846 results.push_back(handle); |
| 847 } |
| 848 break; |
| 849 case FORMAT_PKCS7: |
| 850 results = ParsePKCS7(data, length); |
| 851 break; |
| 852 case FORMAT_LEGACY_NETSCAPE: |
| 853 results = ParseNetscapeSequence(data, length); |
| 854 break; |
| 855 default: |
| 856 NOTREACHED() << "Certificate format " << format << " unimplemented"; |
| 857 break; |
| 858 } |
| 859 |
| 860 return results; |
751 } | 861 } |
752 | 862 |
753 | 863 |
754 // static | 864 // static |
755 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( | 865 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( |
756 OSCertHandle cert_handle) { | 866 OSCertHandle cert_handle) { |
757 return CertDuplicateCertificateContext(cert_handle); | 867 return CertDuplicateCertificateContext(cert_handle); |
758 } | 868 } |
759 | 869 |
760 // static | 870 // static |
(...skipping 12 matching lines...) Expand all Loading... |
773 DWORD sha1_size = sizeof(sha1.data); | 883 DWORD sha1_size = sizeof(sha1.data); |
774 rv = CryptHashCertificate(NULL, CALG_SHA1, 0, cert->pbCertEncoded, | 884 rv = CryptHashCertificate(NULL, CALG_SHA1, 0, cert->pbCertEncoded, |
775 cert->cbCertEncoded, sha1.data, &sha1_size); | 885 cert->cbCertEncoded, sha1.data, &sha1_size); |
776 DCHECK(rv && sha1_size == sizeof(sha1.data)); | 886 DCHECK(rv && sha1_size == sizeof(sha1.data)); |
777 if (!rv) | 887 if (!rv) |
778 memset(sha1.data, 0, sizeof(sha1.data)); | 888 memset(sha1.data, 0, sizeof(sha1.data)); |
779 return sha1; | 889 return sha1; |
780 } | 890 } |
781 | 891 |
782 } // namespace net | 892 } // namespace net |
OLD | NEW |