Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1041)

Side by Side Diff: net/ssl/client_cert_store_chromeos_unittest.cc

Issue 424523002: Enable system NSS key slot. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/ssl/client_cert_store_chromeos.h" 5 #include "net/ssl/client_cert_store_chromeos.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/file_util.h" 11 #include "base/file_util.h"
12 #include "base/run_loop.h" 12 #include "base/run_loop.h"
13 #include "crypto/nss_util.h" 13 #include "crypto/nss_util.h"
14 #include "crypto/nss_util_internal.h" 14 #include "crypto/nss_util_internal.h"
15 #include "crypto/rsa_private_key.h" 15 #include "crypto/rsa_private_key.h"
16 #include "crypto/scoped_test_nss_chromeos_user.h" 16 #include "crypto/scoped_test_nss_chromeos_user.h"
17 #include "crypto/scoped_test_system_nss_key_slot.h"
17 #include "net/base/test_data_directory.h" 18 #include "net/base/test_data_directory.h"
18 #include "net/cert/cert_type.h" 19 #include "net/cert/cert_type.h"
19 #include "net/cert/x509_certificate.h" 20 #include "net/cert/x509_certificate.h"
20 #include "net/ssl/client_cert_store_unittest-inl.h" 21 #include "net/ssl/client_cert_store_unittest-inl.h"
21 #include "net/test/cert_test_util.h" 22 #include "net/test/cert_test_util.h"
22 23
23 namespace net { 24 namespace net {
24 25
25 namespace { 26 namespace {
26 27
(...skipping 12 matching lines...) Expand all
39 return false; 40 return false;
40 } 41 }
41 } 42 }
42 return true; 43 return true;
43 } 44 }
44 45
45 } // namespace 46 } // namespace
46 47
47 // Define a delegate to be used for instantiating the parameterized test set 48 // Define a delegate to be used for instantiating the parameterized test set
48 // ClientCertStoreTest. 49 // ClientCertStoreTest.
50 template <bool read_from_user_slot, bool enable_user_slot>
Ryan Sleevi 2014/07/29 00:23:16 You can use enums here to make these types more de
pneubeck (no reviews) 2014/07/29 16:00:15 Yeah, you're right. Should be much more readable n
49 class ClientCertStoreChromeOSTestDelegate { 51 class ClientCertStoreChromeOSTestDelegate {
50 public: 52 public:
51 ClientCertStoreChromeOSTestDelegate() 53 ClientCertStoreChromeOSTestDelegate()
52 : user_("scopeduser"), 54 : user_("scopeduser"),
53 store_(user_.username_hash(), 55 system_db_(true /* skip TPM initialization */),
56 store_(enable_user_slot,
57 user_.username_hash(),
54 ClientCertStoreChromeOS::PasswordDelegateFactory()) { 58 ClientCertStoreChromeOS::PasswordDelegateFactory()) {
55 // Defer futher initialization and checks to SelectClientCerts, because the 59 // Defer futher initialization and checks to SelectClientCerts, because the
56 // constructor doesn't allow us to return an initialization result. Could be 60 // constructor doesn't allow us to return an initialization result. Could be
57 // cleaned up by adding an Init() function. 61 // cleaned up by adding an Init() function.
58 } 62 }
59 63
60 // Called by the ClientCertStoreTest tests. 64 // Called by the ClientCertStoreTest tests.
61 // |inpurt_certs| contains certificates to select from. Because 65 // |inpurt_certs| contains certificates to select from. Because
62 // ClientCertStoreChromeOS filters also for the right slot, we have to import 66 // ClientCertStoreChromeOS filters also for the right slot, we have to import
63 // the certs at first. 67 // the certs at first.
64 // Since the certs are imported, the store can be tested by using its public 68 // Since the certs are imported, the store can be tested by using its public
65 // interface (GetClientCerts), which will read the certs from NSS. 69 // interface (GetClientCerts), which will read the certs from NSS.
66 bool SelectClientCerts(const CertificateList& input_certs, 70 bool SelectClientCerts(const CertificateList& input_certs,
67 const SSLCertRequestInfo& cert_request_info, 71 const SSLCertRequestInfo& cert_request_info,
68 CertificateList* selected_certs) { 72 CertificateList* selected_certs) {
69 if (!user_.constructed_successfully()) { 73 if (!user_.constructed_successfully()) {
70 LOG(ERROR) << "Scoped test user DB could not be constructed."; 74 LOG(ERROR) << "Scoped test user DB could not be constructed.";
71 return false; 75 return false;
72 } 76 }
73 user_.FinishInit(); 77 user_.FinishInit();
74 78
75 crypto::ScopedPK11Slot slot( 79 crypto::ScopedPK11Slot slot;
76 crypto::GetPublicSlotForChromeOSUser(user_.username_hash())); 80 if (read_from_user_slot)
81 slot = crypto::GetPublicSlotForChromeOSUser(user_.username_hash());
82 else
83 slot.reset(PK11_ReferenceSlot(system_db_.slot()));
77 if (!slot) { 84 if (!slot) {
78 LOG(ERROR) << "Could not get the user's public slot"; 85 LOG(ERROR) << "Could not get the NSS key slot";
79 return false; 86 return false;
80 } 87 }
81 88
82 // Only user certs are considered for the cert request, which means that the 89 // Only user certs are considered for the cert request, which means that the
83 // private key must be known to NSS. Import all private keys for certs that 90 // private key must be known to NSS. Import all private keys for certs that
84 // are used througout the test. 91 // are used througout the test.
85 if (!ImportSensitiveKeyFromFile( 92 if (!ImportSensitiveKeyFromFile(
86 GetTestCertsDirectory(), "client_1.pk8", slot.get()) || 93 GetTestCertsDirectory(), "client_1.pk8", slot.get()) ||
87 !ImportSensitiveKeyFromFile( 94 !ImportSensitiveKeyFromFile(
88 GetTestCertsDirectory(), "client_2.pk8", slot.get())) { 95 GetTestCertsDirectory(), "client_2.pk8", slot.get())) {
89 return false; 96 return false;
90 } 97 }
91 98
92 for (CertificateList::const_iterator it = input_certs.begin(); 99 for (CertificateList::const_iterator it = input_certs.begin();
93 it != input_certs.end(); 100 it != input_certs.end();
94 ++it) { 101 ++it) {
95 if (!ImportClientCertToSlot(*it, slot.get())) 102 if (!ImportClientCertToSlot(*it, slot.get()))
96 return false; 103 return false;
97 } 104 }
98 base::RunLoop run_loop; 105 base::RunLoop run_loop;
99 store_.GetClientCerts( 106 store_.GetClientCerts(
100 cert_request_info, selected_certs, run_loop.QuitClosure()); 107 cert_request_info, selected_certs, run_loop.QuitClosure());
101 run_loop.Run(); 108 run_loop.Run();
102 return true; 109 return true;
103 } 110 }
104 111
105 private: 112 private:
106 crypto::ScopedTestNSSChromeOSUser user_; 113 crypto::ScopedTestNSSChromeOSUser user_;
114 crypto::ScopedTestSystemNSSKeySlot system_db_;
107 ClientCertStoreChromeOS store_; 115 ClientCertStoreChromeOS store_;
108 }; 116 };
109 117
110 // ClientCertStoreChromeOS derives from ClientCertStoreNSS and delegates the 118 // ClientCertStoreChromeOS derives from ClientCertStoreNSS and delegates the
111 // filtering by issuer to that base class. 119 // filtering by issuer to that base class.
112 // To verify that this delegation is functional, run the same filtering tests as 120 // To verify that this delegation is functional, run the same filtering tests as
113 // for the other implementations. These tests are defined in 121 // for the other implementations. These tests are defined in
114 // client_cert_store_unittest-inl.h and are instantiated for each platform. 122 // client_cert_store_unittest-inl.h and are instantiated for each platform.
115 INSTANTIATE_TYPED_TEST_CASE_P(ChromeOS, 123
124 // In this case, all requested certs are read from the user's slot and the
125 // system slot is not enabled in the store.
126 typedef ClientCertStoreChromeOSTestDelegate<true /* read from user slot */,
127 false /* disable system slot */>
128 DelegateReadUserDisableSystem;
129 INSTANTIATE_TYPED_TEST_CASE_P(ChromeOS_ReadUserDisableSystem,
116 ClientCertStoreTest, 130 ClientCertStoreTest,
117 ClientCertStoreChromeOSTestDelegate); 131 DelegateReadUserDisableSystem);
132
133 // In this case, all requested certs are read from the user's slot and the
134 // system slot is enabled in the store.
135 typedef ClientCertStoreChromeOSTestDelegate<true /* read from user slot */,
136 true /* enable system slot */>
137 DelegateReadUserEnableSystem;
138 INSTANTIATE_TYPED_TEST_CASE_P(ChromeOS_ReadUserEnableSystem,
139 ClientCertStoreTest,
140 DelegateReadUserEnableSystem);
141
142 // In this case, all requested certs are read from the system slot, therefore
143 // the system slot is enabled in the store.
144 typedef ClientCertStoreChromeOSTestDelegate<false /* read from system slot */,
145 true /* enable system slot */>
146 DelegateReadSystem;
147 INSTANTIATE_TYPED_TEST_CASE_P(ChromeOS_ReadSystem,
148 ClientCertStoreTest,
149 DelegateReadSystem);
118 150
119 class ClientCertStoreChromeOSTest : public ::testing::Test { 151 class ClientCertStoreChromeOSTest : public ::testing::Test {
120 public: 152 public:
121 scoped_refptr<X509Certificate> ImportCertForUser( 153 scoped_refptr<X509Certificate> ImportCertToSlot(
122 const std::string& username_hash,
123 const std::string& cert_filename, 154 const std::string& cert_filename,
124 const std::string& key_filename) { 155 const std::string& key_filename,
125 crypto::ScopedPK11Slot slot( 156 PK11SlotInfo* slot) {
126 crypto::GetPublicSlotForChromeOSUser(username_hash)); 157 if (!ImportSensitiveKeyFromFile(
127 if (!slot) { 158 GetTestCertsDirectory(), key_filename, slot)) {
128 LOG(ERROR) << "No slot for user " << username_hash; 159 LOG(ERROR) << "Could not import private key from file " << key_filename;
129 return NULL; 160 return NULL;
130 } 161 }
131 162
132 if (!ImportSensitiveKeyFromFile(
133 GetTestCertsDirectory(), key_filename, slot.get())) {
134 LOG(ERROR) << "Could not import private key for user " << username_hash;
135 return NULL;
136 }
137
138 scoped_refptr<X509Certificate> cert( 163 scoped_refptr<X509Certificate> cert(
139 ImportCertFromFile(GetTestCertsDirectory(), cert_filename)); 164 ImportCertFromFile(GetTestCertsDirectory(), cert_filename));
140 165
141 if (!cert) { 166 if (!cert) {
142 LOG(ERROR) << "Failed to parse cert from file " << cert_filename; 167 LOG(ERROR) << "Failed to parse cert from file " << cert_filename;
143 return NULL; 168 return NULL;
144 } 169 }
145 170
146 if (!ImportClientCertToSlot(cert, slot.get())) 171 if (!ImportClientCertToSlot(cert, slot))
147 return NULL; 172 return NULL;
148 173
149 // |cert| continues to point to the original X509Certificate before the 174 // |cert| continues to point to the original X509Certificate before the
150 // import to |slot|. However this should not make a difference for this 175 // import to |slot|. However this should not make a difference for this
151 // test. 176 // test.
152 return cert; 177 return cert;
153 } 178 }
179
180 scoped_refptr<X509Certificate> ImportCertForUser(
181 const std::string& username_hash,
182 const std::string& cert_filename,
183 const std::string& key_filename) {
184 crypto::ScopedPK11Slot slot(
185 crypto::GetPublicSlotForChromeOSUser(username_hash));
186 if (!slot) {
187 LOG(ERROR) << "No slot for user " << username_hash;
188 return NULL;
189 }
190
191 return ImportCertToSlot(cert_filename, key_filename, slot.get());
192 }
193
154 }; 194 };
155 195
156 // Ensure that cert requests, that are started before the user's NSS DB is 196 // Ensure that cert requests, that are started before the user's NSS DB is
157 // initialized, will wait for the initialization and succeed afterwards. 197 // initialized, will wait for the initialization and succeed afterwards.
158 TEST_F(ClientCertStoreChromeOSTest, RequestWaitsForNSSInitAndSucceeds) { 198 TEST_F(ClientCertStoreChromeOSTest, RequestWaitsForNSSInitAndSucceeds) {
159 crypto::ScopedTestNSSChromeOSUser user("scopeduser"); 199 crypto::ScopedTestNSSChromeOSUser user("scopeduser");
160 ASSERT_TRUE(user.constructed_successfully()); 200 ASSERT_TRUE(user.constructed_successfully());
201
202 crypto::ScopedTestSystemNSSKeySlot system_slot(
203 true /* skip TPM initialization */);
204
161 ClientCertStoreChromeOS store( 205 ClientCertStoreChromeOS store(
162 user.username_hash(), ClientCertStoreChromeOS::PasswordDelegateFactory()); 206 true /* use system slot */,
207 user.username_hash(),
208 ClientCertStoreChromeOS::PasswordDelegateFactory());
163 scoped_refptr<X509Certificate> cert_1( 209 scoped_refptr<X509Certificate> cert_1(
164 ImportCertForUser(user.username_hash(), "client_1.pem", "client_1.pk8")); 210 ImportCertForUser(user.username_hash(), "client_1.pem", "client_1.pk8"));
165 ASSERT_TRUE(cert_1); 211 ASSERT_TRUE(cert_1);
166 212
167 // Request any client certificate, which is expected to match client_1. 213 // Request any client certificate, which is expected to match client_1.
168 scoped_refptr<SSLCertRequestInfo> request_all(new SSLCertRequestInfo()); 214 scoped_refptr<SSLCertRequestInfo> request_all(new SSLCertRequestInfo());
169 215
170 base::RunLoop run_loop; 216 base::RunLoop run_loop;
171 store.GetClientCerts( 217 store.GetClientCerts(
172 *request_all, &request_all->client_certs, run_loop.QuitClosure()); 218 *request_all, &request_all->client_certs, run_loop.QuitClosure());
(...skipping 14 matching lines...) Expand all
187 ASSERT_EQ(1u, request_all->client_certs.size()); 233 ASSERT_EQ(1u, request_all->client_certs.size());
188 } 234 }
189 235
190 // Ensure that cert requests, that are started after the user's NSS DB was 236 // Ensure that cert requests, that are started after the user's NSS DB was
191 // initialized, will succeed. 237 // initialized, will succeed.
192 TEST_F(ClientCertStoreChromeOSTest, RequestsAfterNSSInitSucceed) { 238 TEST_F(ClientCertStoreChromeOSTest, RequestsAfterNSSInitSucceed) {
193 crypto::ScopedTestNSSChromeOSUser user("scopeduser"); 239 crypto::ScopedTestNSSChromeOSUser user("scopeduser");
194 ASSERT_TRUE(user.constructed_successfully()); 240 ASSERT_TRUE(user.constructed_successfully());
195 user.FinishInit(); 241 user.FinishInit();
196 242
243 crypto::ScopedTestSystemNSSKeySlot system_slot(
244 true /* skip TPM initialization */);
245
197 ClientCertStoreChromeOS store( 246 ClientCertStoreChromeOS store(
198 user.username_hash(), ClientCertStoreChromeOS::PasswordDelegateFactory()); 247 true /* use system slot */,
248 user.username_hash(),
249 ClientCertStoreChromeOS::PasswordDelegateFactory());
199 scoped_refptr<X509Certificate> cert_1( 250 scoped_refptr<X509Certificate> cert_1(
200 ImportCertForUser(user.username_hash(), "client_1.pem", "client_1.pk8")); 251 ImportCertForUser(user.username_hash(), "client_1.pem", "client_1.pk8"));
201 ASSERT_TRUE(cert_1); 252 ASSERT_TRUE(cert_1);
202 253
203 scoped_refptr<SSLCertRequestInfo> request_all(new SSLCertRequestInfo()); 254 scoped_refptr<SSLCertRequestInfo> request_all(new SSLCertRequestInfo());
204 255
205 base::RunLoop run_loop; 256 base::RunLoop run_loop;
206 store.GetClientCerts( 257 store.GetClientCerts(
207 *request_all, &request_all->client_certs, run_loop.QuitClosure()); 258 *request_all, &request_all->client_certs, run_loop.QuitClosure());
208 run_loop.Run(); 259 run_loop.Run();
209 260
210 ASSERT_EQ(1u, request_all->client_certs.size()); 261 ASSERT_EQ(1u, request_all->client_certs.size());
211 } 262 }
212 263
213 // This verifies that a request in the context of User1 doesn't see certificates 264 // This verifies that a request in the context of User1 doesn't see certificates
214 // of User2, and the other way round. We check both directions, to ensure that 265 // of User2, and the other way round. We check both directions, to ensure that
215 // the behavior doesn't depend on initialization order of the DBs, for example. 266 // the behavior doesn't depend on initialization order of the DBs, for example.
216 TEST_F(ClientCertStoreChromeOSTest, RequestDoesCrossReadSecondDB) { 267 TEST_F(ClientCertStoreChromeOSTest, RequestDoesCrossReadOtherUserDB) {
217 crypto::ScopedTestNSSChromeOSUser user1("scopeduser1"); 268 crypto::ScopedTestNSSChromeOSUser user1("scopeduser1");
218 ASSERT_TRUE(user1.constructed_successfully()); 269 ASSERT_TRUE(user1.constructed_successfully());
219 crypto::ScopedTestNSSChromeOSUser user2("scopeduser2"); 270 crypto::ScopedTestNSSChromeOSUser user2("scopeduser2");
220 ASSERT_TRUE(user2.constructed_successfully()); 271 ASSERT_TRUE(user2.constructed_successfully());
221 272
222 user1.FinishInit(); 273 user1.FinishInit();
223 user2.FinishInit(); 274 user2.FinishInit();
224 275
276 crypto::ScopedTestSystemNSSKeySlot system_slot(
277 true /* skip TPM initialization */);
278
225 ClientCertStoreChromeOS store1( 279 ClientCertStoreChromeOS store1(
280 true /* use system slot */,
226 user1.username_hash(), 281 user1.username_hash(),
227 ClientCertStoreChromeOS::PasswordDelegateFactory()); 282 ClientCertStoreChromeOS::PasswordDelegateFactory());
228 ClientCertStoreChromeOS store2( 283 ClientCertStoreChromeOS store2(
284 true /* use system slot */,
229 user2.username_hash(), 285 user2.username_hash(),
230 ClientCertStoreChromeOS::PasswordDelegateFactory()); 286 ClientCertStoreChromeOS::PasswordDelegateFactory());
231 287
232 scoped_refptr<X509Certificate> cert_1( 288 scoped_refptr<X509Certificate> cert_1(
233 ImportCertForUser(user1.username_hash(), "client_1.pem", "client_1.pk8")); 289 ImportCertForUser(user1.username_hash(), "client_1.pem", "client_1.pk8"));
234 ASSERT_TRUE(cert_1); 290 ASSERT_TRUE(cert_1);
235 scoped_refptr<X509Certificate> cert_2( 291 scoped_refptr<X509Certificate> cert_2(
236 ImportCertForUser(user2.username_hash(), "client_2.pem", "client_2.pk8")); 292 ImportCertForUser(user2.username_hash(), "client_2.pem", "client_2.pk8"));
237 ASSERT_TRUE(cert_2); 293 ASSERT_TRUE(cert_2);
238 294
(...skipping 13 matching lines...) Expand all
252 308
253 // store1 should only return certs of user1, namely cert_1. 309 // store1 should only return certs of user1, namely cert_1.
254 ASSERT_EQ(1u, selected_certs1.size()); 310 ASSERT_EQ(1u, selected_certs1.size());
255 EXPECT_TRUE(cert_1->Equals(selected_certs1[0])); 311 EXPECT_TRUE(cert_1->Equals(selected_certs1[0]));
256 312
257 // store2 should only return certs of user2, namely cert_2. 313 // store2 should only return certs of user2, namely cert_2.
258 ASSERT_EQ(1u, selected_certs2.size()); 314 ASSERT_EQ(1u, selected_certs2.size());
259 EXPECT_TRUE(cert_2->Equals(selected_certs2[0])); 315 EXPECT_TRUE(cert_2->Equals(selected_certs2[0]));
260 } 316 }
261 317
318 // This verifies that a request in the context of User1 doesn't see certificates
319 // of the system store if the system store is disabled.
320 TEST_F(ClientCertStoreChromeOSTest, RequestDoesCrossReadSystemDB) {
321 crypto::ScopedTestNSSChromeOSUser user1("scopeduser1");
322 ASSERT_TRUE(user1.constructed_successfully());
323
324 user1.FinishInit();
325
326 crypto::ScopedTestSystemNSSKeySlot system_slot(
327 true /* skip TPM initialization */);
328
329 ClientCertStoreChromeOS store(
330 false /* do not use system slot */,
331 user1.username_hash(),
332 ClientCertStoreChromeOS::PasswordDelegateFactory());
333
334 scoped_refptr<X509Certificate> cert_1(
335 ImportCertForUser(user1.username_hash(), "client_1.pem", "client_1.pk8"));
336 ASSERT_TRUE(cert_1);
337 scoped_refptr<X509Certificate> cert_2(
338 ImportCertToSlot("client_2.pem", "client_2.pk8", system_slot.slot()));
339 ASSERT_TRUE(cert_2);
340
341 scoped_refptr<SSLCertRequestInfo> request_all(new SSLCertRequestInfo());
342
343 base::RunLoop run_loop;
344
345 CertificateList selected_certs;
346 store.GetClientCerts(*request_all, &selected_certs, run_loop.QuitClosure());
347
348 run_loop.Run();
349
350 // store should only return certs of the user, namely cert_1.
351 ASSERT_EQ(1u, selected_certs.size());
352 EXPECT_TRUE(cert_1->Equals(selected_certs[0]));
353 }
354
262 } // namespace net 355 } // namespace net
OLDNEW
« net/ssl/client_cert_store_chromeos.cc ('K') | « net/ssl/client_cert_store_chromeos.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698