blob: 26862c5d380e7a55e93c41b3eaa254206394beb3 [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
Yingdi Yu41546342014-11-30 23:37:53 -080047const std::string SecTpmFile::SCHEME("tpm-file:");
48
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070049class SecTpmFile::Impl
50{
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080051public:
Yingdi Yu7036ce22014-06-19 18:53:37 -070052 explicit
Yingdi Yu4b752752014-02-18 12:24:03 -080053 Impl(const string& dir)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080054 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070055 if (dir.empty())
Yingdi Yu37e317f2014-03-19 12:16:23 -070056 m_keystorePath = boost::filesystem::path(getenv("HOME")) / ".ndn" / "ndnsec-tpm-file";
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080057 else
Yingdi Yu41546342014-11-30 23:37:53 -080058 m_keystorePath = boost::filesystem::path(dir) / ".ndn" / "ndnsec-tpm-file";
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070059
Yingdi Yu7036ce22014-06-19 18:53:37 -070060 boost::filesystem::create_directories(m_keystorePath);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080061 }
62
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080063 boost::filesystem::path
Yingdi Yu7036ce22014-06-19 18:53:37 -070064 transformName(const string& keyName, const string& extension)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080065 {
66 using namespace CryptoPP;
67 string digest;
68 SHA256 hash;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070069 StringSource src(keyName,
70 true,
71 new HashFilter(hash,
72 new Base64Encoder(new CryptoPP::StringSink(digest))));
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080073
74 boost::algorithm::trim(digest);
75 std::replace(digest.begin(), digest.end(), '/', '%');
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070076
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080077 return m_keystorePath / (digest + extension);
78 }
79
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070080 string
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080081 maintainMapping(const string& keyName)
82 {
Yingdi Yu7036ce22014-06-19 18:53:37 -070083 string keyFileName = transformName(keyName, "").string();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070084
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080085 ofstream outfile;
86 string dirFile = (m_keystorePath / "mapping.txt").string();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070087
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080088 outfile.open(dirFile.c_str(), std::ios_base::app);
89 outfile << keyName << ' ' << keyFileName << '\n';
90 outfile.close();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070091
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080092 return keyFileName;
93 }
94
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080095public:
96 boost::filesystem::path m_keystorePath;
97};
98
Yingdi Yu4b752752014-02-18 12:24:03 -080099
Yingdi Yu41546342014-11-30 23:37:53 -0800100SecTpmFile::SecTpmFile(const string& location)
101 : SecTpm(location)
102 , m_impl(new Impl(location))
Yingdi Yube4150e2014-02-18 13:02:46 -0800103 , m_inTerminal(false)
Yingdi Yu7036ce22014-06-19 18:53:37 -0700104{
105}
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800106
Yingdi Yu41546342014-11-30 23:37:53 -0800107SecTpmFile::~SecTpmFile()
108{
109}
110
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800111void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700112SecTpmFile::generateKeyPairInTpm(const Name& keyName, const KeyParams& params)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800113{
114 string keyURI = keyName.toUri();
115
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700116 if (doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800117 throw Error("public key exists");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700118 if (doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800119 throw Error("private key exists");
120
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800121 string keyFileName = m_impl->maintainMapping(keyURI);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800122
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700123 try
124 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700125 switch (params.getKeyType())
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700126 {
127 case KEY_TYPE_RSA:
128 {
129 using namespace CryptoPP;
Yingdi Yu4b752752014-02-18 12:24:03 -0800130
Yingdi Yu7036ce22014-06-19 18:53:37 -0700131 const RsaKeyParams& rsaParams = static_cast<const RsaKeyParams&>(params);
132 AutoSeededRandomPool rng;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700133 InvertibleRSAFunction privateKey;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700134 privateKey.Initialize(rng, rsaParams.getKeySize());
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700135
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700136 string privateKeyFileName = keyFileName + ".pri";
137 Base64Encoder privateKeySink(new FileSink(privateKeyFileName.c_str()));
138 privateKey.DEREncode(privateKeySink);
139 privateKeySink.MessageEnd();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700140
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700141 RSAFunction publicKey(privateKey);
142 string publicKeyFileName = keyFileName + ".pub";
143 Base64Encoder publicKeySink(new FileSink(publicKeyFileName.c_str()));
144 publicKey.DEREncode(publicKeySink);
145 publicKeySink.MessageEnd();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700146
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700147 /*set file permission*/
148 chmod(privateKeyFileName.c_str(), 0000400);
149 chmod(publicKeyFileName.c_str(), 0000444);
150 return;
151 }
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700152 case KEY_TYPE_ECDSA:
153 {
154 using namespace CryptoPP;
155
156 const EcdsaKeyParams& ecdsaParams = static_cast<const EcdsaKeyParams&>(params);
157
158 OID curveName;
159 switch (ecdsaParams.getKeySize())
160 {
161 case 256:
162 curveName = ASN1::secp256r1();
163 break;
164 case 384:
165 curveName = ASN1::secp384r1();
166 break;
167 default:
168 curveName = ASN1::secp256r1();
169 }
170
171 AutoSeededRandomPool rng;
172
173 ECDSA<ECP, SHA256>::PrivateKey privateKey;
174 DL_GroupParameters_EC<ECP> cryptoParams(curveName);
175 cryptoParams.SetEncodeAsOID(true);
176 privateKey.Initialize(rng, cryptoParams);
177
178 ECDSA<ECP, SHA256>::PublicKey publicKey;
179 privateKey.MakePublicKey(publicKey);
180 publicKey.AccessGroupParameters().SetEncodeAsOID(true);
181
182 string privateKeyFileName = keyFileName + ".pri";
183 Base64Encoder privateKeySink(new FileSink(privateKeyFileName.c_str()));
184 privateKey.DEREncode(privateKeySink);
185 privateKeySink.MessageEnd();
186
187 string publicKeyFileName = keyFileName + ".pub";
188 Base64Encoder publicKeySink(new FileSink(publicKeyFileName.c_str()));
189 publicKey.Save(publicKeySink);
190 publicKeySink.MessageEnd();
191
192 /*set file permission*/
193 chmod(privateKeyFileName.c_str(), 0000400);
194 chmod(publicKeyFileName.c_str(), 0000444);
195 return;
196 }
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700197 default:
198 throw Error("Unsupported key type!");
199 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800200 }
Yingdi Yu7036ce22014-06-19 18:53:37 -0700201 catch (KeyParams::Error& e)
202 {
203 throw Error(e.what());
204 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700205 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700206 {
207 throw Error(e.what());
208 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800209}
210
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800211void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700212SecTpmFile::deleteKeyPairInTpm(const Name& keyName)
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800213{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700214 boost::filesystem::path publicKeyPath(m_impl->transformName(keyName.toUri(), ".pub"));
215 boost::filesystem::path privateKeyPath(m_impl->transformName(keyName.toUri(), ".pri"));
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800216
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700217 if (boost::filesystem::exists(publicKeyPath))
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800218 boost::filesystem::remove(publicKeyPath);
219
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700220 if (boost::filesystem::exists(privateKeyPath))
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800221 boost::filesystem::remove(privateKeyPath);
222}
223
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800224shared_ptr<PublicKey>
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700225SecTpmFile::getPublicKeyFromTpm(const Name& keyName)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800226{
227 string keyURI = keyName.toUri();
228
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700229 if (!doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC))
Yingdi Yu5e96e002014-04-23 18:32:15 -0700230 throw Error("Public Key does not exist");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800231
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800232 ostringstream os;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700233 try
234 {
235 using namespace CryptoPP;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700236 FileSource(m_impl->transformName(keyURI, ".pub").string().c_str(),
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700237 true,
238 new Base64Decoder(new FileSink(os)));
239 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700240 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700241 {
242 throw Error(e.what());
243 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800244
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700245 return make_shared<PublicKey>(reinterpret_cast<const uint8_t*>(os.str().c_str()),
246 os.str().size());
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800247}
248
Yingdi Yu41546342014-11-30 23:37:53 -0800249std::string
250SecTpmFile::getScheme()
251{
252 return SCHEME;
253}
254
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800255ConstBufferPtr
Yingdi Yu5e96e002014-04-23 18:32:15 -0700256SecTpmFile::exportPrivateKeyPkcs8FromTpm(const Name& keyName)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800257{
258 OBufferStream privateKeyOs;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700259 CryptoPP::FileSource(m_impl->transformName(keyName.toUri(), ".pri").string().c_str(), true,
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800260 new CryptoPP::Base64Decoder(new CryptoPP::FileSink(privateKeyOs)));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700261
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800262 return privateKeyOs.buf();
263}
264
265bool
Yingdi Yu5e96e002014-04-23 18:32:15 -0700266SecTpmFile::importPrivateKeyPkcs8IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800267{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700268 try
269 {
270 using namespace CryptoPP;
271
272 string keyFileName = m_impl->maintainMapping(keyName.toUri());
273 keyFileName.append(".pri");
274 StringSource(buf, size,
275 true,
276 new Base64Encoder(new FileSink(keyFileName.c_str())));
277 return true;
278 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700279 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700280 {
281 return false;
282 }
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800283}
284
285bool
286SecTpmFile::importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
287{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700288 try
289 {
290 using namespace CryptoPP;
291
292 string keyFileName = m_impl->maintainMapping(keyName.toUri());
293 keyFileName.append(".pub");
294 StringSource(buf, size,
295 true,
296 new Base64Encoder(new FileSink(keyFileName.c_str())));
297 return true;
298 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700299 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700300 {
301 return false;
302 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800303}
304
305Block
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700306SecTpmFile::signInTpm(const uint8_t* data, size_t dataLength,
307 const Name& keyName, DigestAlgorithm digestAlgorithm)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800308{
309 string keyURI = keyName.toUri();
310
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700311 if (!doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800312 throw Error("private key doesn't exists");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700313
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700314 try
315 {
316 using namespace CryptoPP;
317 AutoSeededRandomPool rng;
Yingdi Yu4b752752014-02-18 12:24:03 -0800318
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700319 //Read public key
320 shared_ptr<PublicKey> pubkeyPtr;
321 pubkeyPtr = getPublicKeyFromTpm(keyName);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700322
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700323 switch (pubkeyPtr->getKeyType())
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700324 {
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700325 case KEY_TYPE_RSA:
326 {
327 //Read private key
328 ByteQueue bytes;
329 FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
330 true, new Base64Decoder);
331 file.TransferTo(bytes);
332 bytes.MessageEnd();
333 RSA::PrivateKey privateKey;
334 privateKey.Load(bytes);
335
336 //Sign message
337 switch (digestAlgorithm)
338 {
339 case DIGEST_ALGORITHM_SHA256:
340 {
341 RSASS<PKCS1v15, SHA256>::Signer signer(privateKey);
342
343 OBufferStream os;
344 StringSource(data, dataLength,
345 true,
346 new SignerFilter(rng, signer, new FileSink(os)));
347
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600348 return Block(tlv::SignatureValue, os.buf());
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700349 }
350 default:
351 throw Error("Unsupported digest algorithm!");
352 }
353 }
354 case KEY_TYPE_ECDSA:
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700355 {
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700356 //Read private key
357 ByteQueue bytes;
358 FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
359 true, new Base64Decoder);
360 file.TransferTo(bytes);
361 bytes.MessageEnd();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700362
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700363 //Sign message
364 switch (digestAlgorithm)
365 {
366 case DIGEST_ALGORITHM_SHA256:
367 {
368 ECDSA<ECP, SHA256>::PrivateKey privateKey;
369 privateKey.Load(bytes);
370 ECDSA<ECP, SHA256>::Signer signer(privateKey);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700371
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700372 OBufferStream os;
373 StringSource(data, dataLength,
374 true,
375 new SignerFilter(rng, signer, new FileSink(os)));
376
377 uint8_t buf[200];
378 size_t bufSize = DSAConvertSignatureFormat(buf, 200, DSA_DER,
379 os.buf()->buf(), os.buf()->size(),
380 DSA_P1363);
381
382 shared_ptr<Buffer> sigBuffer = make_shared<Buffer>(buf, bufSize);
383
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600384 return Block(tlv::SignatureValue, sigBuffer);
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700385 }
386 default:
387 throw Error("Unsupported digest algorithm!");
388 }
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700389 }
390 default:
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700391 throw Error("Unsupported key type!");
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700392 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800393 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700394 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700395 {
396 throw Error(e.what());
397 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800398}
399
400
401ConstBufferPtr
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700402SecTpmFile::decryptInTpm(const uint8_t* data, size_t dataLength,
403 const Name& keyName, bool isSymmetric)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800404{
Yingdi Yu2e57a582014-02-20 23:34:43 -0800405 throw Error("SecTpmFile::decryptInTpm is not supported!");
406 // string keyURI = keyName.toUri();
407 // if (!isSymmetric)
408 // {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700409 // if (!doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
Yingdi Yu2e57a582014-02-20 23:34:43 -0800410 // throw Error("private key doesn't exist");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800411
Yingdi Yu2e57a582014-02-20 23:34:43 -0800412 // try{
413 // using namespace CryptoPP;
414 // AutoSeededRandomPool rng;
Yingdi Yu4b752752014-02-18 12:24:03 -0800415
Yingdi Yu2e57a582014-02-20 23:34:43 -0800416 // //Read private key
417 // ByteQueue bytes;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700418 // FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(), true, new Base64Decoder);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800419 // file.TransferTo(bytes);
420 // bytes.MessageEnd();
421 // RSA::PrivateKey privateKey;
422 // privateKey.Load(bytes);
423 // RSAES_PKCS1v15_Decryptor decryptor(privateKey);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700424
Yingdi Yu2e57a582014-02-20 23:34:43 -0800425 // OBufferStream os;
426 // StringSource(data, dataLength, true, new PK_DecryptorFilter(rng, decryptor, new FileSink(os)));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700427
Yingdi Yu2e57a582014-02-20 23:34:43 -0800428 // return os.buf();
429 // }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700430 // catch (CryptoPP::Exception& e){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800431 // throw Error(e.what());
432 // }
433 // }
434 // else
435 // {
436 // throw Error("Symmetric encryption is not implemented!");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700437 // // if (!doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
Yingdi Yu7036ce22014-06-19 18:53:37 -0700438 // // throw Error("symmetric key doesn't exist");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800439
Yingdi Yu2e57a582014-02-20 23:34:43 -0800440 // // try{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700441 // // string keyBits;
442 // // string symKeyFileName = m_impl->transformName(keyURI, ".key");
443 // // FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700444
Yingdi Yu7036ce22014-06-19 18:53:37 -0700445 // // using CryptoPP::AES;
446 // // AutoSeededRandomPool rnd;
447 // // byte iv[AES::BLOCKSIZE];
448 // // rnd.GenerateBlock(iv, AES::BLOCKSIZE);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800449
Yingdi Yu7036ce22014-06-19 18:53:37 -0700450 // // CFB_Mode<AES>::Decryption decryptor;
451 // // decryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700452
Yingdi Yu7036ce22014-06-19 18:53:37 -0700453 // // OBufferStream os;
454 // // StringSource(data, dataLength, true, new StreamTransformationFilter(decryptor,new FileSink(os)));
455 // // return os.buf();
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800456
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700457 // // }catch (CryptoPP::Exception& e){
Yingdi Yu7036ce22014-06-19 18:53:37 -0700458 // // throw Error(e.what());
Yingdi Yu2e57a582014-02-20 23:34:43 -0800459 // // }
460 // }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800461}
462
463ConstBufferPtr
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700464SecTpmFile::encryptInTpm(const uint8_t* data, size_t dataLength,
465 const Name& keyName, bool isSymmetric)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800466{
Yingdi Yu2e57a582014-02-20 23:34:43 -0800467 throw Error("SecTpmFile::encryptInTpm is not supported!");
468 // string keyURI = keyName.toUri();
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800469
Yingdi Yu2e57a582014-02-20 23:34:43 -0800470 // if (!isSymmetric)
471 // {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700472 // if (!doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC))
Yingdi Yu2e57a582014-02-20 23:34:43 -0800473 // throw Error("public key doesn't exist");
474 // try
475 // {
476 // using namespace CryptoPP;
477 // AutoSeededRandomPool rng;
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800478
Yingdi Yu2e57a582014-02-20 23:34:43 -0800479 // //Read private key
480 // ByteQueue bytes;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700481 // FileSource file(m_impl->transformName(keyURI, ".pub").string().c_str(), true, new Base64Decoder);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800482 // file.TransferTo(bytes);
483 // bytes.MessageEnd();
484 // RSA::PublicKey publicKey;
485 // publicKey.Load(bytes);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800486
Yingdi Yu2e57a582014-02-20 23:34:43 -0800487 // OBufferStream os;
488 // RSAES_PKCS1v15_Encryptor encryptor(publicKey);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800489
Yingdi Yu2e57a582014-02-20 23:34:43 -0800490 // StringSource(data, dataLength, true, new PK_EncryptorFilter(rng, encryptor, new FileSink(os)));
491 // return os.buf();
492 // }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700493 // catch (CryptoPP::Exception& e){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800494 // throw Error(e.what());
495 // }
496 // }
497 // else
498 // {
499 // throw Error("Symmetric encryption is not implemented!");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700500 // // if (!doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
Yingdi Yu7036ce22014-06-19 18:53:37 -0700501 // // throw Error("symmetric key doesn't exist");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800502
Yingdi Yu2e57a582014-02-20 23:34:43 -0800503 // // try{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700504 // // string keyBits;
505 // // string symKeyFileName = m_impl->transformName(keyURI, ".key");
506 // // FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800507
Yingdi Yu7036ce22014-06-19 18:53:37 -0700508 // // using CryptoPP::AES;
509 // // AutoSeededRandomPool rnd;
510 // // byte iv[AES::BLOCKSIZE];
511 // // rnd.GenerateBlock(iv, AES::BLOCKSIZE);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800512
Yingdi Yu7036ce22014-06-19 18:53:37 -0700513 // // CFB_Mode<AES>::Encryption encryptor;
514 // // encryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800515
Yingdi Yu7036ce22014-06-19 18:53:37 -0700516 // // OBufferStream os;
517 // // StringSource(data, dataLength, true, new StreamTransformationFilter(encryptor, new FileSink(os)));
518 // // return os.buf();
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700519 // // }catch (CryptoPP::Exception& e){
Yingdi Yu7036ce22014-06-19 18:53:37 -0700520 // // throw Error(e.what());
Yingdi Yu2e57a582014-02-20 23:34:43 -0800521 // // }
522 // }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800523}
524
525
526void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700527SecTpmFile::generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800528{
Yingdi Yu2e57a582014-02-20 23:34:43 -0800529 throw Error("SecTpmFile::generateSymmetricKeyInTpm is not supported!");
530 // string keyURI = keyName.toUri();
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800531
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700532 // if (doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
Yingdi Yu2e57a582014-02-20 23:34:43 -0800533 // throw Error("symmetric key exists");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800534
Yingdi Yu2e57a582014-02-20 23:34:43 -0800535 // string keyFileName = m_impl->maintainMapping(keyURI);
536 // string symKeyFileName = keyFileName + ".key";
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800537
Yingdi Yu2e57a582014-02-20 23:34:43 -0800538 // try{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700539 // switch (keyType){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800540 // case KEY_TYPE_AES:
541 // {
542 // using namespace CryptoPP;
543 // AutoSeededRandomPool rng;
Yingdi Yu4b752752014-02-18 12:24:03 -0800544
Yingdi Yu2e57a582014-02-20 23:34:43 -0800545 // SecByteBlock key(0x00, keySize);
546 // rng.GenerateBlock(key, keySize);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700547
Yingdi Yu2e57a582014-02-20 23:34:43 -0800548 // StringSource(key, key.size(), true, new HexEncoder(new FileSink(symKeyFileName.c_str())));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700549
Yingdi Yu2e57a582014-02-20 23:34:43 -0800550 // chmod(symKeyFileName.c_str(), 0000400);
551 // return;
552 // }
553 // default:
554 // throw Error("Unsupported symmetric key type!");
555 // }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700556 // }catch (CryptoPP::Exception& e){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800557 // throw Error(e.what());
558 // }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800559}
560
561bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700562SecTpmFile::doesKeyExistInTpm(const Name& keyName, KeyClass keyClass)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800563{
564 string keyURI = keyName.toUri();
565 if (keyClass == KEY_CLASS_PUBLIC)
566 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700567 if (boost::filesystem::exists(m_impl->transformName(keyURI, ".pub")))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800568 return true;
569 else
570 return false;
571 }
572 if (keyClass == KEY_CLASS_PRIVATE)
573 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700574 if (boost::filesystem::exists(m_impl->transformName(keyURI, ".pri")))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800575 return true;
576 else
577 return false;
578 }
579 if (keyClass == KEY_CLASS_SYMMETRIC)
580 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700581 if (boost::filesystem::exists(m_impl->transformName(keyURI, ".key")))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800582 return true;
583 else
584 return false;
585 }
586 return false;
587}
588
Yingdi Yu4b752752014-02-18 12:24:03 -0800589bool
590SecTpmFile::generateRandomBlock(uint8_t* res, size_t size)
591{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700592 try
593 {
594 CryptoPP::AutoSeededRandomPool rng;
595 rng.GenerateBlock(res, size);
596 return true;
597 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700598 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700599 {
600 return false;
601 }
Yingdi Yu4b752752014-02-18 12:24:03 -0800602}
603
Yingdi Yufc40d872014-02-18 12:56:04 -0800604} // namespace ndn