Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/lazy_instance.h" | 7 #include "base/lazy_instance.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/pickle.h" | 9 #include "base/pickle.h" |
| 10 #include "base/sha1.h" | 10 #include "base/sha1.h" |
| (...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 543 return false; | 543 return false; |
| 544 PCERT_CHAIN_ELEMENT* element = first_chain->rgpElement; | 544 PCERT_CHAIN_ELEMENT* element = first_chain->rgpElement; |
| 545 PCCERT_CONTEXT cert = element[num_elements - 1]->pCertContext; | 545 PCCERT_CONTEXT cert = element[num_elements - 1]->pCertContext; |
| 546 | 546 |
| 547 SHA1Fingerprint hash = CalculateFingerprint(cert); | 547 SHA1Fingerprint hash = CalculateFingerprint(cert); |
| 548 return IsSHA1HashInSortedArray( | 548 return IsSHA1HashInSortedArray( |
| 549 hash, &kKnownRootCertSHA1Hashes[0][0], sizeof(kKnownRootCertSHA1Hashes)); | 549 hash, &kKnownRootCertSHA1Hashes[0][0], sizeof(kKnownRootCertSHA1Hashes)); |
| 550 } | 550 } |
| 551 | 551 |
| 552 // static | 552 // static |
| 553 X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle, | |
| 554 void** pickle_iter) { | |
| 555 const char* data; | |
| 556 int length; | |
| 557 if (!pickle.ReadData(pickle_iter, &data, &length)) | |
| 558 return NULL; | |
| 559 | |
| 560 OSCertHandle cert_handle = NULL; | |
| 561 if (!CertAddSerializedElementToStore( | |
| 562 NULL, // the cert won't be persisted in any cert store | |
| 563 reinterpret_cast<const BYTE*>(data), length, | |
| 564 CERT_STORE_ADD_USE_EXISTING, 0, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, | |
| 565 NULL, reinterpret_cast<const void **>(&cert_handle))) | |
| 566 return NULL; | |
| 567 | |
| 568 X509Certificate* cert = CreateFromHandle(cert_handle, | |
| 569 SOURCE_LONE_CERT_IMPORT, | |
| 570 OSCertHandles()); | |
| 571 FreeOSCertHandle(cert_handle); | |
| 572 return cert; | |
| 573 } | |
| 574 | |
| 575 // static | |
| 576 X509Certificate* X509Certificate::CreateSelfSigned( | 553 X509Certificate* X509Certificate::CreateSelfSigned( |
| 577 crypto::RSAPrivateKey* key, | 554 crypto::RSAPrivateKey* key, |
| 578 const std::string& subject, | 555 const std::string& subject, |
| 579 uint32 serial_number, | 556 uint32 serial_number, |
| 580 base::TimeDelta valid_duration) { | 557 base::TimeDelta valid_duration) { |
| 581 // Get the ASN.1 encoding of the certificate subject. | 558 // Get the ASN.1 encoding of the certificate subject. |
| 582 std::wstring w_subject = ASCIIToWide(subject); | 559 std::wstring w_subject = ASCIIToWide(subject); |
| 583 DWORD encoded_subject_length = 0; | 560 DWORD encoded_subject_length = 0; |
| 584 if (!CertStrToName( | 561 if (!CertStrToName( |
| 585 X509_ASN_ENCODING, | 562 X509_ASN_ENCODING, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 628 if (!cert_handle) | 605 if (!cert_handle) |
| 629 return NULL; | 606 return NULL; |
| 630 | 607 |
| 631 X509Certificate* cert = CreateFromHandle(cert_handle, | 608 X509Certificate* cert = CreateFromHandle(cert_handle, |
| 632 SOURCE_LONE_CERT_IMPORT, | 609 SOURCE_LONE_CERT_IMPORT, |
| 633 OSCertHandles()); | 610 OSCertHandles()); |
| 634 FreeOSCertHandle(cert_handle); | 611 FreeOSCertHandle(cert_handle); |
| 635 return cert; | 612 return cert; |
| 636 } | 613 } |
| 637 | 614 |
| 638 void X509Certificate::Persist(Pickle* pickle) { | |
| 639 DCHECK(cert_handle_); | |
| 640 DWORD length; | |
| 641 if (!CertSerializeCertificateStoreElement(cert_handle_, 0, | |
| 642 NULL, &length)) { | |
| 643 NOTREACHED(); | |
| 644 return; | |
| 645 } | |
| 646 BYTE* data = reinterpret_cast<BYTE*>(pickle->BeginWriteData(length)); | |
| 647 if (!CertSerializeCertificateStoreElement(cert_handle_, 0, | |
| 648 data, &length)) { | |
| 649 NOTREACHED(); | |
| 650 length = 0; | |
| 651 } | |
| 652 pickle->TrimWriteData(length); | |
| 653 } | |
| 654 | |
| 655 void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const { | 615 void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const { |
| 656 dns_names->clear(); | 616 dns_names->clear(); |
| 657 if (cert_handle_) { | 617 if (cert_handle_) { |
| 658 scoped_ptr_malloc<CERT_ALT_NAME_INFO> alt_name_info; | 618 scoped_ptr_malloc<CERT_ALT_NAME_INFO> alt_name_info; |
| 659 GetCertSubjectAltName(cert_handle_, &alt_name_info); | 619 GetCertSubjectAltName(cert_handle_, &alt_name_info); |
| 660 CERT_ALT_NAME_INFO* alt_name = alt_name_info.get(); | 620 CERT_ALT_NAME_INFO* alt_name = alt_name_info.get(); |
| 661 if (alt_name) { | 621 if (alt_name) { |
| 662 int num_entries = alt_name->cAltEntry; | 622 int num_entries = alt_name->cAltEntry; |
| 663 for (int i = 0; i < num_entries; i++) { | 623 for (int i = 0; i < num_entries; i++) { |
| 664 // dNSName is an ASN.1 IA5String representing a string of ASCII | 624 // dNSName is an ASN.1 IA5String representing a string of ASCII |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1037 SHA1Fingerprint sha1; | 997 SHA1Fingerprint sha1; |
| 1038 DWORD sha1_size = sizeof(sha1.data); | 998 DWORD sha1_size = sizeof(sha1.data); |
| 1039 rv = CryptHashCertificate(NULL, CALG_SHA1, 0, cert->pbCertEncoded, | 999 rv = CryptHashCertificate(NULL, CALG_SHA1, 0, cert->pbCertEncoded, |
| 1040 cert->cbCertEncoded, sha1.data, &sha1_size); | 1000 cert->cbCertEncoded, sha1.data, &sha1_size); |
| 1041 DCHECK(rv && sha1_size == sizeof(sha1.data)); | 1001 DCHECK(rv && sha1_size == sizeof(sha1.data)); |
| 1042 if (!rv) | 1002 if (!rv) |
| 1043 memset(sha1.data, 0, sizeof(sha1.data)); | 1003 memset(sha1.data, 0, sizeof(sha1.data)); |
| 1044 return sha1; | 1004 return sha1; |
| 1045 } | 1005 } |
| 1046 | 1006 |
| 1007 // static | |
| 1008 X509Certificate::OSCertHandle | |
| 1009 X509Certificate::ReadCertHandleFromPickle(const Pickle& pickle, | |
| 1010 void** pickle_iter) { | |
| 1011 const char* data; | |
| 1012 int length; | |
| 1013 if (!pickle.ReadData(pickle_iter, &data, &length)) | |
| 1014 return NULL; | |
| 1015 | |
| 1016 OSCertHandle cert_handle = NULL; | |
| 1017 if (!CertAddSerializedElementToStore( | |
| 1018 NULL, // the cert won't be persisted in any cert store | |
| 1019 reinterpret_cast<const BYTE*>(data), length, | |
| 1020 CERT_STORE_ADD_USE_EXISTING, 0, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, | |
| 1021 NULL, reinterpret_cast<const void **>(&cert_handle))) { | |
| 1022 return NULL; | |
| 1023 } | |
| 1024 | |
| 1025 return cert_handle; | |
| 1026 } | |
| 1027 | |
| 1028 // static | |
| 1029 bool X509Certificate::WriteCertHandleToPickle(OSCertHandle cert_handle, | |
| 1030 Pickle* pickle) { | |
| 1031 DWORD length = 0; | |
| 1032 if (!CertSerializeCertificateStoreElement(cert_handle, 0, NULL, &length)) | |
| 1033 return false; | |
| 1034 | |
| 1035 std::vector<BYTE> buffer(length); | |
| 1036 // Serialize |cert_handle| in a way that will preserve any extended | |
| 1037 // attributes set on the handle, such as the location to the certificate's | |
| 1038 // private key. | |
| 1039 if (!CertSerializeCertificateStoreElement(cert_handle, 0, &buffer[0], | |
| 1040 &length)) { | |
| 1041 return false; | |
| 1042 } | |
| 1043 | |
| 1044 return pickle->WriteData(reinterpret_cast<const char*>(&buffer[0]), | |
| 1045 length); | |
|
wtc
2011/04/20 23:07:58
Why don't you use the original code (pickle->Begin
Ryan Sleevi
2011/04/20 23:59:10
Per pickle.cc, there can only be one variable buff
| |
| 1046 } | |
| 1047 | |
| 1047 } // namespace net | 1048 } // namespace net |
| OLD | NEW |