xref: /aosp_15_r20/external/cronet/net/ssl/client_cert_store_unittest-inl.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2013 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 #ifndef NET_SSL_CLIENT_CERT_STORE_UNITTEST_INL_H_
6 #define NET_SSL_CLIENT_CERT_STORE_UNITTEST_INL_H_
7 
8 #include <memory>
9 #include <string>
10 #include <vector>
11 
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/memory/ref_counted.h"
15 #include "net/cert/x509_util.h"
16 #include "net/ssl/ssl_cert_request_info.h"
17 #include "net/test/cert_test_util.h"
18 #include "net/test/test_data_directory.h"
19 #include "net/test/test_with_task_environment.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "third_party/boringssl/src/pki/pem.h"
22 
23 namespace net {
24 
25 namespace {
26 
27 // "CN=B CA" - DER encoded DN of the issuer of client_1.pem
28 const unsigned char kAuthority1DN[] = {
29     0x30, 0x0f, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55,
30     0x04, 0x03, 0x0c, 0x04, 0x42, 0x20, 0x43, 0x41,
31 };
32 
33 // "CN=E CA" - DER encoded DN of the issuer of client_2.pem
34 const unsigned char kAuthority2DN[] = {
35     0x30, 0x0f, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55,
36     0x04, 0x03, 0x0c, 0x04, 0x45, 0x20, 0x43, 0x41,
37 };
38 
39 // "CN=C Root CA" - DER encoded DN of the issuer of client_1_ca.pem,
40 // client_2_ca.pem, and client_3_ca.pem.
41 const unsigned char kAuthorityRootDN[] = {
42     0x30, 0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03,
43     0x0c, 0x09, 0x43, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
44 };
45 
46 }  // namespace
47 
48 // Use a templated test to provide common testcases for all the platform
49 // implementations of ClientCertStore. These cases test the client cert
50 // filtering behavior.
51 //
52 // NOTE: If any test cases are added, removed, or renamed, the
53 // REGISTER_TYPED_TEST_SUITE_P macro at the bottom of this file must be updated.
54 //
55 // The type T provided as the third argument to INSTANTIATE_TYPED_TEST_SUITE_P
56 // by the platform implementation should implement this method: bool
57 // SelectClientCerts(const CertificateList& input_certs,
58 //                        const SSLCertRequestInfo& cert_request_info,
59 //                        ClientCertIdentityList* selected_identities);
60 template <typename T>
61 class ClientCertStoreTest : public TestWithTaskEnvironment {
62  public:
63   T delegate_;
64 };
65 
66 TYPED_TEST_SUITE_P(ClientCertStoreTest);
67 
TYPED_TEST_P(ClientCertStoreTest,EmptyQuery)68 TYPED_TEST_P(ClientCertStoreTest, EmptyQuery) {
69   CertificateList certs;
70   auto request = base::MakeRefCounted<SSLCertRequestInfo>();
71 
72   ClientCertIdentityList selected_identities;
73   bool rv = this->delegate_.SelectClientCerts(certs, *request.get(),
74                                               &selected_identities);
75   EXPECT_TRUE(rv);
76   EXPECT_EQ(0u, selected_identities.size());
77 }
78 
79 // Verify that CertRequestInfo with empty |cert_authorities| matches all
80 // issuers, rather than no issuers.
TYPED_TEST_P(ClientCertStoreTest,AllIssuersAllowed)81 TYPED_TEST_P(ClientCertStoreTest, AllIssuersAllowed) {
82   scoped_refptr<X509Certificate> cert(
83       ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem"));
84   ASSERT_TRUE(cert.get());
85 
86   std::vector<scoped_refptr<X509Certificate> > certs;
87   certs.push_back(cert);
88   auto request = base::MakeRefCounted<SSLCertRequestInfo>();
89 
90   ClientCertIdentityList selected_identities;
91   bool rv = this->delegate_.SelectClientCerts(certs, *request.get(),
92                                               &selected_identities);
93   EXPECT_TRUE(rv);
94   ASSERT_EQ(1u, selected_identities.size());
95   EXPECT_TRUE(
96       selected_identities[0]->certificate()->EqualsExcludingChain(cert.get()));
97 }
98 
99 // Verify that certificates are correctly filtered against CertRequestInfo with
100 // |cert_authorities| containing only |authority_1_DN|.
TYPED_TEST_P(ClientCertStoreTest,CertAuthorityFiltering)101 TYPED_TEST_P(ClientCertStoreTest, CertAuthorityFiltering) {
102   scoped_refptr<X509Certificate> cert_1(
103       ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem"));
104   ASSERT_TRUE(cert_1.get());
105   scoped_refptr<X509Certificate> cert_2(
106       ImportCertFromFile(GetTestCertsDirectory(), "client_2.pem"));
107   ASSERT_TRUE(cert_2.get());
108 
109   std::vector<std::string> authority_1(
110       1, std::string(reinterpret_cast<const char*>(kAuthority1DN),
111                      sizeof(kAuthority1DN)));
112   std::vector<std::string> authority_2(
113       1, std::string(reinterpret_cast<const char*>(kAuthority2DN),
114                      sizeof(kAuthority2DN)));
115   EXPECT_TRUE(cert_1->IsIssuedByEncoded(authority_1));
116   EXPECT_FALSE(cert_1->IsIssuedByEncoded(authority_2));
117   EXPECT_TRUE(cert_2->IsIssuedByEncoded(authority_2));
118   EXPECT_FALSE(cert_2->IsIssuedByEncoded(authority_1));
119 
120   std::vector<scoped_refptr<X509Certificate> > certs;
121   certs.push_back(cert_1);
122   certs.push_back(cert_2);
123   auto request = base::MakeRefCounted<SSLCertRequestInfo>();
124   request->cert_authorities = authority_1;
125 
126   ClientCertIdentityList selected_identities;
127   bool rv = this->delegate_.SelectClientCerts(certs, *request.get(),
128                                               &selected_identities);
129   EXPECT_TRUE(rv);
130   ASSERT_EQ(1u, selected_identities.size());
131   EXPECT_TRUE(selected_identities[0]->certificate()->EqualsExcludingChain(
132       cert_1.get()));
133 }
134 
TYPED_TEST_P(ClientCertStoreTest,PrintableStringContainingUTF8)135 TYPED_TEST_P(ClientCertStoreTest, PrintableStringContainingUTF8) {
136   base::FilePath certs_dir =
137       GetTestNetDataDirectory().AppendASCII("parse_certificate_unittest");
138 
139   std::string file_data;
140   ASSERT_TRUE(base::ReadFileToString(
141       certs_dir.AppendASCII(
142           "subject_printable_string_containing_utf8_client_cert.pem"),
143       &file_data));
144 
145   bssl::PEMTokenizer pem_tokenizer(file_data, {"CERTIFICATE"});
146   ASSERT_TRUE(pem_tokenizer.GetNext());
147   std::string cert_der(pem_tokenizer.data());
148   ASSERT_FALSE(pem_tokenizer.GetNext());
149 
150   bssl::UniquePtr<CRYPTO_BUFFER> cert_handle =
151       x509_util::CreateCryptoBuffer(cert_der);
152   ASSERT_TRUE(cert_handle);
153 
154   X509Certificate::UnsafeCreateOptions options;
155   options.printable_string_is_utf8 = true;
156   scoped_refptr<X509Certificate> cert =
157       X509Certificate::CreateFromBufferUnsafeOptions(std::move(cert_handle), {},
158                                                      options);
159   ASSERT_TRUE(cert);
160 
161   auto request = base::MakeRefCounted<SSLCertRequestInfo>();
162 
163   ClientCertIdentityList selected_identities;
164   bool rv = this->delegate_.SelectClientCerts({cert}, *request.get(),
165                                               &selected_identities);
166   EXPECT_TRUE(rv);
167   ASSERT_EQ(1u, selected_identities.size());
168   EXPECT_TRUE(
169       selected_identities[0]->certificate()->EqualsExcludingChain(cert.get()));
170 }
171 
172 REGISTER_TYPED_TEST_SUITE_P(ClientCertStoreTest,
173                             EmptyQuery,
174                             AllIssuersAllowed,
175                             CertAuthorityFiltering,
176                             PrintableStringContainingUTF8);
177 
178 }  // namespace net
179 
180 #endif  // NET_SSL_CLIENT_CERT_STORE_UNITTEST_INL_H_
181