blob: 4551ce542c84f01de30d7364180e4d56c7214d8d [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 Afanasyevaf99f462015-01-19 21:43:09 -08003 * Copyright (c) 2013-2015 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 "sec-tpm-file.hpp"
Alexander Afanasyev07113802015-01-15 19:14:36 -080027
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070028#include "../encoding/buffer-stream.hpp"
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080029
30#include <boost/filesystem.hpp>
31#include <boost/algorithm/string.hpp>
32
Junxiao Shi482ccc52014-03-31 13:05:24 -070033#include "cryptopp.hpp"
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080034
35#include <sys/types.h>
36#include <sys/stat.h>
37
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080038#include <algorithm>
39
Yingdi Yufc40d872014-02-18 12:56:04 -080040namespace ndn {
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080041
Yingdi Yu7036ce22014-06-19 18:53:37 -070042using std::string;
43using std::ostringstream;
44using std::ofstream;
45
Alexander Afanasyev07113802015-01-15 19:14:36 -080046const std::string SecTpmFile::SCHEME("tpm-file");
Yingdi Yu41546342014-11-30 23:37:53 -080047
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070048class SecTpmFile::Impl
49{
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080050public:
Yingdi Yu7036ce22014-06-19 18:53:37 -070051 explicit
Yingdi Yu4b752752014-02-18 12:24:03 -080052 Impl(const string& dir)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080053 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070054 if (dir.empty())
Yingdi Yu37e317f2014-03-19 12:16:23 -070055 m_keystorePath = boost::filesystem::path(getenv("HOME")) / ".ndn" / "ndnsec-tpm-file";
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080056 else
Yingdi Yu41546342014-11-30 23:37:53 -080057 m_keystorePath = boost::filesystem::path(dir) / ".ndn" / "ndnsec-tpm-file";
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070058
Yingdi Yu7036ce22014-06-19 18:53:37 -070059 boost::filesystem::create_directories(m_keystorePath);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080060 }
61
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080062 boost::filesystem::path
Yingdi Yu7036ce22014-06-19 18:53:37 -070063 transformName(const string& keyName, const string& extension)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080064 {
65 using namespace CryptoPP;
66 string digest;
67 SHA256 hash;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070068 StringSource src(keyName,
69 true,
70 new HashFilter(hash,
71 new Base64Encoder(new CryptoPP::StringSink(digest))));
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080072
73 boost::algorithm::trim(digest);
74 std::replace(digest.begin(), digest.end(), '/', '%');
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070075
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080076 return m_keystorePath / (digest + extension);
77 }
78
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070079 string
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080080 maintainMapping(const string& keyName)
81 {
Yingdi Yu7036ce22014-06-19 18:53:37 -070082 string keyFileName = transformName(keyName, "").string();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070083
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080084 ofstream outfile;
85 string dirFile = (m_keystorePath / "mapping.txt").string();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070086
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080087 outfile.open(dirFile.c_str(), std::ios_base::app);
88 outfile << keyName << ' ' << keyFileName << '\n';
89 outfile.close();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070090
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080091 return keyFileName;
92 }
93
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080094public:
95 boost::filesystem::path m_keystorePath;
96};
97
Yingdi Yu4b752752014-02-18 12:24:03 -080098
Yingdi Yu41546342014-11-30 23:37:53 -080099SecTpmFile::SecTpmFile(const string& location)
100 : SecTpm(location)
101 , m_impl(new Impl(location))
Yingdi Yube4150e2014-02-18 13:02:46 -0800102 , m_inTerminal(false)
Yingdi Yu7036ce22014-06-19 18:53:37 -0700103{
104}
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800105
Yingdi Yu41546342014-11-30 23:37:53 -0800106SecTpmFile::~SecTpmFile()
107{
108}
109
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800110void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700111SecTpmFile::generateKeyPairInTpm(const Name& keyName, const KeyParams& params)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800112{
113 string keyURI = keyName.toUri();
114
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700115 if (doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800116 throw Error("public key exists");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700117 if (doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800118 throw Error("private key exists");
119
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800120 string keyFileName = m_impl->maintainMapping(keyURI);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800121
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700122 try
123 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700124 switch (params.getKeyType())
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700125 {
126 case KEY_TYPE_RSA:
127 {
128 using namespace CryptoPP;
Yingdi Yu4b752752014-02-18 12:24:03 -0800129
Yingdi Yu7036ce22014-06-19 18:53:37 -0700130 const RsaKeyParams& rsaParams = static_cast<const RsaKeyParams&>(params);
131 AutoSeededRandomPool rng;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700132 InvertibleRSAFunction privateKey;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700133 privateKey.Initialize(rng, rsaParams.getKeySize());
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700134
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700135 string privateKeyFileName = keyFileName + ".pri";
136 Base64Encoder privateKeySink(new FileSink(privateKeyFileName.c_str()));
137 privateKey.DEREncode(privateKeySink);
138 privateKeySink.MessageEnd();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700139
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700140 RSAFunction publicKey(privateKey);
141 string publicKeyFileName = keyFileName + ".pub";
142 Base64Encoder publicKeySink(new FileSink(publicKeyFileName.c_str()));
143 publicKey.DEREncode(publicKeySink);
144 publicKeySink.MessageEnd();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700145
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700146 /*set file permission*/
147 chmod(privateKeyFileName.c_str(), 0000400);
148 chmod(publicKeyFileName.c_str(), 0000444);
149 return;
150 }
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700151 case KEY_TYPE_ECDSA:
152 {
153 using namespace CryptoPP;
154
155 const EcdsaKeyParams& ecdsaParams = static_cast<const EcdsaKeyParams&>(params);
156
Alexander Afanasyev07113802015-01-15 19:14:36 -0800157 CryptoPP::OID curveName;
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700158 switch (ecdsaParams.getKeySize())
159 {
160 case 256:
161 curveName = ASN1::secp256r1();
162 break;
163 case 384:
164 curveName = ASN1::secp384r1();
165 break;
166 default:
167 curveName = ASN1::secp256r1();
168 }
169
170 AutoSeededRandomPool rng;
171
172 ECDSA<ECP, SHA256>::PrivateKey privateKey;
173 DL_GroupParameters_EC<ECP> cryptoParams(curveName);
174 cryptoParams.SetEncodeAsOID(true);
175 privateKey.Initialize(rng, cryptoParams);
176
177 ECDSA<ECP, SHA256>::PublicKey publicKey;
178 privateKey.MakePublicKey(publicKey);
179 publicKey.AccessGroupParameters().SetEncodeAsOID(true);
180
181 string privateKeyFileName = keyFileName + ".pri";
182 Base64Encoder privateKeySink(new FileSink(privateKeyFileName.c_str()));
183 privateKey.DEREncode(privateKeySink);
184 privateKeySink.MessageEnd();
185
186 string publicKeyFileName = keyFileName + ".pub";
187 Base64Encoder publicKeySink(new FileSink(publicKeyFileName.c_str()));
188 publicKey.Save(publicKeySink);
189 publicKeySink.MessageEnd();
190
191 /*set file permission*/
192 chmod(privateKeyFileName.c_str(), 0000400);
193 chmod(publicKeyFileName.c_str(), 0000444);
194 return;
195 }
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700196 default:
197 throw Error("Unsupported key type!");
198 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800199 }
Yingdi Yu7036ce22014-06-19 18:53:37 -0700200 catch (KeyParams::Error& e)
201 {
202 throw Error(e.what());
203 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700204 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700205 {
206 throw Error(e.what());
207 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800208}
209
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800210void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700211SecTpmFile::deleteKeyPairInTpm(const Name& keyName)
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800212{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700213 boost::filesystem::path publicKeyPath(m_impl->transformName(keyName.toUri(), ".pub"));
214 boost::filesystem::path privateKeyPath(m_impl->transformName(keyName.toUri(), ".pri"));
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800215
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700216 if (boost::filesystem::exists(publicKeyPath))
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800217 boost::filesystem::remove(publicKeyPath);
218
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700219 if (boost::filesystem::exists(privateKeyPath))
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800220 boost::filesystem::remove(privateKeyPath);
221}
222
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800223shared_ptr<PublicKey>
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700224SecTpmFile::getPublicKeyFromTpm(const Name& keyName)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800225{
226 string keyURI = keyName.toUri();
227
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700228 if (!doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC))
Yingdi Yu5e96e002014-04-23 18:32:15 -0700229 throw Error("Public Key does not exist");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800230
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800231 ostringstream os;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700232 try
233 {
234 using namespace CryptoPP;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700235 FileSource(m_impl->transformName(keyURI, ".pub").string().c_str(),
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700236 true,
237 new Base64Decoder(new FileSink(os)));
238 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700239 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700240 {
241 throw Error(e.what());
242 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800243
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700244 return make_shared<PublicKey>(reinterpret_cast<const uint8_t*>(os.str().c_str()),
245 os.str().size());
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800246}
247
Yingdi Yu41546342014-11-30 23:37:53 -0800248std::string
249SecTpmFile::getScheme()
250{
251 return SCHEME;
252}
253
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800254ConstBufferPtr
Yingdi Yu5e96e002014-04-23 18:32:15 -0700255SecTpmFile::exportPrivateKeyPkcs8FromTpm(const Name& keyName)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800256{
257 OBufferStream privateKeyOs;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700258 CryptoPP::FileSource(m_impl->transformName(keyName.toUri(), ".pri").string().c_str(), true,
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800259 new CryptoPP::Base64Decoder(new CryptoPP::FileSink(privateKeyOs)));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700260
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800261 return privateKeyOs.buf();
262}
263
264bool
Yingdi Yu5e96e002014-04-23 18:32:15 -0700265SecTpmFile::importPrivateKeyPkcs8IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800266{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700267 try
268 {
269 using namespace CryptoPP;
270
271 string keyFileName = m_impl->maintainMapping(keyName.toUri());
272 keyFileName.append(".pri");
273 StringSource(buf, size,
274 true,
275 new Base64Encoder(new FileSink(keyFileName.c_str())));
276 return true;
277 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700278 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700279 {
280 return false;
281 }
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800282}
283
284bool
285SecTpmFile::importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
286{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700287 try
288 {
289 using namespace CryptoPP;
290
291 string keyFileName = m_impl->maintainMapping(keyName.toUri());
292 keyFileName.append(".pub");
293 StringSource(buf, size,
294 true,
295 new Base64Encoder(new FileSink(keyFileName.c_str())));
296 return true;
297 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700298 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700299 {
300 return false;
301 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800302}
303
304Block
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700305SecTpmFile::signInTpm(const uint8_t* data, size_t dataLength,
306 const Name& keyName, DigestAlgorithm digestAlgorithm)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800307{
308 string keyURI = keyName.toUri();
309
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700310 if (!doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800311 throw Error("private key doesn't exists");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700312
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700313 try
314 {
315 using namespace CryptoPP;
316 AutoSeededRandomPool rng;
Yingdi Yu4b752752014-02-18 12:24:03 -0800317
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700318 //Read public key
319 shared_ptr<PublicKey> pubkeyPtr;
320 pubkeyPtr = getPublicKeyFromTpm(keyName);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700321
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700322 switch (pubkeyPtr->getKeyType())
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700323 {
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700324 case KEY_TYPE_RSA:
325 {
326 //Read private key
327 ByteQueue bytes;
328 FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
329 true, new Base64Decoder);
330 file.TransferTo(bytes);
331 bytes.MessageEnd();
332 RSA::PrivateKey privateKey;
333 privateKey.Load(bytes);
334
335 //Sign message
336 switch (digestAlgorithm)
337 {
338 case DIGEST_ALGORITHM_SHA256:
339 {
340 RSASS<PKCS1v15, SHA256>::Signer signer(privateKey);
341
342 OBufferStream os;
343 StringSource(data, dataLength,
344 true,
345 new SignerFilter(rng, signer, new FileSink(os)));
346
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600347 return Block(tlv::SignatureValue, os.buf());
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700348 }
349 default:
350 throw Error("Unsupported digest algorithm!");
351 }
352 }
353 case KEY_TYPE_ECDSA:
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700354 {
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700355 //Read private key
356 ByteQueue bytes;
357 FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
358 true, new Base64Decoder);
359 file.TransferTo(bytes);
360 bytes.MessageEnd();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700361
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700362 //Sign message
363 switch (digestAlgorithm)
364 {
365 case DIGEST_ALGORITHM_SHA256:
366 {
367 ECDSA<ECP, SHA256>::PrivateKey privateKey;
368 privateKey.Load(bytes);
369 ECDSA<ECP, SHA256>::Signer signer(privateKey);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700370
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700371 OBufferStream os;
372 StringSource(data, dataLength,
373 true,
374 new SignerFilter(rng, signer, new FileSink(os)));
375
376 uint8_t buf[200];
377 size_t bufSize = DSAConvertSignatureFormat(buf, 200, DSA_DER,
378 os.buf()->buf(), os.buf()->size(),
379 DSA_P1363);
380
381 shared_ptr<Buffer> sigBuffer = make_shared<Buffer>(buf, bufSize);
382
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600383 return Block(tlv::SignatureValue, sigBuffer);
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700384 }
385 default:
386 throw Error("Unsupported digest algorithm!");
387 }
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700388 }
389 default:
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700390 throw Error("Unsupported key type!");
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700391 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800392 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700393 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700394 {
395 throw Error(e.what());
396 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800397}
398
399
400ConstBufferPtr
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700401SecTpmFile::decryptInTpm(const uint8_t* data, size_t dataLength,
402 const Name& keyName, bool isSymmetric)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800403{
Yingdi Yu2e57a582014-02-20 23:34:43 -0800404 throw Error("SecTpmFile::decryptInTpm is not supported!");
405 // string keyURI = keyName.toUri();
406 // if (!isSymmetric)
407 // {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700408 // if (!doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
Yingdi Yu2e57a582014-02-20 23:34:43 -0800409 // throw Error("private key doesn't exist");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800410
Yingdi Yu2e57a582014-02-20 23:34:43 -0800411 // try{
412 // using namespace CryptoPP;
413 // AutoSeededRandomPool rng;
Yingdi Yu4b752752014-02-18 12:24:03 -0800414
Yingdi Yu2e57a582014-02-20 23:34:43 -0800415 // //Read private key
416 // ByteQueue bytes;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700417 // FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(), true, new Base64Decoder);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800418 // file.TransferTo(bytes);
419 // bytes.MessageEnd();
420 // RSA::PrivateKey privateKey;
421 // privateKey.Load(bytes);
422 // RSAES_PKCS1v15_Decryptor decryptor(privateKey);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700423
Yingdi Yu2e57a582014-02-20 23:34:43 -0800424 // OBufferStream os;
425 // StringSource(data, dataLength, true, new PK_DecryptorFilter(rng, decryptor, new FileSink(os)));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700426
Yingdi Yu2e57a582014-02-20 23:34:43 -0800427 // return os.buf();
428 // }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700429 // catch (CryptoPP::Exception& e){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800430 // throw Error(e.what());
431 // }
432 // }
433 // else
434 // {
435 // throw Error("Symmetric encryption is not implemented!");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700436 // // if (!doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
Yingdi Yu7036ce22014-06-19 18:53:37 -0700437 // // throw Error("symmetric key doesn't exist");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800438
Yingdi Yu2e57a582014-02-20 23:34:43 -0800439 // // try{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700440 // // string keyBits;
441 // // string symKeyFileName = m_impl->transformName(keyURI, ".key");
442 // // FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700443
Yingdi Yu7036ce22014-06-19 18:53:37 -0700444 // // using CryptoPP::AES;
445 // // AutoSeededRandomPool rnd;
446 // // byte iv[AES::BLOCKSIZE];
447 // // rnd.GenerateBlock(iv, AES::BLOCKSIZE);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800448
Yingdi Yu7036ce22014-06-19 18:53:37 -0700449 // // CFB_Mode<AES>::Decryption decryptor;
450 // // decryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700451
Yingdi Yu7036ce22014-06-19 18:53:37 -0700452 // // OBufferStream os;
453 // // StringSource(data, dataLength, true, new StreamTransformationFilter(decryptor,new FileSink(os)));
454 // // return os.buf();
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800455
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700456 // // }catch (CryptoPP::Exception& e){
Yingdi Yu7036ce22014-06-19 18:53:37 -0700457 // // throw Error(e.what());
Yingdi Yu2e57a582014-02-20 23:34:43 -0800458 // // }
459 // }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800460}
461
462ConstBufferPtr
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700463SecTpmFile::encryptInTpm(const uint8_t* data, size_t dataLength,
464 const Name& keyName, bool isSymmetric)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800465{
Yingdi Yu2e57a582014-02-20 23:34:43 -0800466 throw Error("SecTpmFile::encryptInTpm is not supported!");
467 // string keyURI = keyName.toUri();
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800468
Yingdi Yu2e57a582014-02-20 23:34:43 -0800469 // if (!isSymmetric)
470 // {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700471 // if (!doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC))
Yingdi Yu2e57a582014-02-20 23:34:43 -0800472 // throw Error("public key doesn't exist");
473 // try
474 // {
475 // using namespace CryptoPP;
476 // AutoSeededRandomPool rng;
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800477
Yingdi Yu2e57a582014-02-20 23:34:43 -0800478 // //Read private key
479 // ByteQueue bytes;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700480 // FileSource file(m_impl->transformName(keyURI, ".pub").string().c_str(), true, new Base64Decoder);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800481 // file.TransferTo(bytes);
482 // bytes.MessageEnd();
483 // RSA::PublicKey publicKey;
484 // publicKey.Load(bytes);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800485
Yingdi Yu2e57a582014-02-20 23:34:43 -0800486 // OBufferStream os;
487 // RSAES_PKCS1v15_Encryptor encryptor(publicKey);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800488
Yingdi Yu2e57a582014-02-20 23:34:43 -0800489 // StringSource(data, dataLength, true, new PK_EncryptorFilter(rng, encryptor, new FileSink(os)));
490 // return os.buf();
491 // }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700492 // catch (CryptoPP::Exception& e){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800493 // throw Error(e.what());
494 // }
495 // }
496 // else
497 // {
498 // throw Error("Symmetric encryption is not implemented!");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700499 // // if (!doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
Yingdi Yu7036ce22014-06-19 18:53:37 -0700500 // // throw Error("symmetric key doesn't exist");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800501
Yingdi Yu2e57a582014-02-20 23:34:43 -0800502 // // try{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700503 // // string keyBits;
504 // // string symKeyFileName = m_impl->transformName(keyURI, ".key");
505 // // FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800506
Yingdi Yu7036ce22014-06-19 18:53:37 -0700507 // // using CryptoPP::AES;
508 // // AutoSeededRandomPool rnd;
509 // // byte iv[AES::BLOCKSIZE];
510 // // rnd.GenerateBlock(iv, AES::BLOCKSIZE);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800511
Yingdi Yu7036ce22014-06-19 18:53:37 -0700512 // // CFB_Mode<AES>::Encryption encryptor;
513 // // encryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800514
Yingdi Yu7036ce22014-06-19 18:53:37 -0700515 // // OBufferStream os;
516 // // StringSource(data, dataLength, true, new StreamTransformationFilter(encryptor, new FileSink(os)));
517 // // return os.buf();
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700518 // // }catch (CryptoPP::Exception& e){
Yingdi Yu7036ce22014-06-19 18:53:37 -0700519 // // throw Error(e.what());
Yingdi Yu2e57a582014-02-20 23:34:43 -0800520 // // }
521 // }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800522}
523
524
525void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700526SecTpmFile::generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800527{
Yingdi Yu2e57a582014-02-20 23:34:43 -0800528 throw Error("SecTpmFile::generateSymmetricKeyInTpm is not supported!");
529 // string keyURI = keyName.toUri();
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800530
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700531 // if (doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
Yingdi Yu2e57a582014-02-20 23:34:43 -0800532 // throw Error("symmetric key exists");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800533
Yingdi Yu2e57a582014-02-20 23:34:43 -0800534 // string keyFileName = m_impl->maintainMapping(keyURI);
535 // string symKeyFileName = keyFileName + ".key";
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800536
Yingdi Yu2e57a582014-02-20 23:34:43 -0800537 // try{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700538 // switch (keyType){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800539 // case KEY_TYPE_AES:
540 // {
541 // using namespace CryptoPP;
542 // AutoSeededRandomPool rng;
Yingdi Yu4b752752014-02-18 12:24:03 -0800543
Yingdi Yu2e57a582014-02-20 23:34:43 -0800544 // SecByteBlock key(0x00, keySize);
545 // rng.GenerateBlock(key, keySize);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700546
Yingdi Yu2e57a582014-02-20 23:34:43 -0800547 // StringSource(key, key.size(), true, new HexEncoder(new FileSink(symKeyFileName.c_str())));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700548
Yingdi Yu2e57a582014-02-20 23:34:43 -0800549 // chmod(symKeyFileName.c_str(), 0000400);
550 // return;
551 // }
552 // default:
553 // throw Error("Unsupported symmetric key type!");
554 // }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700555 // }catch (CryptoPP::Exception& e){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800556 // throw Error(e.what());
557 // }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800558}
559
560bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700561SecTpmFile::doesKeyExistInTpm(const Name& keyName, KeyClass keyClass)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800562{
563 string keyURI = keyName.toUri();
564 if (keyClass == KEY_CLASS_PUBLIC)
565 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700566 if (boost::filesystem::exists(m_impl->transformName(keyURI, ".pub")))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800567 return true;
568 else
569 return false;
570 }
571 if (keyClass == KEY_CLASS_PRIVATE)
572 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700573 if (boost::filesystem::exists(m_impl->transformName(keyURI, ".pri")))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800574 return true;
575 else
576 return false;
577 }
578 if (keyClass == KEY_CLASS_SYMMETRIC)
579 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700580 if (boost::filesystem::exists(m_impl->transformName(keyURI, ".key")))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800581 return true;
582 else
583 return false;
584 }
585 return false;
586}
587
Yingdi Yu4b752752014-02-18 12:24:03 -0800588bool
589SecTpmFile::generateRandomBlock(uint8_t* res, size_t size)
590{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700591 try
592 {
593 CryptoPP::AutoSeededRandomPool rng;
594 rng.GenerateBlock(res, size);
595 return true;
596 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700597 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700598 {
599 return false;
600 }
Yingdi Yu4b752752014-02-18 12:24:03 -0800601}
602
Yingdi Yufc40d872014-02-18 12:56:04 -0800603} // namespace ndn