blob: 5d348c44c1a5df1a660ca221111fbe553657387c [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
Yingdi Yu5ec0ee32014-06-24 16:26:09 -070078 ~KeyChain();
Yingdi Yuf56c68f2014-04-24 21:50:13 -070079
Yingdi Yube4150e2014-02-18 13:02:46 -080080 /**
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070081 * @brief Create an identity by creating a pair of Key-Signing-Key (KSK) for this identity and a
82 * self-signed certificate of the KSK.
Yingdi Yube4150e2014-02-18 13:02:46 -080083 *
Yingdi Yu2abd73f2014-01-08 23:34:11 -080084 * @param identityName The name of the identity.
Yingdi Yu7036ce22014-06-19 18:53:37 -070085 * @param params The key parameter if a key needs to be generated for the identity.
Yingdi Yu28fd32f2014-01-28 19:03:03 -080086 * @return The name of the default certificate of the identity.
Yingdi Yu2abd73f2014-01-08 23:34:11 -080087 */
Yingdi Yu7036ce22014-06-19 18:53:37 -070088 Name
89 createIdentity(const Name& identityName, const KeyParams& params = DEFAULT_KEY_PARAMS);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -070090
Yingdi Yu2abd73f2014-01-08 23:34:11 -080091 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -080092 * @brief Generate a pair of RSA keys for the specified identity.
93 *
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
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700100 generateRsaKeyPair(const Name& identityName, bool isKsk = false, uint32_t keySize = 2048);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700101
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700102 inline Name
103 generateEcdsaKeyPair(const Name& identityName, bool isKsk = false, uint32_t keySize = 256);
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800104 /**
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700105 * @brief Generate a pair of RSA keys for the specified identity and set it as default key for
106 * the identity.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800107 *
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800108 * @param identityName The name of the identity.
109 * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
110 * @param keySize The size of the key.
111 * @return The generated key name.
112 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700113 Name
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700114 generateRsaKeyPairAsDefault(const Name& identityName, bool isKsk = false,
115 uint32_t keySize = 2048);
116
117 Name
118 generateEcdsaKeyPairAsDefault(const Name& identityName, bool isKsk, uint32_t keySize = 256);
Jeff Thompson79a2d5d2013-09-27 14:32:23 -0700119
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800120 /**
Yingdi Yuc55680b2014-02-26 12:31:35 -0800121 * @brief prepare an unsigned identity certificate
122 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700123 * @param keyName Key name, e.g., `/<identity_name>/ksk-123456`.
Yingdi Yuc55680b2014-02-26 12:31:35 -0800124 * @param signingIdentity The signing identity.
125 * @param notBefore Refer to IdentityCertificate.
126 * @param notAfter Refer to IdentityCertificate.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700127 * @param subjectDescription Refer to IdentityCertificate.
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700128 * @param certPrefix Prefix before `KEY` component. By default, KeyChain will infer the
129 * certificate name according to the relation between the signingIdentity and
130 * the subject identity. If signingIdentity is a prefix of the subject identity,
131 * `KEY` will be inserted after the signingIdentity, otherwise `KEY` is inserted
132 * after subject identity (i.e., before `ksk-....`).
Yingdi Yuc55680b2014-02-26 12:31:35 -0800133 * @return IdentityCertificate.
134 */
135 shared_ptr<IdentityCertificate>
136 prepareUnsignedIdentityCertificate(const Name& keyName,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700137 const Name& signingIdentity,
138 const time::system_clock::TimePoint& notBefore,
139 const time::system_clock::TimePoint& notAfter,
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700140 const std::vector<CertificateSubjectDescription>& subjectDescription,
141 const Name& certPrefix = DEFAULT_PREFIX);
142
143 /**
144 * @brief prepare an unsigned identity certificate
145 *
146 * @param keyName Key name, e.g., `/<identity_name>/ksk-123456`.
147 * @param publicKey Public key to sign.
148 * @param signingIdentity The signing identity.
149 * @param notBefore Refer to IdentityCertificate.
150 * @param notAfter Refer to IdentityCertificate.
151 * @param subjectDescription Refer to IdentityCertificate.
152 * @param certPrefix Prefix before `KEY` component. By default, KeyChain will infer the
153 * certificate name according to the relation between the signingIdentity and
154 * the subject identity. If signingIdentity is a prefix of the subject identity,
155 * `KEY` will be inserted after the signingIdentity, otherwise `KEY` is inserted
156 * after subject identity (i.e., before `ksk-....`).
157 * @return IdentityCertificate.
158 */
159 shared_ptr<IdentityCertificate>
160 prepareUnsignedIdentityCertificate(const Name& keyName,
161 const PublicKey& publicKey,
162 const Name& signingIdentity,
163 const time::system_clock::TimePoint& notBefore,
164 const time::system_clock::TimePoint& notAfter,
165 const std::vector<CertificateSubjectDescription>& subjectDescription,
166 const Name& certPrefix = DEFAULT_PREFIX);
Yingdi Yuc55680b2014-02-26 12:31:35 -0800167
168 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800169 * @brief Sign packet with default identity
170 *
Yingdi Yu60bd7082014-03-25 18:18:54 -0700171 * On return, signatureInfo and signatureValue in the packet are set.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700172 * If default identity does not exist,
Yingdi Yu60bd7082014-03-25 18:18:54 -0700173 * a temporary identity will be created and set as default.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800174 *
175 * @param packet The packet to be signed
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800176 */
Yingdi Yu2e57a582014-02-20 23:34:43 -0800177 template<typename T>
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800178 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700179 sign(T& packet);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700180
Jeff Thompson47c93cf2013-08-09 00:38:48 -0700181 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800182 * @brief Sign packet with a particular certificate.
183 *
184 * @param packet The packet to be signed.
185 * @param certificateName The certificate name of the key to use for signing.
186 * @throws SecPublicInfo::Error if certificate does not exist.
Jeff Thompson3c73da42013-08-12 11:19:05 -0700187 */
Yingdi Yu2e57a582014-02-20 23:34:43 -0800188 template<typename T>
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700189 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700190 sign(T& packet, const Name& certificateName);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700191
Jeff Thompson29ce3102013-09-27 11:47:48 -0700192 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800193 * @brief Sign the byte array using a particular certificate.
194 *
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700195 * @param buffer The byte array to be signed.
196 * @param bufferLength the length of buffer.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800197 * @param certificateName The certificate name of the signing key.
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700198 * @return The Signature.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800199 * @throws SecPublicInfo::Error if certificate does not exist.
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700200 */
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800201 Signature
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700202 sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName);
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700203
204 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800205 * @brief Sign packet using the default certificate of a particular identity.
206 *
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700207 * If there is no default certificate of that identity, this method will create a self-signed
208 * certificate.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800209 *
210 * @param packet The packet to be signed.
211 * @param identityName The signing identity name.
Jeff Thompson29ce3102013-09-27 11:47:48 -0700212 */
Yingdi Yu2e57a582014-02-20 23:34:43 -0800213 template<typename T>
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700214 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700215 signByIdentity(T& packet, const Name& identityName);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700216
Jeff Thompson3c73da42013-08-12 11:19:05 -0700217 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800218 * @brief Sign the byte array using the default certificate of a particular identity.
219 *
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700220 * @param buffer The byte array to be signed.
221 * @param bufferLength the length of buffer.
222 * @param identityName The identity name.
223 * @return The Signature.
224 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700225 Signature
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700226 signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName);
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700227
228 /**
Yingdi Yu6ab67812014-11-27 15:00:34 -0800229 * @brief Set Sha256 weak signature for @p data
Yingdi Yu21157162014-02-28 13:02:34 -0800230 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700231 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700232 signWithSha256(Data& data);
Yingdi Yu21157162014-02-28 13:02:34 -0800233
234 /**
Yingdi Yu6ab67812014-11-27 15:00:34 -0800235 * @brief Set Sha256 weak signature for @p interest
236 */
237 void
238 signWithSha256(Interest& interest);
239
240 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800241 * @brief Generate a self-signed certificate for a public key.
242 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700243 * @param keyName The name of the public key
244 * @return The generated certificate, shared_ptr<IdentityCertificate>() if selfSign fails
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800245 */
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800246 shared_ptr<IdentityCertificate>
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700247 selfSign(const Name& keyName);
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800248
249 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800250 * @brief Self-sign the supplied identity certificate.
251 *
252 * @param cert The supplied cert.
253 * @throws SecTpm::Error if the private key does not exist.
Jeff Thompson8efe5ad2013-08-20 17:36:38 -0700254 */
Jeff Thompson2ce8f492013-09-17 18:01:25 -0700255 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700256 selfSign(IdentityCertificate& cert);
Yingdi Yu31b4af22014-01-14 14:13:00 -0800257
Yingdi Yu2e57a582014-02-20 23:34:43 -0800258 /**
259 * @brief delete a certificate.
260 *
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700261 * If the certificate to be deleted is current default system default,
Yingdi Yu2e57a582014-02-20 23:34:43 -0800262 * the method will not delete the certificate and return immediately.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700263 *
Yingdi Yu2e57a582014-02-20 23:34:43 -0800264 * @param certificateName The certificate to be deleted.
265 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700266 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700267 deleteCertificate(const Name& certificateName);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800268
Yingdi Yu2e57a582014-02-20 23:34:43 -0800269 /**
270 * @brief delete a key.
271 *
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700272 * If the key to be deleted is current default system default,
Yingdi Yu2e57a582014-02-20 23:34:43 -0800273 * the method will not delete the key and return immediately.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700274 *
Yingdi Yu2e57a582014-02-20 23:34:43 -0800275 * @param keyName The key to be deleted.
276 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700277 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700278 deleteKey(const Name& keyName);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800279
Yingdi Yu2e57a582014-02-20 23:34:43 -0800280 /**
281 * @brief delete an identity.
282 *
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700283 * If the identity to be deleted is current default system default,
Yingdi Yu2e57a582014-02-20 23:34:43 -0800284 * the method will not delete the identity and return immediately.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700285 *
Yingdi Yu2e57a582014-02-20 23:34:43 -0800286 * @param identity The identity to be deleted.
287 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700288 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700289 deleteIdentity(const Name& identity);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800290
Yingdi Yu2e57a582014-02-20 23:34:43 -0800291 /**
292 * @brief export an identity.
293 *
294 * @param identity The identity to export.
295 * @param passwordStr The password to secure the private key.
Yingdi Yu64c3fb42014-02-26 17:30:04 -0800296 * @return The encoded export data.
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700297 * @throws SecPublicInfo::Error if anything goes wrong in exporting.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800298 */
Yingdi Yu64c3fb42014-02-26 17:30:04 -0800299 shared_ptr<SecuredBag>
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700300 exportIdentity(const Name& identity, const std::string& passwordStr);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800301
Yingdi Yu2e57a582014-02-20 23:34:43 -0800302 /**
303 * @brief import an identity.
304 *
Yingdi Yu64c3fb42014-02-26 17:30:04 -0800305 * @param securedBag The encoded import data.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800306 * @param passwordStr The password to secure the private key.
307 */
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800308 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700309 importIdentity(const SecuredBag& securedBag, const std::string& passwordStr);
310
311 SecPublicInfo&
312 getPib()
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800313 {
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700314 return *m_pib;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800315 }
316
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700317 const SecPublicInfo&
318 getPib() const
319 {
320 return *m_pib;
321 }
322
323 SecTpm&
324 getTpm()
325 {
326 return *m_tpm;
327 }
328
329 const SecTpm&
330 getTpm() const
331 {
332 return *m_tpm;
333 }
334
335 /*******************************
336 * Wrapper of SecPublicInfo *
337 *******************************/
338 bool
339 doesIdentityExist(const Name& identityName) const
340 {
341 return m_pib->doesIdentityExist(identityName);
342 }
343
344 void
345 addIdentity(const Name& identityName)
346 {
347 return m_pib->addIdentity(identityName);
348 }
349
350 bool
351 doesPublicKeyExist(const Name& keyName) const
352 {
353 return m_pib->doesPublicKeyExist(keyName);
354 }
355
356 void
357 addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer)
358 {
359 return m_pib->addPublicKey(keyName, keyType, publicKeyDer);
360 }
361
Yingdi Yu7036ce22014-06-19 18:53:37 -0700362 void
363 addKey(const Name& keyName, const PublicKey& publicKeyDer)
364 {
365 return m_pib->addKey(keyName, publicKeyDer);
366 }
367
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700368 shared_ptr<PublicKey>
369 getPublicKey(const Name& keyName) const
370 {
371 return m_pib->getPublicKey(keyName);
372 }
373
374 bool
375 doesCertificateExist(const Name& certificateName) const
376 {
377 return m_pib->doesCertificateExist(certificateName);
378 }
379
380 void
381 addCertificate(const IdentityCertificate& certificate)
382 {
383 return m_pib->addCertificate(certificate);
384 }
385
386 shared_ptr<IdentityCertificate>
387 getCertificate(const Name& certificateName) const
388 {
389 return m_pib->getCertificate(certificateName);
390 }
391
392 Name
393 getDefaultIdentity() const
394 {
395 return m_pib->getDefaultIdentity();
396 }
397
398 Name
399 getDefaultKeyNameForIdentity(const Name& identityName) const
400 {
401 return m_pib->getDefaultKeyNameForIdentity(identityName);
402 }
403
404 Name
405 getDefaultCertificateNameForKey(const Name& keyName) const
406 {
407 return m_pib->getDefaultCertificateNameForKey(keyName);
408 }
409
410 void
411 getAllIdentities(std::vector<Name>& nameList, bool isDefault) const
412 {
413 return m_pib->getAllIdentities(nameList, isDefault);
414 }
415
416 void
417 getAllKeyNames(std::vector<Name>& nameList, bool isDefault) const
418 {
419 return m_pib->getAllKeyNames(nameList, isDefault);
420 }
421
422 void
423 getAllKeyNamesOfIdentity(const Name& identity, std::vector<Name>& nameList, bool isDefault) const
424 {
425 return m_pib->getAllKeyNamesOfIdentity(identity, nameList, isDefault);
426 }
427
428 void
429 getAllCertificateNames(std::vector<Name>& nameList, bool isDefault) const
430 {
431 return m_pib->getAllCertificateNames(nameList, isDefault);
432 }
433
434 void
435 getAllCertificateNamesOfKey(const Name& keyName,
436 std::vector<Name>& nameList,
437 bool isDefault) const
438 {
439 return m_pib->getAllCertificateNamesOfKey(keyName, nameList, isDefault);
440 }
441
442 void
443 deleteCertificateInfo(const Name& certificateName)
444 {
445 return m_pib->deleteCertificateInfo(certificateName);
446 }
447
448 void
449 deletePublicKeyInfo(const Name& keyName)
450 {
451 return m_pib->deletePublicKeyInfo(keyName);
452 }
453
454 void
455 deleteIdentityInfo(const Name& identity)
456 {
457 return m_pib->deleteIdentityInfo(identity);
458 }
459
460 void
461 setDefaultIdentity(const Name& identityName)
462 {
463 return m_pib->setDefaultIdentity(identityName);
464 }
465
466 void
467 setDefaultKeyNameForIdentity(const Name& keyName)
468 {
469 return m_pib->setDefaultKeyNameForIdentity(keyName);
470 }
471
472 void
473 setDefaultCertificateNameForKey(const Name& certificateName)
474 {
475 return m_pib->setDefaultCertificateNameForKey(certificateName);
476 }
477
478 Name
479 getNewKeyName(const Name& identityName, bool useKsk)
480 {
481 return m_pib->getNewKeyName(identityName, useKsk);
482 }
483
484 Name
485 getDefaultCertificateNameForIdentity(const Name& identityName) const
486 {
487 return m_pib->getDefaultCertificateNameForIdentity(identityName);
488 }
489
490 Name
491 getDefaultCertificateName() const
492 {
493 return m_pib->getDefaultCertificateName();
494 }
495
496 void
497 addCertificateAsKeyDefault(const IdentityCertificate& certificate)
498 {
499 return m_pib->addCertificateAsKeyDefault(certificate);
500 }
501
502 void
503 addCertificateAsIdentityDefault(const IdentityCertificate& certificate)
504 {
505 return m_pib->addCertificateAsIdentityDefault(certificate);
506 }
507
508 void
509 addCertificateAsSystemDefault(const IdentityCertificate& certificate)
510 {
511 return m_pib->addCertificateAsSystemDefault(certificate);
512 }
513
514 shared_ptr<IdentityCertificate>
515 getDefaultCertificate() const
516 {
Alexander Afanasyevaab79662014-07-07 17:35:34 -0700517 if (!static_cast<bool>(m_pib->getDefaultCertificate()))
518 const_cast<KeyChain*>(this)->setDefaultCertificateInternal();
519
520 return m_pib->getDefaultCertificate();
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700521 }
522
523 void
524 refreshDefaultCertificate()
525 {
526 return m_pib->refreshDefaultCertificate();
527 }
528
529 /*******************************
530 * Wrapper of SecTpm *
531 *******************************/
532
533 void
534 setTpmPassword(const uint8_t* password, size_t passwordLength)
535 {
536 return m_tpm->setTpmPassword(password, passwordLength);
537 }
538
539 void
540 resetTpmPassword()
541 {
542 return m_tpm->resetTpmPassword();
543 }
544
545 void
546 setInTerminal(bool inTerminal)
547 {
548 return m_tpm->setInTerminal(inTerminal);
549 }
550
551 bool
552 getInTerminal() const
553 {
554 return m_tpm->getInTerminal();
555 }
556
557 bool
558 isLocked() const
559 {
560 return m_tpm->isLocked();
561 }
562
563 bool
564 unlockTpm(const char* password, size_t passwordLength, bool usePassword)
565 {
566 return m_tpm->unlockTpm(password, passwordLength, usePassword);
567 }
568
569 void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700570 generateKeyPairInTpm(const Name& keyName, const KeyParams& params)
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700571 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700572 return m_tpm->generateKeyPairInTpm(keyName, params);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700573 }
574
575 void
576 deleteKeyPairInTpm(const Name& keyName)
577 {
578 return m_tpm->deleteKeyPairInTpm(keyName);
579 }
580
581 shared_ptr<PublicKey>
582 getPublicKeyFromTpm(const Name& keyName) const
583 {
584 return m_tpm->getPublicKeyFromTpm(keyName);
585 }
586
587 Block
588 signInTpm(const uint8_t* data, size_t dataLength,
589 const Name& keyName,
590 DigestAlgorithm digestAlgorithm)
591 {
592 return m_tpm->signInTpm(data, dataLength, keyName, digestAlgorithm);
593 }
594
595 ConstBufferPtr
596 decryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric)
597 {
598 return m_tpm->decryptInTpm(data, dataLength, keyName, isSymmetric);
599 }
600
601 ConstBufferPtr
602 encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric)
603 {
604 return m_tpm->encryptInTpm(data, dataLength, keyName, isSymmetric);
605 }
606
607 void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700608 generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params)
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700609 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700610 return m_tpm->generateSymmetricKeyInTpm(keyName, params);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700611 }
612
613 bool
614 doesKeyExistInTpm(const Name& keyName, KeyClass keyClass) const
615 {
616 return m_tpm->doesKeyExistInTpm(keyName, keyClass);
617 }
618
619 bool
620 generateRandomBlock(uint8_t* res, size_t size) const
621 {
622 return m_tpm->generateRandomBlock(res, size);
623 }
624
625 void
626 addAppToAcl(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl)
627 {
628 return m_tpm->addAppToAcl(keyName, keyClass, appPath, acl);
629 }
630
631 ConstBufferPtr
632 exportPrivateKeyPkcs5FromTpm(const Name& keyName, const std::string& password)
633 {
634 return m_tpm->exportPrivateKeyPkcs5FromTpm(keyName, password);
635 }
636
637 bool
638 importPrivateKeyPkcs5IntoTpm(const Name& keyName,
639 const uint8_t* buf, size_t size,
640 const std::string& password)
641 {
642 return m_tpm->importPrivateKeyPkcs5IntoTpm(keyName, buf, size, password);
643 }
Jeff Thompson8efe5ad2013-08-20 17:36:38 -0700644
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800645private:
Yingdi Yu2e57a582014-02-20 23:34:43 -0800646 /**
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700647 * @brief Determine signature type
648 *
649 * An empty pointer will be returned if there is no valid signature.
650 */
Yingdi Yu4a557052014-07-09 16:40:37 -0700651 shared_ptr<Signature>
652 determineSignatureWithPublicKey(const KeyLocator& keyLocator,
653 KeyType keyType,
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700654 DigestAlgorithm digestAlgorithm = DIGEST_ALGORITHM_SHA256);
655
656 /**
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700657 * @brief Set default certificate if it is not initialized
658 */
659 void
660 setDefaultCertificateInternal();
661
662 /**
663 * @brief Sign a packet using a pariticular certificate.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800664 *
665 * @param packet The packet to be signed.
666 * @param certificate The signing certificate.
667 */
668 template<typename T>
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800669 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700670 sign(T& packet, const IdentityCertificate& certificate);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800671
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800672 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800673 * @brief Generate a key pair for the specified identity.
674 *
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800675 * @param identityName The name of the specified identity.
676 * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
Yingdi Yu7036ce22014-06-19 18:53:37 -0700677 * @param params The parameter of the key.
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800678 * @return The name of the generated key.
679 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700680 Name
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700681 generateKeyPair(const Name& identityName, bool isKsk = false,
Yingdi Yu7036ce22014-06-19 18:53:37 -0700682 const KeyParams& params = DEFAULT_KEY_PARAMS);
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800683
Yingdi Yu8726f652014-01-23 10:35:12 -0800684 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800685 * @brief Sign the data using a particular key.
686 *
687 * @param data Reference to the data packet.
688 * @param signature Signature to be added.
Yingdi Yu8726f652014-01-23 10:35:12 -0800689 * @param keyName The name of the signing key.
690 * @param digestAlgorithm the digest algorithm.
691 * @throws Tpm::Error
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700692 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700693 void
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700694 signPacketWrapper(Data& data, const Signature& signature,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700695 const Name& keyName, DigestAlgorithm digestAlgorithm);
Yingdi Yu8726f652014-01-23 10:35:12 -0800696
Yingdi Yu2e57a582014-02-20 23:34:43 -0800697 /**
698 * @brief Sign the interest using a particular key.
699 *
700 * @param interest Reference to the interest packet.
701 * @param signature Signature to be added.
702 * @param keyName The name of the signing key.
703 * @param digestAlgorithm the digest algorithm.
704 * @throws Tpm::Error
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700705 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700706 void
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700707 signPacketWrapper(Interest& interest, const Signature& signature,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700708 const Name& keyName, DigestAlgorithm digestAlgorithm);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800709
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700710
711private:
712 SecPublicInfo* m_pib;
713 SecTpm* m_tpm;
Yingdi Yu0f5fb692014-06-10 12:07:28 -0700714 time::milliseconds m_lastTimestamp;
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700715};
716
717template<class T>
718inline
719KeyChain::KeyChain(T)
720 : m_pib(new typename T::Pib)
721 , m_tpm(new typename T::Tpm)
Yingdi Yu0f5fb692014-06-10 12:07:28 -0700722 , m_lastTimestamp(time::toUnixTimestamp(time::system_clock::now()))
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700723{
724}
725
726inline Name
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700727KeyChain::generateRsaKeyPair(const Name& identityName, bool isKsk, uint32_t keySize)
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700728{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700729 RsaKeyParams params(keySize);
730 return generateKeyPair(identityName, isKsk, params);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700731}
732
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700733inline Name
734KeyChain::generateEcdsaKeyPair(const Name& identityName, bool isKsk, uint32_t keySize)
735{
736 EcdsaKeyParams params(keySize);
737 return generateKeyPair(identityName, isKsk, params);
738}
739
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700740template<typename T>
741void
742KeyChain::sign(T& packet)
743{
Alexander Afanasyevaab79662014-07-07 17:35:34 -0700744 if (!static_cast<bool>(m_pib->getDefaultCertificate()))
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700745 setDefaultCertificateInternal();
746
Alexander Afanasyevaab79662014-07-07 17:35:34 -0700747 sign(packet, *m_pib->getDefaultCertificate());
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700748}
749
750template<typename T>
751void
752KeyChain::sign(T& packet, const Name& certificateName)
753{
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700754 shared_ptr<IdentityCertificate> certificate = m_pib->getCertificate(certificateName);
755 sign(packet, *certificate);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700756}
757
758template<typename T>
759void
760KeyChain::signByIdentity(T& packet, const Name& identityName)
761{
762 Name signingCertificateName;
763 try
764 {
765 signingCertificateName = m_pib->getDefaultCertificateNameForIdentity(identityName);
766 }
767 catch (SecPublicInfo::Error& e)
768 {
769 signingCertificateName = createIdentity(identityName);
770 // Ideally, no exception will be thrown out, unless something goes wrong in the TPM, which
771 // is a fatal error.
772 }
773
774 // We either get or create the signing certificate, sign packet! (no exception unless fatal
775 // error in TPM)
776 sign(packet, signingCertificateName);
777}
778
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700779template<typename T>
780void
781KeyChain::sign(T& packet, const IdentityCertificate& certificate)
782{
Yingdi Yu4a557052014-07-09 16:40:37 -0700783 KeyLocator keyLocator(certificate.getName().getPrefix(-1));
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700784
Yingdi Yu4a557052014-07-09 16:40:37 -0700785 shared_ptr<Signature> signature =
786 determineSignatureWithPublicKey(keyLocator, certificate.getPublicKeyInfo().getKeyType());
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700787
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700788 if (!static_cast<bool>(signature))
789 throw SecPublicInfo::Error("unknown key type!");
790
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700791 signPacketWrapper(packet, *signature,
792 certificate.getPublicKeyName(),
793 DIGEST_ALGORITHM_SHA256);
794
795 return;
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700796}
797
Yingdi Yu6ab67812014-11-27 15:00:34 -0800798} // namespace ndn
Jeff Thompson47c93cf2013-08-09 00:38:48 -0700799
Alexander Afanasyev766cea72014-04-24 19:16:42 -0700800#endif // NDN_SECURITY_KEY_CHAIN_HPP