blob: 7d0748d3a55cea6c87480c73caee0a8b01a281e1 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Yingdi Yu2d9c50f2014-01-21 18:25:00 -08002/**
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 Xingyu Ma <http://www.linkedin.com/pub/xingyu-ma/1a/384/5a8>
22 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
23 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080024 */
25
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080026#include "common.hpp"
Yingdi Yu04020922014-01-22 12:46:53 -080027
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080028#include "sec-tpm-file.hpp"
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070029#include "../encoding/buffer-stream.hpp"
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080030
31#include <boost/filesystem.hpp>
32#include <boost/algorithm/string.hpp>
33
Junxiao Shi482ccc52014-03-31 13:05:24 -070034#include "cryptopp.hpp"
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080035
36#include <sys/types.h>
37#include <sys/stat.h>
38
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080039#include <algorithm>
40
Yingdi Yufc40d872014-02-18 12:56:04 -080041namespace ndn {
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080042
Yingdi Yu7036ce22014-06-19 18:53:37 -070043using std::string;
44using std::ostringstream;
45using std::ofstream;
46
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070047class SecTpmFile::Impl
48{
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080049public:
Yingdi Yu7036ce22014-06-19 18:53:37 -070050 explicit
Yingdi Yu4b752752014-02-18 12:24:03 -080051 Impl(const string& dir)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080052 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070053 if (dir.empty())
Yingdi Yu37e317f2014-03-19 12:16:23 -070054 m_keystorePath = boost::filesystem::path(getenv("HOME")) / ".ndn" / "ndnsec-tpm-file";
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080055 else
56 m_keystorePath = dir;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070057
Yingdi Yu7036ce22014-06-19 18:53:37 -070058 boost::filesystem::create_directories(m_keystorePath);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080059 }
60
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080061 boost::filesystem::path
Yingdi Yu7036ce22014-06-19 18:53:37 -070062 transformName(const string& keyName, const string& extension)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080063 {
64 using namespace CryptoPP;
65 string digest;
66 SHA256 hash;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070067 StringSource src(keyName,
68 true,
69 new HashFilter(hash,
70 new Base64Encoder(new CryptoPP::StringSink(digest))));
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080071
72 boost::algorithm::trim(digest);
73 std::replace(digest.begin(), digest.end(), '/', '%');
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070074
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080075 return m_keystorePath / (digest + extension);
76 }
77
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070078 string
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080079 maintainMapping(const string& keyName)
80 {
Yingdi Yu7036ce22014-06-19 18:53:37 -070081 string keyFileName = transformName(keyName, "").string();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070082
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080083 ofstream outfile;
84 string dirFile = (m_keystorePath / "mapping.txt").string();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070085
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080086 outfile.open(dirFile.c_str(), std::ios_base::app);
87 outfile << keyName << ' ' << keyFileName << '\n';
88 outfile.close();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070089
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080090 return keyFileName;
91 }
92
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080093public:
94 boost::filesystem::path m_keystorePath;
95};
96
Yingdi Yu4b752752014-02-18 12:24:03 -080097
Yingdi Yube4150e2014-02-18 13:02:46 -080098SecTpmFile::SecTpmFile(const string& dir)
Yingdi Yu4b752752014-02-18 12:24:03 -080099 : m_impl(new Impl(dir))
Yingdi Yube4150e2014-02-18 13:02:46 -0800100 , m_inTerminal(false)
Yingdi Yu7036ce22014-06-19 18:53:37 -0700101{
102}
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800103
104void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700105SecTpmFile::generateKeyPairInTpm(const Name& keyName, const KeyParams& params)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800106{
107 string keyURI = keyName.toUri();
108
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700109 if (doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800110 throw Error("public key exists");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700111 if (doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800112 throw Error("private key exists");
113
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800114 string keyFileName = m_impl->maintainMapping(keyURI);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800115
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700116 try
117 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700118 switch (params.getKeyType())
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700119 {
120 case KEY_TYPE_RSA:
121 {
122 using namespace CryptoPP;
Yingdi Yu4b752752014-02-18 12:24:03 -0800123
Yingdi Yu7036ce22014-06-19 18:53:37 -0700124 const RsaKeyParams& rsaParams = static_cast<const RsaKeyParams&>(params);
125 AutoSeededRandomPool rng;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700126 InvertibleRSAFunction privateKey;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700127 privateKey.Initialize(rng, rsaParams.getKeySize());
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700128
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700129 string privateKeyFileName = keyFileName + ".pri";
130 Base64Encoder privateKeySink(new FileSink(privateKeyFileName.c_str()));
131 privateKey.DEREncode(privateKeySink);
132 privateKeySink.MessageEnd();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700133
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700134 RSAFunction publicKey(privateKey);
135 string publicKeyFileName = keyFileName + ".pub";
136 Base64Encoder publicKeySink(new FileSink(publicKeyFileName.c_str()));
137 publicKey.DEREncode(publicKeySink);
138 publicKeySink.MessageEnd();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700139
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700140 /*set file permission*/
141 chmod(privateKeyFileName.c_str(), 0000400);
142 chmod(publicKeyFileName.c_str(), 0000444);
143 return;
144 }
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700145 case KEY_TYPE_ECDSA:
146 {
147 using namespace CryptoPP;
148
149 const EcdsaKeyParams& ecdsaParams = static_cast<const EcdsaKeyParams&>(params);
150
151 OID curveName;
152 switch (ecdsaParams.getKeySize())
153 {
154 case 256:
155 curveName = ASN1::secp256r1();
156 break;
157 case 384:
158 curveName = ASN1::secp384r1();
159 break;
160 default:
161 curveName = ASN1::secp256r1();
162 }
163
164 AutoSeededRandomPool rng;
165
166 ECDSA<ECP, SHA256>::PrivateKey privateKey;
167 DL_GroupParameters_EC<ECP> cryptoParams(curveName);
168 cryptoParams.SetEncodeAsOID(true);
169 privateKey.Initialize(rng, cryptoParams);
170
171 ECDSA<ECP, SHA256>::PublicKey publicKey;
172 privateKey.MakePublicKey(publicKey);
173 publicKey.AccessGroupParameters().SetEncodeAsOID(true);
174
175 string privateKeyFileName = keyFileName + ".pri";
176 Base64Encoder privateKeySink(new FileSink(privateKeyFileName.c_str()));
177 privateKey.DEREncode(privateKeySink);
178 privateKeySink.MessageEnd();
179
180 string publicKeyFileName = keyFileName + ".pub";
181 Base64Encoder publicKeySink(new FileSink(publicKeyFileName.c_str()));
182 publicKey.Save(publicKeySink);
183 publicKeySink.MessageEnd();
184
185 /*set file permission*/
186 chmod(privateKeyFileName.c_str(), 0000400);
187 chmod(publicKeyFileName.c_str(), 0000444);
188 return;
189 }
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700190 default:
191 throw Error("Unsupported key type!");
192 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800193 }
Yingdi Yu7036ce22014-06-19 18:53:37 -0700194 catch (KeyParams::Error& e)
195 {
196 throw Error(e.what());
197 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700198 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700199 {
200 throw Error(e.what());
201 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800202}
203
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800204void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700205SecTpmFile::deleteKeyPairInTpm(const Name& keyName)
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800206{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700207 boost::filesystem::path publicKeyPath(m_impl->transformName(keyName.toUri(), ".pub"));
208 boost::filesystem::path privateKeyPath(m_impl->transformName(keyName.toUri(), ".pri"));
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800209
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700210 if (boost::filesystem::exists(publicKeyPath))
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800211 boost::filesystem::remove(publicKeyPath);
212
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700213 if (boost::filesystem::exists(privateKeyPath))
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800214 boost::filesystem::remove(privateKeyPath);
215}
216
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800217shared_ptr<PublicKey>
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700218SecTpmFile::getPublicKeyFromTpm(const Name& keyName)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800219{
220 string keyURI = keyName.toUri();
221
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700222 if (!doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC))
Yingdi Yu5e96e002014-04-23 18:32:15 -0700223 throw Error("Public Key does not exist");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800224
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800225 ostringstream os;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700226 try
227 {
228 using namespace CryptoPP;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700229 FileSource(m_impl->transformName(keyURI, ".pub").string().c_str(),
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700230 true,
231 new Base64Decoder(new FileSink(os)));
232 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700233 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700234 {
235 throw Error(e.what());
236 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800237
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700238 return make_shared<PublicKey>(reinterpret_cast<const uint8_t*>(os.str().c_str()),
239 os.str().size());
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800240}
241
242ConstBufferPtr
Yingdi Yu5e96e002014-04-23 18:32:15 -0700243SecTpmFile::exportPrivateKeyPkcs8FromTpm(const Name& keyName)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800244{
245 OBufferStream privateKeyOs;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700246 CryptoPP::FileSource(m_impl->transformName(keyName.toUri(), ".pri").string().c_str(), true,
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800247 new CryptoPP::Base64Decoder(new CryptoPP::FileSink(privateKeyOs)));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700248
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800249 return privateKeyOs.buf();
250}
251
252bool
Yingdi Yu5e96e002014-04-23 18:32:15 -0700253SecTpmFile::importPrivateKeyPkcs8IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800254{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700255 try
256 {
257 using namespace CryptoPP;
258
259 string keyFileName = m_impl->maintainMapping(keyName.toUri());
260 keyFileName.append(".pri");
261 StringSource(buf, size,
262 true,
263 new Base64Encoder(new FileSink(keyFileName.c_str())));
264 return true;
265 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700266 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700267 {
268 return false;
269 }
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800270}
271
272bool
273SecTpmFile::importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
274{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700275 try
276 {
277 using namespace CryptoPP;
278
279 string keyFileName = m_impl->maintainMapping(keyName.toUri());
280 keyFileName.append(".pub");
281 StringSource(buf, size,
282 true,
283 new Base64Encoder(new FileSink(keyFileName.c_str())));
284 return true;
285 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700286 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700287 {
288 return false;
289 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800290}
291
292Block
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700293SecTpmFile::signInTpm(const uint8_t* data, size_t dataLength,
294 const Name& keyName, DigestAlgorithm digestAlgorithm)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800295{
296 string keyURI = keyName.toUri();
297
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700298 if (!doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800299 throw Error("private key doesn't exists");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700300
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700301 try
302 {
303 using namespace CryptoPP;
304 AutoSeededRandomPool rng;
Yingdi Yu4b752752014-02-18 12:24:03 -0800305
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700306 //Read public key
307 shared_ptr<PublicKey> pubkeyPtr;
308 pubkeyPtr = getPublicKeyFromTpm(keyName);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700309
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700310 switch (pubkeyPtr->getKeyType())
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700311 {
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700312 case KEY_TYPE_RSA:
313 {
314 //Read private key
315 ByteQueue bytes;
316 FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
317 true, new Base64Decoder);
318 file.TransferTo(bytes);
319 bytes.MessageEnd();
320 RSA::PrivateKey privateKey;
321 privateKey.Load(bytes);
322
323 //Sign message
324 switch (digestAlgorithm)
325 {
326 case DIGEST_ALGORITHM_SHA256:
327 {
328 RSASS<PKCS1v15, SHA256>::Signer signer(privateKey);
329
330 OBufferStream os;
331 StringSource(data, dataLength,
332 true,
333 new SignerFilter(rng, signer, new FileSink(os)));
334
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600335 return Block(tlv::SignatureValue, os.buf());
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700336 }
337 default:
338 throw Error("Unsupported digest algorithm!");
339 }
340 }
341 case KEY_TYPE_ECDSA:
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700342 {
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700343 //Read private key
344 ByteQueue bytes;
345 FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
346 true, new Base64Decoder);
347 file.TransferTo(bytes);
348 bytes.MessageEnd();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700349
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700350 //Sign message
351 switch (digestAlgorithm)
352 {
353 case DIGEST_ALGORITHM_SHA256:
354 {
355 ECDSA<ECP, SHA256>::PrivateKey privateKey;
356 privateKey.Load(bytes);
357 ECDSA<ECP, SHA256>::Signer signer(privateKey);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700358
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700359 OBufferStream os;
360 StringSource(data, dataLength,
361 true,
362 new SignerFilter(rng, signer, new FileSink(os)));
363
364 uint8_t buf[200];
365 size_t bufSize = DSAConvertSignatureFormat(buf, 200, DSA_DER,
366 os.buf()->buf(), os.buf()->size(),
367 DSA_P1363);
368
369 shared_ptr<Buffer> sigBuffer = make_shared<Buffer>(buf, bufSize);
370
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600371 return Block(tlv::SignatureValue, sigBuffer);
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700372 }
373 default:
374 throw Error("Unsupported digest algorithm!");
375 }
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700376 }
377 default:
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700378 throw Error("Unsupported key type!");
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700379 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800380 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700381 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700382 {
383 throw Error(e.what());
384 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800385}
386
387
388ConstBufferPtr
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700389SecTpmFile::decryptInTpm(const uint8_t* data, size_t dataLength,
390 const Name& keyName, bool isSymmetric)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800391{
Yingdi Yu2e57a582014-02-20 23:34:43 -0800392 throw Error("SecTpmFile::decryptInTpm is not supported!");
393 // string keyURI = keyName.toUri();
394 // if (!isSymmetric)
395 // {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700396 // if (!doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
Yingdi Yu2e57a582014-02-20 23:34:43 -0800397 // throw Error("private key doesn't exist");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800398
Yingdi Yu2e57a582014-02-20 23:34:43 -0800399 // try{
400 // using namespace CryptoPP;
401 // AutoSeededRandomPool rng;
Yingdi Yu4b752752014-02-18 12:24:03 -0800402
Yingdi Yu2e57a582014-02-20 23:34:43 -0800403 // //Read private key
404 // ByteQueue bytes;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700405 // FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(), true, new Base64Decoder);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800406 // file.TransferTo(bytes);
407 // bytes.MessageEnd();
408 // RSA::PrivateKey privateKey;
409 // privateKey.Load(bytes);
410 // RSAES_PKCS1v15_Decryptor decryptor(privateKey);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700411
Yingdi Yu2e57a582014-02-20 23:34:43 -0800412 // OBufferStream os;
413 // StringSource(data, dataLength, true, new PK_DecryptorFilter(rng, decryptor, new FileSink(os)));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700414
Yingdi Yu2e57a582014-02-20 23:34:43 -0800415 // return os.buf();
416 // }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700417 // catch (CryptoPP::Exception& e){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800418 // throw Error(e.what());
419 // }
420 // }
421 // else
422 // {
423 // throw Error("Symmetric encryption is not implemented!");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700424 // // if (!doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
Yingdi Yu7036ce22014-06-19 18:53:37 -0700425 // // throw Error("symmetric key doesn't exist");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800426
Yingdi Yu2e57a582014-02-20 23:34:43 -0800427 // // try{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700428 // // string keyBits;
429 // // string symKeyFileName = m_impl->transformName(keyURI, ".key");
430 // // FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700431
Yingdi Yu7036ce22014-06-19 18:53:37 -0700432 // // using CryptoPP::AES;
433 // // AutoSeededRandomPool rnd;
434 // // byte iv[AES::BLOCKSIZE];
435 // // rnd.GenerateBlock(iv, AES::BLOCKSIZE);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800436
Yingdi Yu7036ce22014-06-19 18:53:37 -0700437 // // CFB_Mode<AES>::Decryption decryptor;
438 // // decryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700439
Yingdi Yu7036ce22014-06-19 18:53:37 -0700440 // // OBufferStream os;
441 // // StringSource(data, dataLength, true, new StreamTransformationFilter(decryptor,new FileSink(os)));
442 // // return os.buf();
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800443
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700444 // // }catch (CryptoPP::Exception& e){
Yingdi Yu7036ce22014-06-19 18:53:37 -0700445 // // throw Error(e.what());
Yingdi Yu2e57a582014-02-20 23:34:43 -0800446 // // }
447 // }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800448}
449
450ConstBufferPtr
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700451SecTpmFile::encryptInTpm(const uint8_t* data, size_t dataLength,
452 const Name& keyName, bool isSymmetric)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800453{
Yingdi Yu2e57a582014-02-20 23:34:43 -0800454 throw Error("SecTpmFile::encryptInTpm is not supported!");
455 // string keyURI = keyName.toUri();
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800456
Yingdi Yu2e57a582014-02-20 23:34:43 -0800457 // if (!isSymmetric)
458 // {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700459 // if (!doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC))
Yingdi Yu2e57a582014-02-20 23:34:43 -0800460 // throw Error("public key doesn't exist");
461 // try
462 // {
463 // using namespace CryptoPP;
464 // AutoSeededRandomPool rng;
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800465
Yingdi Yu2e57a582014-02-20 23:34:43 -0800466 // //Read private key
467 // ByteQueue bytes;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700468 // FileSource file(m_impl->transformName(keyURI, ".pub").string().c_str(), true, new Base64Decoder);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800469 // file.TransferTo(bytes);
470 // bytes.MessageEnd();
471 // RSA::PublicKey publicKey;
472 // publicKey.Load(bytes);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800473
Yingdi Yu2e57a582014-02-20 23:34:43 -0800474 // OBufferStream os;
475 // RSAES_PKCS1v15_Encryptor encryptor(publicKey);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800476
Yingdi Yu2e57a582014-02-20 23:34:43 -0800477 // StringSource(data, dataLength, true, new PK_EncryptorFilter(rng, encryptor, new FileSink(os)));
478 // return os.buf();
479 // }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700480 // catch (CryptoPP::Exception& e){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800481 // throw Error(e.what());
482 // }
483 // }
484 // else
485 // {
486 // throw Error("Symmetric encryption is not implemented!");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700487 // // if (!doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
Yingdi Yu7036ce22014-06-19 18:53:37 -0700488 // // throw Error("symmetric key doesn't exist");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800489
Yingdi Yu2e57a582014-02-20 23:34:43 -0800490 // // try{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700491 // // string keyBits;
492 // // string symKeyFileName = m_impl->transformName(keyURI, ".key");
493 // // FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800494
Yingdi Yu7036ce22014-06-19 18:53:37 -0700495 // // using CryptoPP::AES;
496 // // AutoSeededRandomPool rnd;
497 // // byte iv[AES::BLOCKSIZE];
498 // // rnd.GenerateBlock(iv, AES::BLOCKSIZE);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800499
Yingdi Yu7036ce22014-06-19 18:53:37 -0700500 // // CFB_Mode<AES>::Encryption encryptor;
501 // // encryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800502
Yingdi Yu7036ce22014-06-19 18:53:37 -0700503 // // OBufferStream os;
504 // // StringSource(data, dataLength, true, new StreamTransformationFilter(encryptor, new FileSink(os)));
505 // // return os.buf();
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700506 // // }catch (CryptoPP::Exception& e){
Yingdi Yu7036ce22014-06-19 18:53:37 -0700507 // // throw Error(e.what());
Yingdi Yu2e57a582014-02-20 23:34:43 -0800508 // // }
509 // }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800510}
511
512
513void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700514SecTpmFile::generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800515{
Yingdi Yu2e57a582014-02-20 23:34:43 -0800516 throw Error("SecTpmFile::generateSymmetricKeyInTpm is not supported!");
517 // string keyURI = keyName.toUri();
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800518
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700519 // if (doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
Yingdi Yu2e57a582014-02-20 23:34:43 -0800520 // throw Error("symmetric key exists");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800521
Yingdi Yu2e57a582014-02-20 23:34:43 -0800522 // string keyFileName = m_impl->maintainMapping(keyURI);
523 // string symKeyFileName = keyFileName + ".key";
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800524
Yingdi Yu2e57a582014-02-20 23:34:43 -0800525 // try{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700526 // switch (keyType){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800527 // case KEY_TYPE_AES:
528 // {
529 // using namespace CryptoPP;
530 // AutoSeededRandomPool rng;
Yingdi Yu4b752752014-02-18 12:24:03 -0800531
Yingdi Yu2e57a582014-02-20 23:34:43 -0800532 // SecByteBlock key(0x00, keySize);
533 // rng.GenerateBlock(key, keySize);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700534
Yingdi Yu2e57a582014-02-20 23:34:43 -0800535 // StringSource(key, key.size(), true, new HexEncoder(new FileSink(symKeyFileName.c_str())));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700536
Yingdi Yu2e57a582014-02-20 23:34:43 -0800537 // chmod(symKeyFileName.c_str(), 0000400);
538 // return;
539 // }
540 // default:
541 // throw Error("Unsupported symmetric key type!");
542 // }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700543 // }catch (CryptoPP::Exception& e){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800544 // throw Error(e.what());
545 // }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800546}
547
548bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700549SecTpmFile::doesKeyExistInTpm(const Name& keyName, KeyClass keyClass)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800550{
551 string keyURI = keyName.toUri();
552 if (keyClass == KEY_CLASS_PUBLIC)
553 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700554 if (boost::filesystem::exists(m_impl->transformName(keyURI, ".pub")))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800555 return true;
556 else
557 return false;
558 }
559 if (keyClass == KEY_CLASS_PRIVATE)
560 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700561 if (boost::filesystem::exists(m_impl->transformName(keyURI, ".pri")))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800562 return true;
563 else
564 return false;
565 }
566 if (keyClass == KEY_CLASS_SYMMETRIC)
567 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700568 if (boost::filesystem::exists(m_impl->transformName(keyURI, ".key")))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800569 return true;
570 else
571 return false;
572 }
573 return false;
574}
575
Yingdi Yu4b752752014-02-18 12:24:03 -0800576bool
577SecTpmFile::generateRandomBlock(uint8_t* res, size_t size)
578{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700579 try
580 {
581 CryptoPP::AutoSeededRandomPool rng;
582 rng.GenerateBlock(res, size);
583 return true;
584 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700585 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700586 {
587 return false;
588 }
Yingdi Yu4b752752014-02-18 12:24:03 -0800589}
590
Yingdi Yufc40d872014-02-18 12:56:04 -0800591} // namespace ndn