[content shell] implement testRunner.overridePreference
[chromium-blink-merge.git] / chromeos / network / onc / onc_certificate_importer_unittest.cc
blob736c3a9810d382725c93df2b10ca8a602b4e9296
1 // Copyright (c) 2012 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 "chromeos/network/onc/onc_certificate_importer.h"
7 #include <cert.h>
8 #include <certdb.h>
9 #include <keyhi.h>
10 #include <pk11pub.h>
11 #include <string>
13 #include "base/logging.h"
14 #include "base/string_number_conversions.h"
15 #include "base/values.h"
16 #include "chromeos/network/onc/onc_constants.h"
17 #include "chromeos/network/onc/onc_test_utils.h"
18 #include "crypto/nss_util.h"
19 #include "net/base/cert_type.h"
20 #include "net/base/crypto_module.h"
21 #include "net/base/nss_cert_database.h"
22 #include "net/base/x509_certificate.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 namespace chromeos {
26 namespace onc {
28 #if defined(USE_NSS)
29 // In NSS 3.13, CERTDB_VALID_PEER was renamed CERTDB_TERMINAL_RECORD. So we use
30 // the new name of the macro.
31 #if !defined(CERTDB_TERMINAL_RECORD)
32 #define CERTDB_TERMINAL_RECORD CERTDB_VALID_PEER
33 #endif
35 net::CertType GetCertType(net::X509Certificate::OSCertHandle cert) {
36 CERTCertTrust trust = {0};
37 CERT_GetCertTrust(cert, &trust);
39 unsigned all_flags = trust.sslFlags | trust.emailFlags |
40 trust.objectSigningFlags;
42 if (cert->nickname && (all_flags & CERTDB_USER))
43 return net::USER_CERT;
44 if ((all_flags & CERTDB_VALID_CA) || CERT_IsCACert(cert, NULL))
45 return net::CA_CERT;
46 // TODO(mattm): http://crbug.com/128633.
47 if (trust.sslFlags & CERTDB_TERMINAL_RECORD)
48 return net::SERVER_CERT;
49 return net::UNKNOWN_CERT;
51 #else
52 net::CertType GetCertType(net::X509Certificate::OSCertHandle cert) {
53 NOTIMPLEMENTED();
54 return net::UNKNOWN_CERT;
56 #endif // USE_NSS
58 class ONCCertificateImporterTest : public testing::Test {
59 public:
60 virtual void SetUp() {
61 ASSERT_TRUE(test_nssdb_.is_open());
63 slot_ = net::NSSCertDatabase::GetInstance()->GetPublicModule();
65 // Don't run the test if the setup failed.
66 ASSERT_TRUE(slot_->os_module_handle());
68 // Test db should be empty at start of test.
69 EXPECT_EQ(0ul, ListCertsInSlot(slot_->os_module_handle()).size());
72 virtual void TearDown() {
73 EXPECT_TRUE(CleanupSlotContents(slot_->os_module_handle()));
74 EXPECT_EQ(0ul, ListCertsInSlot(slot_->os_module_handle()).size());
77 virtual ~ONCCertificateImporterTest() {}
79 protected:
80 void AddCertificateFromFile(std::string filename,
81 net::CertType expected_type,
82 std::string* guid) {
83 scoped_ptr<base::DictionaryValue> onc =
84 test_utils::ReadTestDictionary(filename);
85 base::ListValue* certificates;
86 onc->GetListWithoutPathExpansion(kCertificates, &certificates);
88 base::DictionaryValue* certificate;
89 certificates->GetDictionary(0, &certificate);
90 certificate->GetStringWithoutPathExpansion(kGUID, guid);
92 CertificateImporter importer(ONC_SOURCE_USER_IMPORT,
93 false /* don't allow web trust */);
94 EXPECT_EQ(CertificateImporter::IMPORT_OK,
95 importer.ParseAndStoreCertificates(*certificates));
97 net::CertificateList result_list;
98 CertificateImporter::ListCertsWithNickname(*guid, &result_list);
99 ASSERT_EQ(1ul, result_list.size());
100 EXPECT_EQ(expected_type, GetCertType(result_list[0]->os_cert_handle()));
103 scoped_refptr<net::CryptoModule> slot_;
105 private:
106 net::CertificateList ListCertsInSlot(PK11SlotInfo* slot) {
107 net::CertificateList result;
108 CERTCertList* cert_list = PK11_ListCertsInSlot(slot);
109 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
110 !CERT_LIST_END(node, cert_list);
111 node = CERT_LIST_NEXT(node)) {
112 result.push_back(net::X509Certificate::CreateFromHandle(
113 node->cert, net::X509Certificate::OSCertHandles()));
115 CERT_DestroyCertList(cert_list);
117 // Sort the result so that test comparisons can be deterministic.
118 std::sort(result.begin(), result.end(), net::X509Certificate::LessThan());
119 return result;
122 bool CleanupSlotContents(PK11SlotInfo* slot) {
123 bool ok = true;
124 net::CertificateList certs = ListCertsInSlot(slot);
125 for (size_t i = 0; i < certs.size(); ++i) {
126 if (!net::NSSCertDatabase::GetInstance()->DeleteCertAndKey(certs[i]))
127 ok = false;
129 return ok;
132 crypto::ScopedTestNSSDB test_nssdb_;
135 TEST_F(ONCCertificateImporterTest, AddClientCertificate) {
136 std::string guid;
137 AddCertificateFromFile("certificate-client.onc", net::USER_CERT, &guid);
139 SECKEYPrivateKeyList* privkey_list =
140 PK11_ListPrivKeysInSlot(slot_->os_module_handle(), NULL, NULL);
141 EXPECT_TRUE(privkey_list);
142 if (privkey_list) {
143 SECKEYPrivateKeyListNode* node = PRIVKEY_LIST_HEAD(privkey_list);
144 int count = 0;
145 while (!PRIVKEY_LIST_END(node, privkey_list)) {
146 char* name = PK11_GetPrivateKeyNickname(node->key);
147 EXPECT_STREQ(guid.c_str(), name);
148 PORT_Free(name);
149 count++;
150 node = PRIVKEY_LIST_NEXT(node);
152 EXPECT_EQ(1, count);
153 SECKEY_DestroyPrivateKeyList(privkey_list);
156 SECKEYPublicKeyList* pubkey_list =
157 PK11_ListPublicKeysInSlot(slot_->os_module_handle(), NULL);
158 EXPECT_TRUE(pubkey_list);
159 if (pubkey_list) {
160 SECKEYPublicKeyListNode* node = PUBKEY_LIST_HEAD(pubkey_list);
161 int count = 0;
162 while (!PUBKEY_LIST_END(node, pubkey_list)) {
163 count++;
164 node = PUBKEY_LIST_NEXT(node);
166 EXPECT_EQ(1, count);
167 SECKEY_DestroyPublicKeyList(pubkey_list);
171 TEST_F(ONCCertificateImporterTest, AddServerCertificate) {
172 std::string guid;
173 AddCertificateFromFile("certificate-server.onc", net::SERVER_CERT, &guid);
175 SECKEYPrivateKeyList* privkey_list =
176 PK11_ListPrivKeysInSlot(slot_->os_module_handle(), NULL, NULL);
177 EXPECT_FALSE(privkey_list);
179 SECKEYPublicKeyList* pubkey_list =
180 PK11_ListPublicKeysInSlot(slot_->os_module_handle(), NULL);
181 EXPECT_FALSE(pubkey_list);
184 TEST_F(ONCCertificateImporterTest, AddWebAuthorityCertificate) {
185 std::string guid;
186 AddCertificateFromFile("certificate-web-authority.onc", net::CA_CERT, &guid);
188 SECKEYPrivateKeyList* privkey_list =
189 PK11_ListPrivKeysInSlot(slot_->os_module_handle(), NULL, NULL);
190 EXPECT_FALSE(privkey_list);
192 SECKEYPublicKeyList* pubkey_list =
193 PK11_ListPublicKeysInSlot(slot_->os_module_handle(), NULL);
194 EXPECT_FALSE(pubkey_list);
197 class ONCCertificateImporterTestWithParam :
198 public ONCCertificateImporterTest,
199 public testing::WithParamInterface<
200 std::pair<net::CertType, std::pair<const char*, const char*> > > {
201 protected:
202 net::CertType GetCertTypeParam() {
203 return GetParam().first;
206 std::string GetOriginalFilename() {
207 return GetParam().second.first;
210 std::string GetUpdatedFilename() {
211 return GetParam().second.second;
215 TEST_P(ONCCertificateImporterTestWithParam, UpdateCertificate) {
216 // First we import a certificate.
218 SCOPED_TRACE("Import original certificate");
219 std::string guid_original;
220 AddCertificateFromFile(GetOriginalFilename(), GetCertTypeParam(),
221 &guid_original);
224 // Now we import the same certificate with a different GUID. The cert should
225 // be retrievable via the new GUID.
227 SCOPED_TRACE("Import updated certificate");
228 std::string guid_updated;
229 AddCertificateFromFile(GetUpdatedFilename(), GetCertTypeParam(),
230 &guid_updated);
234 TEST_P(ONCCertificateImporterTestWithParam, ReimportCertificate) {
235 // Verify that reimporting a client certificate works.
236 for (int i = 0; i < 2; ++i) {
237 SCOPED_TRACE("Import certificate, iteration " + base::IntToString(i));
239 std::string guid_original;
240 AddCertificateFromFile(GetOriginalFilename(), GetCertTypeParam(),
241 &guid_original);
245 INSTANTIATE_TEST_CASE_P(
246 ONCCertificateImporterTestWithParam,
247 ONCCertificateImporterTestWithParam,
248 ::testing::Values(
249 std::make_pair(net::USER_CERT,
250 std::make_pair("certificate-client.onc",
251 "certificate-client-update.onc")),
252 std::make_pair(net::SERVER_CERT,
253 std::make_pair("certificate-server.onc",
254 "certificate-server-update.onc")),
255 std::make_pair(
256 net::CA_CERT,
257 std::make_pair("certificate-web-authority.onc",
258 "certificate-web-authority-update.onc"))));
260 } // namespace onc
261 } // namespace chromeos