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