Home | History | Annotate | Download | only in ssl
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/ssl/client_cert_store_impl.h"
      6 
      7 #include <string>
      8 #include <vector>
      9 
     10 #include "base/files/file_path.h"
     11 #include "base/memory/ref_counted.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "net/base/test_data_directory.h"
     14 #include "net/test/cert_test_util.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 namespace net {
     18 
     19 namespace {
     20 
     21 // "CN=B CA" - DER encoded DN of the issuer of client_1.pem
     22 const unsigned char kAuthority1DN[] = {
     23   0x30, 0x0f, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
     24   0x04, 0x42, 0x20, 0x43, 0x41
     25 };
     26 
     27 // "CN=E CA" - DER encoded DN of the issuer of client_2.pem
     28 unsigned char kAuthority2DN[] = {
     29   0x30, 0x0f, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
     30   0x04, 0x45, 0x20, 0x43, 0x41
     31 };
     32 
     33 }  // namespace
     34 
     35 class ClientCertStoreImplTest : public ::testing::Test {
     36  protected:
     37   bool SelectClientCerts(const CertificateList& input_certs,
     38                          const SSLCertRequestInfo& cert_request_info,
     39                          CertificateList* selected_certs) {
     40     return store_.SelectClientCertsForTesting(
     41         input_certs, cert_request_info, selected_certs);
     42   }
     43 
     44 #if defined(OS_MACOSX) && !defined(OS_IOS)
     45   bool SelectClientCertsGivenPreferred(
     46       const scoped_refptr<X509Certificate>& preferred_cert,
     47       const CertificateList& regular_certs,
     48       const SSLCertRequestInfo& request,
     49       CertificateList* selected_certs) {
     50     return store_.SelectClientCertsGivenPreferredForTesting(
     51         preferred_cert, regular_certs, request, selected_certs);
     52   }
     53 #endif
     54 
     55  private:
     56   ClientCertStoreImpl store_;
     57 };
     58 
     59 TEST_F(ClientCertStoreImplTest, EmptyQuery) {
     60   std::vector<scoped_refptr<X509Certificate> > certs;
     61   scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo());
     62 
     63   std::vector<scoped_refptr<X509Certificate> > selected_certs;
     64   bool rv = SelectClientCerts(certs, *request.get(), &selected_certs);
     65   EXPECT_TRUE(rv);
     66   EXPECT_EQ(0u, selected_certs.size());
     67 }
     68 
     69 // Verify that CertRequestInfo with empty |cert_authorities| matches all
     70 // issuers, rather than no issuers.
     71 TEST_F(ClientCertStoreImplTest, AllIssuersAllowed) {
     72   scoped_refptr<X509Certificate> cert(
     73       ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem"));
     74   ASSERT_TRUE(cert.get());
     75 
     76   std::vector<scoped_refptr<X509Certificate> > certs;
     77   certs.push_back(cert);
     78   scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo());
     79 
     80   std::vector<scoped_refptr<X509Certificate> > selected_certs;
     81   bool rv = SelectClientCerts(certs, *request.get(), &selected_certs);
     82   EXPECT_TRUE(rv);
     83   ASSERT_EQ(1u, selected_certs.size());
     84   EXPECT_TRUE(selected_certs[0]->Equals(cert.get()));
     85 }
     86 
     87 // Verify that certificates are correctly filtered against CertRequestInfo with
     88 // |cert_authorities| containing only |authority_1_DN|.
     89 TEST_F(ClientCertStoreImplTest, CertAuthorityFiltering) {
     90   scoped_refptr<X509Certificate> cert_1(
     91       ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem"));
     92   ASSERT_TRUE(cert_1.get());
     93   scoped_refptr<X509Certificate> cert_2(
     94       ImportCertFromFile(GetTestCertsDirectory(), "client_2.pem"));
     95   ASSERT_TRUE(cert_2.get());
     96 
     97   std::vector<std::string> authority_1(
     98       1, std::string(reinterpret_cast<const char*>(kAuthority1DN),
     99                      sizeof(kAuthority1DN)));
    100   std::vector<std::string> authority_2(
    101       1, std::string(reinterpret_cast<const char*>(kAuthority2DN),
    102                      sizeof(kAuthority2DN)));
    103   EXPECT_TRUE(cert_1->IsIssuedByEncoded(authority_1));
    104   EXPECT_FALSE(cert_1->IsIssuedByEncoded(authority_2));
    105   EXPECT_TRUE(cert_2->IsIssuedByEncoded(authority_2));
    106   EXPECT_FALSE(cert_2->IsIssuedByEncoded(authority_1));
    107 
    108   std::vector<scoped_refptr<X509Certificate> > certs;
    109   certs.push_back(cert_1);
    110   certs.push_back(cert_2);
    111   scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo());
    112   request->cert_authorities = authority_1;
    113 
    114   std::vector<scoped_refptr<X509Certificate> > selected_certs;
    115   bool rv = SelectClientCerts(certs, *request.get(), &selected_certs);
    116   EXPECT_TRUE(rv);
    117   ASSERT_EQ(1u, selected_certs.size());
    118   EXPECT_TRUE(selected_certs[0]->Equals(cert_1.get()));
    119 }
    120 
    121 #if defined(OS_MACOSX) && !defined(OS_IOS)
    122 // Verify that the preferred cert gets filtered out when it doesn't match the
    123 // server criteria.
    124 TEST_F(ClientCertStoreImplTest, FilterOutThePreferredCert) {
    125   scoped_refptr<X509Certificate> cert_1(
    126       ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem"));
    127   ASSERT_TRUE(cert_1.get());
    128 
    129   std::vector<std::string> authority_2(
    130       1, std::string(reinterpret_cast<const char*>(kAuthority2DN),
    131                      sizeof(kAuthority2DN)));
    132   EXPECT_FALSE(cert_1->IsIssuedByEncoded(authority_2));
    133 
    134   std::vector<scoped_refptr<X509Certificate> > certs;
    135   scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo());
    136   request->cert_authorities = authority_2;
    137 
    138   std::vector<scoped_refptr<X509Certificate> > selected_certs;
    139   bool rv = SelectClientCertsGivenPreferred(
    140       cert_1, certs, *request.get(), &selected_certs);
    141   EXPECT_TRUE(rv);
    142   EXPECT_EQ(0u, selected_certs.size());
    143 }
    144 
    145 // Verify that the preferred cert takes the first position in the output list,
    146 // when it does not get filtered out.
    147 TEST_F(ClientCertStoreImplTest, PreferredCertGoesFirst) {
    148   scoped_refptr<X509Certificate> cert_1(
    149       ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem"));
    150   ASSERT_TRUE(cert_1.get());
    151   scoped_refptr<X509Certificate> cert_2(
    152       ImportCertFromFile(GetTestCertsDirectory(), "client_2.pem"));
    153   ASSERT_TRUE(cert_2.get());
    154 
    155   std::vector<scoped_refptr<X509Certificate> > certs;
    156   certs.push_back(cert_2);
    157   scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo());
    158 
    159   std::vector<scoped_refptr<X509Certificate> > selected_certs;
    160   bool rv = SelectClientCertsGivenPreferred(
    161       cert_1, certs, *request.get(), &selected_certs);
    162   EXPECT_TRUE(rv);
    163   ASSERT_EQ(2u, selected_certs.size());
    164   EXPECT_TRUE(selected_certs[0]->Equals(cert_1.get()));
    165   EXPECT_TRUE(selected_certs[1]->Equals(cert_2.get()));
    166 }
    167 #endif
    168 
    169 }  // namespace net
    170