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
3 // found in the LICENSE file.
5 #include "net/cert/nss_cert_database_chromeos.h"
8 #include "base/callback.h"
9 #include "base/run_loop.h"
10 #include "crypto/nss_util.h"
11 #include "crypto/nss_util_internal.h"
12 #include "net/base/test_data_directory.h"
13 #include "net/cert/cert_database.h"
14 #include "net/test/cert_test_util.h"
15 #include "testing/gtest/include/gtest/gtest.h"
21 bool IsCertInCertificateList(const X509Certificate
* cert
,
22 const CertificateList
& cert_list
) {
23 for (CertificateList::const_iterator it
= cert_list
.begin();
24 it
!= cert_list
.end();
26 if (X509Certificate::IsSameOSCert((*it
)->os_cert_handle(),
27 cert
->os_cert_handle()))
35 class NSSCertDatabaseChromeOSTest
: public testing::Test
,
36 public CertDatabase::Observer
{
38 NSSCertDatabaseChromeOSTest()
39 : observer_added_(false), user_1_("user1"), user_2_("user2") {}
41 virtual void SetUp() OVERRIDE
{
42 // Initialize nss_util slots.
43 ASSERT_TRUE(user_1_
.constructed_successfully());
44 ASSERT_TRUE(user_2_
.constructed_successfully());
48 // Create NSSCertDatabaseChromeOS for each user.
49 db_1_
.reset(new NSSCertDatabaseChromeOS(
50 crypto::GetPublicSlotForChromeOSUser(user_1_
.username_hash()),
51 crypto::GetPrivateSlotForChromeOSUser(
52 user_1_
.username_hash(),
53 base::Callback
<void(crypto::ScopedPK11Slot
)>())));
54 db_2_
.reset(new NSSCertDatabaseChromeOS(
55 crypto::GetPublicSlotForChromeOSUser(user_2_
.username_hash()),
56 crypto::GetPrivateSlotForChromeOSUser(
57 user_2_
.username_hash(),
58 base::Callback
<void(crypto::ScopedPK11Slot
)>())));
60 // Add observer to CertDatabase for checking that notifications from
61 // NSSCertDatabaseChromeOS are proxied to the CertDatabase.
62 CertDatabase::GetInstance()->AddObserver(this);
63 observer_added_
= true;
66 virtual void TearDown() OVERRIDE
{
68 CertDatabase::GetInstance()->RemoveObserver(this);
71 // CertDatabase::Observer:
72 virtual void OnCertAdded(const X509Certificate
* cert
) OVERRIDE
{
73 added_
.push_back(cert
? cert
->os_cert_handle() : NULL
);
76 virtual void OnCertRemoved(const X509Certificate
* cert
) OVERRIDE
{}
78 virtual void OnCACertChanged(const X509Certificate
* cert
) OVERRIDE
{
79 added_ca_
.push_back(cert
? cert
->os_cert_handle() : NULL
);
84 // Certificates that were passed to the CertDatabase observers.
85 std::vector
<CERTCertificate
*> added_ca_
;
86 std::vector
<CERTCertificate
*> added_
;
88 crypto::ScopedTestNSSChromeOSUser user_1_
;
89 crypto::ScopedTestNSSChromeOSUser user_2_
;
90 scoped_ptr
<NSSCertDatabaseChromeOS
> db_1_
;
91 scoped_ptr
<NSSCertDatabaseChromeOS
> db_2_
;
94 // Test that ListModules() on each user includes that user's NSS software slot,
95 // and does not include the software slot of the other user. (Does not check the
96 // private slot, since it is the same as the public slot in tests.)
97 TEST_F(NSSCertDatabaseChromeOSTest
, ListModules
) {
98 CryptoModuleList modules_1
;
99 CryptoModuleList modules_2
;
101 db_1_
->ListModules(&modules_1
, false /* need_rw */);
102 db_2_
->ListModules(&modules_2
, false /* need_rw */);
104 bool found_1
= false;
105 for (CryptoModuleList::iterator it
= modules_1
.begin(); it
!= modules_1
.end();
107 EXPECT_NE(db_2_
->GetPublicSlot().get(), (*it
)->os_module_handle());
108 if ((*it
)->os_module_handle() == db_1_
->GetPublicSlot().get())
111 EXPECT_TRUE(found_1
);
113 bool found_2
= false;
114 for (CryptoModuleList::iterator it
= modules_2
.begin(); it
!= modules_2
.end();
116 EXPECT_NE(db_1_
->GetPublicSlot().get(), (*it
)->os_module_handle());
117 if ((*it
)->os_module_handle() == db_2_
->GetPublicSlot().get())
120 EXPECT_TRUE(found_2
);
123 // Test that ImportCACerts imports the cert to the correct slot, and that
124 // ListCerts includes the added cert for the correct user, and does not include
125 // it for the other user.
126 TEST_F(NSSCertDatabaseChromeOSTest
, ImportCACerts
) {
127 // Load test certs from disk.
128 CertificateList certs_1
=
129 CreateCertificateListFromFile(GetTestCertsDirectory(),
131 X509Certificate::FORMAT_AUTO
);
132 ASSERT_EQ(1U, certs_1
.size());
134 CertificateList certs_2
=
135 CreateCertificateListFromFile(GetTestCertsDirectory(),
137 X509Certificate::FORMAT_AUTO
);
138 ASSERT_EQ(1U, certs_2
.size());
140 // Import one cert for each user.
141 NSSCertDatabase::ImportCertFailureList failed
;
143 db_1_
->ImportCACerts(certs_1
, NSSCertDatabase::TRUSTED_SSL
, &failed
));
144 EXPECT_EQ(0U, failed
.size());
147 db_2_
->ImportCACerts(certs_2
, NSSCertDatabase::TRUSTED_SSL
, &failed
));
148 EXPECT_EQ(0U, failed
.size());
150 // Get cert list for each user.
151 CertificateList user_1_certlist
;
152 CertificateList user_2_certlist
;
153 db_1_
->ListCerts(&user_1_certlist
);
154 db_2_
->ListCerts(&user_2_certlist
);
156 // Check that the imported certs only shows up in the list for the user that
158 EXPECT_TRUE(IsCertInCertificateList(certs_1
[0], user_1_certlist
));
159 EXPECT_FALSE(IsCertInCertificateList(certs_1
[0], user_2_certlist
));
161 EXPECT_TRUE(IsCertInCertificateList(certs_2
[0], user_2_certlist
));
162 EXPECT_FALSE(IsCertInCertificateList(certs_2
[0], user_1_certlist
));
164 // Run the message loop so the observer notifications get processed.
165 base::RunLoop().RunUntilIdle();
166 // Should have gotten two OnCACertChanged notifications.
167 ASSERT_EQ(2U, added_ca_
.size());
168 // TODO(mattm): make NSSCertDatabase actually pass the cert to the callback,
169 // and enable these checks:
170 // EXPECT_EQ(certs_1[0]->os_cert_handle(), added_ca_[0]);
171 // EXPECT_EQ(certs_2[0]->os_cert_handle(), added_ca_[1]);
172 EXPECT_EQ(0U, added_
.size());
175 // Test that ImportServerCerts imports the cert to the correct slot, and that
176 // ListCerts includes the added cert for the correct user, and does not include
177 // it for the other user.
178 TEST_F(NSSCertDatabaseChromeOSTest
, ImportServerCert
) {
179 // Load test certs from disk.
180 CertificateList certs_1
= CreateCertificateListFromFile(
181 GetTestCertsDirectory(), "ok_cert.pem", X509Certificate::FORMAT_AUTO
);
182 ASSERT_EQ(1U, certs_1
.size());
184 CertificateList certs_2
=
185 CreateCertificateListFromFile(GetTestCertsDirectory(),
186 "2048-rsa-ee-by-2048-rsa-intermediate.pem",
187 X509Certificate::FORMAT_AUTO
);
188 ASSERT_EQ(1U, certs_2
.size());
190 // Import one cert for each user.
191 NSSCertDatabase::ImportCertFailureList failed
;
193 db_1_
->ImportServerCert(certs_1
, NSSCertDatabase::TRUSTED_SSL
, &failed
));
194 EXPECT_EQ(0U, failed
.size());
197 db_2_
->ImportServerCert(certs_2
, NSSCertDatabase::TRUSTED_SSL
, &failed
));
198 EXPECT_EQ(0U, failed
.size());
200 // Get cert list for each user.
201 CertificateList user_1_certlist
;
202 CertificateList user_2_certlist
;
203 db_1_
->ListCerts(&user_1_certlist
);
204 db_2_
->ListCerts(&user_2_certlist
);
206 // Check that the imported certs only shows up in the list for the user that
208 EXPECT_TRUE(IsCertInCertificateList(certs_1
[0], user_1_certlist
));
209 EXPECT_FALSE(IsCertInCertificateList(certs_1
[0], user_2_certlist
));
211 EXPECT_TRUE(IsCertInCertificateList(certs_2
[0], user_2_certlist
));
212 EXPECT_FALSE(IsCertInCertificateList(certs_2
[0], user_1_certlist
));
214 // Run the message loop so the observer notifications get processed.
215 base::RunLoop().RunUntilIdle();
216 // TODO(mattm): ImportServerCert doesn't actually cause any observers to
217 // fire. Is that correct?
218 EXPECT_EQ(0U, added_ca_
.size());
219 EXPECT_EQ(0U, added_
.size());