1// Copyright (c) 2009 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/ssl_client_auth_cache.h"
6
7#include "base/time/time.h"
8#include "net/cert/x509_certificate.h"
9#include "testing/gtest/include/gtest/gtest.h"
10
11namespace net {
12
13TEST(SSLClientAuthCacheTest, LookupAddRemove) {
14  SSLClientAuthCache cache;
15
16  base::Time start_date = base::Time::Now();
17  base::Time expiration_date = start_date + base::TimeDelta::FromDays(1);
18
19  HostPortPair server1("foo1", 443);
20  scoped_refptr<X509Certificate> cert1(
21      new X509Certificate("foo1", "CA", start_date, expiration_date));
22
23  HostPortPair server2("foo2", 443);
24  scoped_refptr<X509Certificate> cert2(
25      new X509Certificate("foo2", "CA", start_date, expiration_date));
26
27  HostPortPair server3("foo3", 443);
28  scoped_refptr<X509Certificate> cert3(
29    new X509Certificate("foo3", "CA", start_date, expiration_date));
30
31  scoped_refptr<X509Certificate> cached_cert;
32  // Lookup non-existent client certificate.
33  cached_cert = NULL;
34  EXPECT_FALSE(cache.Lookup(server1, &cached_cert));
35
36  // Add client certificate for server1.
37  cache.Add(server1, cert1.get());
38  cached_cert = NULL;
39  EXPECT_TRUE(cache.Lookup(server1, &cached_cert));
40  EXPECT_EQ(cert1, cached_cert);
41
42  // Add client certificate for server2.
43  cache.Add(server2, cert2.get());
44  cached_cert = NULL;
45  EXPECT_TRUE(cache.Lookup(server1, &cached_cert));
46  EXPECT_EQ(cert1.get(), cached_cert.get());
47  cached_cert = NULL;
48  EXPECT_TRUE(cache.Lookup(server2, &cached_cert));
49  EXPECT_EQ(cert2, cached_cert);
50
51  // Overwrite the client certificate for server1.
52  cache.Add(server1, cert3.get());
53  cached_cert = NULL;
54  EXPECT_TRUE(cache.Lookup(server1, &cached_cert));
55  EXPECT_EQ(cert3, cached_cert);
56  cached_cert = NULL;
57  EXPECT_TRUE(cache.Lookup(server2, &cached_cert));
58  EXPECT_EQ(cert2, cached_cert);
59
60  // Remove client certificate of server1.
61  cache.Remove(server1);
62  cached_cert = NULL;
63  EXPECT_FALSE(cache.Lookup(server1, &cached_cert));
64  cached_cert = NULL;
65  EXPECT_TRUE(cache.Lookup(server2, &cached_cert));
66  EXPECT_EQ(cert2, cached_cert);
67
68  // Remove non-existent client certificate.
69  cache.Remove(server1);
70  cached_cert = NULL;
71  EXPECT_FALSE(cache.Lookup(server1, &cached_cert));
72  cached_cert = NULL;
73  EXPECT_TRUE(cache.Lookup(server2, &cached_cert));
74  EXPECT_EQ(cert2, cached_cert);
75}
76
77// Check that if the server differs only by port number, it is considered
78// a separate server.
79TEST(SSLClientAuthCacheTest, LookupWithPort) {
80  SSLClientAuthCache cache;
81
82  base::Time start_date = base::Time::Now();
83  base::Time expiration_date = start_date + base::TimeDelta::FromDays(1);
84
85  HostPortPair server1("foo", 443);
86  scoped_refptr<X509Certificate> cert1(
87      new X509Certificate("foo", "CA", start_date, expiration_date));
88
89  HostPortPair server2("foo", 8443);
90  scoped_refptr<X509Certificate> cert2(
91      new X509Certificate("foo", "CA", start_date, expiration_date));
92
93  cache.Add(server1, cert1.get());
94  cache.Add(server2, cert2.get());
95
96  scoped_refptr<X509Certificate> cached_cert;
97  EXPECT_TRUE(cache.Lookup(server1, &cached_cert));
98  EXPECT_EQ(cert1.get(), cached_cert.get());
99  EXPECT_TRUE(cache.Lookup(server2, &cached_cert));
100  EXPECT_EQ(cert2.get(), cached_cert.get());
101}
102
103// Check that the a NULL certificate, indicating the user has declined to send
104// a certificate, is properly cached.
105TEST(SSLClientAuthCacheTest, LookupNullPreference) {
106  SSLClientAuthCache cache;
107  base::Time start_date = base::Time::Now();
108  base::Time expiration_date = start_date + base::TimeDelta::FromDays(1);
109
110  HostPortPair server1("foo", 443);
111  scoped_refptr<X509Certificate> cert1(
112      new X509Certificate("foo", "CA", start_date, expiration_date));
113
114  cache.Add(server1, NULL);
115
116  scoped_refptr<X509Certificate> cached_cert(cert1);
117  // Make sure that |cached_cert| is updated to NULL, indicating the user
118  // declined to send a certificate to |server1|.
119  EXPECT_TRUE(cache.Lookup(server1, &cached_cert));
120  EXPECT_EQ(NULL, cached_cert.get());
121
122  // Remove the existing cached certificate.
123  cache.Remove(server1);
124  cached_cert = NULL;
125  EXPECT_FALSE(cache.Lookup(server1, &cached_cert));
126
127  // Add a new preference for a specific certificate.
128  cache.Add(server1, cert1.get());
129  cached_cert = NULL;
130  EXPECT_TRUE(cache.Lookup(server1, &cached_cert));
131  EXPECT_EQ(cert1, cached_cert);
132
133  // Replace the specific preference with a NULL certificate.
134  cache.Add(server1, NULL);
135  cached_cert = NULL;
136  EXPECT_TRUE(cache.Lookup(server1, &cached_cert));
137  EXPECT_EQ(NULL, cached_cert.get());
138}
139
140// Check that the OnCertAdded() method removes all cache entries.
141TEST(SSLClientAuthCacheTest, OnCertAdded) {
142  SSLClientAuthCache cache;
143  base::Time start_date = base::Time::Now();
144  base::Time expiration_date = start_date + base::TimeDelta::FromDays(1);
145
146  HostPortPair server1("foo", 443);
147  scoped_refptr<X509Certificate> cert1(
148      new X509Certificate("foo", "CA", start_date, expiration_date));
149
150  cache.Add(server1, cert1.get());
151
152  HostPortPair server2("foo2", 443);
153  cache.Add(server2, NULL);
154
155  scoped_refptr<X509Certificate> cached_cert;
156
157  // Demonstrate the set up is correct.
158  EXPECT_TRUE(cache.Lookup(server1, &cached_cert));
159  EXPECT_EQ(cert1, cached_cert);
160
161  EXPECT_TRUE(cache.Lookup(server2, &cached_cert));
162  EXPECT_EQ(NULL, cached_cert.get());
163
164  cache.OnCertAdded(NULL);
165
166  // Check that we no longer have entries for either server.
167  EXPECT_FALSE(cache.Lookup(server1, &cached_cert));
168  EXPECT_FALSE(cache.Lookup(server2, &cached_cert));
169}
170
171}  // namespace net
172