blob: d9d475d47e886fa2d150949ef59c37fad7c8acb6 [file] [log] [blame]
Jeff Thompson25b4e612013-10-10 16:03:24 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Jeff Thompson47c93cf2013-08-09 00:38:48 -07002/**
Jeff Thompson7687dc02013-09-13 11:54:07 -07003 * Copyright (C) 2013 Regents of the University of California.
Jeff Thompsonba16b8f2013-12-16 13:11:47 -08004 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
Jeff Thompson7687dc02013-09-13 11:54:07 -07005 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompson47c93cf2013-08-09 00:38:48 -07006 * See COPYING for copyright and distribution information.
7 */
8
9#ifndef NDN_KEY_CHAIN_HPP
Jeff Thompson2d27e2f2013-08-09 12:55:00 -070010#define NDN_KEY_CHAIN_HPP
Jeff Thompson47c93cf2013-08-09 00:38:48 -070011
Yingdi Yu4f324632014-01-15 18:10:03 -080012#include "identity-certificate.hpp"
13#include "public-key.hpp"
14#include "signature-sha256-with-rsa.hpp"
Yingdi Yu4270f202014-01-28 14:19:16 -080015#include "../interest.hpp"
Yingdi Yu31b4af22014-01-14 14:13:00 -080016
Yingdi Yu04020922014-01-22 12:46:53 -080017//PublicInfo
Yingdi Yu4f324632014-01-15 18:10:03 -080018#include "sec-public-info-sqlite3.hpp"
19#include "sec-public-info-memory.hpp"
Yingdi Yu04020922014-01-22 12:46:53 -080020//TPM
21#include "sec-tpm-file.hpp"
Yingdi Yu4f324632014-01-15 18:10:03 -080022#include "sec-tpm-memory.hpp"
Yingdi Yu2abd73f2014-01-08 23:34:11 -080023
Yingdi Yu04020922014-01-22 12:46:53 -080024#ifdef NDN_CPP_HAVE_OSX_SECURITY
25#include "sec-tpm-osx.hpp"
26#endif
27
Jeff Thompson47c93cf2013-08-09 00:38:48 -070028
29namespace ndn {
30
Jeff Thompson2ce8f492013-09-17 18:01:25 -070031/**
Yingdi Yu2abd73f2014-01-08 23:34:11 -080032 * KeyChain is one of the main classes of the security library.
Jeff Thompsonffa36f92013-09-20 08:42:41 -070033 *
Yingdi Yu2abd73f2014-01-08 23:34:11 -080034 * The KeyChain class provides a set of interfaces of identity management and private key related operations.
Jeff Thompsonffa36f92013-09-20 08:42:41 -070035 */
Yingdi Yu31b4af22014-01-14 14:13:00 -080036template<class Info, class Tpm>
37class KeyChainImpl : public Info, public Tpm
38{
Yingdi Yu4270f202014-01-28 14:19:16 -080039 typedef typename Info::Error InfoError;
Jeff Thompson47c93cf2013-08-09 00:38:48 -070040public:
Yingdi Yu2abd73f2014-01-08 23:34:11 -080041
42 /**
43 * Create an identity by creating a pair of Key-Signing-Key (KSK) for this identity and a self-signed certificate of the KSK.
44 * @param identityName The name of the identity.
Yingdi Yu28fd32f2014-01-28 19:03:03 -080045 * @return The name of the default certificate of the identity.
Yingdi Yu2abd73f2014-01-08 23:34:11 -080046 */
47 Name
Yingdi Yu31b4af22014-01-14 14:13:00 -080048 createIdentity(const Name& identityName)
49 {
Yingdi Yu28fd32f2014-01-28 19:03:03 -080050 if (!Info::doesIdentityExist(identityName))
Yingdi Yu31b4af22014-01-14 14:13:00 -080051 Info::addIdentity(identityName);
Yingdi Yu28fd32f2014-01-28 19:03:03 -080052
53 Name keyName = Info::getDefaultKeyNameForIdentity(identityName);
54
55 if(keyName.empty())
56 keyName = generateRSAKeyPairAsDefault(identityName, true);
Yingdi Yu31b4af22014-01-14 14:13:00 -080057
Yingdi Yu28fd32f2014-01-28 19:03:03 -080058 Name certName = Info::getDefaultCertificateNameForKey(keyName);
Yingdi Yu31b4af22014-01-14 14:13:00 -080059
Yingdi Yu28fd32f2014-01-28 19:03:03 -080060 if(certName.empty())
61 {
62 ptr_lib::shared_ptr<IdentityCertificate> selfCert = selfSign(keyName);
63 Info::addCertificateAsIdentityDefault(*selfCert);
64 certName = selfCert->getName();
65 }
66
67 return certName;
Yingdi Yu31b4af22014-01-14 14:13:00 -080068 }
Yingdi Yu2abd73f2014-01-08 23:34:11 -080069
70 /**
Yingdi Yu2abd73f2014-01-08 23:34:11 -080071 * Generate a pair of RSA keys for the specified identity.
72 * @param identityName The name of the identity.
73 * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
74 * @param keySize The size of the key.
75 * @return The generated key name.
76 */
77 Name
Yingdi Yu31b4af22014-01-14 14:13:00 -080078 generateRSAKeyPair(const Name& identityName, bool isKsk = false, int keySize = 2048)
Yingdi Yu2abd73f2014-01-08 23:34:11 -080079 {
Yingdi Yu31b4af22014-01-14 14:13:00 -080080 return generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
Yingdi Yu2abd73f2014-01-08 23:34:11 -080081 }
Alexander Afanasyev64a3d812014-01-05 23:35:05 -080082
Yingdi Yu2abd73f2014-01-08 23:34:11 -080083 /**
84 * Generate a pair of RSA keys for the specified identity and set it as default key for the identity.
85 * @param identityName The name of the identity.
86 * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
87 * @param keySize The size of the key.
88 * @return The generated key name.
89 */
90 Name
Yingdi Yu31b4af22014-01-14 14:13:00 -080091 generateRSAKeyPairAsDefault(const Name& identityName, bool isKsk = false, int keySize = 2048)
92 {
93 Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
94
95 Info::setDefaultKeyNameForIdentity(keyName);
Yingdi Yu31b4af22014-01-14 14:13:00 -080096
97 return keyName;
98 }
Jeff Thompson79a2d5d2013-09-27 14:32:23 -070099
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800100 /**
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800101 * Create an identity certificate for a public key managed by this IdentityManager.
102 * @param certificatePrefix The name of public key to be signed.
103 * @param signerCertificateName The name of signing certificate.
104 * @param notBefore The notBefore value in the validity field of the generated certificate.
105 * @param notAfter The notAfter vallue in validity field of the generated certificate.
106 * @return The name of generated identity certificate.
107 */
108 ptr_lib::shared_ptr<IdentityCertificate>
109 createIdentityCertificate
110 (const Name& certificatePrefix,
111 const Name& signerCertificateName,
112 const MillisecondsSince1970& notBefore,
Yingdi Yu31b4af22014-01-14 14:13:00 -0800113 const MillisecondsSince1970& notAfter)
114 {
115 Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
116
117 ptr_lib::shared_ptr<PublicKey> pubKey = Info::getPublicKey(keyName);
118 if (!pubKey)
Yingdi Yu4270f202014-01-28 14:19:16 -0800119 throw InfoError("Requested public key [" + keyName.toUri() + "] doesn't exist");
Yingdi Yu31b4af22014-01-14 14:13:00 -0800120
121 ptr_lib::shared_ptr<IdentityCertificate> certificate =
122 createIdentityCertificate(certificatePrefix,
123 *pubKey,
124 signerCertificateName,
125 notBefore, notAfter);
126
127 Info::addCertificate(*certificate);
128
129 return certificate;
130 }
131
Jeff Thompson79a2d5d2013-09-27 14:32:23 -0700132
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800133 /**
134 * Create an identity certificate for a public key supplied by the caller.
135 * @param certificatePrefix The name of public key to be signed.
136 * @param publickey The public key to be signed.
137 * @param signerCertificateName The name of signing certificate.
138 * @param notBefore The notBefore value in the validity field of the generated certificate.
139 * @param notAfter The notAfter vallue in validity field of the generated certificate.
140 * @return The generated identity certificate.
141 */
142 ptr_lib::shared_ptr<IdentityCertificate>
143 createIdentityCertificate
144 (const Name& certificatePrefix,
Yingdi Yu31b4af22014-01-14 14:13:00 -0800145 const PublicKey& publicKey,
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800146 const Name& signerCertificateName,
147 const MillisecondsSince1970& notBefore,
Yingdi Yu31b4af22014-01-14 14:13:00 -0800148 const MillisecondsSince1970& notAfter)
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800149 {
Yingdi Yu31b4af22014-01-14 14:13:00 -0800150 ptr_lib::shared_ptr<IdentityCertificate> certificate (new IdentityCertificate());
151 Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
152
153 Name certificateName = certificatePrefix;
154 certificateName.append("ID-CERT").appendVersion();
155
156 certificate->setName(certificateName);
157 certificate->setNotBefore(notBefore);
158 certificate->setNotAfter(notAfter);
159 certificate->setPublicKeyInfo(publicKey);
160 certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
161 certificate->encode();
162
163 sign(*certificate, signerCertificateName);
164
165 return certificate;
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800166 }
167
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800168 void
Yingdi Yu31b4af22014-01-14 14:13:00 -0800169 sign(Data &data)
170 {
171 if (!Info::defaultCertificate())
172 {
173 Info::refreshDefaultCertificate();
174
175 if(!Info::defaultCertificate())
Yingdi Yu4270f202014-01-28 14:19:16 -0800176 throw InfoError("Default IdentityCertificate cannot be determined");
Yingdi Yu31b4af22014-01-14 14:13:00 -0800177 }
178
179 sign(data, *Info::defaultCertificate());
180 }
Yingdi Yu4270f202014-01-28 14:19:16 -0800181
182 void
183 sign(Interest &interest)
184 {
185 if (!Info::defaultCertificate())
186 {
187 Info::refreshDefaultCertificate();
188
189 if(!Info::defaultCertificate())
190 throw InfoError("Default IdentityCertificate cannot be determined");
191 }
192
193 sign(interest, *Info::defaultCertificate());
194 }
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800195
Jeff Thompson47c93cf2013-08-09 00:38:48 -0700196 /**
Jeff Thompson2ce8f492013-09-17 18:01:25 -0700197 * Wire encode the Data object, sign it and set its signature.
Jeff Thompson2ce8f492013-09-17 18:01:25 -0700198 * @param data The Data object to be signed. This updates its signature and key locator field and wireEncoding.
Jeff Thompson9296f0c2013-09-23 18:10:27 -0700199 * @param certificateName The certificate name of the key to use for signing. If omitted, infer the signing identity from the data packet name.
Jeff Thompson3c73da42013-08-12 11:19:05 -0700200 */
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800201 void
Yingdi Yu31b4af22014-01-14 14:13:00 -0800202 sign(Data& data, const Name& certificateName)
203 {
Yingdi Yu17bc3012014-02-10 17:37:12 -0800204 shared_ptr<IdentityCertificate> cert = Info::getCertificate(certificateName);
Yingdi Yu31b4af22014-01-14 14:13:00 -0800205 if (!cert)
Yingdi Yu4270f202014-01-28 14:19:16 -0800206 throw InfoError("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
Yingdi Yu31b4af22014-01-14 14:13:00 -0800207
208 SignatureSha256WithRsa signature;
209 signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
210 data.setSignature(signature);
211
212 // For temporary usage, we support RSA + SHA256 only, but will support more.
Yingdi Yu8726f652014-01-23 10:35:12 -0800213 signDataInTpm(data, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
Yingdi Yu31b4af22014-01-14 14:13:00 -0800214 }
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800215
216 void
Yingdi Yu4270f202014-01-28 14:19:16 -0800217 sign(Interest &interest, const Name &certificateName)
218 {
Yingdi Yu17bc3012014-02-10 17:37:12 -0800219 shared_ptr<IdentityCertificate> cert = Info::getCertificate(certificateName);
Yingdi Yu4270f202014-01-28 14:19:16 -0800220 if(!static_cast<bool>(cert))
221 throw InfoError("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
222
223 SignatureSha256WithRsa signature;
224 signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
225
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800226 Name signedName = Name(interest.getName()).append(signature.getInfo());
Yingdi Yu4270f202014-01-28 14:19:16 -0800227
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800228 signature.setValue(Tpm::signInTpm(signedName.wireEncode().value(),
229 signedName.wireEncode().value_size(),
Yingdi Yu4270f202014-01-28 14:19:16 -0800230 cert->getPublicKeyName(),
231 DIGEST_ALGORITHM_SHA256));
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800232 signedName.append(signature.getValue());
233 interest.setName(signedName);
Yingdi Yu4270f202014-01-28 14:19:16 -0800234 }
Jeff Thompson79a2d5d2013-09-27 14:32:23 -0700235
Jeff Thompson29ce3102013-09-27 11:47:48 -0700236 /**
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700237 * Sign the byte array using a certificate name and return a Signature object.
238 * @param buffer The byte array to be signed.
239 * @param bufferLength the length of buffer.
240 * @param certificateName The certificate name used to get the signing key and which will be put into KeyLocator.
241 * @return The Signature.
242 */
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800243 Signature
Yingdi Yu31b4af22014-01-14 14:13:00 -0800244 sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
245 {
246 ptr_lib::shared_ptr<IdentityCertificate> cert = Info::getCertificate(certificateName);
Yingdi Yu4270f202014-01-28 14:19:16 -0800247 if (!static_cast<bool>(cert))
248 throw InfoError("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
Yingdi Yu31b4af22014-01-14 14:13:00 -0800249
250 SignatureSha256WithRsa signature;
251 signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
252
253 // For temporary usage, we support RSA + SHA256 only, but will support more.
Yingdi Yub4bb85a2014-01-16 10:11:04 -0800254 signature.setValue(Tpm::signInTpm(buffer, bufferLength, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
Yingdi Yu31b4af22014-01-14 14:13:00 -0800255 return signature;
256 }
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700257
258 /**
Jeff Thompson29ce3102013-09-27 11:47:48 -0700259 * Wire encode the Data object, sign it and set its signature.
Jeff Thompson29ce3102013-09-27 11:47:48 -0700260 * @param data The Data object to be signed. This updates its signature and key locator field and wireEncoding.
261 * @param identityName The identity name for the key to use for signing. If omitted, infer the signing identity from the data packet name.
Jeff Thompson29ce3102013-09-27 11:47:48 -0700262 */
263 void
Yingdi Yu4270f202014-01-28 14:19:16 -0800264 signByIdentity(Data& data, const Name& identityName)
Yingdi Yu31b4af22014-01-14 14:13:00 -0800265 {
266 Name signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);
267
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800268 if (signingCertificateName.empty())
269 signingCertificateName = createIdentity(identityName);
Yingdi Yu31b4af22014-01-14 14:13:00 -0800270
271 sign(data, signingCertificateName);
272 }
Jeff Thompson3c73da42013-08-12 11:19:05 -0700273
Yingdi Yu4270f202014-01-28 14:19:16 -0800274 void
275 signByIdentity(Interest& interest, const Name& identityName)
276 {
277 Name signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);
278
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800279 if (signingCertificateName.empty())
280 signingCertificateName = createIdentity(identityName);
Yingdi Yu4270f202014-01-28 14:19:16 -0800281
282 sign(interest, signingCertificateName);
283 }
284
285
Jeff Thompson3c73da42013-08-12 11:19:05 -0700286 /**
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700287 * Sign the byte array using an identity name and return a Signature object.
288 * @param buffer The byte array to be signed.
289 * @param bufferLength the length of buffer.
290 * @param identityName The identity name.
291 * @return The Signature.
292 */
Alexander Afanasyev64a3d812014-01-05 23:35:05 -0800293 Signature
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800294 signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
Yingdi Yu31b4af22014-01-14 14:13:00 -0800295 {
296 Name signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);
297
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800298 if (signingCertificateName.empty())
299 signingCertificateName = createIdentity(identityName);
Yingdi Yu31b4af22014-01-14 14:13:00 -0800300
301 return sign(buffer, bufferLength, signingCertificateName);
302 }
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700303
304 /**
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800305 * Generate a self-signed certificate for a public key.
306 * @param keyName The name of the public key.
307 * @return The generated certificate.
308 */
309 ptr_lib::shared_ptr<IdentityCertificate>
Yingdi Yu31b4af22014-01-14 14:13:00 -0800310 selfSign(const Name& keyName)
311 {
Yingdi Yu7ea69502014-01-15 17:21:29 -0800312 if(keyName.empty())
Yingdi Yu4270f202014-01-28 14:19:16 -0800313 throw InfoError("Incorrect key name: " + keyName.toUri());
Yingdi Yu7ea69502014-01-15 17:21:29 -0800314
Yingdi Yu31b4af22014-01-14 14:13:00 -0800315 ptr_lib::shared_ptr<IdentityCertificate> certificate = ptr_lib::make_shared<IdentityCertificate>();
316
317 Name certificateName = keyName.getPrefix(-1);
318 certificateName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
319
320 ptr_lib::shared_ptr<PublicKey> pubKey = Info::getPublicKey(keyName);
321 if (!pubKey)
Yingdi Yu4270f202014-01-28 14:19:16 -0800322 throw InfoError("Requested public key [" + keyName.toUri() + "] doesn't exist");
Yingdi Yu31b4af22014-01-14 14:13:00 -0800323
324 certificate->setName(certificateName);
325 certificate->setNotBefore(getNow());
326 certificate->setNotAfter(getNow() + 630720000 /* 20 years*/);
327 certificate->setPublicKeyInfo(*pubKey);
328 certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
329 certificate->encode();
330
331 selfSign(*certificate);
332 return certificate;
333 }
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800334
335 /**
336 * @brief Self-sign the supplied identity certificate
Jeff Thompson8efe5ad2013-08-20 17:36:38 -0700337 */
Jeff Thompson2ce8f492013-09-17 18:01:25 -0700338 void
Yingdi Yu31b4af22014-01-14 14:13:00 -0800339 selfSign (IdentityCertificate& cert)
340 {
341 SignatureSha256WithRsa signature;
342 signature.setKeyLocator(cert.getName().getPrefix(-1)); // implicit conversion should take care
343 cert.setSignature(signature);
344
345 // For temporary usage, we support RSA + SHA256 only, but will support more.
Yingdi Yu8726f652014-01-23 10:35:12 -0800346 signDataInTpm(cert, cert.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
Yingdi Yu31b4af22014-01-14 14:13:00 -0800347 }
348
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800349 void
350 deleteCertificate (const Name &certificateName)
351 {
352 if(Info::getDefaultIdentity() == IdentityCertificate::certificateNameToPublicKeyName(certificateName).getPrefix(-1))
353 return;
354
355 Info::deleteCertificateInfo(certificateName);
356 }
357
358 void
359 deleteKey (const Name &keyName)
360 {
361 if(Info::getDefaultIdentity() == keyName.getPrefix(-1))
362 return;
363
364 Info::deletePublicKeyInfo(keyName);
365 Tpm::deleteKeyPairInTpm(keyName);
366 }
367
368 void
369 deleteIdentity (const Name &identity)
370 {
371 if(Info::getDefaultIdentity() == identity)
372 return;
373
374 std::vector<Name> nameList;
375 Info::getAllKeyNamesOfIdentity(identity, nameList, true);
376 Info::getAllKeyNamesOfIdentity(identity, nameList, false);
377
378 Info::deleteIdentityInfo(identity);
379
380 std::vector<Name>::const_iterator it = nameList.begin();
381 for(; it != nameList.end(); it++)
382 Tpm::deleteKeyPairInTpm(*it);
383 }
384
Jeff Thompson8efe5ad2013-08-20 17:36:38 -0700385
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800386private:
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800387
388 void
389 sign(Data &data, const IdentityCertificate& certificate)
390 {
391 SignatureSha256WithRsa signature;
392 signature.setKeyLocator(certificate.getName().getPrefix(-1));
393 data.setSignature(signature);
394
395 // For temporary usage, we support RSA + SHA256 only, but will support more.
396 signDataInTpm(data, certificate.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
397 }
398
399 void
400 sign(Interest &interest, const IdentityCertificate& certificate)
401 {
402 SignatureSha256WithRsa signature;
403 signature.setKeyLocator(certificate.getName().getPrefix(-1)); // implicit conversion should take care
404
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800405 Name signedName = Name(interest.getName()).append(signature.getInfo());
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800406
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800407 signature.setValue(Tpm::signInTpm(signedName.wireEncode().value(),
408 signedName.wireEncode().value_size(),
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800409 certificate.getPublicKeyName(),
410 DIGEST_ALGORITHM_SHA256));
411
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800412 signedName.append(signature.getValue());
413 interest.setName(signedName);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800414 }
415
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800416 /**
417 * Generate a key pair for the specified identity.
418 * @param identityName The name of the specified identity.
419 * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
420 * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
421 * @param keySize The size of the key pair.
422 * @return The name of the generated key.
423 */
424 Name
Yingdi Yu31b4af22014-01-14 14:13:00 -0800425 generateKeyPair(const Name& identityName, bool isKsk = false, KeyType keyType = KEY_TYPE_RSA, int keySize = 2048)
426 {
427 Name keyName = Info::getNewKeyName(identityName, isKsk);
428
429 Tpm::generateKeyPairInTpm(keyName.toUri(), keyType, keySize);
430
431 ptr_lib::shared_ptr<PublicKey> pubKey = Tpm::getPublicKeyFromTpm(keyName.toUri());
Yingdi Yuef26ee32014-01-15 16:41:14 -0800432 Info::addPublicKey(keyName, keyType, *pubKey);
Yingdi Yu31b4af22014-01-14 14:13:00 -0800433
434 return keyName;
435 }
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800436
437 static Name
Yingdi Yu31b4af22014-01-14 14:13:00 -0800438 getKeyNameFromCertificatePrefix(const Name& certificatePrefix)
439 {
440 Name result;
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800441
Yingdi Yu31b4af22014-01-14 14:13:00 -0800442 std::string keyString("KEY");
443 int i = 0;
444 for(; i < certificatePrefix.size(); i++) {
445 if (certificatePrefix.get(i).toEscapedString() == keyString)
446 break;
447 }
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800448
Yingdi Yu31b4af22014-01-14 14:13:00 -0800449 if (i >= certificatePrefix.size())
Yingdi Yu4270f202014-01-28 14:19:16 -0800450 throw InfoError("Identity Certificate Prefix does not have a KEY component");
Alexander Afanasyevbd5ba402014-01-05 22:41:09 -0800451
Yingdi Yu31b4af22014-01-14 14:13:00 -0800452 result.append(certificatePrefix.getSubName(0, i));
453 result.append(certificatePrefix.getSubName(i + 1, certificatePrefix.size()-i-1));
454
455 return result;
456 }
457
Yingdi Yu8726f652014-01-23 10:35:12 -0800458 /**
459 * Fetch the private key for keyName and sign the data, and set the signature block of the data packet.
460 * @param data Reference to the input data packet.
461 * @param keyName The name of the signing key.
462 * @param digestAlgorithm the digest algorithm.
463 * @throws Tpm::Error
464 */
465 void
466 signDataInTpm(Data &data, const Name& keyName, DigestAlgorithm digestAlgorithm)
467 {
468 data.setSignatureValue
469 (Tpm::signInTpm(data.wireEncode().value(),
470 data.wireEncode().value_size() - data.getSignature().getValue().size(),
471 keyName, digestAlgorithm));
472 }
473
Jeff Thompson47c93cf2013-08-09 00:38:48 -0700474};
475
Yingdi Yu31b4af22014-01-14 14:13:00 -0800476}
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800477
Yingdi Yu04020922014-01-22 12:46:53 -0800478
479
Alexander Afanasyev3e08d5d2014-02-12 19:24:28 -0800480#if defined(NDN_CPP_HAVE_OSX_SECURITY) and defined(NDN_CPP_WITH_OSX_KEYCHAIN)
Yingdi Yu31b4af22014-01-14 14:13:00 -0800481
482namespace ndn
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800483{
Yingdi Yu31b4af22014-01-14 14:13:00 -0800484typedef KeyChainImpl<SecPublicInfoSqlite3, SecTpmOsx> KeyChain;
485};
Yingdi Yu2abd73f2014-01-08 23:34:11 -0800486
Yingdi Yu31b4af22014-01-14 14:13:00 -0800487#else
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800488
Yingdi Yu31b4af22014-01-14 14:13:00 -0800489namespace ndn
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800490{
Yingdi Yu04020922014-01-22 12:46:53 -0800491typedef KeyChainImpl<SecPublicInfoSqlite3, SecTpmFile> KeyChain;
Yingdi Yu31b4af22014-01-14 14:13:00 -0800492};
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800493
Yingdi Yu31b4af22014-01-14 14:13:00 -0800494#endif //NDN_CPP_HAVE_OSX_SECURITY
Jeff Thompson47c93cf2013-08-09 00:38:48 -0700495
496#endif