blob: 28de73551bbc2aa2898949e3323c4ac6f538e6df [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 Yu41546342014-11-30 23:37:53 -080063 /**
64 * This error is thrown when the TPM locator retrieved from PIB is
65 * different from what is supplied to the KeyChain constructor.
66 */
67 class MismatchError : public Error
68 {
69 public:
70 explicit
71 MismatchError(const std::string& what)
72 : Error(what)
73 {
74 }
75 };
Yingdi Yu7036ce22014-06-19 18:53:37 -070076
Yingdi Yuf56c68f2014-04-24 21:50:13 -070077 KeyChain();
78
79 template<class KeyChainTraits>
Alexander Afanasyeva4297a62014-06-19 13:29:34 -070080 explicit
Yingdi Yuf56c68f2014-04-24 21:50:13 -070081 KeyChain(KeyChainTraits traits);
82
Yingdi Yu41546342014-11-30 23:37:53 -080083 /**
84 * @brief KeyChain constructor
85 *
86 * @sa http://redmine.named-data.net/issues/2260
87 *
88 * @param pibLocator
89 * @param tpmLocator
90 * @param allowReset if true, the PIB will be reset when the supplied tpmLocator
91 * mismatches the one in PIB
92 */
93 KeyChain(const std::string& pibLocator,
94 const std::string& tpmLocator,
95 bool allowReset = false);
Yingdi Yuf56c68f2014-04-24 21:50:13 -070096
97 virtual
Yingdi Yu5ec0ee32014-06-24 16:26:09 -070098 ~KeyChain();
Yingdi Yuf56c68f2014-04-24 21:50:13 -070099
Yingdi Yube4150e2014-02-18 13:02:46 -0800100 /**
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700101 * @brief Create an identity by creating a pair of Key-Signing-Key (KSK) for this identity and a
102 * self-signed certificate of the KSK.
Yingdi Yube4150e2014-02-18 13:02:46 -0800103 *
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800104 * @param identityName The name of the identity.
Yingdi Yu7036ce22014-06-19 18:53:37 -0700105 * @param params The key parameter if a key needs to be generated for the identity.
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800106 * @return The name of the default certificate of the identity.
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800107 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700108 Name
109 createIdentity(const Name& identityName, const KeyParams& params = DEFAULT_KEY_PARAMS);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700110
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800111 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800112 * @brief Generate a pair of RSA keys for the specified identity.
113 *
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800114 * @param identityName The name of the identity.
115 * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
116 * @param keySize The size of the key.
117 * @return The generated key name.
118 */
Yingdi Yu41546342014-11-30 23:37:53 -0800119 Name
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700120 generateRsaKeyPair(const Name& identityName, bool isKsk = false, uint32_t keySize = 2048);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700121
Yingdi Yu41546342014-11-30 23:37:53 -0800122 Name
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700123 generateEcdsaKeyPair(const Name& identityName, bool isKsk = false, uint32_t keySize = 256);
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800124 /**
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700125 * @brief Generate a pair of RSA keys for the specified identity and set it as default key for
126 * the identity.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800127 *
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800128 * @param identityName The name of the identity.
129 * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
130 * @param keySize The size of the key.
131 * @return The generated key name.
132 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700133 Name
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700134 generateRsaKeyPairAsDefault(const Name& identityName, bool isKsk = false,
135 uint32_t keySize = 2048);
136
137 Name
138 generateEcdsaKeyPairAsDefault(const Name& identityName, bool isKsk, uint32_t keySize = 256);
Jeff Thompson79a2d5d2013-09-27 14:32:23 -0700139
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800140 /**
Yingdi Yuc55680b2014-02-26 12:31:35 -0800141 * @brief prepare an unsigned identity certificate
142 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700143 * @param keyName Key name, e.g., `/<identity_name>/ksk-123456`.
Yingdi Yuc55680b2014-02-26 12:31:35 -0800144 * @param signingIdentity The signing identity.
145 * @param notBefore Refer to IdentityCertificate.
146 * @param notAfter Refer to IdentityCertificate.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700147 * @param subjectDescription Refer to IdentityCertificate.
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700148 * @param certPrefix Prefix before `KEY` component. By default, KeyChain will infer the
149 * certificate name according to the relation between the signingIdentity and
150 * the subject identity. If signingIdentity is a prefix of the subject identity,
151 * `KEY` will be inserted after the signingIdentity, otherwise `KEY` is inserted
152 * after subject identity (i.e., before `ksk-....`).
Yingdi Yuc55680b2014-02-26 12:31:35 -0800153 * @return IdentityCertificate.
154 */
155 shared_ptr<IdentityCertificate>
156 prepareUnsignedIdentityCertificate(const Name& keyName,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700157 const Name& signingIdentity,
158 const time::system_clock::TimePoint& notBefore,
159 const time::system_clock::TimePoint& notAfter,
Yingdi Yu0eb5d722014-06-10 15:06:25 -0700160 const std::vector<CertificateSubjectDescription>& subjectDescription,
161 const Name& certPrefix = DEFAULT_PREFIX);
162
163 /**
164 * @brief prepare an unsigned identity certificate
165 *
166 * @param keyName Key name, e.g., `/<identity_name>/ksk-123456`.
167 * @param publicKey Public key to sign.
168 * @param signingIdentity The signing identity.
169 * @param notBefore Refer to IdentityCertificate.
170 * @param notAfter Refer to IdentityCertificate.
171 * @param subjectDescription Refer to IdentityCertificate.
172 * @param certPrefix Prefix before `KEY` component. By default, KeyChain will infer the
173 * certificate name according to the relation between the signingIdentity and
174 * the subject identity. If signingIdentity is a prefix of the subject identity,
175 * `KEY` will be inserted after the signingIdentity, otherwise `KEY` is inserted
176 * after subject identity (i.e., before `ksk-....`).
177 * @return IdentityCertificate.
178 */
179 shared_ptr<IdentityCertificate>
180 prepareUnsignedIdentityCertificate(const Name& keyName,
181 const PublicKey& publicKey,
182 const Name& signingIdentity,
183 const time::system_clock::TimePoint& notBefore,
184 const time::system_clock::TimePoint& notAfter,
185 const std::vector<CertificateSubjectDescription>& subjectDescription,
186 const Name& certPrefix = DEFAULT_PREFIX);
Yingdi Yuc55680b2014-02-26 12:31:35 -0800187
188 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800189 * @brief Sign packet with default identity
190 *
Yingdi Yu60bd7082014-03-25 18:18:54 -0700191 * On return, signatureInfo and signatureValue in the packet are set.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700192 * If default identity does not exist,
Yingdi Yu60bd7082014-03-25 18:18:54 -0700193 * a temporary identity will be created and set as default.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800194 *
195 * @param packet The packet to be signed
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800196 */
Yingdi Yu2e57a582014-02-20 23:34:43 -0800197 template<typename T>
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800198 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700199 sign(T& packet);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700200
Jeff Thompson47c93cf2013-08-09 00:38:48 -0700201 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800202 * @brief Sign packet with a particular certificate.
203 *
204 * @param packet The packet to be signed.
205 * @param certificateName The certificate name of the key to use for signing.
206 * @throws SecPublicInfo::Error if certificate does not exist.
Jeff Thompson3c73da42013-08-12 11:19:05 -0700207 */
Yingdi Yu2e57a582014-02-20 23:34:43 -0800208 template<typename T>
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700209 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700210 sign(T& packet, const Name& certificateName);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700211
Jeff Thompson29ce3102013-09-27 11:47:48 -0700212 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800213 * @brief Sign the byte array using a particular certificate.
214 *
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700215 * @param buffer The byte array to be signed.
216 * @param bufferLength the length of buffer.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800217 * @param certificateName The certificate name of the signing key.
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700218 * @return The Signature.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800219 * @throws SecPublicInfo::Error if certificate does not exist.
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700220 */
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800221 Signature
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700222 sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName);
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700223
224 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800225 * @brief Sign packet using the default certificate of a particular identity.
226 *
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700227 * If there is no default certificate of that identity, this method will create a self-signed
228 * certificate.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800229 *
230 * @param packet The packet to be signed.
231 * @param identityName The signing identity name.
Jeff Thompson29ce3102013-09-27 11:47:48 -0700232 */
Yingdi Yu2e57a582014-02-20 23:34:43 -0800233 template<typename T>
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700234 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700235 signByIdentity(T& packet, const Name& identityName);
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700236
Jeff Thompson3c73da42013-08-12 11:19:05 -0700237 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800238 * @brief Sign the byte array using the default certificate of a particular identity.
239 *
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700240 * @param buffer The byte array to be signed.
241 * @param bufferLength the length of buffer.
242 * @param identityName The identity name.
243 * @return The Signature.
244 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700245 Signature
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700246 signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName);
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700247
248 /**
Yingdi Yu6ab67812014-11-27 15:00:34 -0800249 * @brief Set Sha256 weak signature for @p data
Yingdi Yu21157162014-02-28 13:02:34 -0800250 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700251 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700252 signWithSha256(Data& data);
Yingdi Yu21157162014-02-28 13:02:34 -0800253
254 /**
Yingdi Yu6ab67812014-11-27 15:00:34 -0800255 * @brief Set Sha256 weak signature for @p interest
256 */
257 void
258 signWithSha256(Interest& interest);
259
260 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800261 * @brief Generate a self-signed certificate for a public key.
262 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700263 * @param keyName The name of the public key
264 * @return The generated certificate, shared_ptr<IdentityCertificate>() if selfSign fails
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800265 */
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800266 shared_ptr<IdentityCertificate>
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700267 selfSign(const Name& keyName);
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800268
269 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800270 * @brief Self-sign the supplied identity certificate.
271 *
272 * @param cert The supplied cert.
273 * @throws SecTpm::Error if the private key does not exist.
Jeff Thompson8efe5ad2013-08-20 17:36:38 -0700274 */
Jeff Thompson2ce8f492013-09-17 18:01:25 -0700275 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700276 selfSign(IdentityCertificate& cert);
Yingdi Yu31b4af22014-01-14 14:13:00 -0800277
Yingdi Yu2e57a582014-02-20 23:34:43 -0800278 /**
279 * @brief delete a certificate.
280 *
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700281 * If the certificate to be deleted is current default system default,
Yingdi Yu2e57a582014-02-20 23:34:43 -0800282 * the method will not delete the certificate and return immediately.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700283 *
Yingdi Yu2e57a582014-02-20 23:34:43 -0800284 * @param certificateName The certificate to be deleted.
285 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700286 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700287 deleteCertificate(const Name& certificateName);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800288
Yingdi Yu2e57a582014-02-20 23:34:43 -0800289 /**
290 * @brief delete a key.
291 *
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700292 * If the key to be deleted is current default system default,
Yingdi Yu2e57a582014-02-20 23:34:43 -0800293 * the method will not delete the key and return immediately.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700294 *
Yingdi Yu2e57a582014-02-20 23:34:43 -0800295 * @param keyName The key to be deleted.
296 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700297 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700298 deleteKey(const Name& keyName);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800299
Yingdi Yu2e57a582014-02-20 23:34:43 -0800300 /**
301 * @brief delete an identity.
302 *
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700303 * If the identity to be deleted is current default system default,
Yingdi Yu2e57a582014-02-20 23:34:43 -0800304 * the method will not delete the identity and return immediately.
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700305 *
Yingdi Yu2e57a582014-02-20 23:34:43 -0800306 * @param identity The identity to be deleted.
307 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700308 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700309 deleteIdentity(const Name& identity);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800310
Yingdi Yu2e57a582014-02-20 23:34:43 -0800311 /**
312 * @brief export an identity.
313 *
314 * @param identity The identity to export.
315 * @param passwordStr The password to secure the private key.
Yingdi Yu64c3fb42014-02-26 17:30:04 -0800316 * @return The encoded export data.
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700317 * @throws SecPublicInfo::Error if anything goes wrong in exporting.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800318 */
Yingdi Yu64c3fb42014-02-26 17:30:04 -0800319 shared_ptr<SecuredBag>
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700320 exportIdentity(const Name& identity, const std::string& passwordStr);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800321
Yingdi Yu2e57a582014-02-20 23:34:43 -0800322 /**
323 * @brief import an identity.
324 *
Yingdi Yu64c3fb42014-02-26 17:30:04 -0800325 * @param securedBag The encoded import data.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800326 * @param passwordStr The password to secure the private key.
327 */
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800328 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700329 importIdentity(const SecuredBag& securedBag, const std::string& passwordStr);
330
331 SecPublicInfo&
332 getPib()
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800333 {
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700334 return *m_pib;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800335 }
336
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700337 const SecPublicInfo&
338 getPib() const
339 {
340 return *m_pib;
341 }
342
343 SecTpm&
344 getTpm()
345 {
346 return *m_tpm;
347 }
348
349 const SecTpm&
350 getTpm() const
351 {
352 return *m_tpm;
353 }
354
355 /*******************************
356 * Wrapper of SecPublicInfo *
357 *******************************/
358 bool
359 doesIdentityExist(const Name& identityName) const
360 {
361 return m_pib->doesIdentityExist(identityName);
362 }
363
364 void
365 addIdentity(const Name& identityName)
366 {
367 return m_pib->addIdentity(identityName);
368 }
369
370 bool
371 doesPublicKeyExist(const Name& keyName) const
372 {
373 return m_pib->doesPublicKeyExist(keyName);
374 }
375
376 void
377 addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer)
378 {
Yingdi Yu41546342014-11-30 23:37:53 -0800379 return m_pib->addKey(keyName, publicKeyDer);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700380 }
381
Yingdi Yu7036ce22014-06-19 18:53:37 -0700382 void
383 addKey(const Name& keyName, const PublicKey& publicKeyDer)
384 {
385 return m_pib->addKey(keyName, publicKeyDer);
386 }
387
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700388 shared_ptr<PublicKey>
389 getPublicKey(const Name& keyName) const
390 {
391 return m_pib->getPublicKey(keyName);
392 }
393
394 bool
395 doesCertificateExist(const Name& certificateName) const
396 {
397 return m_pib->doesCertificateExist(certificateName);
398 }
399
400 void
401 addCertificate(const IdentityCertificate& certificate)
402 {
403 return m_pib->addCertificate(certificate);
404 }
405
406 shared_ptr<IdentityCertificate>
407 getCertificate(const Name& certificateName) const
408 {
409 return m_pib->getCertificate(certificateName);
410 }
411
412 Name
413 getDefaultIdentity() const
414 {
415 return m_pib->getDefaultIdentity();
416 }
417
418 Name
419 getDefaultKeyNameForIdentity(const Name& identityName) const
420 {
421 return m_pib->getDefaultKeyNameForIdentity(identityName);
422 }
423
424 Name
425 getDefaultCertificateNameForKey(const Name& keyName) const
426 {
427 return m_pib->getDefaultCertificateNameForKey(keyName);
428 }
429
430 void
431 getAllIdentities(std::vector<Name>& nameList, bool isDefault) const
432 {
433 return m_pib->getAllIdentities(nameList, isDefault);
434 }
435
436 void
437 getAllKeyNames(std::vector<Name>& nameList, bool isDefault) const
438 {
439 return m_pib->getAllKeyNames(nameList, isDefault);
440 }
441
442 void
443 getAllKeyNamesOfIdentity(const Name& identity, std::vector<Name>& nameList, bool isDefault) const
444 {
445 return m_pib->getAllKeyNamesOfIdentity(identity, nameList, isDefault);
446 }
447
448 void
449 getAllCertificateNames(std::vector<Name>& nameList, bool isDefault) const
450 {
451 return m_pib->getAllCertificateNames(nameList, isDefault);
452 }
453
454 void
455 getAllCertificateNamesOfKey(const Name& keyName,
456 std::vector<Name>& nameList,
457 bool isDefault) const
458 {
459 return m_pib->getAllCertificateNamesOfKey(keyName, nameList, isDefault);
460 }
461
462 void
463 deleteCertificateInfo(const Name& certificateName)
464 {
465 return m_pib->deleteCertificateInfo(certificateName);
466 }
467
468 void
469 deletePublicKeyInfo(const Name& keyName)
470 {
471 return m_pib->deletePublicKeyInfo(keyName);
472 }
473
474 void
475 deleteIdentityInfo(const Name& identity)
476 {
477 return m_pib->deleteIdentityInfo(identity);
478 }
479
480 void
481 setDefaultIdentity(const Name& identityName)
482 {
483 return m_pib->setDefaultIdentity(identityName);
484 }
485
486 void
487 setDefaultKeyNameForIdentity(const Name& keyName)
488 {
489 return m_pib->setDefaultKeyNameForIdentity(keyName);
490 }
491
492 void
493 setDefaultCertificateNameForKey(const Name& certificateName)
494 {
495 return m_pib->setDefaultCertificateNameForKey(certificateName);
496 }
497
498 Name
499 getNewKeyName(const Name& identityName, bool useKsk)
500 {
501 return m_pib->getNewKeyName(identityName, useKsk);
502 }
503
504 Name
505 getDefaultCertificateNameForIdentity(const Name& identityName) const
506 {
507 return m_pib->getDefaultCertificateNameForIdentity(identityName);
508 }
509
510 Name
511 getDefaultCertificateName() const
512 {
513 return m_pib->getDefaultCertificateName();
514 }
515
516 void
517 addCertificateAsKeyDefault(const IdentityCertificate& certificate)
518 {
519 return m_pib->addCertificateAsKeyDefault(certificate);
520 }
521
522 void
523 addCertificateAsIdentityDefault(const IdentityCertificate& certificate)
524 {
525 return m_pib->addCertificateAsIdentityDefault(certificate);
526 }
527
528 void
529 addCertificateAsSystemDefault(const IdentityCertificate& certificate)
530 {
531 return m_pib->addCertificateAsSystemDefault(certificate);
532 }
533
534 shared_ptr<IdentityCertificate>
535 getDefaultCertificate() const
536 {
Alexander Afanasyevaab79662014-07-07 17:35:34 -0700537 if (!static_cast<bool>(m_pib->getDefaultCertificate()))
538 const_cast<KeyChain*>(this)->setDefaultCertificateInternal();
539
540 return m_pib->getDefaultCertificate();
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700541 }
542
543 void
544 refreshDefaultCertificate()
545 {
546 return m_pib->refreshDefaultCertificate();
547 }
548
549 /*******************************
550 * Wrapper of SecTpm *
551 *******************************/
552
553 void
554 setTpmPassword(const uint8_t* password, size_t passwordLength)
555 {
556 return m_tpm->setTpmPassword(password, passwordLength);
557 }
558
559 void
560 resetTpmPassword()
561 {
562 return m_tpm->resetTpmPassword();
563 }
564
565 void
566 setInTerminal(bool inTerminal)
567 {
568 return m_tpm->setInTerminal(inTerminal);
569 }
570
571 bool
572 getInTerminal() const
573 {
574 return m_tpm->getInTerminal();
575 }
576
577 bool
578 isLocked() const
579 {
580 return m_tpm->isLocked();
581 }
582
583 bool
584 unlockTpm(const char* password, size_t passwordLength, bool usePassword)
585 {
586 return m_tpm->unlockTpm(password, passwordLength, usePassword);
587 }
588
589 void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700590 generateKeyPairInTpm(const Name& keyName, const KeyParams& params)
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700591 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700592 return m_tpm->generateKeyPairInTpm(keyName, params);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700593 }
594
595 void
596 deleteKeyPairInTpm(const Name& keyName)
597 {
598 return m_tpm->deleteKeyPairInTpm(keyName);
599 }
600
601 shared_ptr<PublicKey>
602 getPublicKeyFromTpm(const Name& keyName) const
603 {
604 return m_tpm->getPublicKeyFromTpm(keyName);
605 }
606
607 Block
608 signInTpm(const uint8_t* data, size_t dataLength,
609 const Name& keyName,
610 DigestAlgorithm digestAlgorithm)
611 {
612 return m_tpm->signInTpm(data, dataLength, keyName, digestAlgorithm);
613 }
614
615 ConstBufferPtr
616 decryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric)
617 {
618 return m_tpm->decryptInTpm(data, dataLength, keyName, isSymmetric);
619 }
620
621 ConstBufferPtr
622 encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric)
623 {
624 return m_tpm->encryptInTpm(data, dataLength, keyName, isSymmetric);
625 }
626
627 void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700628 generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params)
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700629 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700630 return m_tpm->generateSymmetricKeyInTpm(keyName, params);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700631 }
632
633 bool
634 doesKeyExistInTpm(const Name& keyName, KeyClass keyClass) const
635 {
636 return m_tpm->doesKeyExistInTpm(keyName, keyClass);
637 }
638
639 bool
640 generateRandomBlock(uint8_t* res, size_t size) const
641 {
642 return m_tpm->generateRandomBlock(res, size);
643 }
644
645 void
646 addAppToAcl(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl)
647 {
648 return m_tpm->addAppToAcl(keyName, keyClass, appPath, acl);
649 }
650
651 ConstBufferPtr
652 exportPrivateKeyPkcs5FromTpm(const Name& keyName, const std::string& password)
653 {
654 return m_tpm->exportPrivateKeyPkcs5FromTpm(keyName, password);
655 }
656
657 bool
658 importPrivateKeyPkcs5IntoTpm(const Name& keyName,
659 const uint8_t* buf, size_t size,
660 const std::string& password)
661 {
662 return m_tpm->importPrivateKeyPkcs5IntoTpm(keyName, buf, size, password);
663 }
Jeff Thompson8efe5ad2013-08-20 17:36:38 -0700664
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800665private:
Yingdi Yu41546342014-11-30 23:37:53 -0800666 void
667 initialize(const std::string& pibLocator,
668 const std::string& tpmLocator,
669 bool needReset);
670
671 void
672 initializeTpm(const std::string& locator);
673
674 void
675 initializePib(const std::string& locator);
676
Yingdi Yu2e57a582014-02-20 23:34:43 -0800677 /**
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700678 * @brief Determine signature type
679 *
680 * An empty pointer will be returned if there is no valid signature.
681 */
Yingdi Yu4a557052014-07-09 16:40:37 -0700682 shared_ptr<Signature>
683 determineSignatureWithPublicKey(const KeyLocator& keyLocator,
684 KeyType keyType,
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700685 DigestAlgorithm digestAlgorithm = DIGEST_ALGORITHM_SHA256);
686
687 /**
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700688 * @brief Set default certificate if it is not initialized
689 */
690 void
691 setDefaultCertificateInternal();
692
693 /**
694 * @brief Sign a packet using a pariticular certificate.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800695 *
696 * @param packet The packet to be signed.
697 * @param certificate The signing certificate.
698 */
699 template<typename T>
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800700 void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700701 sign(T& packet, const IdentityCertificate& certificate);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800702
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800703 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800704 * @brief Generate a key pair for the specified identity.
705 *
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800706 * @param identityName The name of the specified identity.
707 * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
Yingdi Yu7036ce22014-06-19 18:53:37 -0700708 * @param params The parameter of the key.
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800709 * @return The name of the generated key.
710 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700711 Name
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700712 generateKeyPair(const Name& identityName, bool isKsk = false,
Yingdi Yu7036ce22014-06-19 18:53:37 -0700713 const KeyParams& params = DEFAULT_KEY_PARAMS);
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800714
Yingdi Yu8726f652014-01-23 10:35:12 -0800715 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800716 * @brief Sign the data using a particular key.
717 *
718 * @param data Reference to the data packet.
719 * @param signature Signature to be added.
Yingdi Yu8726f652014-01-23 10:35:12 -0800720 * @param keyName The name of the signing key.
721 * @param digestAlgorithm the digest algorithm.
722 * @throws Tpm::Error
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700723 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700724 void
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700725 signPacketWrapper(Data& data, const Signature& signature,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700726 const Name& keyName, DigestAlgorithm digestAlgorithm);
Yingdi Yu8726f652014-01-23 10:35:12 -0800727
Yingdi Yu2e57a582014-02-20 23:34:43 -0800728 /**
729 * @brief Sign the interest using a particular key.
730 *
731 * @param interest Reference to the interest packet.
732 * @param signature Signature to be added.
733 * @param keyName The name of the signing key.
734 * @param digestAlgorithm the digest algorithm.
735 * @throws Tpm::Error
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -0700736 */
Yingdi Yu7036ce22014-06-19 18:53:37 -0700737 void
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700738 signPacketWrapper(Interest& interest, const Signature& signature,
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700739 const Name& keyName, DigestAlgorithm digestAlgorithm);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800740
Yingdi Yu41546342014-11-30 23:37:53 -0800741public:
742 static const Name DEFAULT_PREFIX;
743 // RsaKeyParams is set to be default for backward compatibility.
744 static const RsaKeyParams DEFAULT_KEY_PARAMS;
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700745
746private:
747 SecPublicInfo* m_pib;
748 SecTpm* m_tpm;
Yingdi Yu0f5fb692014-06-10 12:07:28 -0700749 time::milliseconds m_lastTimestamp;
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700750};
751
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700752template<typename T>
753void
754KeyChain::sign(T& packet)
755{
Alexander Afanasyevaab79662014-07-07 17:35:34 -0700756 if (!static_cast<bool>(m_pib->getDefaultCertificate()))
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700757 setDefaultCertificateInternal();
758
Alexander Afanasyevaab79662014-07-07 17:35:34 -0700759 sign(packet, *m_pib->getDefaultCertificate());
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700760}
761
762template<typename T>
763void
764KeyChain::sign(T& packet, const Name& certificateName)
765{
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700766 shared_ptr<IdentityCertificate> certificate = m_pib->getCertificate(certificateName);
767 sign(packet, *certificate);
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700768}
769
770template<typename T>
771void
772KeyChain::signByIdentity(T& packet, const Name& identityName)
773{
774 Name signingCertificateName;
775 try
776 {
777 signingCertificateName = m_pib->getDefaultCertificateNameForIdentity(identityName);
778 }
779 catch (SecPublicInfo::Error& e)
780 {
781 signingCertificateName = createIdentity(identityName);
782 // Ideally, no exception will be thrown out, unless something goes wrong in the TPM, which
783 // is a fatal error.
784 }
785
786 // We either get or create the signing certificate, sign packet! (no exception unless fatal
787 // error in TPM)
788 sign(packet, signingCertificateName);
789}
790
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700791template<typename T>
792void
793KeyChain::sign(T& packet, const IdentityCertificate& certificate)
794{
Yingdi Yu4a557052014-07-09 16:40:37 -0700795 KeyLocator keyLocator(certificate.getName().getPrefix(-1));
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700796
Yingdi Yu4a557052014-07-09 16:40:37 -0700797 shared_ptr<Signature> signature =
798 determineSignatureWithPublicKey(keyLocator, certificate.getPublicKeyInfo().getKeyType());
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700799
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700800 if (!static_cast<bool>(signature))
801 throw SecPublicInfo::Error("unknown key type!");
802
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700803 signPacketWrapper(packet, *signature,
804 certificate.getPublicKeyName(),
805 DIGEST_ALGORITHM_SHA256);
806
807 return;
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700808}
809
Yingdi Yu6ab67812014-11-27 15:00:34 -0800810} // namespace ndn
Jeff Thompson47c93cf2013-08-09 00:38:48 -0700811
Alexander Afanasyev766cea72014-04-24 19:16:42 -0700812#endif // NDN_SECURITY_KEY_CHAIN_HPP