Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: net/base/x509_certificate_nss.cc

Issue 2668005: Bring the handling of <keygen> and support for the application/x-x509-user-ce... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Whitespace/style Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/x509_certificate_mac.cc ('k') | net/base/x509_certificate_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <cert.h> 7 #include <cert.h>
8 #include <nss.h> 8 #include <nss.h>
9 #include <pk11pub.h> 9 #include <pk11pub.h>
10 #include <prerror.h> 10 #include <prerror.h>
11 #include <prtime.h> 11 #include <prtime.h>
12 #include <secder.h> 12 #include <secder.h>
13 #include <secerr.h> 13 #include <secerr.h>
14 #include <sechash.h> 14 #include <sechash.h>
15 #include <sslerr.h> 15 #include <sslerr.h>
16 16
17 #include <limits>
18
17 #include "base/logging.h" 19 #include "base/logging.h"
18 #include "base/pickle.h" 20 #include "base/pickle.h"
19 #include "base/time.h" 21 #include "base/time.h"
20 #include "base/nss_util.h" 22 #include "base/nss_util.h"
23 #include "base/crypto/scoped_nss_types.h"
21 #include "net/base/cert_status_flags.h" 24 #include "net/base/cert_status_flags.h"
22 #include "net/base/cert_verify_result.h" 25 #include "net/base/cert_verify_result.h"
23 #include "net/base/ev_root_ca_metadata.h" 26 #include "net/base/ev_root_ca_metadata.h"
24 #include "net/base/net_errors.h" 27 #include "net/base/net_errors.h"
25 28
26 namespace net { 29 namespace net {
27 30
28 namespace { 31 namespace {
29 32
30 class ScopedCERTCertificate { 33 typedef scoped_ptr_malloc<CERTCertificatePolicies,
31 public: 34 base::NSSDestroyer<CERTCertificatePolicies,
32 explicit ScopedCERTCertificate(CERTCertificate* cert) 35 CERT_DestroyCertificatePoliciesExtension> >
33 : cert_(cert) {} 36 ScopedCERTCertificatePolicies;
34
35 ~ScopedCERTCertificate() {
36 if (cert_)
37 CERT_DestroyCertificate(cert_);
38 }
39
40 private:
41 CERTCertificate* cert_;
42
43 DISALLOW_COPY_AND_ASSIGN(ScopedCERTCertificate);
44 };
45
46 class ScopedCERTCertList {
47 public:
48 explicit ScopedCERTCertList(CERTCertList* cert_list)
49 : cert_list_(cert_list) {}
50
51 ~ScopedCERTCertList() {
52 if (cert_list_)
53 CERT_DestroyCertList(cert_list_);
54 }
55
56 private:
57 CERTCertList* cert_list_;
58
59 DISALLOW_COPY_AND_ASSIGN(ScopedCERTCertList);
60 };
61
62 class ScopedCERTCertificatePolicies {
63 public:
64 explicit ScopedCERTCertificatePolicies(CERTCertificatePolicies* policies)
65 : policies_(policies) {}
66
67 ~ScopedCERTCertificatePolicies() {
68 if (policies_)
69 CERT_DestroyCertificatePoliciesExtension(policies_);
70 }
71
72 private:
73 CERTCertificatePolicies* policies_;
74
75 DISALLOW_COPY_AND_ASSIGN(ScopedCERTCertificatePolicies);
76 };
77 37
78 // ScopedCERTValOutParam manages destruction of values in the CERTValOutParam 38 // ScopedCERTValOutParam manages destruction of values in the CERTValOutParam
79 // array that cvout points to. cvout must be initialized as passed to 39 // array that cvout points to. cvout must be initialized as passed to
80 // CERT_PKIXVerifyCert, so that the array must be terminated with 40 // CERT_PKIXVerifyCert, so that the array must be terminated with
81 // cert_po_end type. 41 // cert_po_end type.
82 // When it goes out of scope, it destroys values of cert_po_trustAnchor 42 // When it goes out of scope, it destroys values of cert_po_trustAnchor
83 // and cert_po_certList types, but doesn't release the array itself. 43 // and cert_po_certList types, but doesn't release the array itself.
84 class ScopedCERTValOutParam { 44 class ScopedCERTValOutParam {
85 public: 45 public:
86 explicit ScopedCERTValOutParam(CERTValOutParam* cvout) 46 explicit ScopedCERTValOutParam(CERTValOutParam* cvout)
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 SECOidTag oid_tag = policy_info->oid; 524 SECOidTag oid_tag = policy_info->oid;
565 if (oid_tag == SEC_OID_UNKNOWN) 525 if (oid_tag == SEC_OID_UNKNOWN)
566 continue; 526 continue;
567 if (oid_tag == ev_policy_tag) 527 if (oid_tag == ev_policy_tag)
568 return true; 528 return true;
569 } 529 }
570 LOG(ERROR) << "No EV Policy Tag"; 530 LOG(ERROR) << "No EV Policy Tag";
571 return false; 531 return false;
572 } 532 }
573 533
534 struct CollectCertsCallbackArgs {
535 X509Certificate::OSCertHandle (*createFn)(const char* data, size_t length);
536 X509Certificate::OSCertHandles* results;
537 };
538
539 SECStatus PR_CALLBACK
540 CollectCertsCallback(void* arg, SECItem** certs, int numcerts) {
541 if (numcerts < 0)
542 return SECFailure; // In the event of wrapping
543
544 CollectCertsCallbackArgs* args =
545 reinterpret_cast<CollectCertsCallbackArgs*>(arg);
546
547 for (int i = 0; i < numcerts; ++i) {
548 X509Certificate::OSCertHandle handle = args->createFn(
549 reinterpret_cast<char*>(certs[i]->data), certs[i]->len);
550 if (handle)
551 args->results->push_back(handle);
552 }
553
554 return SECSuccess;
555 }
556
574 } // namespace 557 } // namespace
575 558
576 void X509Certificate::Initialize() { 559 void X509Certificate::Initialize() {
577 ParsePrincipal(&cert_handle_->subject, &subject_); 560 ParsePrincipal(&cert_handle_->subject, &subject_);
578 ParsePrincipal(&cert_handle_->issuer, &issuer_); 561 ParsePrincipal(&cert_handle_->issuer, &issuer_);
579 562
580 ParseDate(&cert_handle_->validity.notBefore, &valid_start_); 563 ParseDate(&cert_handle_->validity.notBefore, &valid_start_);
581 ParseDate(&cert_handle_->validity.notAfter, &valid_expiry_); 564 ParseDate(&cert_handle_->validity.notAfter, &valid_expiry_);
582 565
583 fingerprint_ = CalculateFingerprint(cert_handle_); 566 fingerprint_ = CalculateFingerprint(cert_handle_);
584 } 567 }
585 568
586 // static 569 // static
587 X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle, 570 X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle,
588 void** pickle_iter) { 571 void** pickle_iter) {
589 const char* data; 572 const char* data;
590 int length; 573 int length;
591 if (!pickle.ReadData(pickle_iter, &data, &length)) 574 if (!pickle.ReadData(pickle_iter, &data, &length))
592 return NULL; 575 return NULL;
593 576
594 return CreateFromBytes(data, length); 577 return CreateFromBytes(data, length, FORMAT_DER);
595 } 578 }
596 579
597 void X509Certificate::Persist(Pickle* pickle) { 580 void X509Certificate::Persist(Pickle* pickle) {
598 pickle->WriteData(reinterpret_cast<const char*>(cert_handle_->derCert.data), 581 pickle->WriteData(reinterpret_cast<const char*>(cert_handle_->derCert.data),
599 cert_handle_->derCert.len); 582 cert_handle_->derCert.len);
600 } 583 }
601 584
602 void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const { 585 void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const {
603 dns_names->clear(); 586 dns_names->clear();
604 587
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 return false; 696 return false;
714 697
715 if (!CheckCertPolicies(cert_handle_, ev_policy_tag)) 698 if (!CheckCertPolicies(cert_handle_, ev_policy_tag))
716 return false; 699 return false;
717 700
718 return true; 701 return true;
719 } 702 }
720 703
721 // static 704 // static
722 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( 705 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
723 const char* data, int length) { 706 const char* data, size_t length) {
707 if (length > static_cast<size_t>(std::numeric_limits<unsigned int>::max()))
708 return NULL;
709
724 base::EnsureNSSInit(); 710 base::EnsureNSSInit();
725 711
726 if (!NSS_IsInitialized()) 712 if (!NSS_IsInitialized())
727 return NULL; 713 return NULL;
728 714
729 // Make a copy of |data| since CERT_DecodeCertPackage might modify it. 715 SECItem der_cert;
730 char* data_copy = new char[length]; 716 der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data));
731 memcpy(data_copy, data, length); 717 der_cert.len = static_cast<unsigned int>(length);
718 der_cert.type = siDERCertBuffer;
732 719
733 // Parse into a certificate structure. 720 // Parse into a certificate structure.
734 CERTCertificate* cert = CERT_DecodeCertFromPackage(data_copy, length); 721 CERTCertificate* cert =
735 delete [] data_copy; 722 CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &der_cert, NULL,
723 PR_FALSE, PR_TRUE);
736 if (!cert) 724 if (!cert)
737 LOG(ERROR) << "Couldn't parse a certificate from " << length << " bytes"; 725 return NULL;
726
738 return cert; 727 return cert;
739 } 728 }
740 729
741 // static 730 // static
731 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
732 const char* data, size_t length, CertificateFormat format) {
733 OSCertHandles results;
734
735 if (length > static_cast<size_t>(std::numeric_limits<int>::max()))
736 return results;
737
738 switch (format) {
739 case FORMAT_DER:
740 {
741 OSCertHandle handle = CreateOSCertHandleFromBytes(data, length);
742 if (handle)
743 results.push_back(handle);
744 }
745 break;
746 case FORMAT_LEGACY_NETSCAPE:
747 case FORMAT_PKCS7:
748 {
749 // Make a copy since CERT_DecodeCertPackage may modify it
750 scoped_array<char> data_copy(new char[length]);
751 memcpy(data_copy.get(), data, length);
752
753 CollectCertsCallbackArgs args;
754 args.results = &results;
755 args.createFn = &X509Certificate::CreateOSCertHandleFromBytes;
756
757 SECStatus result = CERT_DecodeCertPackage(data_copy.get(),
758 static_cast<int>(length), CollectCertsCallback, &args);
759 if (result != SECSuccess)
760 results.clear();
761 }
762 break;
763 default:
764 NOTREACHED() << "Certificate format " << format << " unimplemented";
765 break;
766 }
767
768 return results;
769 }
770
771 // static
742 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( 772 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle(
743 OSCertHandle cert_handle) { 773 OSCertHandle cert_handle) {
744 return CERT_DupCertificate(cert_handle); 774 return CERT_DupCertificate(cert_handle);
745 } 775 }
746 776
747 // static 777 // static
748 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { 778 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
749 CERT_DestroyCertificate(cert_handle); 779 CERT_DestroyCertificate(cert_handle);
750 } 780 }
751 781
752 // static 782 // static
753 X509Certificate::Fingerprint X509Certificate::CalculateFingerprint( 783 X509Certificate::Fingerprint X509Certificate::CalculateFingerprint(
754 OSCertHandle cert) { 784 OSCertHandle cert) {
755 Fingerprint sha1; 785 Fingerprint sha1;
756 memset(sha1.data, 0, sizeof(sha1.data)); 786 memset(sha1.data, 0, sizeof(sha1.data));
757 787
758 DCHECK(NULL != cert->derCert.data); 788 DCHECK(NULL != cert->derCert.data);
759 DCHECK(0 != cert->derCert.len); 789 DCHECK(0 != cert->derCert.len);
760 790
761 SECStatus rv = HASH_HashBuf(HASH_AlgSHA1, sha1.data, 791 SECStatus rv = HASH_HashBuf(HASH_AlgSHA1, sha1.data,
762 cert->derCert.data, cert->derCert.len); 792 cert->derCert.data, cert->derCert.len);
763 DCHECK(rv == SECSuccess); 793 DCHECK(rv == SECSuccess);
764 794
765 return sha1; 795 return sha1;
766 } 796 }
767 797
768 } // namespace net 798 } // namespace net
OLDNEW
« no previous file with comments | « net/base/x509_certificate_mac.cc ('k') | net/base/x509_certificate_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698