blob: f22c5a9988492912038393c9cff7587af61a655e [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/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 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"
25
26#include "sec-public-info-sqlite3.hpp"
27#include "sec-tpm-file.hpp"
28
29#ifdef NDN_CXX_HAVE_OSX_SECURITY
30#include "sec-tpm-osx.hpp"
31#endif
32
33#include "../util/random.hpp"
34#include "../util/config-file.hpp"
35
36namespace ndn {
37
Yingdi Yu0eb5d722014-06-10 15:06:25 -070038// Use a GUID as a magic number of KeyChain::DEFAULT_PREFIX identifier
39const Name KeyChain::DEFAULT_PREFIX("/723821fd-f534-44b3-80d9-44bf5f58bbbb");
40
Yingdi Yu7036ce22014-06-19 18:53:37 -070041const RsaKeyParams KeyChain::DEFAULT_KEY_PARAMS;
42
Yingdi Yuf56c68f2014-04-24 21:50:13 -070043KeyChain::KeyChain()
44 : m_pib(0)
45 , m_tpm(0)
Yingdi Yu0f5fb692014-06-10 12:07:28 -070046 , m_lastTimestamp(time::toUnixTimestamp(time::system_clock::now()))
Yingdi Yuf56c68f2014-04-24 21:50:13 -070047{
48
49 ConfigFile config;
50 const ConfigFile::Parsed& parsed = config.getParsedConfiguration();
51
52 std::string pibName;
53 try
54 {
55 pibName = parsed.get<std::string>("pib");
56 }
57 catch (boost::property_tree::ptree_bad_path& error)
58 {
59 // pib is not specified, take the default
60 }
61 catch (boost::property_tree::ptree_bad_data& error)
62 {
63 throw ConfigFile::Error(error.what());
64 }
65
66 std::string tpmName;
67 try
68 {
69 tpmName = parsed.get<std::string>("tpm");
70 }
71 catch (boost::property_tree::ptree_bad_path& error)
72 {
73 // tpm is not specified, take the default
74 }
75 catch (boost::property_tree::ptree_bad_data& error)
76 {
77 throw ConfigFile::Error(error.what());
78 }
79
80
81 if (pibName.empty() || pibName == "sqlite3")
82 m_pib = new SecPublicInfoSqlite3;
83 else
84 throw Error("PIB type '" + pibName + "' is not supported");
85
86 if (tpmName.empty())
87#if defined(NDN_CXX_HAVE_OSX_SECURITY) and defined(NDN_CXX_WITH_OSX_KEYCHAIN)
88 m_tpm = new SecTpmOsx();
89#else
90 m_tpm = new SecTpmFile();
91#endif // defined(NDN_CXX_HAVE_OSX_SECURITY) and defined(NDN_CXX_WITH_OSX_KEYCHAIN)
92 else if (tpmName == "osx-keychain")
93#if defined(NDN_CXX_HAVE_OSX_SECURITY)
94 m_tpm = new SecTpmOsx();
95#else
96 throw Error("TPM type '" + tpmName + "' is not supported on this platform");
97#endif // NDN_CXX_HAVE_OSX_SECURITY
98 else if (tpmName == "file")
99 m_tpm = new SecTpmFile();
100 else
101 throw Error("TPM type '" + tpmName + "' is not supported");
102}
103
104KeyChain::KeyChain(const std::string& pibName,
105 const std::string& tpmName)
106 : m_pib(0)
107 , m_tpm(0)
Yingdi Yu0f5fb692014-06-10 12:07:28 -0700108 , m_lastTimestamp(time::toUnixTimestamp(time::system_clock::now()))
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700109{
110 if (pibName == "sqlite3")
111 m_pib = new SecPublicInfoSqlite3;
112 else
113 throw Error("PIB type '" + pibName + "' is not supported");
114
115 if (tpmName == "file")
116 m_tpm = new SecTpmFile;
117#if defined(NDN_CXX_HAVE_OSX_SECURITY)
118 else if (tpmName == "osx-keychain")
119 m_tpm = new SecTpmOsx();
120#endif //NDN_CXX_HAVE_OSX_SECURITY
121 else
122 throw Error("TPM type '" + tpmName + "' is not supported");
123}
124
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700125KeyChain::~KeyChain()
126{
127 if (m_pib != 0)
128 delete m_pib;
129
130 if (m_tpm != 0)
131 delete m_tpm;
132}
133
Yingdi Yu7036ce22014-06-19 18:53:37 -0700134Name
135KeyChain::createIdentity(const Name& identityName, const KeyParams& params)
136{
137 m_pib->addIdentity(identityName);
138
139 Name keyName;
140 try
141 {
142 keyName = m_pib->getDefaultKeyNameForIdentity(identityName);
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700143
144 shared_ptr<PublicKey> key = m_pib->getPublicKey(keyName);
145
146 if (key->getKeyType() != params.getKeyType())
147 {
148 keyName = generateKeyPair(identityName, true, params);
149 m_pib->setDefaultKeyNameForIdentity(keyName);
150 }
Yingdi Yu7036ce22014-06-19 18:53:37 -0700151 }
152 catch (SecPublicInfo::Error& e)
153 {
154 keyName = generateKeyPair(identityName, true, params);
155 m_pib->setDefaultKeyNameForIdentity(keyName);
156 }
157
158 Name certName;
159 try
160 {
161 certName = m_pib->getDefaultCertificateNameForKey(keyName);
162 }
163 catch (SecPublicInfo::Error& e)
164 {
165 shared_ptr<IdentityCertificate> selfCert = selfSign(keyName);
166 m_pib->addCertificateAsIdentityDefault(*selfCert);
167 certName = selfCert->getName();
168 }
169
170 return certName;
171}
172
173Name
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700174KeyChain::generateRsaKeyPairAsDefault(const Name& identityName, bool isKsk, uint32_t keySize)
Yingdi Yu7036ce22014-06-19 18:53:37 -0700175{
176 RsaKeyParams params(keySize);
177
178 Name keyName = generateKeyPair(identityName, isKsk, params);
179
180 m_pib->setDefaultKeyNameForIdentity(keyName);
181
182 return keyName;
183}
184
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700185Name
186KeyChain::generateEcdsaKeyPairAsDefault(const Name& identityName, bool isKsk, uint32_t keySize)
187{
188 EcdsaKeyParams params(keySize);
189
190 Name keyName = generateKeyPair(identityName, isKsk, params);
191
192 m_pib->setDefaultKeyNameForIdentity(keyName);
193
194 return keyName;
195}
196
197
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700198shared_ptr<IdentityCertificate>
199KeyChain::prepareUnsignedIdentityCertificate(const Name& keyName,
200 const Name& signingIdentity,
201 const time::system_clock::TimePoint& notBefore,
202 const time::system_clock::TimePoint& notAfter,
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700203 const std::vector<CertificateSubjectDescription>& subjectDescription,
204 const Name& certPrefix)
205{
206 shared_ptr<PublicKey> publicKey;
207 try
208 {
209 publicKey = m_pib->getPublicKey(keyName);
210 }
211 catch (SecPublicInfo::Error& e)
212 {
213 return shared_ptr<IdentityCertificate>();
214 }
215
216 return prepareUnsignedIdentityCertificate(keyName, *publicKey, signingIdentity,
217 notBefore, notAfter,
218 subjectDescription, certPrefix);
219}
220
221shared_ptr<IdentityCertificate>
222KeyChain::prepareUnsignedIdentityCertificate(const Name& keyName,
223 const PublicKey& publicKey,
224 const Name& signingIdentity,
225 const time::system_clock::TimePoint& notBefore,
226 const time::system_clock::TimePoint& notAfter,
227 const std::vector<CertificateSubjectDescription>& subjectDescription,
228 const Name& certPrefix)
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700229{
230 if (keyName.size() < 1)
231 return shared_ptr<IdentityCertificate>();
232
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700233 std::string keyIdPrefix = keyName.get(-1).toUri().substr(0, 4);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700234 if (keyIdPrefix != "ksk-" && keyIdPrefix != "dsk-")
235 return shared_ptr<IdentityCertificate>();
236
237 shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>();
238 Name certName;
239
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700240 if (certPrefix == KeyChain::DEFAULT_PREFIX)
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700241 {
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700242 // No certificate prefix hint, infer the prefix
243 if (signingIdentity.isPrefixOf(keyName))
244 certName.append(signingIdentity)
245 .append("KEY")
246 .append(keyName.getSubName(signingIdentity.size()))
247 .append("ID-CERT")
248 .appendVersion();
249 else
250 certName.append(keyName.getPrefix(-1))
251 .append("KEY")
252 .append(keyName.get(-1))
253 .append("ID-CERT")
254 .appendVersion();
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700255 }
256 else
257 {
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700258 // cert prefix hint is supplied, determine the cert name.
259 if (certPrefix.isPrefixOf(keyName) && certPrefix != keyName)
260 certName.append(certPrefix)
261 .append("KEY")
262 .append(keyName.getSubName(certPrefix.size()))
263 .append("ID-CERT")
264 .appendVersion();
265 else
266 return shared_ptr<IdentityCertificate>();
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700267 }
268
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700269
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700270 certificate->setName(certName);
271 certificate->setNotBefore(notBefore);
272 certificate->setNotAfter(notAfter);
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700273 certificate->setPublicKeyInfo(publicKey);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700274
275 if (subjectDescription.empty())
276 {
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700277 CertificateSubjectDescription subjectName(oid::ATTRIBUTE_NAME, keyName.getPrefix(-1).toUri());
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700278 certificate->addSubjectDescription(subjectName);
279 }
280 else
281 {
282 std::vector<CertificateSubjectDescription>::const_iterator sdIt =
283 subjectDescription.begin();
284 std::vector<CertificateSubjectDescription>::const_iterator sdEnd =
285 subjectDescription.end();
286 for(; sdIt != sdEnd; sdIt++)
287 certificate->addSubjectDescription(*sdIt);
288 }
289
290 certificate->encode();
291
292 return certificate;
293}
294
295Signature
296KeyChain::sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
297{
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700298 shared_ptr<IdentityCertificate> certificate = m_pib->getCertificate(certificateName);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700299
Yingdi Yu4a557052014-07-09 16:40:37 -0700300 KeyLocator keyLocator(certificate->getName().getPrefix(-1));
301 shared_ptr<Signature> sig =
302 determineSignatureWithPublicKey(keyLocator, certificate->getPublicKeyInfo().getKeyType());
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700303
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700304 if (!static_cast<bool>(sig))
305 throw SecTpm::Error("unknown key type");
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700306
Yingdi Yu4a557052014-07-09 16:40:37 -0700307
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700308 // For temporary usage, we support SHA256 only, but will support more.
309 sig->setValue(m_tpm->signInTpm(buffer, bufferLength,
310 certificate->getPublicKeyName(),
311 DIGEST_ALGORITHM_SHA256));
312
313 return *sig;
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700314}
315
316shared_ptr<IdentityCertificate>
317KeyChain::selfSign(const Name& keyName)
318{
319 shared_ptr<PublicKey> pubKey;
320 try
321 {
322 pubKey = m_pib->getPublicKey(keyName); // may throw an exception.
323 }
324 catch (SecPublicInfo::Error& e)
325 {
326 return shared_ptr<IdentityCertificate>();
327 }
328
329 shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>();
330
331 Name certificateName = keyName.getPrefix(-1);
332 certificateName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
333
334 certificate->setName(certificateName);
335 certificate->setNotBefore(time::system_clock::now());
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700336 certificate->setNotAfter(time::system_clock::now() + time::days(7300)); // ~20 years
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700337 certificate->setPublicKeyInfo(*pubKey);
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700338 certificate->addSubjectDescription(CertificateSubjectDescription(oid::ATTRIBUTE_NAME,
339 keyName.toUri()));
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700340 certificate->encode();
341
342 selfSign(*certificate);
343 return certificate;
344}
345
346void
347KeyChain::selfSign(IdentityCertificate& cert)
348{
349 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(cert.getName());
350 if (!m_tpm->doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
Yingdi Yu7036ce22014-06-19 18:53:37 -0700351 throw SecTpm::Error("Private key does not exist");
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700352
Yingdi Yu4a557052014-07-09 16:40:37 -0700353
354 KeyLocator keyLocator(cert.getName().getPrefix(-1));
355 shared_ptr<Signature> sig =
356 determineSignatureWithPublicKey(keyLocator, cert.getPublicKeyInfo().getKeyType());
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700357
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700358 if (!static_cast<bool>(sig))
359 throw SecTpm::Error("unknown key type");
360
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700361 signPacketWrapper(cert, *sig, keyName, DIGEST_ALGORITHM_SHA256);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700362}
363
364shared_ptr<SecuredBag>
365KeyChain::exportIdentity(const Name& identity, const std::string& passwordStr)
366{
367 if (!m_pib->doesIdentityExist(identity))
Yingdi Yu7036ce22014-06-19 18:53:37 -0700368 throw SecPublicInfo::Error("Identity does not exist");
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700369
370 Name keyName = m_pib->getDefaultKeyNameForIdentity(identity);
371
372 ConstBufferPtr pkcs5;
373 try
374 {
375 pkcs5 = m_tpm->exportPrivateKeyPkcs5FromTpm(keyName, passwordStr);
376 }
377 catch (SecTpm::Error& e)
378 {
379 throw SecPublicInfo::Error("Fail to export PKCS5 of private key");
380 }
381
382 shared_ptr<IdentityCertificate> cert;
383 try
384 {
385 cert = m_pib->getCertificate(m_pib->getDefaultCertificateNameForKey(keyName));
386 }
387 catch (SecPublicInfo::Error& e)
388 {
389 cert = selfSign(keyName);
390 m_pib->addCertificateAsIdentityDefault(*cert);
391 }
392
Alexander Afanasyevb67090a2014-04-29 22:31:01 -0700393 // make_shared on OSX 10.9 has some strange problem here
394 shared_ptr<SecuredBag> secureBag(new SecuredBag(*cert, pkcs5));
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700395
396 return secureBag;
397}
398
399void
400KeyChain::importIdentity(const SecuredBag& securedBag, const std::string& passwordStr)
401{
402 Name certificateName = securedBag.getCertificate().getName();
403 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
404 Name identity = keyName.getPrefix(-1);
405
406 // Add identity
407 m_pib->addIdentity(identity);
408
409 // Add key
410 m_tpm->importPrivateKeyPkcs5IntoTpm(keyName,
411 securedBag.getKey()->buf(),
412 securedBag.getKey()->size(),
413 passwordStr);
414
415 shared_ptr<PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.toUri());
416 // HACK! We should set key type according to the pkcs8 info.
417 m_pib->addPublicKey(keyName, KEY_TYPE_RSA, *pubKey);
418 m_pib->setDefaultKeyNameForIdentity(keyName);
419
420 // Add cert
421 m_pib->addCertificateAsIdentityDefault(securedBag.getCertificate());
422}
423
Yingdi Yu4a557052014-07-09 16:40:37 -0700424shared_ptr<Signature>
425KeyChain::determineSignatureWithPublicKey(const KeyLocator& keyLocator,
426 KeyType keyType, DigestAlgorithm digestAlgorithm)
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700427{
428 switch (keyType)
429 {
430 case KEY_TYPE_RSA:
431 {
432 // For temporary usage, we support SHA256 only, but will support more.
433 if (digestAlgorithm != DIGEST_ALGORITHM_SHA256)
Yingdi Yu4a557052014-07-09 16:40:37 -0700434 return shared_ptr<Signature>();
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700435
Yingdi Yu4a557052014-07-09 16:40:37 -0700436 return make_shared<SignatureSha256WithRsa>(keyLocator);
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700437 }
438 case KEY_TYPE_ECDSA:
439 {
440 // For temporary usage, we support SHA256 only, but will support more.
441 if (digestAlgorithm != DIGEST_ALGORITHM_SHA256)
Yingdi Yu4a557052014-07-09 16:40:37 -0700442 return shared_ptr<Signature>();
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700443
Yingdi Yu4a557052014-07-09 16:40:37 -0700444 return make_shared<SignatureSha256WithEcdsa>(keyLocator);
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700445 }
446 default:
Yingdi Yu4a557052014-07-09 16:40:37 -0700447 return shared_ptr<Signature>();
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700448 }
449}
450
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700451void
452KeyChain::setDefaultCertificateInternal()
453{
454 m_pib->refreshDefaultCertificate();
455
Alexander Afanasyevaab79662014-07-07 17:35:34 -0700456 if (!static_cast<bool>(m_pib->getDefaultCertificate()))
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700457 {
458 Name defaultIdentity;
459 try
460 {
461 defaultIdentity = m_pib->getDefaultIdentity();
462 }
463 catch (SecPublicInfo::Error& e)
464 {
465 uint32_t random = random::generateWord32();
466 defaultIdentity.append("tmp-identity")
467 .append(reinterpret_cast<uint8_t*>(&random), 4);
468 }
469 createIdentity(defaultIdentity);
470 m_pib->setDefaultIdentity(defaultIdentity);
471 m_pib->refreshDefaultCertificate();
472 }
473}
474
Yingdi Yu7036ce22014-06-19 18:53:37 -0700475Name
476KeyChain::generateKeyPair(const Name& identityName, bool isKsk, const KeyParams& params)
477{
478 Name keyName = m_pib->getNewKeyName(identityName, isKsk);
479
480 m_tpm->generateKeyPairInTpm(keyName.toUri(), params);
481
482 shared_ptr<PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.toUri());
483 m_pib->addKey(keyName, *pubKey);
484
485 return keyName;
486}
487
488void
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700489KeyChain::signPacketWrapper(Data& data, const Signature& signature,
Yingdi Yu7036ce22014-06-19 18:53:37 -0700490 const Name& keyName, DigestAlgorithm digestAlgorithm)
491{
492 data.setSignature(signature);
493
494 EncodingBuffer encoder;
495 data.wireEncode(encoder, true);
496
497 Block signatureValue = m_tpm->signInTpm(encoder.buf(), encoder.size(),
498 keyName, digestAlgorithm);
499 data.wireEncode(encoder, signatureValue);
500}
501
502void
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700503KeyChain::signPacketWrapper(Interest& interest, const Signature& signature,
Yingdi Yu7036ce22014-06-19 18:53:37 -0700504 const Name& keyName, DigestAlgorithm digestAlgorithm)
505{
506 time::milliseconds timestamp = time::toUnixTimestamp(time::system_clock::now());
507 if (timestamp <= m_lastTimestamp)
508 {
509 timestamp = m_lastTimestamp + time::milliseconds(1);
510 }
511
512 Name signedName = interest.getName();
513 signedName
514 .append(name::Component::fromNumber(timestamp.count())) // timestamp
515 .append(name::Component::fromNumber(random::generateWord64())) // nonce
516 .append(signature.getInfo()); // signatureInfo
517
518 Block sigValue = m_tpm->signInTpm(signedName.wireEncode().value(),
519 signedName.wireEncode().value_size(),
520 keyName,
521 digestAlgorithm);
522 sigValue.encode();
523 signedName.append(sigValue); // signatureValue
524 interest.setName(signedName);
525}
526
527Signature
528KeyChain::signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
529{
530 Name signingCertificateName;
531 try
532 {
533 signingCertificateName = m_pib->getDefaultCertificateNameForIdentity(identityName);
534 }
535 catch (SecPublicInfo::Error& e)
536 {
537 signingCertificateName = createIdentity(identityName);
538 // Ideally, no exception will be thrown out, unless something goes wrong in the TPM, which
539 // is a fatal error.
540 }
541
542 // We either get or create the signing certificate, sign data! (no exception unless fatal error
543 // in TPM)
544 return sign(buffer, bufferLength, signingCertificateName);
545}
546
547void
548KeyChain::signWithSha256(Data& data)
549{
550 DigestSha256 sig;
551 data.setSignature(sig);
552
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600553 Block sigValue(tlv::SignatureValue,
Yingdi Yu7036ce22014-06-19 18:53:37 -0700554 crypto::sha256(data.wireEncode().value(),
555 data.wireEncode().value_size() -
556 data.getSignature().getValue().size()));
557 data.setSignatureValue(sigValue);
558}
559
560void
Yingdi Yu6ab67812014-11-27 15:00:34 -0800561KeyChain::signWithSha256(Interest& interest)
562{
563 DigestSha256 sig;
564
565 time::milliseconds timestamp = time::toUnixTimestamp(time::system_clock::now());
566 if (timestamp <= m_lastTimestamp)
567 timestamp = m_lastTimestamp + time::milliseconds(1);
568
569 Name signedName = interest.getName();
570 signedName
571 .append(name::Component::fromNumber(timestamp.count())) // timestamp
572 .append(name::Component::fromNumber(random::generateWord64())) // nonce
573 .append(sig.getInfo()); // signatureInfo
574
575 Block sigValue(tlv::SignatureValue,
576 crypto::sha256(signedName.wireEncode().value(),
577 signedName.wireEncode().value_size()));
578
579 sigValue.encode();
580 signedName.append(sigValue); // signatureValue
581 interest.setName(signedName);
582}
583
584void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700585KeyChain::deleteCertificate(const Name& certificateName)
586{
587 try
588 {
589 if (m_pib->getDefaultCertificateName() == certificateName)
590 return;
591 }
592 catch (SecPublicInfo::Error& e)
593 {
594 // Not a real error, just try to delete the certificate
595 }
596
597 m_pib->deleteCertificateInfo(certificateName);
598}
599
600void
601KeyChain::deleteKey(const Name& keyName)
602{
603 try
604 {
605 if (m_pib->getDefaultKeyNameForIdentity(m_pib->getDefaultIdentity()) == keyName)
606 return;
607 }
608 catch (SecPublicInfo::Error& e)
609 {
610 // Not a real error, just try to delete the key
611 }
612
613 m_pib->deletePublicKeyInfo(keyName);
614 m_tpm->deleteKeyPairInTpm(keyName);
615}
616
617void
618KeyChain::deleteIdentity(const Name& identity)
619{
620 try
621 {
622 if (m_pib->getDefaultIdentity() == identity)
623 return;
624 }
625 catch (SecPublicInfo::Error& e)
626 {
627 // Not a real error, just try to delete the identity
628 }
629
630 std::vector<Name> nameList;
631 m_pib->getAllKeyNamesOfIdentity(identity, nameList, true);
632 m_pib->getAllKeyNamesOfIdentity(identity, nameList, false);
633
634 m_pib->deleteIdentityInfo(identity);
635
636 std::vector<Name>::const_iterator it = nameList.begin();
637 for(; it != nameList.end(); it++)
638 m_tpm->deleteKeyPairInTpm(*it);
639}
640
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700641}