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.
5 #include "net/ssl/client_cert_store_impl.h"
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"
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
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
35 class ClientCertStoreImplTest : public ::testing::Test {
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);
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);
56 ClientCertStoreImpl store_;
59 TEST_F(ClientCertStoreImplTest, EmptyQuery) {
60 std::vector<scoped_refptr<X509Certificate> > certs;
61 scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo());
63 std::vector<scoped_refptr<X509Certificate> > selected_certs;
64 bool rv = SelectClientCerts(certs, *request.get(), &selected_certs);
66 EXPECT_EQ(0u, selected_certs.size());
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());
76 std::vector<scoped_refptr<X509Certificate> > certs;
77 certs.push_back(cert);
78 scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo());
80 std::vector<scoped_refptr<X509Certificate> > selected_certs;
81 bool rv = SelectClientCerts(certs, *request.get(), &selected_certs);
83 ASSERT_EQ(1u, selected_certs.size());
84 EXPECT_TRUE(selected_certs[0]->Equals(cert.get()));
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());
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));
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;
114 std::vector<scoped_refptr<X509Certificate> > selected_certs;
115 bool rv = SelectClientCerts(certs, *request.get(), &selected_certs);
117 ASSERT_EQ(1u, selected_certs.size());
118 EXPECT_TRUE(selected_certs[0]->Equals(cert_1.get()));
121 #if defined(OS_MACOSX) && !defined(OS_IOS)
122 // Verify that the preferred cert gets filtered out when it doesn't match the
124 TEST_F(ClientCertStoreImplTest, FilterOutThePreferredCert) {
125 scoped_refptr<X509Certificate> cert_1(
126 ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem"));
127 ASSERT_TRUE(cert_1.get());
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));
134 std::vector<scoped_refptr<X509Certificate> > certs;
135 scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo());
136 request->cert_authorities = authority_2;
138 std::vector<scoped_refptr<X509Certificate> > selected_certs;
139 bool rv = SelectClientCertsGivenPreferred(
140 cert_1, certs, *request.get(), &selected_certs);
142 EXPECT_EQ(0u, selected_certs.size());
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());
155 std::vector<scoped_refptr<X509Certificate> > certs;
156 certs.push_back(cert_2);
157 scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo());
159 std::vector<scoped_refptr<X509Certificate> > selected_certs;
160 bool rv = SelectClientCertsGivenPreferred(
161 cert_1, certs, *request.get(), &selected_certs);
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()));