blob: 191653259775f250d017253f70000b3f62d3de82 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Yingdi Yuf56c68f2014-04-24 21:50:13 -07002/**
Yingdi Yufe4733a2015-10-22 14:24:12 -07003 * Copyright (c) 2013-2017 Regents of the University of California.
Yingdi Yuf56c68f2014-04-24 21:50:13 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Yingdi Yuf56c68f2014-04-24 21:50:13 -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 Yuf56c68f2014-04-24 21:50:13 -070020 *
21 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
22 */
23
24#include "key-chain.hpp"
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -080025#include "../signing-helpers.hpp"
Yingdi Yuf56c68f2014-04-24 21:50:13 -070026
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -080027#include "../../util/random.hpp"
28#include "../../util/config-file.hpp"
Alexander Afanasyev07113802015-01-15 19:14:36 -080029
Yingdi Yuf56c68f2014-04-24 21:50:13 -070030#include "sec-public-info-sqlite3.hpp"
Yingdi Yuf56c68f2014-04-24 21:50:13 -070031
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -050032#ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS
Yingdi Yuf56c68f2014-04-24 21:50:13 -070033#include "sec-tpm-osx.hpp"
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -050034#endif // NDN_CXX_HAVE_OSX_FRAMEWORKS
Yingdi Yuf56c68f2014-04-24 21:50:13 -070035
Alexander Afanasyev07113802015-01-15 19:14:36 -080036#include "sec-tpm-file.hpp"
Yingdi Yuf56c68f2014-04-24 21:50:13 -070037
38namespace ndn {
Yingdi Yu1b0311c2015-06-10 14:58:47 -070039namespace security {
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -080040namespace v1 {
Yingdi Yuf56c68f2014-04-24 21:50:13 -070041
Yingdi Yu0eb5d722014-06-10 15:06:25 -070042// Use a GUID as a magic number of KeyChain::DEFAULT_PREFIX identifier
43const Name KeyChain::DEFAULT_PREFIX("/723821fd-f534-44b3-80d9-44bf5f58bbbb");
Yingdi Yu1b0311c2015-06-10 14:58:47 -070044
45// Note: cannot use default constructor, as it depends on static variables which may or may not be
46// initialized at this point
47const SigningInfo KeyChain::DEFAULT_SIGNING_INFO(SigningInfo::SIGNER_TYPE_NULL, Name(), SignatureInfo());
Yingdi Yu0eb5d722014-06-10 15:06:25 -070048
Yingdi Yu7036ce22014-06-19 18:53:37 -070049const RsaKeyParams KeyChain::DEFAULT_KEY_PARAMS;
50
Alexander Afanasyev07113802015-01-15 19:14:36 -080051const std::string DEFAULT_PIB_SCHEME = "pib-sqlite3";
52
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -050053#if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) and defined(NDN_CXX_WITH_OSX_KEYCHAIN)
Alexander Afanasyev07113802015-01-15 19:14:36 -080054const std::string DEFAULT_TPM_SCHEME = "tpm-osxkeychain";
55#else
56const std::string DEFAULT_TPM_SCHEME = "tpm-file";
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -050057#endif // defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) and defined(NDN_CXX_WITH_OSX_KEYCHAIN)
Alexander Afanasyev07113802015-01-15 19:14:36 -080058
59// When static library is used, not everything is compiled into the resulting binary.
60// Therefore, the following standard PIB and TPMs need to be registered here.
61// http://stackoverflow.com/q/9459980/2150331
62//
63// Also, cannot use Type::SCHEME, as its value may be uninitialized
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -080064NDN_CXX_V1_KEYCHAIN_REGISTER_PIB(SecPublicInfoSqlite3, "pib-sqlite3", "sqlite3");
Alexander Afanasyev07113802015-01-15 19:14:36 -080065
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -050066#ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -080067NDN_CXX_V1_KEYCHAIN_REGISTER_TPM(SecTpmOsx, "tpm-osxkeychain", "osx-keychain");
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -050068#endif // NDN_CXX_HAVE_OSX_FRAMEWORKS
Alexander Afanasyev07113802015-01-15 19:14:36 -080069
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -080070NDN_CXX_V1_KEYCHAIN_REGISTER_TPM(SecTpmFile, "tpm-file", "file");
Alexander Afanasyev07113802015-01-15 19:14:36 -080071
Alexander Afanasyev34a37632015-01-16 17:37:36 -080072template<class T>
73struct Factory
74{
75 Factory(const std::string& canonicalName, const T& create)
76 : canonicalName(canonicalName)
77 , create(create)
78 {
79 }
80
81 std::string canonicalName;
82 T create;
83};
84typedef Factory<KeyChain::PibCreateFunc> PibFactory;
85typedef Factory<KeyChain::TpmCreateFunc> TpmFactory;
86
87static std::map<std::string, PibFactory>&
Alexander Afanasyev07113802015-01-15 19:14:36 -080088getPibFactories()
89{
Alexander Afanasyev34a37632015-01-16 17:37:36 -080090 static std::map<std::string, PibFactory> pibFactories;
Alexander Afanasyev07113802015-01-15 19:14:36 -080091 return pibFactories;
92}
93
Alexander Afanasyev34a37632015-01-16 17:37:36 -080094static std::map<std::string, TpmFactory>&
Alexander Afanasyev07113802015-01-15 19:14:36 -080095getTpmFactories()
96{
Alexander Afanasyev34a37632015-01-16 17:37:36 -080097 static std::map<std::string, TpmFactory> tpmFactories;
Alexander Afanasyev07113802015-01-15 19:14:36 -080098 return tpmFactories;
99}
100
101void
Alexander Afanasyev34a37632015-01-16 17:37:36 -0800102KeyChain::registerPibImpl(const std::string& canonicalName,
103 std::initializer_list<std::string> aliases,
Alexander Afanasyev07113802015-01-15 19:14:36 -0800104 KeyChain::PibCreateFunc createFunc)
105{
Alexander Afanasyev34a37632015-01-16 17:37:36 -0800106 for (const std::string& alias : aliases) {
107 getPibFactories().insert(make_pair(alias, PibFactory(canonicalName, createFunc)));
Alexander Afanasyev07113802015-01-15 19:14:36 -0800108 }
109}
110
111void
Alexander Afanasyev34a37632015-01-16 17:37:36 -0800112KeyChain::registerTpmImpl(const std::string& canonicalName,
113 std::initializer_list<std::string> aliases,
Alexander Afanasyev07113802015-01-15 19:14:36 -0800114 KeyChain::TpmCreateFunc createFunc)
115{
Alexander Afanasyev34a37632015-01-16 17:37:36 -0800116 for (const std::string& alias : aliases) {
117 getTpmFactories().insert(make_pair(alias, TpmFactory(canonicalName, createFunc)));
Alexander Afanasyev07113802015-01-15 19:14:36 -0800118 }
119}
120
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700121KeyChain::KeyChain()
Yingdi Yu41546342014-11-30 23:37:53 -0800122 : m_pib(nullptr)
123 , m_tpm(nullptr)
Yingdi Yu0f5fb692014-06-10 12:07:28 -0700124 , m_lastTimestamp(time::toUnixTimestamp(time::system_clock::now()))
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700125{
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700126 std::string pibLocator;
127 std::string tpmLocator;
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700128
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700129 if (getenv("NDN_CLIENT_PIB") != nullptr) {
130 pibLocator = getenv("NDN_CLIENT_PIB");
131 }
132
133 if (getenv("NDN_CLIENT_TPM") != nullptr) {
134 tpmLocator = getenv("NDN_CLIENT_TPM");
135 }
136
137 if (pibLocator.empty() || tpmLocator.empty()) {
138 ConfigFile config;
139 const ConfigFile::Parsed& parsed = config.getParsedConfiguration();
140
141 if (pibLocator.empty()) {
142 pibLocator = parsed.get<std::string>("pib", "");
143 }
144
145 if (tpmLocator.empty()) {
146 tpmLocator = parsed.get<std::string>("tpm", "");
147 }
148 }
Alexander Afanasyev07113802015-01-15 19:14:36 -0800149
150 initialize(pibLocator, tpmLocator, false);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700151}
152
153KeyChain::KeyChain(const std::string& pibName,
Yingdi Yu41546342014-11-30 23:37:53 -0800154 const std::string& tpmName,
155 bool allowReset)
156 : m_pib(nullptr)
157 , m_tpm(nullptr)
Yingdi Yu0f5fb692014-06-10 12:07:28 -0700158 , m_lastTimestamp(time::toUnixTimestamp(time::system_clock::now()))
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700159{
Alexander Afanasyev07113802015-01-15 19:14:36 -0800160 initialize(pibName, tpmName, allowReset);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700161}
162
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700163KeyChain::~KeyChain()
164{
Alexander Afanasyev07113802015-01-15 19:14:36 -0800165}
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700166
Alexander Afanasyev07113802015-01-15 19:14:36 -0800167static inline std::tuple<std::string/*type*/, std::string/*location*/>
168parseUri(const std::string& uri)
169{
170 size_t pos = uri.find(':');
171 if (pos != std::string::npos) {
172 return std::make_tuple(uri.substr(0, pos),
173 uri.substr(pos + 1));
174 }
175 else {
176 return std::make_tuple(uri, "");
177 }
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700178}
179
Yingdi Yu281689a2015-06-13 14:32:32 -0700180std::string
181KeyChain::getDefaultPibLocator()
Yingdi Yu41546342014-11-30 23:37:53 -0800182{
Yingdi Yu281689a2015-06-13 14:32:32 -0700183 std::string defaultPibLocator = DEFAULT_PIB_SCHEME + ":";
184 return defaultPibLocator;
185}
Yingdi Yu41546342014-11-30 23:37:53 -0800186
Yingdi Yu281689a2015-06-13 14:32:32 -0700187static inline std::tuple<std::string/*type*/, std::string/*location*/>
188getCanonicalPibLocator(const std::string& pibLocator)
189{
Alexander Afanasyev07113802015-01-15 19:14:36 -0800190 std::string pibScheme, pibLocation;
Yingdi Yu281689a2015-06-13 14:32:32 -0700191 std::tie(pibScheme, pibLocation) = parseUri(pibLocator);
Alexander Afanasyev07113802015-01-15 19:14:36 -0800192
Alexander Afanasyev07113802015-01-15 19:14:36 -0800193 if (pibScheme.empty()) {
194 pibScheme = DEFAULT_PIB_SCHEME;
195 }
Yingdi Yu281689a2015-06-13 14:32:32 -0700196
Alexander Afanasyev07113802015-01-15 19:14:36 -0800197 auto pibFactory = getPibFactories().find(pibScheme);
198 if (pibFactory == getPibFactories().end()) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700199 BOOST_THROW_EXCEPTION(KeyChain::Error("PIB scheme '" + pibScheme + "' is not supported"));
Alexander Afanasyev07113802015-01-15 19:14:36 -0800200 }
Alexander Afanasyev34a37632015-01-16 17:37:36 -0800201 pibScheme = pibFactory->second.canonicalName;
Alexander Afanasyev07113802015-01-15 19:14:36 -0800202
Yingdi Yu281689a2015-06-13 14:32:32 -0700203 return std::make_tuple(pibScheme, pibLocation);
204}
205
206unique_ptr<SecPublicInfo>
207KeyChain::createPib(const std::string& pibLocator)
208{
209 BOOST_ASSERT(!getPibFactories().empty());
210
211 std::string pibScheme, pibLocation;
212 std::tie(pibScheme, pibLocation) = getCanonicalPibLocator(pibLocator);
213 auto pibFactory = getPibFactories().find(pibScheme);
214 BOOST_ASSERT(pibFactory != getPibFactories().end());
215 return pibFactory->second.create(pibLocation);
216}
217
218std::string
219KeyChain::getDefaultTpmLocator()
220{
221 std::string defaultTpmLocator = DEFAULT_TPM_SCHEME + ":";
222 return defaultTpmLocator;
223}
224
225static inline std::tuple<std::string/*type*/, std::string/*location*/>
226getCanonicalTpmLocator(const std::string& tpmLocator)
227{
228 std::string tpmScheme, tpmLocation;
229 std::tie(tpmScheme, tpmLocation) = parseUri(tpmLocator);
230
Alexander Afanasyev07113802015-01-15 19:14:36 -0800231 if (tpmScheme.empty()) {
232 tpmScheme = DEFAULT_TPM_SCHEME;
233 }
234 auto tpmFactory = getTpmFactories().find(tpmScheme);
235 if (tpmFactory == getTpmFactories().end()) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700236 BOOST_THROW_EXCEPTION(KeyChain::Error("TPM scheme '" + tpmScheme + "' is not supported"));
Alexander Afanasyev07113802015-01-15 19:14:36 -0800237 }
Alexander Afanasyev34a37632015-01-16 17:37:36 -0800238 tpmScheme = tpmFactory->second.canonicalName;
Alexander Afanasyev07113802015-01-15 19:14:36 -0800239
Yingdi Yu281689a2015-06-13 14:32:32 -0700240 return std::make_tuple(tpmScheme, tpmLocation);
241}
Alexander Afanasyev07113802015-01-15 19:14:36 -0800242
Yingdi Yu281689a2015-06-13 14:32:32 -0700243unique_ptr<SecTpm>
244KeyChain::createTpm(const std::string& tpmLocator)
245{
246 BOOST_ASSERT(!getTpmFactories().empty());
247
248 std::string tpmScheme, tpmLocation;
249 std::tie(tpmScheme, tpmLocation) = getCanonicalTpmLocator(tpmLocator);
250 auto tpmFactory = getTpmFactories().find(tpmScheme);
251 BOOST_ASSERT(tpmFactory != getTpmFactories().end());
252 return tpmFactory->second.create(tpmLocation);
253}
254
255void
256KeyChain::initialize(const std::string& pibLocator,
257 const std::string& tpmLocator,
258 bool allowReset)
259{
260 // PIB Locator
261 std::string pibScheme, pibLocation;
262 std::tie(pibScheme, pibLocation) = getCanonicalPibLocator(pibLocator);
263 std::string canonicalPibLocator = pibScheme + ":" + pibLocation;
264
265 // Create PIB
266 m_pib = createPib(canonicalPibLocator);
267
268 // TPM Locator
269 std::string tpmScheme, tpmLocation;
270 std::tie(tpmScheme, tpmLocation) = getCanonicalTpmLocator(tpmLocator);
271 std::string canonicalTpmLocator = tpmScheme + ":" + tpmLocation;
Alexander Afanasyev07113802015-01-15 19:14:36 -0800272
273 // Create TPM, checking that it matches to the previously associated one
Yingdi Yu41546342014-11-30 23:37:53 -0800274 try {
Alexander Afanasyev07113802015-01-15 19:14:36 -0800275 if (!allowReset &&
Yingdi Yu281689a2015-06-13 14:32:32 -0700276 !m_pib->getTpmLocator().empty() && m_pib->getTpmLocator() != canonicalTpmLocator)
Alexander Afanasyev07113802015-01-15 19:14:36 -0800277 // Tpm mismatch, but we do not want to reset PIB
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700278 BOOST_THROW_EXCEPTION(MismatchError("TPM locator supplied does not match TPM locator in PIB: "
279 + m_pib->getTpmLocator() + " != " + canonicalTpmLocator));
Yingdi Yu41546342014-11-30 23:37:53 -0800280 }
José Quevedo641de4c2016-01-29 00:11:24 +0000281 catch (const SecPublicInfo::Error&) {
Yingdi Yu41546342014-11-30 23:37:53 -0800282 // TPM locator is not set in PIB yet.
283 }
284
Alexander Afanasyev07113802015-01-15 19:14:36 -0800285 // note that key mismatch may still happen if the TPM locator is initially set to a
286 // wrong one or if the PIB was shared by more than one TPMs before. This is due to the
287 // old PIB does not have TPM info, new pib should not have this problem.
Yingdi Yu281689a2015-06-13 14:32:32 -0700288 m_tpm = createTpm(canonicalTpmLocator);
289 m_pib->setTpmLocator(canonicalTpmLocator);
Yingdi Yu41546342014-11-30 23:37:53 -0800290}
291
Yingdi Yu7036ce22014-06-19 18:53:37 -0700292Name
293KeyChain::createIdentity(const Name& identityName, const KeyParams& params)
294{
295 m_pib->addIdentity(identityName);
296
297 Name keyName;
José Quevedo641de4c2016-01-29 00:11:24 +0000298 try {
299 keyName = m_pib->getDefaultKeyNameForIdentity(identityName);
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700300
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800301 shared_ptr<PublicKey> key = m_pib->getPublicKey(keyName);
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700302
José Quevedo641de4c2016-01-29 00:11:24 +0000303 if (key->getKeyType() != params.getKeyType()) {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700304 keyName = generateKeyPair(identityName, true, params);
305 m_pib->setDefaultKeyNameForIdentity(keyName);
306 }
José Quevedo641de4c2016-01-29 00:11:24 +0000307 }
308 catch (const SecPublicInfo::Error& e) {
309 keyName = generateKeyPair(identityName, true, params);
310 m_pib->setDefaultKeyNameForIdentity(keyName);
311 }
Yingdi Yu7036ce22014-06-19 18:53:37 -0700312
313 Name certName;
José Quevedo641de4c2016-01-29 00:11:24 +0000314 try {
315 certName = m_pib->getDefaultCertificateNameForKey(keyName);
316 }
317 catch (const SecPublicInfo::Error& e) {
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800318 shared_ptr<IdentityCertificate> selfCert = selfSign(keyName);
José Quevedo641de4c2016-01-29 00:11:24 +0000319 m_pib->addCertificateAsIdentityDefault(*selfCert);
320 certName = selfCert->getName();
321 }
Yingdi Yu7036ce22014-06-19 18:53:37 -0700322
323 return certName;
324}
325
326Name
Yingdi Yu41546342014-11-30 23:37:53 -0800327KeyChain::generateRsaKeyPair(const Name& identityName, bool isKsk, uint32_t keySize)
328{
329 RsaKeyParams params(keySize);
330 return generateKeyPair(identityName, isKsk, params);
331}
332
333Name
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700334KeyChain::generateEcKeyPair(const Name& identityName, bool isKsk, uint32_t keySize)
Yingdi Yu41546342014-11-30 23:37:53 -0800335{
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700336 EcKeyParams params(keySize);
Yingdi Yu41546342014-11-30 23:37:53 -0800337 return generateKeyPair(identityName, isKsk, params);
338}
339
340Name
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700341KeyChain::generateRsaKeyPairAsDefault(const Name& identityName, bool isKsk, uint32_t keySize)
Yingdi Yu7036ce22014-06-19 18:53:37 -0700342{
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700343 Name keyName = generateRsaKeyPair(identityName, isKsk, keySize);
Yingdi Yu7036ce22014-06-19 18:53:37 -0700344
345 m_pib->setDefaultKeyNameForIdentity(keyName);
346
347 return keyName;
348}
349
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700350Name
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700351KeyChain::generateEcKeyPairAsDefault(const Name& identityName, bool isKsk, uint32_t keySize)
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700352{
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700353 Name keyName = generateEcKeyPair(identityName, isKsk, keySize);
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700354
355 m_pib->setDefaultKeyNameForIdentity(keyName);
356
357 return keyName;
358}
359
360
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800361shared_ptr<IdentityCertificate>
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700362KeyChain::prepareUnsignedIdentityCertificate(const Name& keyName,
363 const Name& signingIdentity,
364 const time::system_clock::TimePoint& notBefore,
365 const time::system_clock::TimePoint& notAfter,
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800366 const std::vector<CertificateSubjectDescription>& subjectDescription,
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700367 const Name& certPrefix)
368{
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800369 shared_ptr<PublicKey> publicKey;
José Quevedo641de4c2016-01-29 00:11:24 +0000370 try {
371 publicKey = m_pib->getPublicKey(keyName);
372 }
373 catch (const SecPublicInfo::Error& e) {
374 return nullptr;
375 }
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700376
377 return prepareUnsignedIdentityCertificate(keyName, *publicKey, signingIdentity,
378 notBefore, notAfter,
379 subjectDescription, certPrefix);
380}
381
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800382shared_ptr<IdentityCertificate>
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700383KeyChain::prepareUnsignedIdentityCertificate(const Name& keyName,
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800384 const PublicKey& publicKey,
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700385 const Name& signingIdentity,
386 const time::system_clock::TimePoint& notBefore,
387 const time::system_clock::TimePoint& notAfter,
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800388 const std::vector<CertificateSubjectDescription>& subjectDescription,
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700389 const Name& certPrefix)
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700390{
391 if (keyName.size() < 1)
José Quevedo641de4c2016-01-29 00:11:24 +0000392 return nullptr;
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700393
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700394 std::string keyIdPrefix = keyName.get(-1).toUri().substr(0, 4);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700395 if (keyIdPrefix != "ksk-" && keyIdPrefix != "dsk-")
José Quevedo641de4c2016-01-29 00:11:24 +0000396 return nullptr;
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700397
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700398 Name certName;
399
José Quevedo641de4c2016-01-29 00:11:24 +0000400 if (certPrefix == KeyChain::DEFAULT_PREFIX) {
401 // No certificate prefix hint, infer the prefix
402 if (signingIdentity.isPrefixOf(keyName))
403 certName.append(signingIdentity)
404 .append("KEY")
405 .append(keyName.getSubName(signingIdentity.size()))
406 .append("ID-CERT")
407 .appendVersion();
408 else
409 certName.append(keyName.getPrefix(-1))
410 .append("KEY")
411 .append(keyName.get(-1))
412 .append("ID-CERT")
413 .appendVersion();
414 }
415 else {
416 // cert prefix hint is supplied, determine the cert name.
417 if (certPrefix.isPrefixOf(keyName) && certPrefix != keyName)
418 certName.append(certPrefix)
419 .append("KEY")
420 .append(keyName.getSubName(certPrefix.size()))
421 .append("ID-CERT")
422 .appendVersion();
423 else
424 return nullptr;
425 }
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700426
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800427 auto certificate = make_shared<IdentityCertificate>();
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700428 certificate->setName(certName);
429 certificate->setNotBefore(notBefore);
430 certificate->setNotAfter(notAfter);
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700431 certificate->setPublicKeyInfo(publicKey);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700432
José Quevedo641de4c2016-01-29 00:11:24 +0000433 if (subjectDescription.empty()) {
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800434 CertificateSubjectDescription subjectName(oid::ATTRIBUTE_NAME, keyName.getPrefix(-1).toUri());
José Quevedo641de4c2016-01-29 00:11:24 +0000435 certificate->addSubjectDescription(subjectName);
436 }
437 else {
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800438 std::vector<CertificateSubjectDescription>::const_iterator sdIt = subjectDescription.begin();
439 std::vector<CertificateSubjectDescription>::const_iterator sdEnd = subjectDescription.end();
José Quevedo641de4c2016-01-29 00:11:24 +0000440 for(; sdIt != sdEnd; sdIt++)
441 certificate->addSubjectDescription(*sdIt);
442 }
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700443
444 certificate->encode();
445
446 return certificate;
447}
448
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700449std::tuple<Name, SignatureInfo>
450KeyChain::prepareSignatureInfo(const SigningInfo& params)
451{
452 SignatureInfo sigInfo = params.getSignatureInfo();
453
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800454 shared_ptr<IdentityCertificate> signingCert;
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700455
456 switch (params.getSignerType()) {
José Quevedo641de4c2016-01-29 00:11:24 +0000457 case SigningInfo::SIGNER_TYPE_NULL: {
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700458 if (m_pib->getDefaultCertificate() == nullptr)
459 setDefaultCertificateInternal();
460
461 signingCert = m_pib->getDefaultCertificate();
462 break;
463 }
José Quevedo641de4c2016-01-29 00:11:24 +0000464 case SigningInfo::SIGNER_TYPE_ID: {
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700465 Name signingCertName;
466 try {
467 signingCertName = m_pib->getDefaultCertificateNameForIdentity(params.getSignerName());
468 }
José Quevedo641de4c2016-01-29 00:11:24 +0000469 catch (const SecPublicInfo::Error&) {
470 signingCertName = createIdentity(params.getSignerName(), getDefaultKeyParamsForIdentity(params.getSignerName()));
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700471 }
472
473 signingCert = m_pib->getCertificate(signingCertName);
474
475 break;
476 }
José Quevedo641de4c2016-01-29 00:11:24 +0000477 case SigningInfo::SIGNER_TYPE_KEY: {
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700478 Name signingCertName;
479 try {
480 signingCertName = m_pib->getDefaultCertificateNameForKey(params.getSignerName());
481 }
José Quevedo641de4c2016-01-29 00:11:24 +0000482 catch (const SecPublicInfo::Error&) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700483 BOOST_THROW_EXCEPTION(Error("signing certificate does not exist"));
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700484 }
485
486 signingCert = m_pib->getCertificate(signingCertName);
487
488 break;
489 }
José Quevedo641de4c2016-01-29 00:11:24 +0000490 case SigningInfo::SIGNER_TYPE_CERT: {
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700491 signingCert = m_pib->getCertificate(params.getSignerName());
492 if (signingCert == nullptr)
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700493 BOOST_THROW_EXCEPTION(Error("signing certificate does not exist"));
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700494
495 break;
496 }
José Quevedo641de4c2016-01-29 00:11:24 +0000497 case SigningInfo::SIGNER_TYPE_SHA256: {
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700498 sigInfo.setSignatureType(tlv::DigestSha256);
Yingdi Yufe4733a2015-10-22 14:24:12 -0700499 return std::make_tuple(SigningInfo::getDigestSha256Identity(), sigInfo);
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700500 }
José Quevedo641de4c2016-01-29 00:11:24 +0000501 default:
502 BOOST_THROW_EXCEPTION(Error("Unrecognized signer type"));
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700503 }
504
505 sigInfo.setSignatureType(getSignatureType(signingCert->getPublicKeyInfo().getKeyType(),
506 params.getDigestAlgorithm()));
507 sigInfo.setKeyLocator(KeyLocator(signingCert->getName().getPrefix(-1)));
508
509 return std::make_tuple(signingCert->getPublicKeyName(), sigInfo);
510}
511
512void
513KeyChain::sign(Data& data, const SigningInfo& params)
514{
515 signImpl(data, params);
516}
517
518void
519KeyChain::sign(Interest& interest, const SigningInfo& params)
520{
521 signImpl(interest, params);
522}
523
524Block
525KeyChain::sign(const uint8_t* buffer, size_t bufferLength, const SigningInfo& params)
526{
527 Name keyName;
528 SignatureInfo sigInfo;
529 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
Yingdi Yu99b2a002015-08-12 12:47:44 -0700530 return pureSign(buffer, bufferLength, keyName, DigestAlgorithm::SHA256);
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700531}
532
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700533Signature
534KeyChain::sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
535{
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800536 shared_ptr<IdentityCertificate> certificate = m_pib->getCertificate(certificateName);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700537
José Quevedo641de4c2016-01-29 00:11:24 +0000538 if (certificate == nullptr) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700539 BOOST_THROW_EXCEPTION(SecPublicInfo::Error("certificate does not exist"));
José Quevedo641de4c2016-01-29 00:11:24 +0000540 }
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700541
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700542 Signature sig;
Yingdi Yu4a557052014-07-09 16:40:37 -0700543
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700544 // For temporary usage, we support SHA256 only, but will support more.
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700545 sig.setValue(m_tpm->signInTpm(buffer, bufferLength,
546 certificate->getPublicKeyName(),
Yingdi Yu99b2a002015-08-12 12:47:44 -0700547 DigestAlgorithm::SHA256));
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700548
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700549 return sig;
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700550}
551
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800552shared_ptr<IdentityCertificate>
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700553KeyChain::selfSign(const Name& keyName)
554{
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800555 shared_ptr<PublicKey> pubKey;
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700556 try {
557 pubKey = m_pib->getPublicKey(keyName); // may throw an exception.
558 }
José Quevedo641de4c2016-01-29 00:11:24 +0000559 catch (const SecPublicInfo::Error&) {
560 return nullptr;
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700561 }
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700562
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800563 auto certificate = make_shared<IdentityCertificate>();
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700564
565 Name certificateName = keyName.getPrefix(-1);
566 certificateName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
567
568 certificate->setName(certificateName);
569 certificate->setNotBefore(time::system_clock::now());
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700570 certificate->setNotAfter(time::system_clock::now() + time::days(7300)); // ~20 years
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700571 certificate->setPublicKeyInfo(*pubKey);
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800572 certificate->addSubjectDescription(CertificateSubjectDescription(oid::ATTRIBUTE_NAME,
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700573 keyName.toUri()));
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700574 certificate->encode();
575
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700576 certificate->setSignature(Signature(SignatureInfo()));
577
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700578 selfSign(*certificate);
579 return certificate;
580}
581
582void
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800583KeyChain::selfSign(IdentityCertificate& cert)
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700584{
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700585 Name keyName = cert.getPublicKeyName();
Yingdi Yu99b2a002015-08-12 12:47:44 -0700586
587 if (!m_tpm->doesKeyExistInTpm(keyName, KeyClass::PRIVATE))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700588 BOOST_THROW_EXCEPTION(SecTpm::Error("Private key does not exist"));
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700589
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700590 SignatureInfo sigInfo(cert.getSignature().getInfo());
591 sigInfo.setKeyLocator(KeyLocator(cert.getName().getPrefix(-1)));
592 sigInfo.setSignatureType(getSignatureType(cert.getPublicKeyInfo().getKeyType(),
Yingdi Yu99b2a002015-08-12 12:47:44 -0700593 DigestAlgorithm::SHA256));
Yingdi Yu4a557052014-07-09 16:40:37 -0700594
Yingdi Yu99b2a002015-08-12 12:47:44 -0700595 signPacketWrapper(cert, Signature(sigInfo), keyName, DigestAlgorithm::SHA256);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700596}
597
598shared_ptr<SecuredBag>
599KeyChain::exportIdentity(const Name& identity, const std::string& passwordStr)
600{
601 if (!m_pib->doesIdentityExist(identity))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700602 BOOST_THROW_EXCEPTION(SecPublicInfo::Error("Identity does not exist"));
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700603
604 Name keyName = m_pib->getDefaultKeyNameForIdentity(identity);
605
606 ConstBufferPtr pkcs5;
José Quevedo641de4c2016-01-29 00:11:24 +0000607 try {
608 pkcs5 = m_tpm->exportPrivateKeyPkcs5FromTpm(keyName, passwordStr);
609 }
610 catch (const SecTpm::Error& e) {
611 BOOST_THROW_EXCEPTION(SecPublicInfo::Error("Fail to export PKCS5 of private key"));
612 }
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700613
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800614 shared_ptr<IdentityCertificate> cert;
José Quevedo641de4c2016-01-29 00:11:24 +0000615 try {
616 cert = m_pib->getCertificate(m_pib->getDefaultCertificateNameForKey(keyName));
617 }
618 catch (const SecPublicInfo::Error& e) {
619 cert = selfSign(keyName);
620 m_pib->addCertificateAsIdentityDefault(*cert);
621 }
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700622
Alexander Afanasyevb67090a2014-04-29 22:31:01 -0700623 // make_shared on OSX 10.9 has some strange problem here
José Quevedo641de4c2016-01-29 00:11:24 +0000624 return shared_ptr<SecuredBag>(new SecuredBag(*cert, pkcs5));
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700625}
626
627void
628KeyChain::importIdentity(const SecuredBag& securedBag, const std::string& passwordStr)
629{
630 Name certificateName = securedBag.getCertificate().getName();
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800631 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700632 Name identity = keyName.getPrefix(-1);
633
634 // Add identity
635 m_pib->addIdentity(identity);
636
637 // Add key
638 m_tpm->importPrivateKeyPkcs5IntoTpm(keyName,
639 securedBag.getKey()->buf(),
640 securedBag.getKey()->size(),
641 passwordStr);
642
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800643 shared_ptr<PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.toUri());
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700644 // HACK! We should set key type according to the pkcs8 info.
Yingdi Yu41546342014-11-30 23:37:53 -0800645 m_pib->addKey(keyName, *pubKey);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700646 m_pib->setDefaultKeyNameForIdentity(keyName);
647
648 // Add cert
649 m_pib->addCertificateAsIdentityDefault(securedBag.getCertificate());
650}
651
José Quevedo641de4c2016-01-29 00:11:24 +0000652const KeyParams&
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -0500653KeyChain::getDefaultKeyParamsForIdentity(const Name& identityName) const
José Quevedo641de4c2016-01-29 00:11:24 +0000654{
Yingdi Yu99b2a002015-08-12 12:47:44 -0700655 KeyType keyType = KeyType::NONE;
José Quevedo641de4c2016-01-29 00:11:24 +0000656 try {
657 keyType = m_pib->getPublicKeyType(m_pib->getDefaultKeyNameForIdentity(identityName));
658 }
659 catch (const SecPublicInfo::Error& e) { // @TODO Switch to Pib::Error
660 return DEFAULT_KEY_PARAMS;
661 }
662
663 switch (keyType) {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700664 case KeyType::RSA: {
José Quevedo641de4c2016-01-29 00:11:24 +0000665 static RsaKeyParams defaultRsaParams;
666 return defaultRsaParams;
667 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700668 case KeyType::EC: {
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700669 static EcKeyParams defaultEcParams;
670 return defaultEcParams;
José Quevedo641de4c2016-01-29 00:11:24 +0000671 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700672 case KeyType::NONE: {
José Quevedo641de4c2016-01-29 00:11:24 +0000673 return DEFAULT_KEY_PARAMS;
674 }
675 default:
676 BOOST_THROW_EXCEPTION(Error("Unsupported key type"));
677 }
678}
679
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700680void
681KeyChain::setDefaultCertificateInternal()
682{
683 m_pib->refreshDefaultCertificate();
684
José Quevedo641de4c2016-01-29 00:11:24 +0000685 if (m_pib->getDefaultCertificate() == nullptr) {
686 Name defaultIdentity;
687 try {
688 defaultIdentity = m_pib->getDefaultIdentity();
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700689 }
José Quevedo641de4c2016-01-29 00:11:24 +0000690 catch (const SecPublicInfo::Error& e) {
691 uint32_t random = random::generateWord32();
692 defaultIdentity.append("tmp-identity")
693 .append(reinterpret_cast<uint8_t*>(&random), 4);
694 }
695 createIdentity(defaultIdentity);
696 m_pib->setDefaultIdentity(defaultIdentity);
697 m_pib->refreshDefaultCertificate();
698 }
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700699}
700
Yingdi Yu7036ce22014-06-19 18:53:37 -0700701Name
702KeyChain::generateKeyPair(const Name& identityName, bool isKsk, const KeyParams& params)
703{
704 Name keyName = m_pib->getNewKeyName(identityName, isKsk);
705
706 m_tpm->generateKeyPairInTpm(keyName.toUri(), params);
707
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800708 shared_ptr<PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.toUri());
Yingdi Yu7036ce22014-06-19 18:53:37 -0700709 m_pib->addKey(keyName, *pubKey);
710
711 return keyName;
712}
713
714void
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700715KeyChain::signPacketWrapper(Data& data, const Signature& signature,
Yingdi Yu7036ce22014-06-19 18:53:37 -0700716 const Name& keyName, DigestAlgorithm digestAlgorithm)
717{
718 data.setSignature(signature);
719
720 EncodingBuffer encoder;
721 data.wireEncode(encoder, true);
722
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700723 Block sigValue = pureSign(encoder.buf(), encoder.size(), keyName, digestAlgorithm);
724
725 data.wireEncode(encoder, sigValue);
Yingdi Yu7036ce22014-06-19 18:53:37 -0700726}
727
728void
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700729KeyChain::signPacketWrapper(Interest& interest, const Signature& signature,
Yingdi Yu7036ce22014-06-19 18:53:37 -0700730 const Name& keyName, DigestAlgorithm digestAlgorithm)
731{
732 time::milliseconds timestamp = time::toUnixTimestamp(time::system_clock::now());
José Quevedo641de4c2016-01-29 00:11:24 +0000733 if (timestamp <= m_lastTimestamp) {
734 timestamp = m_lastTimestamp + time::milliseconds(1);
735 }
Yingdi Yu7036ce22014-06-19 18:53:37 -0700736
737 Name signedName = interest.getName();
738 signedName
739 .append(name::Component::fromNumber(timestamp.count())) // timestamp
740 .append(name::Component::fromNumber(random::generateWord64())) // nonce
741 .append(signature.getInfo()); // signatureInfo
742
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700743 Block sigValue = pureSign(signedName.wireEncode().value(),
744 signedName.wireEncode().value_size(),
745 keyName,
746 digestAlgorithm);
747
Yingdi Yu7036ce22014-06-19 18:53:37 -0700748 sigValue.encode();
749 signedName.append(sigValue); // signatureValue
750 interest.setName(signedName);
751}
752
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700753Block
754KeyChain::pureSign(const uint8_t* buf, size_t size,
755 const Name& keyName, DigestAlgorithm digestAlgorithm) const
756{
Yingdi Yufe4733a2015-10-22 14:24:12 -0700757 if (keyName == SigningInfo::getDigestSha256Identity())
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700758 return Block(tlv::SignatureValue, crypto::computeSha256Digest(buf, size));
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700759
760 return m_tpm->signInTpm(buf, size, keyName, digestAlgorithm);
761}
762
Yingdi Yu7036ce22014-06-19 18:53:37 -0700763Signature
764KeyChain::signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
765{
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700766 Signature sig;
José Quevedo641de4c2016-01-29 00:11:24 +0000767 sig.setValue(sign(buffer, bufferLength, signingByIdentity(identityName)));
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700768 return sig;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700769}
770
771void
772KeyChain::signWithSha256(Data& data)
773{
José Quevedo641de4c2016-01-29 00:11:24 +0000774 return sign(data, signingWithSha256());
Yingdi Yu7036ce22014-06-19 18:53:37 -0700775}
776
777void
Yingdi Yu6ab67812014-11-27 15:00:34 -0800778KeyChain::signWithSha256(Interest& interest)
779{
780 DigestSha256 sig;
781
782 time::milliseconds timestamp = time::toUnixTimestamp(time::system_clock::now());
783 if (timestamp <= m_lastTimestamp)
784 timestamp = m_lastTimestamp + time::milliseconds(1);
785
786 Name signedName = interest.getName();
787 signedName
788 .append(name::Component::fromNumber(timestamp.count())) // timestamp
789 .append(name::Component::fromNumber(random::generateWord64())) // nonce
790 .append(sig.getInfo()); // signatureInfo
791
792 Block sigValue(tlv::SignatureValue,
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700793 crypto::computeSha256Digest(signedName.wireEncode().value(),
794 signedName.wireEncode().value_size()));
Yingdi Yu6ab67812014-11-27 15:00:34 -0800795
796 sigValue.encode();
797 signedName.append(sigValue); // signatureValue
798 interest.setName(signedName);
799}
800
801void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700802KeyChain::deleteCertificate(const Name& certificateName)
803{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700804 m_pib->deleteCertificateInfo(certificateName);
805}
806
807void
808KeyChain::deleteKey(const Name& keyName)
809{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700810 m_pib->deletePublicKeyInfo(keyName);
811 m_tpm->deleteKeyPairInTpm(keyName);
812}
813
814void
815KeyChain::deleteIdentity(const Name& identity)
816{
Yingdi Yu6147ef42014-12-08 17:48:32 -0800817 std::vector<Name> keyNames;
818 m_pib->getAllKeyNamesOfIdentity(identity, keyNames, true);
819 m_pib->getAllKeyNamesOfIdentity(identity, keyNames, false);
Yingdi Yu7036ce22014-06-19 18:53:37 -0700820
821 m_pib->deleteIdentityInfo(identity);
822
Yingdi Yu6147ef42014-12-08 17:48:32 -0800823 for (const auto& keyName : keyNames)
824 m_tpm->deleteKeyPairInTpm(keyName);
Yingdi Yu7036ce22014-06-19 18:53:37 -0700825}
826
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700827tlv::SignatureTypeValue
828KeyChain::getSignatureType(KeyType keyType, DigestAlgorithm digestAlgorithm)
829{
830 switch (keyType) {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700831 case KeyType::RSA:
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700832 return tlv::SignatureSha256WithRsa;
Yingdi Yu99b2a002015-08-12 12:47:44 -0700833 case KeyType::EC:
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700834 return tlv::SignatureSha256WithEcdsa;
835 default:
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700836 BOOST_THROW_EXCEPTION(Error("Unsupported key types"));
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700837 }
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700838}
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700839
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800840} // namespace v1
Yingdi Yu1b0311c2015-06-10 14:58:47 -0700841} // namespace security
842} // namespace ndn