blob: ce90cc517b9eecb696b6c15612af79a6a2599c13 [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{
93 Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
Jeff Thompsonc69163b2013-10-12 13:49:50 -070094
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080095 info().setDefaultKeyNameForIdentity(keyName, identityName);
Jeff Thompsone7e069b2013-09-27 15:48:48 -070096
Jeff Thompsonc69163b2013-10-12 13:49:50 -070097 return keyName;
98}
99
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800100ptr_lib::shared_ptr<IdentityCertificate>
Jeff Thompson418b05a2013-10-22 17:48:54 -0700101IdentityManager::createIdentityCertificate(const Name& certificatePrefix,
102 const Name& signerCertificateName,
103 const MillisecondsSince1970& notBefore,
104 const MillisecondsSince1970& notAfter)
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700105{
Jeff Thompson418b05a2013-10-22 17:48:54 -0700106 Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
107
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800108 ptr_lib::shared_ptr<IdentityCertificate> certificate =
109 createIdentityCertificate(certificatePrefix,
110 *info().getKey(keyName),
111 signerCertificateName,
112 notBefore, notAfter);
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700113
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800114 info().addCertificate(*certificate);
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700115
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800116 return certificate;
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700117}
118
119ptr_lib::shared_ptr<IdentityCertificate>
Jeff Thompson418b05a2013-10-22 17:48:54 -0700120IdentityManager::createIdentityCertificate(const Name& certificatePrefix,
121 const PublicKey& publicKey,
122 const Name& signerCertificateName,
123 const MillisecondsSince1970& notBefore,
124 const MillisecondsSince1970& notAfter)
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700125{
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800126 ptr_lib::shared_ptr<IdentityCertificate> certificate (new IdentityCertificate());
Jeff Thompson418b05a2013-10-22 17:48:54 -0700127 Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700128
Jeff Thompson418b05a2013-10-22 17:48:54 -0700129 Name certificateName = certificatePrefix;
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800130 certificateName.append("ID-CERT").appendVersion();
Jeff Thompson418b05a2013-10-22 17:48:54 -0700131
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700132 certificate->setName(certificateName);
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700133 certificate->setNotBefore(notBefore);
134 certificate->setNotAfter(notAfter);
135 certificate->setPublicKeyInfo(publicKey);
Jeff Thompsondb686892013-10-18 17:16:31 -0700136 certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700137 certificate->encode();
138
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800139 signByCertificate(*certificate, signerCertificateName);
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700140
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800141 return certificate;
142}
143
144ptr_lib::shared_ptr<IdentityCertificate>
145IdentityManager::selfSign(const Name& keyName)
146{
147 ptr_lib::shared_ptr<IdentityCertificate> certificate(new IdentityCertificate());
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700148
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800149 Name certificateName = keyName.getSubName(0, keyName.size() - 1);
150 certificateName.append("KEY").append(keyName.get(keyName.size() - 1)).append("ID-CERT").appendVersion();
151
152 certificate->setName(certificateName);
153 certificate->setNotBefore(ndn_getNowMilliseconds());
154 certificate->setNotAfter(ndn_getNowMilliseconds() + 630720000 /* 20 years*/);
155 certificate->setPublicKeyInfo(*info().getKey(keyName));
156 certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
157 certificate->encode();
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700158
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800159 selfSign(*certificate);
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700160 return certificate;
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700161}
162
163void
164IdentityManager::addCertificateAsDefault(const IdentityCertificate& certificate)
165{
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800166 info().addCertificate(certificate);
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700167
Jeff Thompson418b05a2013-10-22 17:48:54 -0700168 setDefaultCertificateForKey(certificate);
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700169}
170
171void
Jeff Thompson418b05a2013-10-22 17:48:54 -0700172IdentityManager::addCertificateAsIdentityDefault(const IdentityCertificate& certificate)
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700173{
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800174 info().addCertificate(certificate);
Jeff Thompson418b05a2013-10-22 17:48:54 -0700175
176 Name keyName = certificate.getPublicKeyName();
177
178 setDefaultKeyForIdentity(keyName);
179
180 setDefaultCertificateForKey(certificate);
181}
182
183void
184IdentityManager::setDefaultCertificateForKey(const IdentityCertificate& certificate)
185{
186 Name keyName = certificate.getPublicKeyName();
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700187
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800188 if(!info().doesKeyExist(keyName))
189 throw Error("No corresponding Key record for certificate!");
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700190
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800191 info().setDefaultCertificateNameForKey(keyName, certificate.getName());
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700192}
193
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800194Signature
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700195IdentityManager::signByCertificate(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
Jeff Thompson74942612013-10-24 16:42:32 -0700196{
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800197 ptr_lib::shared_ptr<IdentityCertificate> cert = info().getCertificate(certificateName);
198 SignatureSha256WithRsa signature;
199 signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700200
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800201 // For temporary usage, we support RSA + SHA256 only, but will support more.
202 signature.setValue(tpm().sign(buffer, bufferLength, signature, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
203 return signature;
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700204}
205
206void
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800207IdentityManager::signByCertificate(Data &data, const Name &certificateName)
Jeff Thompson41471912013-09-12 16:21:50 -0700208{
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800209 ptr_lib::shared_ptr<IdentityCertificate> cert = info().getCertificate(certificateName);
210 SignatureSha256WithRsa signature;
211 signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
Jeff Thompson86e1d752013-09-17 17:22:38 -0700212
213 // For temporary usage, we support RSA + SHA256 only, but will support more.
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800214 signature.setValue(tpm().sign(data, signature, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
215 data.setSignature(signature);
Jeff Thompson41471912013-09-12 16:21:50 -0700216}
217
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800218void
219IdentityManager::selfSign (IdentityCertificate& cert)
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700220{
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800221 SignatureSha256WithRsa signature;
222 signature.setKeyLocator(cert.getName().getPrefix(cert.getName().size()-1)); // implicit conversion should take care
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700223
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800224 // For temporary usage, we support RSA + SHA256 only, but will support more.
225 signature.setValue(tpm().sign(cert, signature, cert.getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
226 cert.setSignature(signature);
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700227}
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700228
Jeff Thompson418b05a2013-10-22 17:48:54 -0700229Name
230IdentityManager::getKeyNameFromCertificatePrefix(const Name & certificatePrefix)
231{
232 Name result;
233
234 string keyString("KEY");
235 int i = 0;
236 for(; i < certificatePrefix.size(); i++) {
237 if (certificatePrefix.get(i).toEscapedString() == keyString)
238 break;
239 }
240
241 if (i >= certificatePrefix.size())
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800242 throw Error("Identity Certificate Prefix does not have a KEY component");
Jeff Thompson418b05a2013-10-22 17:48:54 -0700243
244 result.append(certificatePrefix.getSubName(0, i));
245 result.append(certificatePrefix.getSubName(i + 1, certificatePrefix.size()-i-1));
246
247 return result;
248}
249
Jeff Thompson41471912013-09-12 16:21:50 -0700250}