blob: db7188452cece246972a132294a888853371eaba [file] [log] [blame]
Jeff Thompson25b4e612013-10-10 16:03:24 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Jeff Thompson47c93cf2013-08-09 00:38:48 -07002/**
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07003 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
5 *
6 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
8 *
9 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
11 *
12 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
Jeff Thompson47c93cf2013-08-09 00:38:48 -070013 */
14
Yingdi Yufc40d872014-02-18 12:56:04 -080015#ifndef NDN_SECURITY_KEY_CHAIN_HPP
16#define NDN_SECURITY_KEY_CHAIN_HPP
Jeff Thompson47c93cf2013-08-09 00:38:48 -070017
Yingdi Yuf56c68f2014-04-24 21:50:13 -070018#include "sec-public-info.hpp"
19#include "sec-tpm.hpp"
20#include "secured-bag.hpp"
Yingdi Yu4f324632014-01-15 18:10:03 -080021#include "signature-sha256-with-rsa.hpp"
Yingdi Yu21157162014-02-28 13:02:34 -080022#include "signature-sha256.hpp"
Yingdi Yuf56c68f2014-04-24 21:50:13 -070023
Yingdi Yu4270f202014-01-28 14:19:16 -080024#include "../interest.hpp"
Yingdi Yu21157162014-02-28 13:02:34 -080025#include "../util/crypto.hpp"
Yingdi Yu31b4af22014-01-14 14:13:00 -080026
Jeff Thompson47c93cf2013-08-09 00:38:48 -070027
28namespace ndn {
29
Yingdi Yuf56c68f2014-04-24 21:50:13 -070030template<class TypePib, class TypeTpm>
31class KeyChainTraits
Yingdi Yu31b4af22014-01-14 14:13:00 -080032{
Jeff Thompson47c93cf2013-08-09 00:38:48 -070033public:
Yingdi Yuf56c68f2014-04-24 21:50:13 -070034 typedef TypePib Pib;
35 typedef TypeTpm Tpm;
36};
37
Alexander Afanasyev45a37132014-04-28 16:54:57 -070038class KeyChain : noncopyable
Yingdi Yuf56c68f2014-04-24 21:50:13 -070039{
40public:
41 class Error : public std::runtime_error
42 {
43 public:
44 explicit
45 Error(const std::string& what)
46 : std::runtime_error(what)
47 {
48 }
49 };
50
51 KeyChain();
52
53 template<class KeyChainTraits>
54 KeyChain(KeyChainTraits traits);
55
56 KeyChain(const std::string& pibName,
57 const std::string& tpmName);
58
59 virtual
60 ~KeyChain()
61 {
62 if (m_pib != 0)
63 delete m_pib;
64
65 if (m_tpm != 0)
66 delete m_tpm;
67 }
68
Yingdi Yube4150e2014-02-18 13:02:46 -080069 /**
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070070 * @brief Create an identity by creating a pair of Key-Signing-Key (KSK) for this identity and a
71 * self-signed certificate of the KSK.
Yingdi Yube4150e2014-02-18 13:02:46 -080072 *
Yingdi Yu2abd73f2014-01-08 23:34:11 -080073 * @param identityName The name of the identity.
Yingdi Yu28fd32f2014-01-28 19:03:03 -080074 * @return The name of the default certificate of the identity.
Yingdi Yu2abd73f2014-01-08 23:34:11 -080075 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -070076 inline Name
77 createIdentity(const Name& identityName);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -070078
Yingdi Yu2abd73f2014-01-08 23:34:11 -080079 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -080080 * @brief Generate a pair of RSA keys for the specified identity.
81 *
Yingdi Yu2abd73f2014-01-08 23:34:11 -080082 * @param identityName The name of the identity.
83 * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
84 * @param keySize The size of the key.
85 * @return The generated key name.
86 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -070087 inline Name
88 generateRsaKeyPair(const Name& identityName, bool isKsk = false, int keySize = 2048);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -070089
Yingdi Yu2abd73f2014-01-08 23:34:11 -080090 /**
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070091 * @brief Generate a pair of RSA keys for the specified identity and set it as default key for
92 * the identity.
Yingdi Yu2e57a582014-02-20 23:34:43 -080093 *
Yingdi Yu2abd73f2014-01-08 23:34:11 -080094 * @param identityName The name of the identity.
95 * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
96 * @param keySize The size of the key.
97 * @return The generated key name.
98 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -070099 inline Name
100 generateRsaKeyPairAsDefault(const Name& identityName, bool isKsk = false, int keySize = 2048);
Jeff Thompson79a2d5d2013-09-27 14:32:23 -0700101
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800102 /**
Yingdi Yuc55680b2014-02-26 12:31:35 -0800103 * @brief prepare an unsigned identity certificate
104 *
105 * @param keyName Key name, e.g., /<identity_name>/ksk-123456.
106 * @param signingIdentity The signing identity.
107 * @param notBefore Refer to IdentityCertificate.
108 * @param notAfter Refer to IdentityCertificate.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700109 * @param subjectDescription Refer to IdentityCertificate.
Yingdi Yuc55680b2014-02-26 12:31:35 -0800110 * @return IdentityCertificate.
111 */
112 shared_ptr<IdentityCertificate>
113 prepareUnsignedIdentityCertificate(const Name& keyName,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700114 const Name& signingIdentity,
115 const time::system_clock::TimePoint& notBefore,
116 const time::system_clock::TimePoint& notAfter,
117 const std::vector<CertificateSubjectDescription>& subjectDescription);
Yingdi Yuc55680b2014-02-26 12:31:35 -0800118
119 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800120 * @brief Sign packet with default identity
121 *
Yingdi Yu60bd7082014-03-25 18:18:54 -0700122 * On return, signatureInfo and signatureValue in the packet are set.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700123 * If default identity does not exist,
Yingdi Yu60bd7082014-03-25 18:18:54 -0700124 * a temporary identity will be created and set as default.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800125 *
126 * @param packet The packet to be signed
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800127 */
Yingdi Yu2e57a582014-02-20 23:34:43 -0800128 template<typename T>
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800129 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700130 sign(T& packet);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700131
Jeff Thompson47c93cf2013-08-09 00:38:48 -0700132 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800133 * @brief Sign packet with a particular certificate.
134 *
135 * @param packet The packet to be signed.
136 * @param certificateName The certificate name of the key to use for signing.
137 * @throws SecPublicInfo::Error if certificate does not exist.
Jeff Thompson3c73da42013-08-12 11:19:05 -0700138 */
Yingdi Yu2e57a582014-02-20 23:34:43 -0800139 template<typename T>
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700140 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700141 sign(T& packet, const Name& certificateName);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700142
Jeff Thompson29ce3102013-09-27 11:47:48 -0700143 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800144 * @brief Sign the byte array using a particular certificate.
145 *
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700146 * @param buffer The byte array to be signed.
147 * @param bufferLength the length of buffer.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800148 * @param certificateName The certificate name of the signing key.
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700149 * @return The Signature.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800150 * @throws SecPublicInfo::Error if certificate does not exist.
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700151 */
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800152 Signature
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700153 sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName);
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700154
155 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800156 * @brief Sign packet using the default certificate of a particular identity.
157 *
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700158 * If there is no default certificate of that identity, this method will create a self-signed
159 * certificate.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800160 *
161 * @param packet The packet to be signed.
162 * @param identityName The signing identity name.
Jeff Thompson29ce3102013-09-27 11:47:48 -0700163 */
Yingdi Yu2e57a582014-02-20 23:34:43 -0800164 template<typename T>
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700165 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700166 signByIdentity(T& packet, const Name& identityName);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700167
Jeff Thompson3c73da42013-08-12 11:19:05 -0700168 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800169 * @brief Sign the byte array using the default certificate of a particular identity.
170 *
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700171 * @param buffer The byte array to be signed.
172 * @param bufferLength the length of buffer.
173 * @param identityName The identity name.
174 * @return The Signature.
175 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700176 inline Signature
177 signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName);
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700178
179 /**
Yingdi Yu21157162014-02-28 13:02:34 -0800180 * @brief Set Sha256 weak signature.
181 *
182 * @param data.
183 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700184 inline void
185 signWithSha256(Data& data);
Yingdi Yu21157162014-02-28 13:02:34 -0800186
187 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800188 * @brief Generate a self-signed certificate for a public key.
189 *
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800190 * @param keyName The name of the public key.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800191 * @return The generated certificate, NULL if selfSign fails.
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800192 */
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800193 shared_ptr<IdentityCertificate>
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700194 selfSign(const Name& keyName);
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800195
196 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800197 * @brief Self-sign the supplied identity certificate.
198 *
199 * @param cert The supplied cert.
200 * @throws SecTpm::Error if the private key does not exist.
Jeff Thompson8efe5ad2013-08-20 17:36:38 -0700201 */
Jeff Thompson2ce8f492013-09-17 18:01:25 -0700202 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700203 selfSign(IdentityCertificate& cert);
Yingdi Yu31b4af22014-01-14 14:13:00 -0800204
Yingdi Yu2e57a582014-02-20 23:34:43 -0800205 /**
206 * @brief delete a certificate.
207 *
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700208 * If the certificate to be deleted is current default system default,
Yingdi Yu2e57a582014-02-20 23:34:43 -0800209 * the method will not delete the certificate and return immediately.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700210 *
Yingdi Yu2e57a582014-02-20 23:34:43 -0800211 * @param certificateName The certificate to be deleted.
212 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700213 inline void
214 deleteCertificate(const Name& certificateName);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800215
Yingdi Yu2e57a582014-02-20 23:34:43 -0800216 /**
217 * @brief delete a key.
218 *
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700219 * If the key to be deleted is current default system default,
Yingdi Yu2e57a582014-02-20 23:34:43 -0800220 * the method will not delete the key and return immediately.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700221 *
Yingdi Yu2e57a582014-02-20 23:34:43 -0800222 * @param keyName The key to be deleted.
223 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700224 inline void
225 deleteKey(const Name& keyName);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800226
Yingdi Yu2e57a582014-02-20 23:34:43 -0800227 /**
228 * @brief delete an identity.
229 *
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700230 * If the identity to be deleted is current default system default,
Yingdi Yu2e57a582014-02-20 23:34:43 -0800231 * the method will not delete the identity and return immediately.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700232 *
Yingdi Yu2e57a582014-02-20 23:34:43 -0800233 * @param identity The identity to be deleted.
234 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700235 inline void
236 deleteIdentity(const Name& identity);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800237
Yingdi Yu2e57a582014-02-20 23:34:43 -0800238 /**
239 * @brief export an identity.
240 *
241 * @param identity The identity to export.
242 * @param passwordStr The password to secure the private key.
Yingdi Yu64c3fb42014-02-26 17:30:04 -0800243 * @return The encoded export data.
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700244 * @throws SecPublicInfo::Error if anything goes wrong in exporting.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800245 */
Yingdi Yu64c3fb42014-02-26 17:30:04 -0800246 shared_ptr<SecuredBag>
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700247 exportIdentity(const Name& identity, const std::string& passwordStr);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800248
Yingdi Yu2e57a582014-02-20 23:34:43 -0800249 /**
250 * @brief import an identity.
251 *
Yingdi Yu64c3fb42014-02-26 17:30:04 -0800252 * @param securedBag The encoded import data.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800253 * @param passwordStr The password to secure the private key.
254 */
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800255 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700256 importIdentity(const SecuredBag& securedBag, const std::string& passwordStr);
257
258 SecPublicInfo&
259 getPib()
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800260 {
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700261 return *m_pib;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800262 }
263
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700264 const SecPublicInfo&
265 getPib() const
266 {
267 return *m_pib;
268 }
269
270 SecTpm&
271 getTpm()
272 {
273 return *m_tpm;
274 }
275
276 const SecTpm&
277 getTpm() const
278 {
279 return *m_tpm;
280 }
281
282 /*******************************
283 * Wrapper of SecPublicInfo *
284 *******************************/
285 bool
286 doesIdentityExist(const Name& identityName) const
287 {
288 return m_pib->doesIdentityExist(identityName);
289 }
290
291 void
292 addIdentity(const Name& identityName)
293 {
294 return m_pib->addIdentity(identityName);
295 }
296
297 bool
298 doesPublicKeyExist(const Name& keyName) const
299 {
300 return m_pib->doesPublicKeyExist(keyName);
301 }
302
303 void
304 addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer)
305 {
306 return m_pib->addPublicKey(keyName, keyType, publicKeyDer);
307 }
308
309 shared_ptr<PublicKey>
310 getPublicKey(const Name& keyName) const
311 {
312 return m_pib->getPublicKey(keyName);
313 }
314
315 bool
316 doesCertificateExist(const Name& certificateName) const
317 {
318 return m_pib->doesCertificateExist(certificateName);
319 }
320
321 void
322 addCertificate(const IdentityCertificate& certificate)
323 {
324 return m_pib->addCertificate(certificate);
325 }
326
327 shared_ptr<IdentityCertificate>
328 getCertificate(const Name& certificateName) const
329 {
330 return m_pib->getCertificate(certificateName);
331 }
332
333 Name
334 getDefaultIdentity() const
335 {
336 return m_pib->getDefaultIdentity();
337 }
338
339 Name
340 getDefaultKeyNameForIdentity(const Name& identityName) const
341 {
342 return m_pib->getDefaultKeyNameForIdentity(identityName);
343 }
344
345 Name
346 getDefaultCertificateNameForKey(const Name& keyName) const
347 {
348 return m_pib->getDefaultCertificateNameForKey(keyName);
349 }
350
351 void
352 getAllIdentities(std::vector<Name>& nameList, bool isDefault) const
353 {
354 return m_pib->getAllIdentities(nameList, isDefault);
355 }
356
357 void
358 getAllKeyNames(std::vector<Name>& nameList, bool isDefault) const
359 {
360 return m_pib->getAllKeyNames(nameList, isDefault);
361 }
362
363 void
364 getAllKeyNamesOfIdentity(const Name& identity, std::vector<Name>& nameList, bool isDefault) const
365 {
366 return m_pib->getAllKeyNamesOfIdentity(identity, nameList, isDefault);
367 }
368
369 void
370 getAllCertificateNames(std::vector<Name>& nameList, bool isDefault) const
371 {
372 return m_pib->getAllCertificateNames(nameList, isDefault);
373 }
374
375 void
376 getAllCertificateNamesOfKey(const Name& keyName,
377 std::vector<Name>& nameList,
378 bool isDefault) const
379 {
380 return m_pib->getAllCertificateNamesOfKey(keyName, nameList, isDefault);
381 }
382
383 void
384 deleteCertificateInfo(const Name& certificateName)
385 {
386 return m_pib->deleteCertificateInfo(certificateName);
387 }
388
389 void
390 deletePublicKeyInfo(const Name& keyName)
391 {
392 return m_pib->deletePublicKeyInfo(keyName);
393 }
394
395 void
396 deleteIdentityInfo(const Name& identity)
397 {
398 return m_pib->deleteIdentityInfo(identity);
399 }
400
401 void
402 setDefaultIdentity(const Name& identityName)
403 {
404 return m_pib->setDefaultIdentity(identityName);
405 }
406
407 void
408 setDefaultKeyNameForIdentity(const Name& keyName)
409 {
410 return m_pib->setDefaultKeyNameForIdentity(keyName);
411 }
412
413 void
414 setDefaultCertificateNameForKey(const Name& certificateName)
415 {
416 return m_pib->setDefaultCertificateNameForKey(certificateName);
417 }
418
419 Name
420 getNewKeyName(const Name& identityName, bool useKsk)
421 {
422 return m_pib->getNewKeyName(identityName, useKsk);
423 }
424
425 Name
426 getDefaultCertificateNameForIdentity(const Name& identityName) const
427 {
428 return m_pib->getDefaultCertificateNameForIdentity(identityName);
429 }
430
431 Name
432 getDefaultCertificateName() const
433 {
434 return m_pib->getDefaultCertificateName();
435 }
436
437 void
438 addCertificateAsKeyDefault(const IdentityCertificate& certificate)
439 {
440 return m_pib->addCertificateAsKeyDefault(certificate);
441 }
442
443 void
444 addCertificateAsIdentityDefault(const IdentityCertificate& certificate)
445 {
446 return m_pib->addCertificateAsIdentityDefault(certificate);
447 }
448
449 void
450 addCertificateAsSystemDefault(const IdentityCertificate& certificate)
451 {
452 return m_pib->addCertificateAsSystemDefault(certificate);
453 }
454
455 shared_ptr<IdentityCertificate>
456 getDefaultCertificate() const
457 {
458 return m_pib->defaultCertificate();
459 }
460
461 void
462 refreshDefaultCertificate()
463 {
464 return m_pib->refreshDefaultCertificate();
465 }
466
467 /*******************************
468 * Wrapper of SecTpm *
469 *******************************/
470
471 void
472 setTpmPassword(const uint8_t* password, size_t passwordLength)
473 {
474 return m_tpm->setTpmPassword(password, passwordLength);
475 }
476
477 void
478 resetTpmPassword()
479 {
480 return m_tpm->resetTpmPassword();
481 }
482
483 void
484 setInTerminal(bool inTerminal)
485 {
486 return m_tpm->setInTerminal(inTerminal);
487 }
488
489 bool
490 getInTerminal() const
491 {
492 return m_tpm->getInTerminal();
493 }
494
495 bool
496 isLocked() const
497 {
498 return m_tpm->isLocked();
499 }
500
501 bool
502 unlockTpm(const char* password, size_t passwordLength, bool usePassword)
503 {
504 return m_tpm->unlockTpm(password, passwordLength, usePassword);
505 }
506
507 void
508 generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize)
509 {
510 return m_tpm->generateKeyPairInTpm(keyName, keyType, keySize);
511 }
512
513 void
514 deleteKeyPairInTpm(const Name& keyName)
515 {
516 return m_tpm->deleteKeyPairInTpm(keyName);
517 }
518
519 shared_ptr<PublicKey>
520 getPublicKeyFromTpm(const Name& keyName) const
521 {
522 return m_tpm->getPublicKeyFromTpm(keyName);
523 }
524
525 Block
526 signInTpm(const uint8_t* data, size_t dataLength,
527 const Name& keyName,
528 DigestAlgorithm digestAlgorithm)
529 {
530 return m_tpm->signInTpm(data, dataLength, keyName, digestAlgorithm);
531 }
532
533 ConstBufferPtr
534 decryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric)
535 {
536 return m_tpm->decryptInTpm(data, dataLength, keyName, isSymmetric);
537 }
538
539 ConstBufferPtr
540 encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric)
541 {
542 return m_tpm->encryptInTpm(data, dataLength, keyName, isSymmetric);
543 }
544
545 void
546 generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize)
547 {
548 return m_tpm->generateSymmetricKeyInTpm(keyName, keyType, keySize);
549 }
550
551 bool
552 doesKeyExistInTpm(const Name& keyName, KeyClass keyClass) const
553 {
554 return m_tpm->doesKeyExistInTpm(keyName, keyClass);
555 }
556
557 bool
558 generateRandomBlock(uint8_t* res, size_t size) const
559 {
560 return m_tpm->generateRandomBlock(res, size);
561 }
562
563 void
564 addAppToAcl(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl)
565 {
566 return m_tpm->addAppToAcl(keyName, keyClass, appPath, acl);
567 }
568
569 ConstBufferPtr
570 exportPrivateKeyPkcs5FromTpm(const Name& keyName, const std::string& password)
571 {
572 return m_tpm->exportPrivateKeyPkcs5FromTpm(keyName, password);
573 }
574
575 bool
576 importPrivateKeyPkcs5IntoTpm(const Name& keyName,
577 const uint8_t* buf, size_t size,
578 const std::string& password)
579 {
580 return m_tpm->importPrivateKeyPkcs5IntoTpm(keyName, buf, size, password);
581 }
Jeff Thompson8efe5ad2013-08-20 17:36:38 -0700582
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800583private:
Yingdi Yu2e57a582014-02-20 23:34:43 -0800584 /**
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700585 * @brief Set default certificate if it is not initialized
586 */
587 void
588 setDefaultCertificateInternal();
589
590 /**
591 * @brief Sign a packet using a pariticular certificate.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800592 *
593 * @param packet The packet to be signed.
594 * @param certificate The signing certificate.
595 */
596 template<typename T>
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800597 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700598 sign(T& packet, const IdentityCertificate& certificate);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800599
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800600 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800601 * @brief Generate a key pair for the specified identity.
602 *
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800603 * @param identityName The name of the specified identity.
604 * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
605 * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
606 * @param keySize The size of the key pair.
607 * @return The name of the generated key.
608 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700609 inline Name
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700610 generateKeyPair(const Name& identityName, bool isKsk = false,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700611 KeyType keyType = KEY_TYPE_RSA, int keySize = 2048);
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800612
Yingdi Yu8726f652014-01-23 10:35:12 -0800613 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800614 * @brief Sign the data using a particular key.
615 *
616 * @param data Reference to the data packet.
617 * @param signature Signature to be added.
Yingdi Yu8726f652014-01-23 10:35:12 -0800618 * @param keyName The name of the signing key.
619 * @param digestAlgorithm the digest algorithm.
620 * @throws Tpm::Error
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700621 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700622 inline void
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700623 signPacketWrapper(Data& data, const SignatureSha256WithRsa& signature,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700624 const Name& keyName, DigestAlgorithm digestAlgorithm);
Yingdi Yu8726f652014-01-23 10:35:12 -0800625
Yingdi Yu2e57a582014-02-20 23:34:43 -0800626 /**
627 * @brief Sign the interest using a particular key.
628 *
629 * @param interest Reference to the interest packet.
630 * @param signature Signature to be added.
631 * @param keyName The name of the signing key.
632 * @param digestAlgorithm the digest algorithm.
633 * @throws Tpm::Error
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700634 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700635 inline void
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700636 signPacketWrapper(Interest& interest, const SignatureSha256WithRsa& signature,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700637 const Name& keyName, DigestAlgorithm digestAlgorithm);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800638
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700639
640private:
641 SecPublicInfo* m_pib;
642 SecTpm* m_tpm;
643};
644
645template<class T>
646inline
647KeyChain::KeyChain(T)
648 : m_pib(new typename T::Pib)
649 , m_tpm(new typename T::Tpm)
650{
651}
652
653inline Name
654KeyChain::createIdentity(const Name& identityName)
655{
656 m_pib->addIdentity(identityName);
657
658 Name keyName;
659 try
660 {
661 keyName = m_pib->getDefaultKeyNameForIdentity(identityName);
662 }
663 catch (SecPublicInfo::Error& e)
664 {
665 keyName = generateRsaKeyPairAsDefault(identityName, true);
666 }
667
668 Name certName;
669 try
670 {
671 certName = m_pib->getDefaultCertificateNameForKey(keyName);
672 }
673 catch (SecPublicInfo::Error& e)
674 {
675 shared_ptr<IdentityCertificate> selfCert = selfSign(keyName);
676 m_pib->addCertificateAsIdentityDefault(*selfCert);
677 certName = selfCert->getName();
678 }
679
680 return certName;
681}
682
683inline Name
684KeyChain::generateRsaKeyPair(const Name& identityName, bool isKsk, int keySize)
685{
686 return generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
687}
688
689inline Name
690KeyChain::generateRsaKeyPairAsDefault(const Name& identityName, bool isKsk, int keySize)
691{
692 Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
693
694 m_pib->setDefaultKeyNameForIdentity(keyName);
695
696 return keyName;
697}
698
699template<typename T>
700void
701KeyChain::sign(T& packet)
702{
703 if (!static_cast<bool>(m_pib->defaultCertificate()))
704 setDefaultCertificateInternal();
705
706 sign(packet, *m_pib->defaultCertificate());
707}
708
709template<typename T>
710void
711KeyChain::sign(T& packet, const Name& certificateName)
712{
713 if (!m_pib->doesCertificateExist(certificateName))
714 throw SecPublicInfo::Error("Requested certificate [" +
715 certificateName.toUri() + "] doesn't exist");
716
717 SignatureSha256WithRsa signature;
718 // implicit conversion should take care
719 signature.setKeyLocator(certificateName.getPrefix(-1));
720
721 // For temporary usage, we support RSA + SHA256 only, but will support more.
722 signPacketWrapper(packet, signature,
723 IdentityCertificate::certificateNameToPublicKeyName(certificateName),
724 DIGEST_ALGORITHM_SHA256);
725}
726
727template<typename T>
728void
729KeyChain::signByIdentity(T& packet, const Name& identityName)
730{
731 Name signingCertificateName;
732 try
733 {
734 signingCertificateName = m_pib->getDefaultCertificateNameForIdentity(identityName);
735 }
736 catch (SecPublicInfo::Error& e)
737 {
738 signingCertificateName = createIdentity(identityName);
739 // Ideally, no exception will be thrown out, unless something goes wrong in the TPM, which
740 // is a fatal error.
741 }
742
743 // We either get or create the signing certificate, sign packet! (no exception unless fatal
744 // error in TPM)
745 sign(packet, signingCertificateName);
746}
747
748inline Signature
749KeyChain::signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
750{
751 Name signingCertificateName;
752 try
753 {
754 signingCertificateName = m_pib->getDefaultCertificateNameForIdentity(identityName);
755 }
756 catch (SecPublicInfo::Error& e)
757 {
758 signingCertificateName = createIdentity(identityName);
759 // Ideally, no exception will be thrown out, unless something goes wrong in the TPM, which
760 // is a fatal error.
761 }
762
763 // We either get or create the signing certificate, sign data! (no exception unless fatal error
764 // in TPM)
765 return sign(buffer, bufferLength, signingCertificateName);
766}
767
768inline void
769KeyChain::signWithSha256(Data& data)
770{
771 SignatureSha256 sig;
772 data.setSignature(sig);
773
774 Block sigValue(Tlv::SignatureValue,
775 crypto::sha256(data.wireEncode().value(),
776 data.wireEncode().value_size() -
777 data.getSignature().getValue().size()));
778 data.setSignatureValue(sigValue);
779}
780
781inline void
782KeyChain::deleteCertificate(const Name& certificateName)
783{
784 try
785 {
786 if (m_pib->getDefaultCertificateName() == certificateName)
787 return;
788 }
789 catch (SecPublicInfo::Error& e)
790 {
791 // Not a real error, just try to delete the certificate
792 }
793
794 m_pib->deleteCertificateInfo(certificateName);
795}
796
797inline void
798KeyChain::deleteKey(const Name& keyName)
799{
800 try
801 {
802 if (m_pib->getDefaultKeyNameForIdentity(m_pib->getDefaultIdentity()) == keyName)
803 return;
804 }
805 catch (SecPublicInfo::Error& e)
806 {
807 // Not a real error, just try to delete the key
808 }
809
810 m_pib->deletePublicKeyInfo(keyName);
811 m_tpm->deleteKeyPairInTpm(keyName);
812}
813
814inline void
815KeyChain::deleteIdentity(const Name& identity)
816{
817 try
818 {
819 if (m_pib->getDefaultIdentity() == identity)
820 return;
821 }
822 catch (SecPublicInfo::Error& e)
823 {
824 // Not a real error, just try to delete the identity
825 }
826
827 std::vector<Name> nameList;
828 m_pib->getAllKeyNamesOfIdentity(identity, nameList, true);
829 m_pib->getAllKeyNamesOfIdentity(identity, nameList, false);
830
831 m_pib->deleteIdentityInfo(identity);
832
833 std::vector<Name>::const_iterator it = nameList.begin();
834 for(; it != nameList.end(); it++)
835 m_tpm->deleteKeyPairInTpm(*it);
836}
837
838template<typename T>
839void
840KeyChain::sign(T& packet, const IdentityCertificate& certificate)
841{
842 SignatureSha256WithRsa signature;
843 signature.setKeyLocator(certificate.getName().getPrefix(-1));
844
845 // For temporary usage, we support RSA + SHA256 only, but will support more.
846 signPacketWrapper(packet, signature, certificate.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
847}
848
849inline Name
850KeyChain::generateKeyPair(const Name& identityName, bool isKsk, KeyType keyType, int keySize)
851{
852 Name keyName = m_pib->getNewKeyName(identityName, isKsk);
853
854 m_tpm->generateKeyPairInTpm(keyName.toUri(), keyType, keySize);
855
856 shared_ptr<PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.toUri());
857 m_pib->addPublicKey(keyName, keyType, *pubKey);
858
859 return keyName;
860}
861
862inline void
863KeyChain::signPacketWrapper(Data& data, const SignatureSha256WithRsa& signature,
864 const Name& keyName, DigestAlgorithm digestAlgorithm)
865{
866 data.setSignature(signature);
867 data.setSignatureValue(m_tpm->signInTpm(data.wireEncode().value(),
868 data.wireEncode().value_size() -
869 data.getSignature().getValue().size(),
870 keyName, digestAlgorithm));
871}
872
873inline void
874KeyChain::signPacketWrapper(Interest& interest, const SignatureSha256WithRsa& signature,
875 const Name& keyName, DigestAlgorithm digestAlgorithm)
876{
877 Name signedName = interest.getName();
878 signedName.append(signature.getInfo());
879
880 Block sigValue = m_tpm->signInTpm(signedName.wireEncode().value(),
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700881 signedName.wireEncode().value_size(),
Yingdi Yu2e57a582014-02-20 23:34:43 -0800882 keyName,
883 DIGEST_ALGORITHM_SHA256);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700884 sigValue.encode();
885 signedName.append(sigValue);
886 interest.setName(signedName);
887}
Yingdi Yu2e57a582014-02-20 23:34:43 -0800888
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700889}
Jeff Thompson47c93cf2013-08-09 00:38:48 -0700890
Alexander Afanasyev766cea72014-04-24 19:16:42 -0700891#endif // NDN_SECURITY_KEY_CHAIN_HPP