blob: 30efa121cad9aafdb112cfb95eee0fd37ba3c3a3 [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 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700105 * @param keyName Key name, e.g., `/<identity_name>/ksk-123456`.
Yingdi Yuc55680b2014-02-26 12:31:35 -0800106 * @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 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700180 * @brief Set Sha256 weak signature for @param data
Yingdi Yu21157162014-02-28 13:02:34 -0800181 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700182 inline void
183 signWithSha256(Data& data);
Yingdi Yu21157162014-02-28 13:02:34 -0800184
185 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800186 * @brief Generate a self-signed certificate for a public key.
187 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700188 * @param keyName The name of the public key
189 * @return The generated certificate, shared_ptr<IdentityCertificate>() if selfSign fails
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800190 */
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800191 shared_ptr<IdentityCertificate>
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700192 selfSign(const Name& keyName);
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800193
194 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800195 * @brief Self-sign the supplied identity certificate.
196 *
197 * @param cert The supplied cert.
198 * @throws SecTpm::Error if the private key does not exist.
Jeff Thompson8efe5ad2013-08-20 17:36:38 -0700199 */
Jeff Thompson2ce8f492013-09-17 18:01:25 -0700200 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700201 selfSign(IdentityCertificate& cert);
Yingdi Yu31b4af22014-01-14 14:13:00 -0800202
Yingdi Yu2e57a582014-02-20 23:34:43 -0800203 /**
204 * @brief delete a certificate.
205 *
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700206 * If the certificate to be deleted is current default system default,
Yingdi Yu2e57a582014-02-20 23:34:43 -0800207 * the method will not delete the certificate and return immediately.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700208 *
Yingdi Yu2e57a582014-02-20 23:34:43 -0800209 * @param certificateName The certificate to be deleted.
210 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700211 inline void
212 deleteCertificate(const Name& certificateName);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800213
Yingdi Yu2e57a582014-02-20 23:34:43 -0800214 /**
215 * @brief delete a key.
216 *
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700217 * If the key to be deleted is current default system default,
Yingdi Yu2e57a582014-02-20 23:34:43 -0800218 * the method will not delete the key and return immediately.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700219 *
Yingdi Yu2e57a582014-02-20 23:34:43 -0800220 * @param keyName The key to be deleted.
221 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700222 inline void
223 deleteKey(const Name& keyName);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800224
Yingdi Yu2e57a582014-02-20 23:34:43 -0800225 /**
226 * @brief delete an identity.
227 *
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700228 * If the identity to be deleted is current default system default,
Yingdi Yu2e57a582014-02-20 23:34:43 -0800229 * the method will not delete the identity and return immediately.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700230 *
Yingdi Yu2e57a582014-02-20 23:34:43 -0800231 * @param identity The identity to be deleted.
232 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700233 inline void
234 deleteIdentity(const Name& identity);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800235
Yingdi Yu2e57a582014-02-20 23:34:43 -0800236 /**
237 * @brief export an identity.
238 *
239 * @param identity The identity to export.
240 * @param passwordStr The password to secure the private key.
Yingdi Yu64c3fb42014-02-26 17:30:04 -0800241 * @return The encoded export data.
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700242 * @throws SecPublicInfo::Error if anything goes wrong in exporting.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800243 */
Yingdi Yu64c3fb42014-02-26 17:30:04 -0800244 shared_ptr<SecuredBag>
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700245 exportIdentity(const Name& identity, const std::string& passwordStr);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800246
Yingdi Yu2e57a582014-02-20 23:34:43 -0800247 /**
248 * @brief import an identity.
249 *
Yingdi Yu64c3fb42014-02-26 17:30:04 -0800250 * @param securedBag The encoded import data.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800251 * @param passwordStr The password to secure the private key.
252 */
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800253 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700254 importIdentity(const SecuredBag& securedBag, const std::string& passwordStr);
255
256 SecPublicInfo&
257 getPib()
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800258 {
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700259 return *m_pib;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800260 }
261
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700262 const SecPublicInfo&
263 getPib() const
264 {
265 return *m_pib;
266 }
267
268 SecTpm&
269 getTpm()
270 {
271 return *m_tpm;
272 }
273
274 const SecTpm&
275 getTpm() const
276 {
277 return *m_tpm;
278 }
279
280 /*******************************
281 * Wrapper of SecPublicInfo *
282 *******************************/
283 bool
284 doesIdentityExist(const Name& identityName) const
285 {
286 return m_pib->doesIdentityExist(identityName);
287 }
288
289 void
290 addIdentity(const Name& identityName)
291 {
292 return m_pib->addIdentity(identityName);
293 }
294
295 bool
296 doesPublicKeyExist(const Name& keyName) const
297 {
298 return m_pib->doesPublicKeyExist(keyName);
299 }
300
301 void
302 addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer)
303 {
304 return m_pib->addPublicKey(keyName, keyType, publicKeyDer);
305 }
306
307 shared_ptr<PublicKey>
308 getPublicKey(const Name& keyName) const
309 {
310 return m_pib->getPublicKey(keyName);
311 }
312
313 bool
314 doesCertificateExist(const Name& certificateName) const
315 {
316 return m_pib->doesCertificateExist(certificateName);
317 }
318
319 void
320 addCertificate(const IdentityCertificate& certificate)
321 {
322 return m_pib->addCertificate(certificate);
323 }
324
325 shared_ptr<IdentityCertificate>
326 getCertificate(const Name& certificateName) const
327 {
328 return m_pib->getCertificate(certificateName);
329 }
330
331 Name
332 getDefaultIdentity() const
333 {
334 return m_pib->getDefaultIdentity();
335 }
336
337 Name
338 getDefaultKeyNameForIdentity(const Name& identityName) const
339 {
340 return m_pib->getDefaultKeyNameForIdentity(identityName);
341 }
342
343 Name
344 getDefaultCertificateNameForKey(const Name& keyName) const
345 {
346 return m_pib->getDefaultCertificateNameForKey(keyName);
347 }
348
349 void
350 getAllIdentities(std::vector<Name>& nameList, bool isDefault) const
351 {
352 return m_pib->getAllIdentities(nameList, isDefault);
353 }
354
355 void
356 getAllKeyNames(std::vector<Name>& nameList, bool isDefault) const
357 {
358 return m_pib->getAllKeyNames(nameList, isDefault);
359 }
360
361 void
362 getAllKeyNamesOfIdentity(const Name& identity, std::vector<Name>& nameList, bool isDefault) const
363 {
364 return m_pib->getAllKeyNamesOfIdentity(identity, nameList, isDefault);
365 }
366
367 void
368 getAllCertificateNames(std::vector<Name>& nameList, bool isDefault) const
369 {
370 return m_pib->getAllCertificateNames(nameList, isDefault);
371 }
372
373 void
374 getAllCertificateNamesOfKey(const Name& keyName,
375 std::vector<Name>& nameList,
376 bool isDefault) const
377 {
378 return m_pib->getAllCertificateNamesOfKey(keyName, nameList, isDefault);
379 }
380
381 void
382 deleteCertificateInfo(const Name& certificateName)
383 {
384 return m_pib->deleteCertificateInfo(certificateName);
385 }
386
387 void
388 deletePublicKeyInfo(const Name& keyName)
389 {
390 return m_pib->deletePublicKeyInfo(keyName);
391 }
392
393 void
394 deleteIdentityInfo(const Name& identity)
395 {
396 return m_pib->deleteIdentityInfo(identity);
397 }
398
399 void
400 setDefaultIdentity(const Name& identityName)
401 {
402 return m_pib->setDefaultIdentity(identityName);
403 }
404
405 void
406 setDefaultKeyNameForIdentity(const Name& keyName)
407 {
408 return m_pib->setDefaultKeyNameForIdentity(keyName);
409 }
410
411 void
412 setDefaultCertificateNameForKey(const Name& certificateName)
413 {
414 return m_pib->setDefaultCertificateNameForKey(certificateName);
415 }
416
417 Name
418 getNewKeyName(const Name& identityName, bool useKsk)
419 {
420 return m_pib->getNewKeyName(identityName, useKsk);
421 }
422
423 Name
424 getDefaultCertificateNameForIdentity(const Name& identityName) const
425 {
426 return m_pib->getDefaultCertificateNameForIdentity(identityName);
427 }
428
429 Name
430 getDefaultCertificateName() const
431 {
432 return m_pib->getDefaultCertificateName();
433 }
434
435 void
436 addCertificateAsKeyDefault(const IdentityCertificate& certificate)
437 {
438 return m_pib->addCertificateAsKeyDefault(certificate);
439 }
440
441 void
442 addCertificateAsIdentityDefault(const IdentityCertificate& certificate)
443 {
444 return m_pib->addCertificateAsIdentityDefault(certificate);
445 }
446
447 void
448 addCertificateAsSystemDefault(const IdentityCertificate& certificate)
449 {
450 return m_pib->addCertificateAsSystemDefault(certificate);
451 }
452
453 shared_ptr<IdentityCertificate>
454 getDefaultCertificate() const
455 {
456 return m_pib->defaultCertificate();
457 }
458
459 void
460 refreshDefaultCertificate()
461 {
462 return m_pib->refreshDefaultCertificate();
463 }
464
465 /*******************************
466 * Wrapper of SecTpm *
467 *******************************/
468
469 void
470 setTpmPassword(const uint8_t* password, size_t passwordLength)
471 {
472 return m_tpm->setTpmPassword(password, passwordLength);
473 }
474
475 void
476 resetTpmPassword()
477 {
478 return m_tpm->resetTpmPassword();
479 }
480
481 void
482 setInTerminal(bool inTerminal)
483 {
484 return m_tpm->setInTerminal(inTerminal);
485 }
486
487 bool
488 getInTerminal() const
489 {
490 return m_tpm->getInTerminal();
491 }
492
493 bool
494 isLocked() const
495 {
496 return m_tpm->isLocked();
497 }
498
499 bool
500 unlockTpm(const char* password, size_t passwordLength, bool usePassword)
501 {
502 return m_tpm->unlockTpm(password, passwordLength, usePassword);
503 }
504
505 void
506 generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize)
507 {
508 return m_tpm->generateKeyPairInTpm(keyName, keyType, keySize);
509 }
510
511 void
512 deleteKeyPairInTpm(const Name& keyName)
513 {
514 return m_tpm->deleteKeyPairInTpm(keyName);
515 }
516
517 shared_ptr<PublicKey>
518 getPublicKeyFromTpm(const Name& keyName) const
519 {
520 return m_tpm->getPublicKeyFromTpm(keyName);
521 }
522
523 Block
524 signInTpm(const uint8_t* data, size_t dataLength,
525 const Name& keyName,
526 DigestAlgorithm digestAlgorithm)
527 {
528 return m_tpm->signInTpm(data, dataLength, keyName, digestAlgorithm);
529 }
530
531 ConstBufferPtr
532 decryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric)
533 {
534 return m_tpm->decryptInTpm(data, dataLength, keyName, isSymmetric);
535 }
536
537 ConstBufferPtr
538 encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric)
539 {
540 return m_tpm->encryptInTpm(data, dataLength, keyName, isSymmetric);
541 }
542
543 void
544 generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize)
545 {
546 return m_tpm->generateSymmetricKeyInTpm(keyName, keyType, keySize);
547 }
548
549 bool
550 doesKeyExistInTpm(const Name& keyName, KeyClass keyClass) const
551 {
552 return m_tpm->doesKeyExistInTpm(keyName, keyClass);
553 }
554
555 bool
556 generateRandomBlock(uint8_t* res, size_t size) const
557 {
558 return m_tpm->generateRandomBlock(res, size);
559 }
560
561 void
562 addAppToAcl(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl)
563 {
564 return m_tpm->addAppToAcl(keyName, keyClass, appPath, acl);
565 }
566
567 ConstBufferPtr
568 exportPrivateKeyPkcs5FromTpm(const Name& keyName, const std::string& password)
569 {
570 return m_tpm->exportPrivateKeyPkcs5FromTpm(keyName, password);
571 }
572
573 bool
574 importPrivateKeyPkcs5IntoTpm(const Name& keyName,
575 const uint8_t* buf, size_t size,
576 const std::string& password)
577 {
578 return m_tpm->importPrivateKeyPkcs5IntoTpm(keyName, buf, size, password);
579 }
Jeff Thompson8efe5ad2013-08-20 17:36:38 -0700580
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800581private:
Yingdi Yu2e57a582014-02-20 23:34:43 -0800582 /**
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700583 * @brief Set default certificate if it is not initialized
584 */
585 void
586 setDefaultCertificateInternal();
587
588 /**
589 * @brief Sign a packet using a pariticular certificate.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800590 *
591 * @param packet The packet to be signed.
592 * @param certificate The signing certificate.
593 */
594 template<typename T>
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800595 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700596 sign(T& packet, const IdentityCertificate& certificate);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800597
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800598 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800599 * @brief Generate a key pair for the specified identity.
600 *
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800601 * @param identityName The name of the specified identity.
602 * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
603 * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
604 * @param keySize The size of the key pair.
605 * @return The name of the generated key.
606 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700607 inline Name
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700608 generateKeyPair(const Name& identityName, bool isKsk = false,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700609 KeyType keyType = KEY_TYPE_RSA, int keySize = 2048);
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800610
Yingdi Yu8726f652014-01-23 10:35:12 -0800611 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800612 * @brief Sign the data using a particular key.
613 *
614 * @param data Reference to the data packet.
615 * @param signature Signature to be added.
Yingdi Yu8726f652014-01-23 10:35:12 -0800616 * @param keyName The name of the signing key.
617 * @param digestAlgorithm the digest algorithm.
618 * @throws Tpm::Error
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700619 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700620 inline void
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700621 signPacketWrapper(Data& data, const SignatureSha256WithRsa& signature,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700622 const Name& keyName, DigestAlgorithm digestAlgorithm);
Yingdi Yu8726f652014-01-23 10:35:12 -0800623
Yingdi Yu2e57a582014-02-20 23:34:43 -0800624 /**
625 * @brief Sign the interest using a particular key.
626 *
627 * @param interest Reference to the interest packet.
628 * @param signature Signature to be added.
629 * @param keyName The name of the signing key.
630 * @param digestAlgorithm the digest algorithm.
631 * @throws Tpm::Error
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700632 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700633 inline void
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700634 signPacketWrapper(Interest& interest, const SignatureSha256WithRsa& signature,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700635 const Name& keyName, DigestAlgorithm digestAlgorithm);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800636
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700637
638private:
639 SecPublicInfo* m_pib;
640 SecTpm* m_tpm;
641};
642
643template<class T>
644inline
645KeyChain::KeyChain(T)
646 : m_pib(new typename T::Pib)
647 , m_tpm(new typename T::Tpm)
648{
649}
650
651inline Name
652KeyChain::createIdentity(const Name& identityName)
653{
654 m_pib->addIdentity(identityName);
655
656 Name keyName;
657 try
658 {
659 keyName = m_pib->getDefaultKeyNameForIdentity(identityName);
660 }
661 catch (SecPublicInfo::Error& e)
662 {
663 keyName = generateRsaKeyPairAsDefault(identityName, true);
664 }
665
666 Name certName;
667 try
668 {
669 certName = m_pib->getDefaultCertificateNameForKey(keyName);
670 }
671 catch (SecPublicInfo::Error& e)
672 {
673 shared_ptr<IdentityCertificate> selfCert = selfSign(keyName);
674 m_pib->addCertificateAsIdentityDefault(*selfCert);
675 certName = selfCert->getName();
676 }
677
678 return certName;
679}
680
681inline Name
682KeyChain::generateRsaKeyPair(const Name& identityName, bool isKsk, int keySize)
683{
684 return generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
685}
686
687inline Name
688KeyChain::generateRsaKeyPairAsDefault(const Name& identityName, bool isKsk, int keySize)
689{
690 Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
691
692 m_pib->setDefaultKeyNameForIdentity(keyName);
693
694 return keyName;
695}
696
697template<typename T>
698void
699KeyChain::sign(T& packet)
700{
701 if (!static_cast<bool>(m_pib->defaultCertificate()))
702 setDefaultCertificateInternal();
703
704 sign(packet, *m_pib->defaultCertificate());
705}
706
707template<typename T>
708void
709KeyChain::sign(T& packet, const Name& certificateName)
710{
711 if (!m_pib->doesCertificateExist(certificateName))
712 throw SecPublicInfo::Error("Requested certificate [" +
713 certificateName.toUri() + "] doesn't exist");
714
715 SignatureSha256WithRsa signature;
716 // implicit conversion should take care
717 signature.setKeyLocator(certificateName.getPrefix(-1));
718
719 // For temporary usage, we support RSA + SHA256 only, but will support more.
720 signPacketWrapper(packet, signature,
721 IdentityCertificate::certificateNameToPublicKeyName(certificateName),
722 DIGEST_ALGORITHM_SHA256);
723}
724
725template<typename T>
726void
727KeyChain::signByIdentity(T& packet, const Name& identityName)
728{
729 Name signingCertificateName;
730 try
731 {
732 signingCertificateName = m_pib->getDefaultCertificateNameForIdentity(identityName);
733 }
734 catch (SecPublicInfo::Error& e)
735 {
736 signingCertificateName = createIdentity(identityName);
737 // Ideally, no exception will be thrown out, unless something goes wrong in the TPM, which
738 // is a fatal error.
739 }
740
741 // We either get or create the signing certificate, sign packet! (no exception unless fatal
742 // error in TPM)
743 sign(packet, signingCertificateName);
744}
745
746inline Signature
747KeyChain::signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
748{
749 Name signingCertificateName;
750 try
751 {
752 signingCertificateName = m_pib->getDefaultCertificateNameForIdentity(identityName);
753 }
754 catch (SecPublicInfo::Error& e)
755 {
756 signingCertificateName = createIdentity(identityName);
757 // Ideally, no exception will be thrown out, unless something goes wrong in the TPM, which
758 // is a fatal error.
759 }
760
761 // We either get or create the signing certificate, sign data! (no exception unless fatal error
762 // in TPM)
763 return sign(buffer, bufferLength, signingCertificateName);
764}
765
766inline void
767KeyChain::signWithSha256(Data& data)
768{
769 SignatureSha256 sig;
770 data.setSignature(sig);
771
772 Block sigValue(Tlv::SignatureValue,
773 crypto::sha256(data.wireEncode().value(),
774 data.wireEncode().value_size() -
775 data.getSignature().getValue().size()));
776 data.setSignatureValue(sigValue);
777}
778
779inline void
780KeyChain::deleteCertificate(const Name& certificateName)
781{
782 try
783 {
784 if (m_pib->getDefaultCertificateName() == certificateName)
785 return;
786 }
787 catch (SecPublicInfo::Error& e)
788 {
789 // Not a real error, just try to delete the certificate
790 }
791
792 m_pib->deleteCertificateInfo(certificateName);
793}
794
795inline void
796KeyChain::deleteKey(const Name& keyName)
797{
798 try
799 {
800 if (m_pib->getDefaultKeyNameForIdentity(m_pib->getDefaultIdentity()) == keyName)
801 return;
802 }
803 catch (SecPublicInfo::Error& e)
804 {
805 // Not a real error, just try to delete the key
806 }
807
808 m_pib->deletePublicKeyInfo(keyName);
809 m_tpm->deleteKeyPairInTpm(keyName);
810}
811
812inline void
813KeyChain::deleteIdentity(const Name& identity)
814{
815 try
816 {
817 if (m_pib->getDefaultIdentity() == identity)
818 return;
819 }
820 catch (SecPublicInfo::Error& e)
821 {
822 // Not a real error, just try to delete the identity
823 }
824
825 std::vector<Name> nameList;
826 m_pib->getAllKeyNamesOfIdentity(identity, nameList, true);
827 m_pib->getAllKeyNamesOfIdentity(identity, nameList, false);
828
829 m_pib->deleteIdentityInfo(identity);
830
831 std::vector<Name>::const_iterator it = nameList.begin();
832 for(; it != nameList.end(); it++)
833 m_tpm->deleteKeyPairInTpm(*it);
834}
835
836template<typename T>
837void
838KeyChain::sign(T& packet, const IdentityCertificate& certificate)
839{
840 SignatureSha256WithRsa signature;
841 signature.setKeyLocator(certificate.getName().getPrefix(-1));
842
843 // For temporary usage, we support RSA + SHA256 only, but will support more.
844 signPacketWrapper(packet, signature, certificate.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
845}
846
847inline Name
848KeyChain::generateKeyPair(const Name& identityName, bool isKsk, KeyType keyType, int keySize)
849{
850 Name keyName = m_pib->getNewKeyName(identityName, isKsk);
851
852 m_tpm->generateKeyPairInTpm(keyName.toUri(), keyType, keySize);
853
854 shared_ptr<PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.toUri());
855 m_pib->addPublicKey(keyName, keyType, *pubKey);
856
857 return keyName;
858}
859
860inline void
861KeyChain::signPacketWrapper(Data& data, const SignatureSha256WithRsa& signature,
862 const Name& keyName, DigestAlgorithm digestAlgorithm)
863{
864 data.setSignature(signature);
865 data.setSignatureValue(m_tpm->signInTpm(data.wireEncode().value(),
866 data.wireEncode().value_size() -
867 data.getSignature().getValue().size(),
868 keyName, digestAlgorithm));
869}
870
871inline void
872KeyChain::signPacketWrapper(Interest& interest, const SignatureSha256WithRsa& signature,
873 const Name& keyName, DigestAlgorithm digestAlgorithm)
874{
875 Name signedName = interest.getName();
876 signedName.append(signature.getInfo());
877
878 Block sigValue = m_tpm->signInTpm(signedName.wireEncode().value(),
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700879 signedName.wireEncode().value_size(),
Yingdi Yu2e57a582014-02-20 23:34:43 -0800880 keyName,
881 DIGEST_ALGORITHM_SHA256);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700882 sigValue.encode();
883 signedName.append(sigValue);
884 interest.setName(signedName);
885}
Yingdi Yu2e57a582014-02-20 23:34:43 -0800886
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700887}
Jeff Thompson47c93cf2013-08-09 00:38:48 -0700888
Alexander Afanasyev766cea72014-04-24 19:16:42 -0700889#endif // NDN_SECURITY_KEY_CHAIN_HPP