xref: /aosp_15_r20/external/cronet/net/ssl/ssl_client_auth_cache_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2009 The Chromium Authors
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 <utility>
8 
9 #include "base/functional/callback.h"
10 #include "base/time/time.h"
11 #include "net/cert/x509_certificate.h"
12 #include "net/ssl/openssl_private_key.h"
13 #include "net/ssl/ssl_private_key.h"
14 #include "net/test/cert_test_util.h"
15 #include "net/test/test_data_directory.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "third_party/boringssl/src/include/openssl/evp.h"
18 
19 namespace net {
20 
21 namespace {
MakeMockKey()22 scoped_refptr<SSLPrivateKey> MakeMockKey() {
23   bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
24   return WrapOpenSSLPrivateKey(std::move(pkey));
25 }
26 }  // namespace
27 
TEST(SSLClientAuthCacheTest,LookupAddRemove)28 TEST(SSLClientAuthCacheTest, LookupAddRemove) {
29   SSLClientAuthCache cache;
30 
31   HostPortPair server1("foo1", 443);
32   scoped_refptr<X509Certificate> cert1(
33       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
34   ASSERT_TRUE(cert1);
35 
36   HostPortPair server2("foo2", 443);
37   scoped_refptr<X509Certificate> cert2(
38       ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem"));
39   ASSERT_TRUE(cert2);
40 
41   HostPortPair server3("foo3", 443);
42   scoped_refptr<X509Certificate> cert3(
43       ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem"));
44   ASSERT_TRUE(cert3);
45 
46   scoped_refptr<X509Certificate> cached_cert;
47   scoped_refptr<SSLPrivateKey> cached_pkey;
48   // Lookup non-existent client certificate.
49   cached_cert = nullptr;
50   EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey));
51 
52   // Add client certificate for server1.
53   cache.Add(server1, cert1.get(), MakeMockKey());
54   cached_cert = nullptr;
55   EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
56   EXPECT_EQ(cert1, cached_cert);
57 
58   // Add client certificate for server2.
59   cache.Add(server2, cert2.get(), MakeMockKey());
60   cached_cert = nullptr;
61   EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
62   EXPECT_EQ(cert1.get(), cached_cert.get());
63   cached_cert = nullptr;
64   EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey));
65   EXPECT_EQ(cert2, cached_cert);
66 
67   // Overwrite the client certificate for server1.
68   cache.Add(server1, cert3.get(), MakeMockKey());
69   cached_cert = nullptr;
70   EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
71   EXPECT_EQ(cert3, cached_cert);
72   cached_cert = nullptr;
73   EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey));
74   EXPECT_EQ(cert2, cached_cert);
75 
76   // Remove client certificate of server1.
77   cache.Remove(server1);
78   cached_cert = nullptr;
79   EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey));
80   cached_cert = nullptr;
81   EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey));
82   EXPECT_EQ(cert2, cached_cert);
83 
84   // Remove non-existent client certificate.
85   cache.Remove(server1);
86   cached_cert = nullptr;
87   EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey));
88   cached_cert = nullptr;
89   EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey));
90   EXPECT_EQ(cert2, cached_cert);
91 }
92 
93 // Check that if the server differs only by port number, it is considered
94 // a separate server.
TEST(SSLClientAuthCacheTest,LookupWithPort)95 TEST(SSLClientAuthCacheTest, LookupWithPort) {
96   SSLClientAuthCache cache;
97 
98   HostPortPair server1("foo", 443);
99   scoped_refptr<X509Certificate> cert1(
100       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
101   ASSERT_TRUE(cert1);
102 
103   HostPortPair server2("foo", 8443);
104   scoped_refptr<X509Certificate> cert2(
105       ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem"));
106   ASSERT_TRUE(cert2);
107 
108   cache.Add(server1, cert1.get(), MakeMockKey());
109   cache.Add(server2, cert2.get(), MakeMockKey());
110 
111   scoped_refptr<X509Certificate> cached_cert;
112   scoped_refptr<SSLPrivateKey> cached_pkey;
113   EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
114   EXPECT_EQ(cert1.get(), cached_cert.get());
115   EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey));
116   EXPECT_EQ(cert2.get(), cached_cert.get());
117 }
118 
119 // Check that the a nullptr certificate, indicating the user has declined to
120 // send a certificate, is properly cached.
TEST(SSLClientAuthCacheTest,LookupNullPreference)121 TEST(SSLClientAuthCacheTest, LookupNullPreference) {
122   SSLClientAuthCache cache;
123 
124   HostPortPair server1("foo", 443);
125   scoped_refptr<X509Certificate> cert1(
126       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
127   ASSERT_TRUE(cert1);
128 
129   cache.Add(server1, nullptr, MakeMockKey());
130 
131   scoped_refptr<X509Certificate> cached_cert(cert1);
132   scoped_refptr<SSLPrivateKey> cached_pkey;
133   // Make sure that |cached_cert| is updated to nullptr, indicating the user
134   // declined to send a certificate to |server1|.
135   EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
136   EXPECT_EQ(nullptr, cached_cert.get());
137 
138   // Remove the existing cached certificate.
139   cache.Remove(server1);
140   cached_cert = nullptr;
141   EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey));
142 
143   // Add a new preference for a specific certificate.
144   cache.Add(server1, cert1.get(), MakeMockKey());
145   cached_cert = nullptr;
146   EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
147   EXPECT_EQ(cert1, cached_cert);
148 
149   // Replace the specific preference with a nullptr certificate.
150   cache.Add(server1, nullptr, MakeMockKey());
151   cached_cert = nullptr;
152   EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
153   EXPECT_EQ(nullptr, cached_cert.get());
154 }
155 
156 // Check that the Clear() method removes all cache entries.
TEST(SSLClientAuthCacheTest,Clear)157 TEST(SSLClientAuthCacheTest, Clear) {
158   SSLClientAuthCache cache;
159 
160   HostPortPair server1("foo", 443);
161   scoped_refptr<X509Certificate> cert1(
162       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
163   ASSERT_TRUE(cert1);
164 
165   cache.Add(server1, cert1.get(), MakeMockKey());
166 
167   HostPortPair server2("foo2", 443);
168   cache.Add(server2, nullptr, MakeMockKey());
169 
170   scoped_refptr<X509Certificate> cached_cert;
171   scoped_refptr<SSLPrivateKey> cached_pkey;
172 
173   // Demonstrate the set up is correct.
174   EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
175   EXPECT_EQ(cert1, cached_cert);
176 
177   EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey));
178   EXPECT_EQ(nullptr, cached_cert.get());
179 
180   cache.Clear();
181 
182   // Check that we no longer have entries for either server.
183   EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey));
184   EXPECT_FALSE(cache.Lookup(server2, &cached_cert, &cached_pkey));
185 }
186 
187 }  // namespace net
188