blob: 9a2300dfa95b5bd77b6dac67f861a7fd1f691012 [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"
Yingdi Yuf56c68f2014-04-24 21:50:13 -070023#include <boost/filesystem.hpp>
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080024
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070025#include "boost-test.hpp"
26
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080027using namespace std;
28
29namespace ndn {
Yingdi Yuf56c68f2014-04-24 21:50:13 -070030namespace tests {
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080031
Yingdi Yuf56c68f2014-04-24 21:50:13 -070032class KeychainConfigFileFixture
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080033{
Yingdi Yuf56c68f2014-04-24 21:50:13 -070034public:
35 KeychainConfigFileFixture()
36 {
37 if (std::getenv("TEST_HOME"))
38 m_HOME = std::getenv("TEST_HOME");
39 }
40
41 ~KeychainConfigFileFixture()
42 {
43 if (!m_HOME.empty())
44 setenv("TEST_HOME", m_HOME.c_str(), 1);
45 else
46 unsetenv("TEST_HOME");
47 }
48
49protected:
50 std::string m_HOME;
51};
52
53BOOST_FIXTURE_TEST_SUITE(SecurityTestKeyChain, KeychainConfigFileFixture)
54
55BOOST_AUTO_TEST_CASE(ConstructorNormalConfig)
56{
57 using namespace boost::filesystem;
58
Alexander Afanasyev8b1674a2014-05-15 00:58:43 -070059 setenv("TEST_HOME", "tests/unit-tests/security/config-file-home", 1);
Yingdi Yuf56c68f2014-04-24 21:50:13 -070060
61 BOOST_REQUIRE_NO_THROW(KeyChain());
62
63 path pibPath(absolute(std::getenv("TEST_HOME")));
64 pibPath /= ".ndn/ndnsec-public-info.db";
65
66 boost::filesystem::remove(pibPath);
67}
68
69BOOST_AUTO_TEST_CASE(ConstructorEmptyConfig)
70{
71 using namespace boost::filesystem;
72
Alexander Afanasyev8b1674a2014-05-15 00:58:43 -070073 setenv("TEST_HOME", "tests/unit-tests/security/config-file-empty-home", 1);
Yingdi Yuf56c68f2014-04-24 21:50:13 -070074
75 BOOST_REQUIRE_NO_THROW(KeyChain());
76
77 path pibPath(absolute(std::getenv("TEST_HOME")));
78 pibPath /= ".ndn/ndnsec-public-info.db";
79
80 boost::filesystem::remove(pibPath);
81}
82
83BOOST_AUTO_TEST_CASE(ConstructorMalConfig)
84{
85 using namespace boost::filesystem;
86
Alexander Afanasyev8b1674a2014-05-15 00:58:43 -070087 setenv("TEST_HOME", "tests/unit-tests/security/config-file-malformed-home", 1);
Yingdi Yuf56c68f2014-04-24 21:50:13 -070088
89 BOOST_REQUIRE_THROW(KeyChain(), KeyChain::Error); // Wrong configuration. Error expected.
90}
91
92BOOST_AUTO_TEST_CASE(ConstructorMal2Config)
93{
94 using namespace boost::filesystem;
95
Alexander Afanasyev8b1674a2014-05-15 00:58:43 -070096 setenv("TEST_HOME", "tests/unit-tests/security/config-file-malformed2-home", 1);
Yingdi Yuf56c68f2014-04-24 21:50:13 -070097
98 BOOST_REQUIRE_THROW(KeyChain(), KeyChain::Error); // Wrong configuration. Error expected.
99}
100
101BOOST_AUTO_TEST_CASE(ExportIdentity)
102{
103 BOOST_REQUIRE_NO_THROW(KeyChain("sqlite3", "file"));
104 KeyChain keyChain("sqlite3", "file");
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800105
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700106 Name identity("/TestKeyChain/ExportIdentity/");
107 identity.appendVersion();
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800108 keyChain.createIdentity(identity);
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700109
Yingdi Yu64c3fb42014-02-26 17:30:04 -0800110 shared_ptr<SecuredBag> exported = keyChain.exportIdentity(identity, "1234");
111
112 Block block = exported->wireEncode();
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800113
114 Name keyName = keyChain.getDefaultKeyNameForIdentity(identity);
115 Name certName = keyChain.getDefaultCertificateNameForKey(keyName);
116
117 keyChain.deleteIdentity(identity);
118
119 BOOST_REQUIRE(keyChain.doesIdentityExist(identity) == false);
120 BOOST_REQUIRE(keyChain.doesPublicKeyExist(keyName) == false);
121 BOOST_REQUIRE(keyChain.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE) == false);
122 BOOST_REQUIRE(keyChain.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC) == false);
123 BOOST_REQUIRE(keyChain.doesCertificateExist(certName) == false);
124
Yingdi Yu64c3fb42014-02-26 17:30:04 -0800125 SecuredBag imported;
126 imported.wireDecode(block);
127 keyChain.importIdentity(imported, "1234");
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800128
129 BOOST_REQUIRE(keyChain.doesIdentityExist(identity));
130 BOOST_REQUIRE(keyChain.doesPublicKeyExist(keyName));
131 BOOST_REQUIRE(keyChain.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE));
132 BOOST_REQUIRE(keyChain.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC));
133 BOOST_REQUIRE(keyChain.doesCertificateExist(certName));
134
135 keyChain.deleteIdentity(identity);
136
137 BOOST_REQUIRE(keyChain.doesIdentityExist(identity) == false);
138 BOOST_REQUIRE(keyChain.doesPublicKeyExist(keyName) == false);
139 BOOST_REQUIRE(keyChain.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE) == false);
140 BOOST_REQUIRE(keyChain.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC) == false);
141 BOOST_REQUIRE(keyChain.doesCertificateExist(certName) == false);
142}
143
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700144BOOST_AUTO_TEST_CASE(PrepareIdentityCertificate)
Yingdi Yuc55680b2014-02-26 12:31:35 -0800145{
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700146 BOOST_REQUIRE_NO_THROW(KeyChain("sqlite3", "file"));
147 KeyChain keyChain("sqlite3", "file");
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700148
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700149 Name identity("/TestKeyChain/PrepareIdentityCertificate/");
150 identity.appendVersion();
Yingdi Yuc55680b2014-02-26 12:31:35 -0800151 keyChain.createIdentity(identity);
152
153 vector<CertificateSubjectDescription> subjectDescription;
154 Name lowerIdentity = identity;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700155 lowerIdentity.append("Lower").appendVersion();
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700156 Name lowerKeyName = keyChain.generateRsaKeyPair(lowerIdentity, true);
Yingdi Yuc55680b2014-02-26 12:31:35 -0800157 shared_ptr<IdentityCertificate> idCert
158 = keyChain.prepareUnsignedIdentityCertificate(lowerKeyName, identity,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700159 time::system_clock::now(),
160 time::system_clock::now() + time::days(365),
161 subjectDescription);
Yingdi Yuc55680b2014-02-26 12:31:35 -0800162 BOOST_CHECK(static_cast<bool>(idCert));
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700163 BOOST_CHECK(idCert->getName().getPrefix(5) ==
164 Name().append(identity).append("KEY").append("Lower"));
Yingdi Yuc55680b2014-02-26 12:31:35 -0800165
166
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700167 Name anotherIdentity("/TestKeyChain/PrepareIdentityCertificate/Another/");
168 anotherIdentity.appendVersion();
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700169 Name anotherKeyName = keyChain.generateRsaKeyPair(anotherIdentity, true);
Yingdi Yuc55680b2014-02-26 12:31:35 -0800170 shared_ptr<IdentityCertificate> idCert2
171 = keyChain.prepareUnsignedIdentityCertificate(anotherKeyName, identity,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700172 time::system_clock::now(),
173 time::system_clock::now() + time::days(365),
174 subjectDescription);
Yingdi Yuc55680b2014-02-26 12:31:35 -0800175 BOOST_CHECK(static_cast<bool>(idCert2));
176 BOOST_CHECK(idCert2->getName().getPrefix(5) == Name().append(anotherIdentity).append("KEY"));
177
178
179 Name wrongKeyName1;
180 shared_ptr<IdentityCertificate> idCert3
181 = keyChain.prepareUnsignedIdentityCertificate(wrongKeyName1, identity,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700182 time::system_clock::now(),
183 time::system_clock::now() + time::days(365),
184 subjectDescription);
Yingdi Yuc55680b2014-02-26 12:31:35 -0800185 BOOST_CHECK(!static_cast<bool>(idCert3));
186
187
188 Name wrongKeyName2("/TestKeyChain/PrepareIdentityCertificate");
189 shared_ptr<IdentityCertificate> idCert4
190 = keyChain.prepareUnsignedIdentityCertificate(wrongKeyName2, identity,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700191 time::system_clock::now(),
192 time::system_clock::now() + time::days(365),
193 subjectDescription);
Yingdi Yuc55680b2014-02-26 12:31:35 -0800194 BOOST_CHECK(!static_cast<bool>(idCert4));
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700195
Yingdi Yuc55680b2014-02-26 12:31:35 -0800196
197 Name wrongKeyName3("/TestKeyChain/PrepareIdentityCertificate/ksk-1234");
198 shared_ptr<IdentityCertificate> idCert5
199 = keyChain.prepareUnsignedIdentityCertificate(wrongKeyName3, identity,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700200 time::system_clock::now(),
201 time::system_clock::now() + time::days(365),
202 subjectDescription);
Yingdi Yuc55680b2014-02-26 12:31:35 -0800203 BOOST_CHECK(!static_cast<bool>(idCert5));
204
205 keyChain.deleteIdentity(identity);
206 keyChain.deleteIdentity(lowerIdentity);
207 keyChain.deleteIdentity(anotherIdentity);
208}
209
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800210BOOST_AUTO_TEST_SUITE_END()
211
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700212} // namespace tests
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800213} // namespace ndn