blob: 70e8e015338e6d71c60fa94f6419a25544d11fb4 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Yingdi Yu8dceb1d2014-02-18 12:45:10 -08002/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080020 */
21
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080022#include "security/key-chain.hpp"
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -070023#include "../util/test-home-environment-fixture.hpp"
Yingdi Yuf56c68f2014-04-24 21:50:13 -070024#include <boost/filesystem.hpp>
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080025
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070026#include "boost-test.hpp"
27
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080028namespace ndn {
Yingdi Yuf56c68f2014-04-24 21:50:13 -070029namespace tests {
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080030
Yingdi Yu5ec0ee32014-06-24 16:26:09 -070031using std::vector;
32
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -070033BOOST_FIXTURE_TEST_SUITE(SecurityTestKeyChain, util::TestHomeEnvironmentFixture)
Yingdi Yuf56c68f2014-04-24 21:50:13 -070034
35BOOST_AUTO_TEST_CASE(ConstructorNormalConfig)
36{
37 using namespace boost::filesystem;
38
Alexander Afanasyev8b1674a2014-05-15 00:58:43 -070039 setenv("TEST_HOME", "tests/unit-tests/security/config-file-home", 1);
Yingdi Yuf56c68f2014-04-24 21:50:13 -070040
41 BOOST_REQUIRE_NO_THROW(KeyChain());
42
43 path pibPath(absolute(std::getenv("TEST_HOME")));
44 pibPath /= ".ndn/ndnsec-public-info.db";
45
46 boost::filesystem::remove(pibPath);
47}
48
49BOOST_AUTO_TEST_CASE(ConstructorEmptyConfig)
50{
51 using namespace boost::filesystem;
52
Alexander Afanasyev8b1674a2014-05-15 00:58:43 -070053 setenv("TEST_HOME", "tests/unit-tests/security/config-file-empty-home", 1);
Yingdi Yuf56c68f2014-04-24 21:50:13 -070054
Yingdi Yu41546342014-11-30 23:37:53 -080055#if defined(NDN_CXX_HAVE_OSX_SECURITY)
56 std::string oldHOME;
57 if (std::getenv("OLD_HOME"))
58 oldHOME = std::getenv("OLD_HOME");
59
60 std::string HOME;
61 if (std::getenv("HOME"))
62 HOME = std::getenv("HOME");
63
64 if (!oldHOME.empty())
65 setenv("HOME", oldHOME.c_str(), 1);
66 else
67 unsetenv("HOME");
68#endif
69
70 BOOST_REQUIRE_NO_THROW(KeyChain());
71
72#if defined(NDN_CXX_HAVE_OSX_SECURITY)
73 if (!HOME.empty())
74 setenv("HOME", HOME.c_str(), 1);
75 else
76 unsetenv("HOME");
77#endif
78
79 path pibPath(absolute(std::getenv("TEST_HOME")));
80 pibPath /= ".ndn/ndnsec-public-info.db";
81
82 boost::filesystem::remove(pibPath);
83}
84
85BOOST_AUTO_TEST_CASE(ConstructorEmpty2Config)
86{
87 using namespace boost::filesystem;
88
89 setenv("TEST_HOME", "tests/unit-tests/security/config-file-empty2-home", 1);
90
Yingdi Yuf56c68f2014-04-24 21:50:13 -070091 BOOST_REQUIRE_NO_THROW(KeyChain());
92
93 path pibPath(absolute(std::getenv("TEST_HOME")));
94 pibPath /= ".ndn/ndnsec-public-info.db";
95
96 boost::filesystem::remove(pibPath);
97}
98
99BOOST_AUTO_TEST_CASE(ConstructorMalConfig)
100{
101 using namespace boost::filesystem;
102
Alexander Afanasyev8b1674a2014-05-15 00:58:43 -0700103 setenv("TEST_HOME", "tests/unit-tests/security/config-file-malformed-home", 1);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700104
105 BOOST_REQUIRE_THROW(KeyChain(), KeyChain::Error); // Wrong configuration. Error expected.
106}
107
108BOOST_AUTO_TEST_CASE(ConstructorMal2Config)
109{
110 using namespace boost::filesystem;
111
Alexander Afanasyev8b1674a2014-05-15 00:58:43 -0700112 setenv("TEST_HOME", "tests/unit-tests/security/config-file-malformed2-home", 1);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700113
114 BOOST_REQUIRE_THROW(KeyChain(), KeyChain::Error); // Wrong configuration. Error expected.
115}
116
117BOOST_AUTO_TEST_CASE(ExportIdentity)
118{
Yingdi Yu41546342014-11-30 23:37:53 -0800119 KeyChain keyChain;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800120
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700121 Name identity("/TestKeyChain/ExportIdentity/");
122 identity.appendVersion();
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800123 keyChain.createIdentity(identity);
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700124
Yingdi Yu64c3fb42014-02-26 17:30:04 -0800125 shared_ptr<SecuredBag> exported = keyChain.exportIdentity(identity, "1234");
126
127 Block block = exported->wireEncode();
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800128
129 Name keyName = keyChain.getDefaultKeyNameForIdentity(identity);
130 Name certName = keyChain.getDefaultCertificateNameForKey(keyName);
131
132 keyChain.deleteIdentity(identity);
133
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700134 BOOST_CHECK_EQUAL(keyChain.doesIdentityExist(identity), false);
135 BOOST_CHECK_EQUAL(keyChain.doesPublicKeyExist(keyName), false);
136 BOOST_CHECK_EQUAL(keyChain.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE), false);
137 BOOST_CHECK_EQUAL(keyChain.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC), false);
138 BOOST_CHECK_EQUAL(keyChain.doesCertificateExist(certName), false);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800139
Yingdi Yu64c3fb42014-02-26 17:30:04 -0800140 SecuredBag imported;
141 imported.wireDecode(block);
142 keyChain.importIdentity(imported, "1234");
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800143
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700144 BOOST_CHECK(keyChain.doesIdentityExist(identity));
145 BOOST_CHECK(keyChain.doesPublicKeyExist(keyName));
146 BOOST_CHECK(keyChain.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE));
147 BOOST_CHECK(keyChain.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC));
148 BOOST_CHECK(keyChain.doesCertificateExist(certName));
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800149
150 keyChain.deleteIdentity(identity);
151
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700152 BOOST_CHECK_EQUAL(keyChain.doesIdentityExist(identity), false);
153 BOOST_CHECK_EQUAL(keyChain.doesPublicKeyExist(keyName), false);
154 BOOST_CHECK_EQUAL(keyChain.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE), false);
155 BOOST_CHECK_EQUAL(keyChain.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC), false);
156 BOOST_CHECK_EQUAL(keyChain.doesCertificateExist(certName), false);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800157}
158
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700159BOOST_AUTO_TEST_CASE(PrepareIdentityCertificate)
Yingdi Yuc55680b2014-02-26 12:31:35 -0800160{
Yingdi Yu41546342014-11-30 23:37:53 -0800161 KeyChain keyChain;
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700162
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700163 Name identity("/TestKeyChain/PrepareIdentityCertificate/");
164 identity.appendVersion();
Yingdi Yuc55680b2014-02-26 12:31:35 -0800165 keyChain.createIdentity(identity);
166
167 vector<CertificateSubjectDescription> subjectDescription;
168 Name lowerIdentity = identity;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700169 lowerIdentity.append("Lower").appendVersion();
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700170 Name lowerKeyName = keyChain.generateRsaKeyPair(lowerIdentity, true);
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700171 shared_ptr<IdentityCertificate> idCert =
172 keyChain.prepareUnsignedIdentityCertificate(lowerKeyName, identity,
173 time::system_clock::now(),
174 time::system_clock::now() + time::days(365),
175 subjectDescription);
Yingdi Yuc55680b2014-02-26 12:31:35 -0800176 BOOST_CHECK(static_cast<bool>(idCert));
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700177 BOOST_CHECK_EQUAL(idCert->getName().getPrefix(5),
178 Name().append(identity).append("KEY").append("Lower"));
Yingdi Yuc55680b2014-02-26 12:31:35 -0800179
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700180 shared_ptr<IdentityCertificate> idCert11 =
181 keyChain.prepareUnsignedIdentityCertificate(lowerKeyName, identity,
182 time::system_clock::now(),
183 time::system_clock::now() + time::days(365),
184 subjectDescription,
185 lowerIdentity);
186 BOOST_CHECK(static_cast<bool>(idCert11));
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700187 BOOST_CHECK_EQUAL(idCert11->getName().getPrefix(6),
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700188 Name().append(lowerIdentity).append("KEY"));
Yingdi Yuc55680b2014-02-26 12:31:35 -0800189
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700190 Name anotherIdentity("/TestKeyChain/PrepareIdentityCertificate/Another/");
191 anotherIdentity.appendVersion();
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700192 Name anotherKeyName = keyChain.generateRsaKeyPair(anotherIdentity, true);
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700193 shared_ptr<IdentityCertificate> idCert2 =
194 keyChain.prepareUnsignedIdentityCertificate(anotherKeyName, identity,
195 time::system_clock::now(),
196 time::system_clock::now() + time::days(365),
197 subjectDescription);
Yingdi Yuc55680b2014-02-26 12:31:35 -0800198 BOOST_CHECK(static_cast<bool>(idCert2));
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700199 BOOST_CHECK_EQUAL(idCert2->getName().getPrefix(5), Name().append(anotherIdentity).append("KEY"));
Yingdi Yuc55680b2014-02-26 12:31:35 -0800200
201
202 Name wrongKeyName1;
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700203 shared_ptr<IdentityCertificate> idCert3 =
204 keyChain.prepareUnsignedIdentityCertificate(wrongKeyName1, identity,
205 time::system_clock::now(),
206 time::system_clock::now() + time::days(365),
207 subjectDescription);
208 BOOST_CHECK_EQUAL(static_cast<bool>(idCert3), false);
Yingdi Yuc55680b2014-02-26 12:31:35 -0800209
210
211 Name wrongKeyName2("/TestKeyChain/PrepareIdentityCertificate");
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700212 shared_ptr<IdentityCertificate> idCert4 =
213 keyChain.prepareUnsignedIdentityCertificate(wrongKeyName2, identity,
214 time::system_clock::now(),
215 time::system_clock::now() + time::days(365),
216 subjectDescription);
217 BOOST_CHECK_EQUAL(static_cast<bool>(idCert4), false);
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700218
Yingdi Yuc55680b2014-02-26 12:31:35 -0800219
220 Name wrongKeyName3("/TestKeyChain/PrepareIdentityCertificate/ksk-1234");
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700221 shared_ptr<IdentityCertificate> idCert5 =
222 keyChain.prepareUnsignedIdentityCertificate(wrongKeyName3, identity,
223 time::system_clock::now(),
224 time::system_clock::now() + time::days(365),
225 subjectDescription);
226 BOOST_CHECK_EQUAL(static_cast<bool>(idCert5), false);
Yingdi Yuc55680b2014-02-26 12:31:35 -0800227
228 keyChain.deleteIdentity(identity);
229 keyChain.deleteIdentity(lowerIdentity);
230 keyChain.deleteIdentity(anotherIdentity);
231}
232
Yingdi Yu41546342014-11-30 23:37:53 -0800233BOOST_AUTO_TEST_CASE(Delete)
234{
235 KeyChain keyChain;
236
237 Name identity("/TestSecPublicInfoSqlite3/Delete");
238 identity.appendVersion();
239
240 Name certName1;
241 BOOST_REQUIRE_NO_THROW(certName1 = keyChain.createIdentity(identity));
242
243 Name keyName1 = IdentityCertificate::certificateNameToPublicKeyName(certName1);
244 Name keyName2;
245 BOOST_REQUIRE_NO_THROW(keyName2 = keyChain.generateRsaKeyPairAsDefault(identity));
246
247 shared_ptr<IdentityCertificate> cert2;
248 BOOST_REQUIRE_NO_THROW(cert2 = keyChain.selfSign(keyName2));
249 Name certName2 = cert2->getName();
250 BOOST_REQUIRE_NO_THROW(keyChain.addCertificateAsKeyDefault(*cert2));
251
252 Name keyName3;
253 BOOST_REQUIRE_NO_THROW(keyName3 = keyChain.generateRsaKeyPairAsDefault(identity));
254
255 shared_ptr<IdentityCertificate> cert3;
256 BOOST_REQUIRE_NO_THROW(cert3 = keyChain.selfSign(keyName3));
257 Name certName3 = cert3->getName();
258 BOOST_REQUIRE_NO_THROW(keyChain.addCertificateAsKeyDefault(*cert3));
259 shared_ptr<IdentityCertificate> cert4;
260 BOOST_REQUIRE_NO_THROW(cert4 = keyChain.selfSign(keyName3));
261 Name certName4 = cert4->getName();
262 BOOST_REQUIRE_NO_THROW(keyChain.addCertificateAsKeyDefault(*cert4));
263 shared_ptr<IdentityCertificate> cert5;
264 BOOST_REQUIRE_NO_THROW(cert5 = keyChain.selfSign(keyName3));
265 Name certName5 = cert5->getName();
266 BOOST_REQUIRE_NO_THROW(keyChain.addCertificateAsKeyDefault(*cert5));
267
268 BOOST_CHECK_EQUAL(keyChain.doesIdentityExist(identity), true);
269 BOOST_CHECK_EQUAL(keyChain.doesPublicKeyExist(keyName1), true);
270 BOOST_CHECK_EQUAL(keyChain.doesPublicKeyExist(keyName2), true);
271 BOOST_CHECK_EQUAL(keyChain.doesPublicKeyExist(keyName3), true);
272 BOOST_CHECK_EQUAL(keyChain.doesCertificateExist(certName1), true);
273 BOOST_CHECK_EQUAL(keyChain.doesCertificateExist(certName2), true);
274 BOOST_CHECK_EQUAL(keyChain.doesCertificateExist(certName3), true);
275 BOOST_CHECK_EQUAL(keyChain.doesCertificateExist(certName4), true);
276 BOOST_CHECK_EQUAL(keyChain.doesCertificateExist(certName5), true);
277
278 BOOST_REQUIRE_NO_THROW(keyChain.deleteCertificate(certName5));
279 BOOST_CHECK_EQUAL(keyChain.doesCertificateExist(certName5), false);
280 BOOST_CHECK_EQUAL(keyChain.doesCertificateExist(certName3), true);
281 BOOST_CHECK_EQUAL(keyChain.doesCertificateExist(certName4), true);
282 BOOST_CHECK_EQUAL(keyChain.doesPublicKeyExist(keyName3), true);
283
284 BOOST_REQUIRE_NO_THROW(keyChain.deleteKey(keyName3));
285 BOOST_CHECK_EQUAL(keyChain.doesCertificateExist(certName4), false);
286 BOOST_CHECK_EQUAL(keyChain.doesCertificateExist(certName3), false);
287 BOOST_CHECK_EQUAL(keyChain.doesPublicKeyExist(keyName3), false);
288 BOOST_CHECK_EQUAL(keyChain.doesPublicKeyExist(keyName2), true);
289 BOOST_CHECK_EQUAL(keyChain.doesPublicKeyExist(keyName1), true);
290 BOOST_CHECK_EQUAL(keyChain.doesIdentityExist(identity), true);
291
292 BOOST_REQUIRE_NO_THROW(keyChain.deleteIdentity(identity));
293 BOOST_CHECK_EQUAL(keyChain.doesCertificateExist(certName2), false);
294 BOOST_CHECK_EQUAL(keyChain.doesPublicKeyExist(keyName2), false);
295 BOOST_CHECK_EQUAL(keyChain.doesCertificateExist(certName1), false);
296 BOOST_CHECK_EQUAL(keyChain.doesPublicKeyExist(keyName1), false);
297 BOOST_CHECK_EQUAL(keyChain.doesIdentityExist(identity), false);
298}
299
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800300BOOST_AUTO_TEST_SUITE_END()
301
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700302} // namespace tests
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800303} // namespace ndn