blob: e9c80bc805ab12da0ce0ab5339443977ac445b78 [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 Thompson6154ae22013-10-18 10:44:57 -07009#if 1 // TODO: Remove this when we don't throw "not implemented".
Jeff Thompson0f2096f2013-10-01 14:49:42 -070010#include <stdexcept>
11#endif
Jeff Thompsonc69163b2013-10-12 13:49:50 -070012#include <ctime>
13#include <fstream>
14#include <ndn-cpp/key.hpp>
Jeff Thompson25b4e612013-10-10 16:03:24 -070015#include <ndn-cpp/sha256-with-rsa-signature.hpp>
16#include <ndn-cpp/security/security-exception.hpp>
Jeff Thompsonc69163b2013-10-12 13:49:50 -070017#include "../../util/logging.hpp"
Jeff Thompson25b4e612013-10-10 16:03:24 -070018#include <ndn-cpp/security/identity/identity-manager.hpp>
Jeff Thompson41471912013-09-12 16:21:50 -070019
Jeff Thompsonc69163b2013-10-12 13:49:50 -070020INIT_LOGGER("ndn.security.IdentityManager")
21
Jeff Thompson9296f0c2013-09-23 18:10:27 -070022using namespace std;
23using namespace ndn::ptr_lib;
Jeff Thompson41471912013-09-12 16:21:50 -070024
Jeff Thompson9296f0c2013-09-23 18:10:27 -070025namespace ndn {
Jeff Thompson86e1d752013-09-17 17:22:38 -070026
Jeff Thompsone7e069b2013-09-27 15:48:48 -070027Name
Jeff Thompsonc69163b2013-10-12 13:49:50 -070028IdentityManager::createIdentity(const Name& identityName)
Jeff Thompsone7e069b2013-09-27 15:48:48 -070029{
30 if (!identityStorage_->doesIdentityExist(identityName)) {
Jeff Thompsonc69163b2013-10-12 13:49:50 -070031 _LOG_DEBUG("Create Identity");
32 identityStorage_->addIdentity(identityName);
33
34 _LOG_DEBUG("Create Default RSA key pair");
35 Name keyName = generateRSAKeyPairAsDefault(identityName, true);
Jeff Thompsone7e069b2013-09-27 15:48:48 -070036
Jeff Thompsonc69163b2013-10-12 13:49:50 -070037 _LOG_DEBUG("Create self-signed certificate");
38 shared_ptr<IdentityCertificate> selfCert = selfSign(keyName);
39
40 _LOG_DEBUG("Add self-signed certificate as default");
Jeff Thompsone7e069b2013-09-27 15:48:48 -070041
Jeff Thompsonc69163b2013-10-12 13:49:50 -070042 addCertificateAsDefault(*selfCert);
43
44 return keyName;
Jeff Thompsone7e069b2013-09-27 15:48:48 -070045 }
46 else
47 throw SecurityException("Identity has already been created!");
48}
49
50Name
Jeff Thompsonc69163b2013-10-12 13:49:50 -070051IdentityManager::generateKeyPair(const Name& identityName, bool isKsk, KeyType keyType, int keySize)
52{
53 _LOG_DEBUG("Get new key ID");
54 Name keyName = identityStorage_->getNewKeyName(identityName, isKsk);
55
56 _LOG_DEBUG("Generate key pair in private storage");
57 privateKeyStorage_->generateKeyPair(keyName.toUri(), keyType, keySize);
58
59 _LOG_DEBUG("Create a key record in public storage");
60 shared_ptr<PublicKey> pubKey = privateKeyStorage_->getPublicKey(keyName.toUri());
61 identityStorage_->addKey(keyName, keyType, pubKey->getKeyDer());
62 _LOG_DEBUG("OK");
63 return keyName;
64}
65
66Name
Jeff Thompsone7e069b2013-09-27 15:48:48 -070067IdentityManager::generateRSAKeyPair(const Name& identityName, bool isKsk, int keySize)
68{
69 Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
70 _LOG_DEBUG("OK2");
71 return keyName;
72}
73
74Name
75IdentityManager::generateRSAKeyPairAsDefault(const Name& identityName, bool isKsk, int keySize)
76{
77 Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
Jeff Thompsonc69163b2013-10-12 13:49:50 -070078
Jeff Thompsone7e069b2013-09-27 15:48:48 -070079 identityStorage_->setDefaultKeyNameForIdentity(keyName, identityName);
80
Jeff Thompsonc69163b2013-10-12 13:49:50 -070081 return keyName;
82}
83
84Name
Jeff Thompson9a8e82f2013-10-17 14:13:43 -070085IdentityManager::createIdentityCertificate(const Name& keyName, const Name& signerCertificateName, const MillisecondsSince1970& notBefore, const MillisecondsSince1970& notAfter)
Jeff Thompsonc69163b2013-10-12 13:49:50 -070086{
87 Blob keyBlob = identityStorage_->getKey(keyName);
88 shared_ptr<PublicKey> publicKey = PublicKey::fromDer(keyBlob);
89
90 shared_ptr<IdentityCertificate> certificate = createIdentityCertificate
91 (keyName, *publicKey, signerCertificateName, notBefore, notAfter);
92
93 identityStorage_->addCertificate(*certificate);
94
95 return certificate->getName();
96}
97
98ptr_lib::shared_ptr<IdentityCertificate>
99IdentityManager::createIdentityCertificate
Jeff Thompson9a8e82f2013-10-17 14:13:43 -0700100 (const Name& keyName, const PublicKey& publicKey, const Name& signerCertificateName, const MillisecondsSince1970& notBefore, const MillisecondsSince1970& notAfter)
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700101{
102#if 0
103 shared_ptr<IdentityCertificate> certificate(new IdentityCertificate());
104
105 Name certificateName;
106 TimeInterval ti = time::NowUnixTimestamp();
107 ostringstream oss;
108 oss << ti.total_seconds();
109
110 certificateName.append(keyName).append("ID-CERT").append(oss.str());
111 certificate->setName(certificateName);
112
113 certificate->setNotBefore(notBefore);
114 certificate->setNotAfter(notAfter);
115 certificate->setPublicKeyInfo(publicKey);
116 certificate->addSubjectDescription(CertificateSubDescrypt("2.5.4.41", keyName.toUri()));
117 certificate->encode();
118
119 shared_ptr<Sha256WithRsaSignature> sha256Sig(new Sha256WithRsaSignature());
120
121 KeyLocator keyLocator;
122 keyLocator.setType(KeyLocator::KEYNAME);
123 keyLocator.setKeyName(signerCertificateName);
124
125 sha256Sig->setKeyLocator(keyLocator);
126 sha256Sig->setPublisherKeyDigest(*publicKey.getDigest());
127
128 certificate->setSignature(sha256Sig);
129
130 SignedBlob unsignedData = certificate->encodeToUnsignedWire();
131
132 Blob sigBits = privateKeyStorage_->sign(*unsignedData, keyName);
133
134 sha256Sig->setSignatureBits(*sigBits);
135
136 return certificate;
137#else
Jeff Thompson4affbf52013-10-18 14:36:46 -0700138 throw runtime_error("not implemented");
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700139#endif
140}
141
142void
143IdentityManager::addCertificateAsDefault(const IdentityCertificate& certificate)
144{
145 identityStorage_->addCertificate(certificate);
146
147 Name keyName = identityStorage_->getKeyNameForCertificate(certificate.getName());
148
149 setDefaultKeyForIdentity(keyName);
150
151 setDefaultCertificateForKey(certificate.getName());
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700152}
153
154void
155IdentityManager::setDefaultCertificateForKey(const Name& certificateName)
156{
157 Name keyName = identityStorage_->getKeyNameForCertificate(certificateName);
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700158
159 if(!identityStorage_->doesKeyExist(keyName))
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700160 throw SecurityException("No corresponding Key record for certificaite!");
161
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700162 identityStorage_->setDefaultCertificateNameForKey(keyName, certificateName);
163}
164
165ptr_lib::shared_ptr<Signature>
166IdentityManager::signByCertificate(const uint8_t* data, size_t dataLength, const Name& certificateName)
167{
168#if 0
169 Name keyName = identityStorage_->getKeyNameForCertificate(certName);
170
171 shared_ptr<PublicKey> publicKey = privateKeyStorage_->getPublicKey(keyName.toUri());
172
173 Blob sigBits = privateKeyStorage_->sign(blob, keyName.toUri());
174
175 //For temporary usage, we support RSA + SHA256 only, but will support more.
176 shared_ptr<signature::Sha256WithRsa> sha256Sig = shared_ptr<signature::Sha256WithRsa>::Create();
177
178 KeyLocator keyLocator;
179 keyLocator.setType(KeyLocator::KEYNAME);
180 keyLocator.setKeyName(certName);
181
182 sha256Sig->setKeyLocator(keyLocator);
183 sha256Sig->setPublisherKeyDigest(*publicKey->getDigest());
184 sha256Sig->setSignatureBits(*sigBits);
185
186 return sha256Sig;
187#else
Jeff Thompson4affbf52013-10-18 14:36:46 -0700188 throw runtime_error("not implemented");
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700189#endif
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700190}
191
192void
Jeff Thompson86e1d752013-09-17 17:22:38 -0700193IdentityManager::signByCertificate(Data &data, const Name &certificateName, WireFormat& wireFormat)
Jeff Thompson41471912013-09-12 16:21:50 -0700194{
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700195 Name keyName = identityStorage_->getKeyNameForCertificate(certificateName);
Jeff Thompson9296f0c2013-09-23 18:10:27 -0700196
197 shared_ptr<PublicKey> publicKey = privateKeyStorage_->getPublicKey(keyName);
Jeff Thompson86e1d752013-09-17 17:22:38 -0700198
199 // For temporary usage, we support RSA + SHA256 only, but will support more.
200 data.setSignature(Sha256WithRsaSignature());
201 // Get a pointer to the clone which Data made.
202 Sha256WithRsaSignature *signature = dynamic_cast<Sha256WithRsaSignature*>(data.getSignature());
203 DigestAlgorithm digestAlgorithm = DIGEST_ALGORITHM_SHA256;
204
205 signature->getKeyLocator().setType(ndn_KeyLocatorType_KEYNAME);
206 signature->getKeyLocator().setKeyName(certificateName);
Jeff Thompson9296f0c2013-09-23 18:10:27 -0700207 // Omit the certificate digest.
208 signature->getKeyLocator().setKeyNameType((ndn_KeyNameType)-1);
Jeff Thompson86e1d752013-09-17 17:22:38 -0700209 // Ignore witness and leave the digestAlgorithm as the default.
Jeff Thompson9296f0c2013-09-23 18:10:27 -0700210 signature->getPublisherPublicKeyDigest().setPublisherPublicKeyDigest(publicKey->getDigest());
Jeff Thompson41471912013-09-12 16:21:50 -0700211
Jeff Thompson86e1d752013-09-17 17:22:38 -0700212 // Encode once to get the signed portion.
213 SignedBlob encoding = data.wireEncode(wireFormat);
214
215 signature->setSignature
Jeff Thompson9296f0c2013-09-23 18:10:27 -0700216 (privateKeyStorage_->sign(encoding.signedBuf(), encoding.signedSize(), keyName, digestAlgorithm));
Jeff Thompson86e1d752013-09-17 17:22:38 -0700217
218 // Encode again to include the signature.
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700219 data.wireEncode(wireFormat);
Jeff Thompson41471912013-09-12 16:21:50 -0700220}
221
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700222shared_ptr<IdentityCertificate>
223IdentityManager::selfSign(const Name& keyName)
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700224{
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700225#if 0
226 shared_ptr<IdentityCertificate> certificate = Create<IdentityCertificate>();
227
228 Name certificateName;
229 certificateName.append(keyName).append("ID-CERT").append("0");
230 certificate->setName(certificateName);
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700231
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700232 Blob keyBlob = identityStorage_->getKey(keyName);
233 shared_ptr<PublicKey> publicKey = PublicKey::fromDer(keyBlob);
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700234
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700235 tm current = boost::posix_time::to_tm(time::Now());
236 current.tm_hour = 0;
237 current.tm_min = 0;
238 current.tm_sec = 0;
Jeff Thompson9a8e82f2013-10-17 14:13:43 -0700239 MillisecondsSince1970 notBefore = boost::posix_time::ptime_from_tm(current);
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700240 current.tm_year = current.tm_year + 20;
Jeff Thompson9a8e82f2013-10-17 14:13:43 -0700241 MillisecondsSince1970 notAfter = boost::posix_time::ptime_from_tm(current);
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700242
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700243 certificate->setNotBefore(notBefore);
244 certificate->setNotAfter(notAfter);
245 certificate->setPublicKeyInfo(*publicKey);
246 certificate->addSubjectDescription(CertificateSubDescrypt("2.5.4.41", keyName.toUri()));
247 certificate->encode();
248
249 shared_ptr<signature::Sha256WithRsa> sha256Sig = shared_ptr<signature::Sha256WithRsa>::Create();
250
251 KeyLocator keyLocator;
252 keyLocator.setType(KeyLocator::KEYNAME);
253 keyLocator.setKeyName(certificateName);
254
255 sha256Sig->setKeyLocator(keyLocator);
256 sha256Sig->setPublisherKeyDigest(*publicKey->getDigest());
257
258 certificate->setSignature(sha256Sig);
259
260 Blob unsignedData = certificate->encodeToUnsignedWire();
261
262 Blob sigBits = privateKeyStorage_->sign(*unsignedData, keyName.toUri());
263
264 sha256Sig->setSignatureBits(*sigBits);
265
266 return certificate;
267#else
Jeff Thompson4affbf52013-10-18 14:36:46 -0700268 throw runtime_error("not implemented");
Jeff Thompsone7e069b2013-09-27 15:48:48 -0700269#endif
270}
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700271
Jeff Thompson41471912013-09-12 16:21:50 -0700272}