blob: 1befdcd25ebd9750e165d993bc0a07b88d6e714c [file] [log] [blame]
Jeff Thompson25b4e612013-10-10 16:03:24 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Jeff Thompson41471912013-09-12 16:21:50 -07002/**
Jeff Thompson7687dc02013-09-13 11:54:07 -07003 * Copyright (C) 2013 Regents of the University of California.
Jeff Thompson06e787d2013-09-12 19:00:55 -07004 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
Jeff Thompson7687dc02013-09-13 11:54:07 -07005 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompson41471912013-09-12 16:21:50 -07006 * See COPYING for copyright and distribution information.
7 */
8
Jeff Thompsond63baba2013-10-18 17:47:58 -07009#include <ndn-cpp/ndn-cpp-config.h>
10#if NDN_CPP_HAVE_TIME_H
11#include <time.h>
12#endif
13#if NDN_CPP_HAVE_SYS_TIME_H
14#include <sys/time.h>
15#endif
Jeff Thompsonc69163b2013-10-12 13:49:50 -070016#include <ctime>
17#include <fstream>
Jeff Thompsondb686892013-10-18 17:16:31 -070018#include <math.h>
Jeff Thompson71b2f872013-12-17 12:03:17 -080019#include <ndn-cpp/key-locator.hpp>
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080020
Jeff Thompsonc69163b2013-10-12 13:49:50 -070021#include "../../util/logging.hpp"
Jeff Thompsondb686892013-10-18 17:16:31 -070022#include "../../c/util/time.h"
Jeff Thompson25b4e612013-10-10 16:03:24 -070023#include <ndn-cpp/security/identity/identity-manager.hpp>
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080024#include "../certificate/identity-certificate.hpp"
25#include "../signature/signature-sha256-with-rsa.hpp"
Jeff Thompson41471912013-09-12 16:21:50 -070026
Jeff Thompsonc69163b2013-10-12 13:49:50 -070027INIT_LOGGER("ndn.security.IdentityManager")
28
Jeff Thompson9296f0c2013-09-23 18:10:27 -070029using namespace std;
Jeff Thompson41471912013-09-12 16:21:50 -070030
Jeff Thompson9296f0c2013-09-23 18:10:27 -070031namespace ndn {
Jeff Thompson86e1d752013-09-17 17:22:38 -070032
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080033const ptr_lib::shared_ptr<IdentityStorage> IdentityManager::DefaultIdentityStorage = ptr_lib::shared_ptr<IdentityStorage>();
34const ptr_lib::shared_ptr<PrivateKeyStorage> IdentityManager::DefaultPrivateKeyStorage = ptr_lib::shared_ptr<PrivateKeyStorage>();
35
36IdentityManager::IdentityManager(const ptr_lib::shared_ptr<IdentityStorage> &identityStorage /* = DefaultIdentityStorage */,
37 const ptr_lib::shared_ptr<PrivateKeyStorage> &privateKeyStorage /* = DefaultPrivateKeyStorage */)
38 : identityStorage_(identityStorage)
39 , privateKeyStorage_(privateKeyStorage)
40{
41}
42
Jeff Thompsone7e069b2013-09-27 15:48:48 -070043Name
Jeff Thompsonc69163b2013-10-12 13:49:50 -070044IdentityManager::createIdentity(const Name& identityName)
Jeff Thompsone7e069b2013-09-27 15:48:48 -070045{
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080046 if (!info().doesIdentityExist(identityName)) {
47 _LOG_DEBUG("Create Identity");
48 info().addIdentity(identityName);
Jeff Thompsonc69163b2013-10-12 13:49:50 -070049
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080050 _LOG_DEBUG("Create Default RSA key pair");
51 Name keyName = generateRSAKeyPairAsDefault(identityName, true);
Jeff Thompsone7e069b2013-09-27 15:48:48 -070052
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080053 _LOG_DEBUG("Create self-signed certificate");
54 ptr_lib::shared_ptr<IdentityCertificate> selfCert = selfSign(keyName);
Jeff Thompsonc69163b2013-10-12 13:49:50 -070055
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080056 _LOG_DEBUG("Add self-signed certificate as default");
Jeff Thompsone7e069b2013-09-27 15:48:48 -070057
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080058 addCertificateAsDefault(*selfCert);
Jeff Thompsonc69163b2013-10-12 13:49:50 -070059
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080060 return keyName;
Jeff Thompsone7e069b2013-09-27 15:48:48 -070061 }
62 else
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080063 throw Error("Identity has already been created!");
Jeff Thompsone7e069b2013-09-27 15:48:48 -070064}
65
66Name
Jeff Thompsonc69163b2013-10-12 13:49:50 -070067IdentityManager::generateKeyPair(const Name& identityName, bool isKsk, KeyType keyType, int keySize)
68{
69 _LOG_DEBUG("Get new key ID");
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080070 Name keyName = info().getNewKeyName(identityName, isKsk);
Jeff Thompsonc69163b2013-10-12 13:49:50 -070071
72 _LOG_DEBUG("Generate key pair in private storage");
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080073 tpm().generateKeyPair(keyName.toUri(), keyType, keySize);
Jeff Thompsonc69163b2013-10-12 13:49:50 -070074
75 _LOG_DEBUG("Create a key record in public storage");
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080076 ptr_lib::shared_ptr<PublicKey> pubKey = tpm().getPublicKey(keyName.toUri());
77 info().addKey(keyName, keyType, *pubKey);
Jeff Thompson418b05a2013-10-22 17:48:54 -070078
Jeff Thompsonc69163b2013-10-12 13:49:50 -070079 return keyName;
80}
81
82Name
Jeff Thompsone7e069b2013-09-27 15:48:48 -070083IdentityManager::generateRSAKeyPair(const Name& identityName, bool isKsk, int keySize)
84{
85 Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
Jeff Thompson418b05a2013-10-22 17:48:54 -070086
Jeff Thompsone7e069b2013-09-27 15:48:48 -070087 return keyName;
88}
89
90Name
91IdentityManager::generateRSAKeyPairAsDefault(const Name& identityName, bool isKsk, int keySize)
92{
Alexander Afanasyeve64788e2014-01-05 22:38:21 -080093 defaultCertificate_.reset();
94
Jeff Thompsone7e069b2013-09-27 15:48:48 -070095 Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
Jeff Thompsonc69163b2013-10-12 13:49:50 -070096
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080097 info().setDefaultKeyNameForIdentity(keyName, identityName);
Jeff Thompsone7e069b2013-09-27 15:48:48 -070098
Jeff Thompsonc69163b2013-10-12 13:49:50 -070099 return keyName;
100}
101
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800102ptr_lib::shared_ptr<IdentityCertificate>
Jeff Thompson418b05a2013-10-22 17:48:54 -0700103IdentityManager::createIdentityCertificate(const Name& certificatePrefix,
104 const Name& signerCertificateName,
105 const MillisecondsSince1970& notBefore,
106 const MillisecondsSince1970& notAfter)
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700107{
Jeff Thompson418b05a2013-10-22 17:48:54 -0700108 Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800109
110 ptr_lib::shared_ptr<PublicKey> pubKey = info().getKey(keyName);
111 if (!pubKey)
112 throw Error("Requested public key [" + keyName.toUri() + "] doesn't exist");
Jeff Thompson418b05a2013-10-22 17:48:54 -0700113
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800114 ptr_lib::shared_ptr<IdentityCertificate> certificate =
115 createIdentityCertificate(certificatePrefix,
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800116 *pubKey,
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800117 signerCertificateName,
118 notBefore, notAfter);
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700119
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800120 info().addCertificate(*certificate);
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700121
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800122 return certificate;
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700123}
124
125ptr_lib::shared_ptr<IdentityCertificate>
Jeff Thompson418b05a2013-10-22 17:48:54 -0700126IdentityManager::createIdentityCertificate(const Name& certificatePrefix,
127 const PublicKey& publicKey,
128 const Name& signerCertificateName,
129 const MillisecondsSince1970& notBefore,
130 const MillisecondsSince1970& notAfter)
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700131{
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800132 ptr_lib::shared_ptr<IdentityCertificate> certificate (new IdentityCertificate());
Jeff Thompson418b05a2013-10-22 17:48:54 -0700133 Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700134
Jeff Thompson418b05a2013-10-22 17:48:54 -0700135 Name certificateName = certificatePrefix;
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800136 certificateName.append("ID-CERT").appendVersion();
Jeff Thompson418b05a2013-10-22 17:48:54 -0700137
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700138 certificate->setName(certificateName);
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700139 certificate->setNotBefore(notBefore);
140 certificate->setNotAfter(notAfter);
141 certificate->setPublicKeyInfo(publicKey);
Jeff Thompsondb686892013-10-18 17:16:31 -0700142 certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700143 certificate->encode();
144
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800145 signByCertificate(*certificate, signerCertificateName);
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700146
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800147 return certificate;
148}
149
150ptr_lib::shared_ptr<IdentityCertificate>
151IdentityManager::selfSign(const Name& keyName)
152{
153 ptr_lib::shared_ptr<IdentityCertificate> certificate(new IdentityCertificate());
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700154
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800155 Name certificateName = keyName.getSubName(0, keyName.size() - 1);
156 certificateName.append("KEY").append(keyName.get(keyName.size() - 1)).append("ID-CERT").appendVersion();
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800157
158 ptr_lib::shared_ptr<PublicKey> pubKey = info().getKey(keyName);
159 if (!pubKey)
160 throw Error("Requested public key [" + keyName.toUri() + "] doesn't exist");
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800161
162 certificate->setName(certificateName);
163 certificate->setNotBefore(ndn_getNowMilliseconds());
164 certificate->setNotAfter(ndn_getNowMilliseconds() + 630720000 /* 20 years*/);
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800165 certificate->setPublicKeyInfo(*pubKey);
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800166 certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
167 certificate->encode();
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700168
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800169 selfSign(*certificate);
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700170 return certificate;
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700171}
172
173void
174IdentityManager::addCertificateAsDefault(const IdentityCertificate& certificate)
175{
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800176 info().addCertificate(certificate);
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700177
Jeff Thompson418b05a2013-10-22 17:48:54 -0700178 setDefaultCertificateForKey(certificate);
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700179}
180
181void
Jeff Thompson418b05a2013-10-22 17:48:54 -0700182IdentityManager::addCertificateAsIdentityDefault(const IdentityCertificate& certificate)
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700183{
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800184 info().addCertificate(certificate);
Jeff Thompson418b05a2013-10-22 17:48:54 -0700185
186 Name keyName = certificate.getPublicKeyName();
187
188 setDefaultKeyForIdentity(keyName);
189
190 setDefaultCertificateForKey(certificate);
191}
192
193void
194IdentityManager::setDefaultCertificateForKey(const IdentityCertificate& certificate)
195{
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800196 defaultCertificate_.reset();
197
Jeff Thompson418b05a2013-10-22 17:48:54 -0700198 Name keyName = certificate.getPublicKeyName();
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700199
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800200 if(!info().doesKeyExist(keyName))
201 throw Error("No corresponding Key record for certificate!");
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700202
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800203 info().setDefaultCertificateNameForKey(keyName, certificate.getName());
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700204}
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800205
206void
207IdentityManager::sign(Data &data)
208{
209 if (!defaultCertificate_)
210 {
211 defaultCertificate_ = info().getCertificate(
212 info().getDefaultCertificateNameForIdentity(
213 info().getDefaultIdentity()));
214
215 if(!defaultCertificate_)
216 throw Error("Default IdentityCertificate cannot be determined");
217 }
218
219 signByCertificate(data, *defaultCertificate_);
220}
221
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800222Signature
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700223IdentityManager::signByCertificate(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
Jeff Thompson74942612013-10-24 16:42:32 -0700224{
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800225 ptr_lib::shared_ptr<IdentityCertificate> cert = info().getCertificate(certificateName);
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800226 if (!cert)
227 throw Error("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
228
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800229 SignatureSha256WithRsa signature;
230 signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700231
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800232 // For temporary usage, we support RSA + SHA256 only, but will support more.
233 signature.setValue(tpm().sign(buffer, bufferLength, signature, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
234 return signature;
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700235}
236
237void
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800238IdentityManager::signByCertificate(Data &data, const Name &certificateName)
Jeff Thompson41471912013-09-12 16:21:50 -0700239{
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800240 ptr_lib::shared_ptr<IdentityCertificate> cert = info().getCertificate(certificateName);
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800241 if (!cert)
242 throw Error("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
243
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800244 SignatureSha256WithRsa signature;
245 signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
Jeff Thompson86e1d752013-09-17 17:22:38 -0700246
247 // For temporary usage, we support RSA + SHA256 only, but will support more.
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800248 signature.setValue(tpm().sign(data, signature, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
249 data.setSignature(signature);
Jeff Thompson41471912013-09-12 16:21:50 -0700250}
251
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800252void
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800253IdentityManager::signByCertificate(Data& data, const IdentityCertificate& certificate)
254{
255 SignatureSha256WithRsa signature;
256 signature.setKeyLocator(certificate.getName().getPrefix(-1));
257
258 // For temporary usage, we support RSA + SHA256 only, but will support more.
259 signature.setValue(tpm().sign(data, signature, certificate.getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
260 data.setSignature(signature);
261}
262
263void
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800264IdentityManager::selfSign (IdentityCertificate& cert)
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700265{
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800266 SignatureSha256WithRsa signature;
267 signature.setKeyLocator(cert.getName().getPrefix(cert.getName().size()-1)); // implicit conversion should take care
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700268
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800269 // For temporary usage, we support RSA + SHA256 only, but will support more.
270 signature.setValue(tpm().sign(cert, signature, cert.getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
271 cert.setSignature(signature);
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700272}
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700273
Jeff Thompson418b05a2013-10-22 17:48:54 -0700274Name
275IdentityManager::getKeyNameFromCertificatePrefix(const Name & certificatePrefix)
276{
277 Name result;
278
279 string keyString("KEY");
280 int i = 0;
281 for(; i < certificatePrefix.size(); i++) {
282 if (certificatePrefix.get(i).toEscapedString() == keyString)
283 break;
284 }
285
286 if (i >= certificatePrefix.size())
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800287 throw Error("Identity Certificate Prefix does not have a KEY component");
Jeff Thompson418b05a2013-10-22 17:48:54 -0700288
289 result.append(certificatePrefix.getSubName(0, i));
290 result.append(certificatePrefix.getSubName(i + 1, certificatePrefix.size()-i-1));
291
292 return result;
293}
294
Jeff Thompson41471912013-09-12 16:21:50 -0700295}