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()));