blob: b6b9bbf1ad4f38c6a8ae13b4920bd3aac5b40b17 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Jeff Thompson47c93cf2013-08-09 00:38:48 -07002/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070020 *
21 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
Jeff Thompson47c93cf2013-08-09 00:38:48 -070022 */
23
Yingdi Yufc40d872014-02-18 12:56:04 -080024#ifndef NDN_SECURITY_KEY_CHAIN_HPP
25#define NDN_SECURITY_KEY_CHAIN_HPP
Jeff Thompson47c93cf2013-08-09 00:38:48 -070026
Yingdi Yuf56c68f2014-04-24 21:50:13 -070027#include "sec-public-info.hpp"
28#include "sec-tpm.hpp"
Yingdi Yu7036ce22014-06-19 18:53:37 -070029#include "key-params.hpp"
Yingdi Yuf56c68f2014-04-24 21:50:13 -070030#include "secured-bag.hpp"
Yingdi Yu4f324632014-01-15 18:10:03 -080031#include "signature-sha256-with-rsa.hpp"
Yingdi Yuc8f883c2014-06-20 23:25:22 -070032#include "signature-sha256-with-ecdsa.hpp"
Yingdi Yubf6a2812014-06-17 15:32:11 -070033#include "digest-sha256.hpp"
Yingdi Yuf56c68f2014-04-24 21:50:13 -070034
Yingdi Yu4270f202014-01-28 14:19:16 -080035#include "../interest.hpp"
Yingdi Yu21157162014-02-28 13:02:34 -080036#include "../util/crypto.hpp"
Yingdi Yu0f5fb692014-06-10 12:07:28 -070037#include "../util/random.hpp"
Yingdi Yu31b4af22014-01-14 14:13:00 -080038
Jeff Thompson47c93cf2013-08-09 00:38:48 -070039
40namespace ndn {
41
Yingdi Yuf56c68f2014-04-24 21:50:13 -070042template<class TypePib, class TypeTpm>
43class KeyChainTraits
Yingdi Yu31b4af22014-01-14 14:13:00 -080044{
Jeff Thompson47c93cf2013-08-09 00:38:48 -070045public:
Yingdi Yuf56c68f2014-04-24 21:50:13 -070046 typedef TypePib Pib;
47 typedef TypeTpm Tpm;
48};
49
Alexander Afanasyev45a37132014-04-28 16:54:57 -070050class KeyChain : noncopyable
Yingdi Yuf56c68f2014-04-24 21:50:13 -070051{
52public:
53 class Error : public std::runtime_error
54 {
55 public:
56 explicit
57 Error(const std::string& what)
58 : std::runtime_error(what)
59 {
60 }
61 };
62
Yingdi Yu0eb5d722014-06-10 15:06:25 -070063 static const Name DEFAULT_PREFIX;
64
Yingdi Yu7036ce22014-06-19 18:53:37 -070065 // RsaKeyParams is set to be default for backward compatibility.
66 static const RsaKeyParams DEFAULT_KEY_PARAMS;
67
Yingdi Yuf56c68f2014-04-24 21:50:13 -070068 KeyChain();
69
70 template<class KeyChainTraits>
Alexander Afanasyeva4297a62014-06-19 13:29:34 -070071 explicit
Yingdi Yuf56c68f2014-04-24 21:50:13 -070072 KeyChain(KeyChainTraits traits);
73
74 KeyChain(const std::string& pibName,
75 const std::string& tpmName);
76
77 virtual
78 ~KeyChain()
79 {
80 if (m_pib != 0)
81 delete m_pib;
82
83 if (m_tpm != 0)
84 delete m_tpm;
85 }
86
Yingdi Yube4150e2014-02-18 13:02:46 -080087 /**
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070088 * @brief Create an identity by creating a pair of Key-Signing-Key (KSK) for this identity and a
89 * self-signed certificate of the KSK.
Yingdi Yube4150e2014-02-18 13:02:46 -080090 *
Yingdi Yu2abd73f2014-01-08 23:34:11 -080091 * @param identityName The name of the identity.
Yingdi Yu7036ce22014-06-19 18:53:37 -070092 * @param params The key parameter if a key needs to be generated for the identity.
Yingdi Yu28fd32f2014-01-28 19:03:03 -080093 * @return The name of the default certificate of the identity.
Yingdi Yu2abd73f2014-01-08 23:34:11 -080094 */
Yingdi Yu7036ce22014-06-19 18:53:37 -070095 Name
96 createIdentity(const Name& identityName, const KeyParams& params = DEFAULT_KEY_PARAMS);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -070097
Yingdi Yu2abd73f2014-01-08 23:34:11 -080098 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -080099 * @brief Generate a pair of RSA keys for the specified identity.
100 *
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800101 * @param identityName The name of the identity.
102 * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
103 * @param keySize The size of the key.
104 * @return The generated key name.
105 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700106 inline Name
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700107 generateRsaKeyPair(const Name& identityName, bool isKsk = false, uint32_t keySize = 2048);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700108
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700109 inline Name
110 generateEcdsaKeyPair(const Name& identityName, bool isKsk = false, uint32_t keySize = 256);
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800111 /**
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700112 * @brief Generate a pair of RSA keys for the specified identity and set it as default key for
113 * the identity.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800114 *
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800115 * @param identityName The name of the identity.
116 * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
117 * @param keySize The size of the key.
118 * @return The generated key name.
119 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700120 Name
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700121 generateRsaKeyPairAsDefault(const Name& identityName, bool isKsk = false,
122 uint32_t keySize = 2048);
123
124 Name
125 generateEcdsaKeyPairAsDefault(const Name& identityName, bool isKsk, uint32_t keySize = 256);
Jeff Thompson79a2d5d2013-09-27 14:32:23 -0700126
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800127 /**
Yingdi Yuc55680b2014-02-26 12:31:35 -0800128 * @brief prepare an unsigned identity certificate
129 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700130 * @param keyName Key name, e.g., `/<identity_name>/ksk-123456`.
Yingdi Yuc55680b2014-02-26 12:31:35 -0800131 * @param signingIdentity The signing identity.
132 * @param notBefore Refer to IdentityCertificate.
133 * @param notAfter Refer to IdentityCertificate.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700134 * @param subjectDescription Refer to IdentityCertificate.
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700135 * @param certPrefix Prefix before `KEY` component. By default, KeyChain will infer the
136 * certificate name according to the relation between the signingIdentity and
137 * the subject identity. If signingIdentity is a prefix of the subject identity,
138 * `KEY` will be inserted after the signingIdentity, otherwise `KEY` is inserted
139 * after subject identity (i.e., before `ksk-....`).
Yingdi Yuc55680b2014-02-26 12:31:35 -0800140 * @return IdentityCertificate.
141 */
142 shared_ptr<IdentityCertificate>
143 prepareUnsignedIdentityCertificate(const Name& keyName,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700144 const Name& signingIdentity,
145 const time::system_clock::TimePoint& notBefore,
146 const time::system_clock::TimePoint& notAfter,
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700147 const std::vector<CertificateSubjectDescription>& subjectDescription,
148 const Name& certPrefix = DEFAULT_PREFIX);
149
150 /**
151 * @brief prepare an unsigned identity certificate
152 *
153 * @param keyName Key name, e.g., `/<identity_name>/ksk-123456`.
154 * @param publicKey Public key to sign.
155 * @param signingIdentity The signing identity.
156 * @param notBefore Refer to IdentityCertificate.
157 * @param notAfter Refer to IdentityCertificate.
158 * @param subjectDescription Refer to IdentityCertificate.
159 * @param certPrefix Prefix before `KEY` component. By default, KeyChain will infer the
160 * certificate name according to the relation between the signingIdentity and
161 * the subject identity. If signingIdentity is a prefix of the subject identity,
162 * `KEY` will be inserted after the signingIdentity, otherwise `KEY` is inserted
163 * after subject identity (i.e., before `ksk-....`).
164 * @return IdentityCertificate.
165 */
166 shared_ptr<IdentityCertificate>
167 prepareUnsignedIdentityCertificate(const Name& keyName,
168 const PublicKey& publicKey,
169 const Name& signingIdentity,
170 const time::system_clock::TimePoint& notBefore,
171 const time::system_clock::TimePoint& notAfter,
172 const std::vector<CertificateSubjectDescription>& subjectDescription,
173 const Name& certPrefix = DEFAULT_PREFIX);
Yingdi Yuc55680b2014-02-26 12:31:35 -0800174
175 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800176 * @brief Sign packet with default identity
177 *
Yingdi Yu60bd7082014-03-25 18:18:54 -0700178 * On return, signatureInfo and signatureValue in the packet are set.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700179 * If default identity does not exist,
Yingdi Yu60bd7082014-03-25 18:18:54 -0700180 * a temporary identity will be created and set as default.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800181 *
182 * @param packet The packet to be signed
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800183 */
Yingdi Yu2e57a582014-02-20 23:34:43 -0800184 template<typename T>
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800185 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700186 sign(T& packet);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700187
Jeff Thompson47c93cf2013-08-09 00:38:48 -0700188 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800189 * @brief Sign packet with a particular certificate.
190 *
191 * @param packet The packet to be signed.
192 * @param certificateName The certificate name of the key to use for signing.
193 * @throws SecPublicInfo::Error if certificate does not exist.
Jeff Thompson3c73da42013-08-12 11:19:05 -0700194 */
Yingdi Yu2e57a582014-02-20 23:34:43 -0800195 template<typename T>
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700196 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700197 sign(T& packet, const Name& certificateName);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700198
Jeff Thompson29ce3102013-09-27 11:47:48 -0700199 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800200 * @brief Sign the byte array using a particular certificate.
201 *
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700202 * @param buffer The byte array to be signed.
203 * @param bufferLength the length of buffer.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800204 * @param certificateName The certificate name of the signing key.
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700205 * @return The Signature.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800206 * @throws SecPublicInfo::Error if certificate does not exist.
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700207 */
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800208 Signature
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700209 sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName);
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700210
211 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800212 * @brief Sign packet using the default certificate of a particular identity.
213 *
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700214 * If there is no default certificate of that identity, this method will create a self-signed
215 * certificate.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800216 *
217 * @param packet The packet to be signed.
218 * @param identityName The signing identity name.
Jeff Thompson29ce3102013-09-27 11:47:48 -0700219 */
Yingdi Yu2e57a582014-02-20 23:34:43 -0800220 template<typename T>
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700221 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700222 signByIdentity(T& packet, const Name& identityName);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700223
Jeff Thompson3c73da42013-08-12 11:19:05 -0700224 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800225 * @brief Sign the byte array using the default certificate of a particular identity.
226 *
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700227 * @param buffer The byte array to be signed.
228 * @param bufferLength the length of buffer.
229 * @param identityName The identity name.
230 * @return The Signature.
231 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700232 Signature
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700233 signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName);
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700234
235 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700236 * @brief Set Sha256 weak signature for @param data
Yingdi Yu21157162014-02-28 13:02:34 -0800237 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700238 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700239 signWithSha256(Data& data);
Yingdi Yu21157162014-02-28 13:02:34 -0800240
241 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800242 * @brief Generate a self-signed certificate for a public key.
243 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700244 * @param keyName The name of the public key
245 * @return The generated certificate, shared_ptr<IdentityCertificate>() if selfSign fails
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800246 */
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800247 shared_ptr<IdentityCertificate>
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700248 selfSign(const Name& keyName);
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800249
250 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800251 * @brief Self-sign the supplied identity certificate.
252 *
253 * @param cert The supplied cert.
254 * @throws SecTpm::Error if the private key does not exist.
Jeff Thompson8efe5ad2013-08-20 17:36:38 -0700255 */
Jeff Thompson2ce8f492013-09-17 18:01:25 -0700256 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700257 selfSign(IdentityCertificate& cert);
Yingdi Yu31b4af22014-01-14 14:13:00 -0800258
Yingdi Yu2e57a582014-02-20 23:34:43 -0800259 /**
260 * @brief delete a certificate.
261 *
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700262 * If the certificate to be deleted is current default system default,
Yingdi Yu2e57a582014-02-20 23:34:43 -0800263 * the method will not delete the certificate and return immediately.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700264 *
Yingdi Yu2e57a582014-02-20 23:34:43 -0800265 * @param certificateName The certificate to be deleted.
266 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700267 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700268 deleteCertificate(const Name& certificateName);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800269
Yingdi Yu2e57a582014-02-20 23:34:43 -0800270 /**
271 * @brief delete a key.
272 *
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700273 * If the key to be deleted is current default system default,
Yingdi Yu2e57a582014-02-20 23:34:43 -0800274 * the method will not delete the key and return immediately.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700275 *
Yingdi Yu2e57a582014-02-20 23:34:43 -0800276 * @param keyName The key to be deleted.
277 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700278 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700279 deleteKey(const Name& keyName);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800280
Yingdi Yu2e57a582014-02-20 23:34:43 -0800281 /**
282 * @brief delete an identity.
283 *
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700284 * If the identity to be deleted is current default system default,
Yingdi Yu2e57a582014-02-20 23:34:43 -0800285 * the method will not delete the identity and return immediately.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700286 *
Yingdi Yu2e57a582014-02-20 23:34:43 -0800287 * @param identity The identity to be deleted.
288 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700289 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700290 deleteIdentity(const Name& identity);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800291
Yingdi Yu2e57a582014-02-20 23:34:43 -0800292 /**
293 * @brief export an identity.
294 *
295 * @param identity The identity to export.
296 * @param passwordStr The password to secure the private key.
Yingdi Yu64c3fb42014-02-26 17:30:04 -0800297 * @return The encoded export data.
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700298 * @throws SecPublicInfo::Error if anything goes wrong in exporting.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800299 */
Yingdi Yu64c3fb42014-02-26 17:30:04 -0800300 shared_ptr<SecuredBag>
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700301 exportIdentity(const Name& identity, const std::string& passwordStr);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800302
Yingdi Yu2e57a582014-02-20 23:34:43 -0800303 /**
304 * @brief import an identity.
305 *
Yingdi Yu64c3fb42014-02-26 17:30:04 -0800306 * @param securedBag The encoded import data.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800307 * @param passwordStr The password to secure the private key.
308 */
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800309 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700310 importIdentity(const SecuredBag& securedBag, const std::string& passwordStr);
311
312 SecPublicInfo&
313 getPib()
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800314 {
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700315 return *m_pib;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800316 }
317
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700318 const SecPublicInfo&
319 getPib() const
320 {
321 return *m_pib;
322 }
323
324 SecTpm&
325 getTpm()
326 {
327 return *m_tpm;
328 }
329
330 const SecTpm&
331 getTpm() const
332 {
333 return *m_tpm;
334 }
335
336 /*******************************
337 * Wrapper of SecPublicInfo *
338 *******************************/
339 bool
340 doesIdentityExist(const Name& identityName) const
341 {
342 return m_pib->doesIdentityExist(identityName);
343 }
344
345 void
346 addIdentity(const Name& identityName)
347 {
348 return m_pib->addIdentity(identityName);
349 }
350
351 bool
352 doesPublicKeyExist(const Name& keyName) const
353 {
354 return m_pib->doesPublicKeyExist(keyName);
355 }
356
357 void
358 addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer)
359 {
360 return m_pib->addPublicKey(keyName, keyType, publicKeyDer);
361 }
362
Yingdi Yu7036ce22014-06-19 18:53:37 -0700363 void
364 addKey(const Name& keyName, const PublicKey& publicKeyDer)
365 {
366 return m_pib->addKey(keyName, publicKeyDer);
367 }
368
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700369 shared_ptr<PublicKey>
370 getPublicKey(const Name& keyName) const
371 {
372 return m_pib->getPublicKey(keyName);
373 }
374
375 bool
376 doesCertificateExist(const Name& certificateName) const
377 {
378 return m_pib->doesCertificateExist(certificateName);
379 }
380
381 void
382 addCertificate(const IdentityCertificate& certificate)
383 {
384 return m_pib->addCertificate(certificate);
385 }
386
387 shared_ptr<IdentityCertificate>
388 getCertificate(const Name& certificateName) const
389 {
390 return m_pib->getCertificate(certificateName);
391 }
392
393 Name
394 getDefaultIdentity() const
395 {
396 return m_pib->getDefaultIdentity();
397 }
398
399 Name
400 getDefaultKeyNameForIdentity(const Name& identityName) const
401 {
402 return m_pib->getDefaultKeyNameForIdentity(identityName);
403 }
404
405 Name
406 getDefaultCertificateNameForKey(const Name& keyName) const
407 {
408 return m_pib->getDefaultCertificateNameForKey(keyName);
409 }
410
411 void
412 getAllIdentities(std::vector<Name>& nameList, bool isDefault) const
413 {
414 return m_pib->getAllIdentities(nameList, isDefault);
415 }
416
417 void
418 getAllKeyNames(std::vector<Name>& nameList, bool isDefault) const
419 {
420 return m_pib->getAllKeyNames(nameList, isDefault);
421 }
422
423 void
424 getAllKeyNamesOfIdentity(const Name& identity, std::vector<Name>& nameList, bool isDefault) const
425 {
426 return m_pib->getAllKeyNamesOfIdentity(identity, nameList, isDefault);
427 }
428
429 void
430 getAllCertificateNames(std::vector<Name>& nameList, bool isDefault) const
431 {
432 return m_pib->getAllCertificateNames(nameList, isDefault);
433 }
434
435 void
436 getAllCertificateNamesOfKey(const Name& keyName,
437 std::vector<Name>& nameList,
438 bool isDefault) const
439 {
440 return m_pib->getAllCertificateNamesOfKey(keyName, nameList, isDefault);
441 }
442
443 void
444 deleteCertificateInfo(const Name& certificateName)
445 {
446 return m_pib->deleteCertificateInfo(certificateName);
447 }
448
449 void
450 deletePublicKeyInfo(const Name& keyName)
451 {
452 return m_pib->deletePublicKeyInfo(keyName);
453 }
454
455 void
456 deleteIdentityInfo(const Name& identity)
457 {
458 return m_pib->deleteIdentityInfo(identity);
459 }
460
461 void
462 setDefaultIdentity(const Name& identityName)
463 {
464 return m_pib->setDefaultIdentity(identityName);
465 }
466
467 void
468 setDefaultKeyNameForIdentity(const Name& keyName)
469 {
470 return m_pib->setDefaultKeyNameForIdentity(keyName);
471 }
472
473 void
474 setDefaultCertificateNameForKey(const Name& certificateName)
475 {
476 return m_pib->setDefaultCertificateNameForKey(certificateName);
477 }
478
479 Name
480 getNewKeyName(const Name& identityName, bool useKsk)
481 {
482 return m_pib->getNewKeyName(identityName, useKsk);
483 }
484
485 Name
486 getDefaultCertificateNameForIdentity(const Name& identityName) const
487 {
488 return m_pib->getDefaultCertificateNameForIdentity(identityName);
489 }
490
491 Name
492 getDefaultCertificateName() const
493 {
494 return m_pib->getDefaultCertificateName();
495 }
496
497 void
498 addCertificateAsKeyDefault(const IdentityCertificate& certificate)
499 {
500 return m_pib->addCertificateAsKeyDefault(certificate);
501 }
502
503 void
504 addCertificateAsIdentityDefault(const IdentityCertificate& certificate)
505 {
506 return m_pib->addCertificateAsIdentityDefault(certificate);
507 }
508
509 void
510 addCertificateAsSystemDefault(const IdentityCertificate& certificate)
511 {
512 return m_pib->addCertificateAsSystemDefault(certificate);
513 }
514
515 shared_ptr<IdentityCertificate>
516 getDefaultCertificate() const
517 {
518 return m_pib->defaultCertificate();
519 }
520
521 void
522 refreshDefaultCertificate()
523 {
524 return m_pib->refreshDefaultCertificate();
525 }
526
527 /*******************************
528 * Wrapper of SecTpm *
529 *******************************/
530
531 void
532 setTpmPassword(const uint8_t* password, size_t passwordLength)
533 {
534 return m_tpm->setTpmPassword(password, passwordLength);
535 }
536
537 void
538 resetTpmPassword()
539 {
540 return m_tpm->resetTpmPassword();
541 }
542
543 void
544 setInTerminal(bool inTerminal)
545 {
546 return m_tpm->setInTerminal(inTerminal);
547 }
548
549 bool
550 getInTerminal() const
551 {
552 return m_tpm->getInTerminal();
553 }
554
555 bool
556 isLocked() const
557 {
558 return m_tpm->isLocked();
559 }
560
561 bool
562 unlockTpm(const char* password, size_t passwordLength, bool usePassword)
563 {
564 return m_tpm->unlockTpm(password, passwordLength, usePassword);
565 }
566
567 void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700568 generateKeyPairInTpm(const Name& keyName, const KeyParams& params)
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700569 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700570 return m_tpm->generateKeyPairInTpm(keyName, params);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700571 }
572
573 void
574 deleteKeyPairInTpm(const Name& keyName)
575 {
576 return m_tpm->deleteKeyPairInTpm(keyName);
577 }
578
579 shared_ptr<PublicKey>
580 getPublicKeyFromTpm(const Name& keyName) const
581 {
582 return m_tpm->getPublicKeyFromTpm(keyName);
583 }
584
585 Block
586 signInTpm(const uint8_t* data, size_t dataLength,
587 const Name& keyName,
588 DigestAlgorithm digestAlgorithm)
589 {
590 return m_tpm->signInTpm(data, dataLength, keyName, digestAlgorithm);
591 }
592
593 ConstBufferPtr
594 decryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric)
595 {
596 return m_tpm->decryptInTpm(data, dataLength, keyName, isSymmetric);
597 }
598
599 ConstBufferPtr
600 encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric)
601 {
602 return m_tpm->encryptInTpm(data, dataLength, keyName, isSymmetric);
603 }
604
605 void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700606 generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params)
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700607 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700608 return m_tpm->generateSymmetricKeyInTpm(keyName, params);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700609 }
610
611 bool
612 doesKeyExistInTpm(const Name& keyName, KeyClass keyClass) const
613 {
614 return m_tpm->doesKeyExistInTpm(keyName, keyClass);
615 }
616
617 bool
618 generateRandomBlock(uint8_t* res, size_t size) const
619 {
620 return m_tpm->generateRandomBlock(res, size);
621 }
622
623 void
624 addAppToAcl(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl)
625 {
626 return m_tpm->addAppToAcl(keyName, keyClass, appPath, acl);
627 }
628
629 ConstBufferPtr
630 exportPrivateKeyPkcs5FromTpm(const Name& keyName, const std::string& password)
631 {
632 return m_tpm->exportPrivateKeyPkcs5FromTpm(keyName, password);
633 }
634
635 bool
636 importPrivateKeyPkcs5IntoTpm(const Name& keyName,
637 const uint8_t* buf, size_t size,
638 const std::string& password)
639 {
640 return m_tpm->importPrivateKeyPkcs5IntoTpm(keyName, buf, size, password);
641 }
Jeff Thompson8efe5ad2013-08-20 17:36:38 -0700642
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800643private:
Yingdi Yu2e57a582014-02-20 23:34:43 -0800644 /**
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700645 * @brief Determine signature type
646 *
647 * An empty pointer will be returned if there is no valid signature.
648 */
649 shared_ptr<SignatureWithPublicKey>
650 determineSignatureWithPublicKey(KeyType keyType,
651 DigestAlgorithm digestAlgorithm = DIGEST_ALGORITHM_SHA256);
652
653 /**
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700654 * @brief Set default certificate if it is not initialized
655 */
656 void
657 setDefaultCertificateInternal();
658
659 /**
660 * @brief Sign a packet using a pariticular certificate.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800661 *
662 * @param packet The packet to be signed.
663 * @param certificate The signing certificate.
664 */
665 template<typename T>
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800666 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700667 sign(T& packet, const IdentityCertificate& certificate);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800668
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800669 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800670 * @brief Generate a key pair for the specified identity.
671 *
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800672 * @param identityName The name of the specified identity.
673 * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
Yingdi Yu7036ce22014-06-19 18:53:37 -0700674 * @param params The parameter of the key.
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800675 * @return The name of the generated key.
676 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700677 Name
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700678 generateKeyPair(const Name& identityName, bool isKsk = false,
Yingdi Yu7036ce22014-06-19 18:53:37 -0700679 const KeyParams& params = DEFAULT_KEY_PARAMS);
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800680
Yingdi Yu8726f652014-01-23 10:35:12 -0800681 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800682 * @brief Sign the data using a particular key.
683 *
684 * @param data Reference to the data packet.
685 * @param signature Signature to be added.
Yingdi Yu8726f652014-01-23 10:35:12 -0800686 * @param keyName The name of the signing key.
687 * @param digestAlgorithm the digest algorithm.
688 * @throws Tpm::Error
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700689 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700690 void
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700691 signPacketWrapper(Data& data, const Signature& signature,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700692 const Name& keyName, DigestAlgorithm digestAlgorithm);
Yingdi Yu8726f652014-01-23 10:35:12 -0800693
Yingdi Yu2e57a582014-02-20 23:34:43 -0800694 /**
695 * @brief Sign the interest using a particular key.
696 *
697 * @param interest Reference to the interest packet.
698 * @param signature Signature to be added.
699 * @param keyName The name of the signing key.
700 * @param digestAlgorithm the digest algorithm.
701 * @throws Tpm::Error
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700702 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700703 void
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700704 signPacketWrapper(Interest& interest, const Signature& signature,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700705 const Name& keyName, DigestAlgorithm digestAlgorithm);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800706
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700707
708private:
709 SecPublicInfo* m_pib;
710 SecTpm* m_tpm;
Yingdi Yu0f5fb692014-06-10 12:07:28 -0700711 time::milliseconds m_lastTimestamp;
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700712};
713
714template<class T>
715inline
716KeyChain::KeyChain(T)
717 : m_pib(new typename T::Pib)
718 , m_tpm(new typename T::Tpm)
Yingdi Yu0f5fb692014-06-10 12:07:28 -0700719 , m_lastTimestamp(time::toUnixTimestamp(time::system_clock::now()))
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700720{
721}
722
723inline Name
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700724KeyChain::generateRsaKeyPair(const Name& identityName, bool isKsk, uint32_t keySize)
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700725{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700726 RsaKeyParams params(keySize);
727 return generateKeyPair(identityName, isKsk, params);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700728}
729
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700730inline Name
731KeyChain::generateEcdsaKeyPair(const Name& identityName, bool isKsk, uint32_t keySize)
732{
733 EcdsaKeyParams params(keySize);
734 return generateKeyPair(identityName, isKsk, params);
735}
736
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700737template<typename T>
738void
739KeyChain::sign(T& packet)
740{
741 if (!static_cast<bool>(m_pib->defaultCertificate()))
742 setDefaultCertificateInternal();
743
744 sign(packet, *m_pib->defaultCertificate());
745}
746
747template<typename T>
748void
749KeyChain::sign(T& packet, const Name& certificateName)
750{
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700751 shared_ptr<IdentityCertificate> certificate = m_pib->getCertificate(certificateName);
752 sign(packet, *certificate);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700753}
754
755template<typename T>
756void
757KeyChain::signByIdentity(T& packet, const Name& identityName)
758{
759 Name signingCertificateName;
760 try
761 {
762 signingCertificateName = m_pib->getDefaultCertificateNameForIdentity(identityName);
763 }
764 catch (SecPublicInfo::Error& e)
765 {
766 signingCertificateName = createIdentity(identityName);
767 // Ideally, no exception will be thrown out, unless something goes wrong in the TPM, which
768 // is a fatal error.
769 }
770
771 // We either get or create the signing certificate, sign packet! (no exception unless fatal
772 // error in TPM)
773 sign(packet, signingCertificateName);
774}
775
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700776template<typename T>
777void
778KeyChain::sign(T& packet, const IdentityCertificate& certificate)
779{
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700780 switch (certificate.getPublicKeyInfo().getKeyType())
781 {
782 case KEY_TYPE_RSA:
783 {
784 // For temporary usage, we support SHA256 only, but will support more.
785 SignatureSha256WithRsa signature;
786 // implicit conversion should take care
787 signature.setKeyLocator(certificate.getName().getPrefix(-1));
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700788
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700789 signPacketWrapper(packet, signature,
790 certificate.getPublicKeyName(),
791 DIGEST_ALGORITHM_SHA256);
792 return;
793 }
794 case KEY_TYPE_ECDSA:
795 {
796 // For temporary usage, we support SHA256 only, but will support more.
797 SignatureSha256WithEcdsa signature;
798 // implicit conversion should take care
799 signature.setKeyLocator(certificate.getName().getPrefix(-1));
800
801 signPacketWrapper(packet, signature,
802 certificate.getPublicKeyName(),
803 DIGEST_ALGORITHM_SHA256);
804 return;
805 }
806 default:
807 throw SecPublicInfo::Error("unknown key type!");
808 }
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700809}
810
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700811}
Jeff Thompson47c93cf2013-08-09 00:38:48 -0700812
Alexander Afanasyev766cea72014-04-24 19:16:42 -0700813#endif // NDN_SECURITY_KEY_CHAIN_HPP