blob: 931d8fdb57d5efd796b2454539ac825e48ca895b [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 Afanasyev57e00362016-06-23 13:22:54 -07003 * Copyright (c) 2013-2016 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
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070033#include "v1/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 {
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070041namespace security {
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 Afanasyev07113802015-01-15 19:14:36 -080047const std::string SecTpmFile::SCHEME("tpm-file");
Yingdi Yu41546342014-11-30 23:37:53 -080048
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 Afanasyev57e00362016-06-23 13:22:54 -070055 boost::filesystem::path actualDir;
56 if (dir.empty()) {
57#ifdef NDN_CXX_HAVE_TESTS
58 if (getenv("TEST_HOME") != nullptr) {
59 actualDir = boost::filesystem::path(getenv("TEST_HOME")) / ".ndn";
60 }
61 else
62#endif // NDN_CXX_HAVE_TESTS
63 if (getenv("HOME") != nullptr) {
64 actualDir = boost::filesystem::path(getenv("HOME")) / ".ndn";
65 }
66 else {
67 actualDir = boost::filesystem::path(".") / ".ndn";
68 }
69 }
70 else {
71 actualDir = boost::filesystem::path(dir);
72 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070073
Alexander Afanasyev57e00362016-06-23 13:22:54 -070074 m_keystorePath = actualDir / "ndnsec-tpm-file";
Yingdi Yu7036ce22014-06-19 18:53:37 -070075 boost::filesystem::create_directories(m_keystorePath);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080076 }
77
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080078 boost::filesystem::path
Yingdi Yu7036ce22014-06-19 18:53:37 -070079 transformName(const string& keyName, const string& extension)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080080 {
81 using namespace CryptoPP;
82 string digest;
83 SHA256 hash;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070084 StringSource src(keyName,
85 true,
86 new HashFilter(hash,
87 new Base64Encoder(new CryptoPP::StringSink(digest))));
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080088
89 boost::algorithm::trim(digest);
90 std::replace(digest.begin(), digest.end(), '/', '%');
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070091
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080092 return m_keystorePath / (digest + extension);
93 }
94
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070095 string
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080096 maintainMapping(const string& keyName)
97 {
Yingdi Yu7036ce22014-06-19 18:53:37 -070098 string keyFileName = transformName(keyName, "").string();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070099
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800100 ofstream outfile;
101 string dirFile = (m_keystorePath / "mapping.txt").string();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700102
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800103 outfile.open(dirFile.c_str(), std::ios_base::app);
104 outfile << keyName << ' ' << keyFileName << '\n';
105 outfile.close();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700106
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800107 return keyFileName;
108 }
109
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800110public:
111 boost::filesystem::path m_keystorePath;
112};
113
Yingdi Yu4b752752014-02-18 12:24:03 -0800114
Yingdi Yu41546342014-11-30 23:37:53 -0800115SecTpmFile::SecTpmFile(const string& location)
116 : SecTpm(location)
117 , m_impl(new Impl(location))
Yingdi Yube4150e2014-02-18 13:02:46 -0800118 , m_inTerminal(false)
Yingdi Yu7036ce22014-06-19 18:53:37 -0700119{
120}
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800121
Yingdi Yu41546342014-11-30 23:37:53 -0800122SecTpmFile::~SecTpmFile()
123{
124}
125
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800126void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700127SecTpmFile::generateKeyPairInTpm(const Name& keyName, const KeyParams& params)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800128{
129 string keyURI = keyName.toUri();
130
Yingdi Yu99b2a002015-08-12 12:47:44 -0700131 if (doesKeyExistInTpm(keyName, KeyClass::PUBLIC))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700132 BOOST_THROW_EXCEPTION(Error("public key exists"));
Yingdi Yu99b2a002015-08-12 12:47:44 -0700133 if (doesKeyExistInTpm(keyName, KeyClass::PRIVATE))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700134 BOOST_THROW_EXCEPTION(Error("private key exists"));
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800135
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800136 string keyFileName = m_impl->maintainMapping(keyURI);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800137
Yingdi Yu99b2a002015-08-12 12:47:44 -0700138 try {
139 switch (params.getKeyType()) {
140 case KeyType::RSA: {
141 using namespace CryptoPP;
Yingdi Yu4b752752014-02-18 12:24:03 -0800142
Yingdi Yu99b2a002015-08-12 12:47:44 -0700143 const RsaKeyParams& rsaParams = static_cast<const RsaKeyParams&>(params);
144 AutoSeededRandomPool rng;
145 InvertibleRSAFunction privateKey;
146 privateKey.Initialize(rng, rsaParams.getKeySize());
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700147
Yingdi Yu99b2a002015-08-12 12:47:44 -0700148 string privateKeyFileName = keyFileName + ".pri";
149 Base64Encoder privateKeySink(new FileSink(privateKeyFileName.c_str()));
150 privateKey.DEREncode(privateKeySink);
151 privateKeySink.MessageEnd();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700152
Yingdi Yu99b2a002015-08-12 12:47:44 -0700153 RSAFunction publicKey(privateKey);
154 string publicKeyFileName = keyFileName + ".pub";
155 Base64Encoder publicKeySink(new FileSink(publicKeyFileName.c_str()));
156 publicKey.DEREncode(publicKeySink);
157 publicKeySink.MessageEnd();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700158
Yingdi Yu99b2a002015-08-12 12:47:44 -0700159 // set file permission
160 chmod(privateKeyFileName.c_str(), 0000400);
161 chmod(publicKeyFileName.c_str(), 0000444);
162 return;
163 }
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700164
Yingdi Yu99b2a002015-08-12 12:47:44 -0700165 case KeyType::EC: {
166 using namespace CryptoPP;
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700167
Yingdi Yu99b2a002015-08-12 12:47:44 -0700168 const EcdsaKeyParams& ecdsaParams = static_cast<const EcdsaKeyParams&>(params);
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700169
Yingdi Yu99b2a002015-08-12 12:47:44 -0700170 CryptoPP::OID curveName;
171 switch (ecdsaParams.getKeySize()) {
172 case 256:
173 curveName = ASN1::secp256r1();
174 break;
175 case 384:
176 curveName = ASN1::secp384r1();
177 break;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700178 default:
Yingdi Yu99b2a002015-08-12 12:47:44 -0700179 curveName = ASN1::secp256r1();
180 break;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700181 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700182
183 AutoSeededRandomPool rng;
184
185 ECDSA<ECP, SHA256>::PrivateKey privateKey;
186 DL_GroupParameters_EC<ECP> cryptoParams(curveName);
187 cryptoParams.SetEncodeAsOID(true);
188 privateKey.Initialize(rng, cryptoParams);
189
190 ECDSA<ECP, SHA256>::PublicKey publicKey;
191 privateKey.MakePublicKey(publicKey);
192 publicKey.AccessGroupParameters().SetEncodeAsOID(true);
193
194 string privateKeyFileName = keyFileName + ".pri";
195 Base64Encoder privateKeySink(new FileSink(privateKeyFileName.c_str()));
196 privateKey.DEREncode(privateKeySink);
197 privateKeySink.MessageEnd();
198
199 string publicKeyFileName = keyFileName + ".pub";
200 Base64Encoder publicKeySink(new FileSink(publicKeyFileName.c_str()));
201 publicKey.Save(publicKeySink);
202 publicKeySink.MessageEnd();
203
204 // set file permission
205 chmod(privateKeyFileName.c_str(), 0000400);
206 chmod(publicKeyFileName.c_str(), 0000444);
207 return;
208 }
209
210 default:
211 BOOST_THROW_EXCEPTION(Error("Unsupported key type"));
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800212 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700213 }
214 catch (const KeyParams::Error& e) {
215 BOOST_THROW_EXCEPTION(Error(e.what()));
216 }
217 catch (const CryptoPP::Exception& e) {
218 BOOST_THROW_EXCEPTION(Error(e.what()));
219 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800220}
221
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800222void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700223SecTpmFile::deleteKeyPairInTpm(const Name& keyName)
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800224{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700225 boost::filesystem::path publicKeyPath(m_impl->transformName(keyName.toUri(), ".pub"));
226 boost::filesystem::path privateKeyPath(m_impl->transformName(keyName.toUri(), ".pri"));
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800227
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700228 if (boost::filesystem::exists(publicKeyPath))
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800229 boost::filesystem::remove(publicKeyPath);
230
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700231 if (boost::filesystem::exists(privateKeyPath))
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800232 boost::filesystem::remove(privateKeyPath);
233}
234
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700235shared_ptr<v1::PublicKey>
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700236SecTpmFile::getPublicKeyFromTpm(const Name& keyName)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800237{
238 string keyURI = keyName.toUri();
239
Yingdi Yu99b2a002015-08-12 12:47:44 -0700240 if (!doesKeyExistInTpm(keyName, KeyClass::PUBLIC))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700241 BOOST_THROW_EXCEPTION(Error("Public Key does not exist"));
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800242
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800243 ostringstream os;
Yingdi Yu99b2a002015-08-12 12:47:44 -0700244 try {
245 using namespace CryptoPP;
246 FileSource(m_impl->transformName(keyURI, ".pub").string().c_str(),
247 true,
248 new Base64Decoder(new FileSink(os)));
249 }
250 catch (const CryptoPP::Exception& e) {
251 BOOST_THROW_EXCEPTION(Error(e.what()));
252 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800253
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700254 return make_shared<v1::PublicKey>(reinterpret_cast<const uint8_t*>(os.str().c_str()),
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700255 os.str().size());
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800256}
257
Yingdi Yu41546342014-11-30 23:37:53 -0800258std::string
259SecTpmFile::getScheme()
260{
261 return SCHEME;
262}
263
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800264ConstBufferPtr
Yingdi Yu5e96e002014-04-23 18:32:15 -0700265SecTpmFile::exportPrivateKeyPkcs8FromTpm(const Name& keyName)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800266{
267 OBufferStream privateKeyOs;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700268 CryptoPP::FileSource(m_impl->transformName(keyName.toUri(), ".pri").string().c_str(), true,
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800269 new CryptoPP::Base64Decoder(new CryptoPP::FileSink(privateKeyOs)));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700270
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800271 return privateKeyOs.buf();
272}
273
274bool
Yingdi Yu5e96e002014-04-23 18:32:15 -0700275SecTpmFile::importPrivateKeyPkcs8IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800276{
Yingdi Yu99b2a002015-08-12 12:47:44 -0700277 try {
278 using namespace CryptoPP;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700279
Yingdi Yu99b2a002015-08-12 12:47:44 -0700280 string keyFileName = m_impl->maintainMapping(keyName.toUri());
281 keyFileName.append(".pri");
282 StringSource(buf, size,
283 true,
284 new Base64Encoder(new FileSink(keyFileName.c_str())));
285 return true;
286 }
287 catch (const CryptoPP::Exception& e) {
288 return false;
289 }
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800290}
291
292bool
293SecTpmFile::importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
294{
Yingdi Yu99b2a002015-08-12 12:47:44 -0700295 try {
296 using namespace CryptoPP;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700297
Yingdi Yu99b2a002015-08-12 12:47:44 -0700298 string keyFileName = m_impl->maintainMapping(keyName.toUri());
299 keyFileName.append(".pub");
300 StringSource(buf, size,
301 true,
302 new Base64Encoder(new FileSink(keyFileName.c_str())));
303 return true;
304 }
305 catch (const CryptoPP::Exception& e) {
306 return false;
307 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800308}
309
310Block
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700311SecTpmFile::signInTpm(const uint8_t* data, size_t dataLength,
312 const Name& keyName, DigestAlgorithm digestAlgorithm)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800313{
314 string keyURI = keyName.toUri();
315
Yingdi Yu99b2a002015-08-12 12:47:44 -0700316 if (!doesKeyExistInTpm(keyName, KeyClass::PRIVATE))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700317 BOOST_THROW_EXCEPTION(Error("private key doesn't exist"));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700318
Yingdi Yu99b2a002015-08-12 12:47:44 -0700319 try {
320 using namespace CryptoPP;
321 AutoSeededRandomPool rng;
Yingdi Yu4b752752014-02-18 12:24:03 -0800322
Yingdi Yu99b2a002015-08-12 12:47:44 -0700323 // Read public key
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700324 shared_ptr<v1::PublicKey> pubkeyPtr;
Yingdi Yu99b2a002015-08-12 12:47:44 -0700325 pubkeyPtr = getPublicKeyFromTpm(keyName);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700326
Yingdi Yu99b2a002015-08-12 12:47:44 -0700327 switch (pubkeyPtr->getKeyType()) {
328 case KeyType::RSA: {
329 // Read private key
330 ByteQueue bytes;
331 FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
332 true, new Base64Decoder);
333 file.TransferTo(bytes);
334 bytes.MessageEnd();
335 RSA::PrivateKey privateKey;
336 privateKey.Load(bytes);
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700337
Yingdi Yu99b2a002015-08-12 12:47:44 -0700338 // Sign message
339 switch (digestAlgorithm) {
340 case DigestAlgorithm::SHA256: {
341 RSASS<PKCS1v15, SHA256>::Signer signer(privateKey);
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700342
Yingdi Yu99b2a002015-08-12 12:47:44 -0700343 OBufferStream os;
344 StringSource(data, dataLength,
345 true,
346 new SignerFilter(rng, signer, new FileSink(os)));
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700347
Yingdi Yu99b2a002015-08-12 12:47:44 -0700348 return Block(tlv::SignatureValue, os.buf());
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700349 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700350
351 default:
352 BOOST_THROW_EXCEPTION(Error("Unsupported digest algorithm"));
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700353 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700354 }
355
356 case KeyType::EC: {
357 // Read private key
358 ByteQueue bytes;
359 FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
360 true, new Base64Decoder);
361 file.TransferTo(bytes);
362 bytes.MessageEnd();
363
364 // Sign message
365 switch (digestAlgorithm) {
366 case DigestAlgorithm::SHA256: {
367 ECDSA<ECP, SHA256>::PrivateKey privateKey;
368 privateKey.Load(bytes);
369 ECDSA<ECP, SHA256>::Signer signer(privateKey);
370
371 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, sizeof(buf), DSA_DER,
378 os.buf()->buf(), os.buf()->size(),
379 DSA_P1363);
380
381 shared_ptr<Buffer> sigBuffer = make_shared<Buffer>(buf, bufSize);
382
383 return Block(tlv::SignatureValue, sigBuffer);
384 }
385
386 default:
387 BOOST_THROW_EXCEPTION(Error("Unsupported digest algorithm"));
388 }
389 }
390
391 default:
392 BOOST_THROW_EXCEPTION(Error("Unsupported key type"));
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800393 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700394 }
395 catch (const CryptoPP::Exception& e) {
396 BOOST_THROW_EXCEPTION(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{
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700405 BOOST_THROW_EXCEPTION(Error("SecTpmFile::decryptInTpm is not supported"));
Yingdi Yu2e57a582014-02-20 23:34:43 -0800406 // string keyURI = keyName.toUri();
407 // if (!isSymmetric)
408 // {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700409 // if (!doesKeyExistInTpm(keyName, KeyClass::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 // }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700430 // catch (const 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!");
Yingdi Yu99b2a002015-08-12 12:47:44 -0700437 // // if (!doesKeyExistInTpm(keyName, KeyClass::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
Yingdi Yu99b2a002015-08-12 12:47:44 -0700457 // // }
458 // // catch (const CryptoPP::Exception& e){
Yingdi Yu7036ce22014-06-19 18:53:37 -0700459 // // throw Error(e.what());
Yingdi Yu2e57a582014-02-20 23:34:43 -0800460 // // }
461 // }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800462}
463
464ConstBufferPtr
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700465SecTpmFile::encryptInTpm(const uint8_t* data, size_t dataLength,
466 const Name& keyName, bool isSymmetric)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800467{
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700468 BOOST_THROW_EXCEPTION(Error("SecTpmFile::encryptInTpm is not supported"));
Yingdi Yu2e57a582014-02-20 23:34:43 -0800469 // string keyURI = keyName.toUri();
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800470
Yingdi Yu2e57a582014-02-20 23:34:43 -0800471 // if (!isSymmetric)
472 // {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700473 // if (!doesKeyExistInTpm(keyName, KeyClass::PUBLIC))
Yingdi Yu2e57a582014-02-20 23:34:43 -0800474 // throw Error("public key doesn't exist");
475 // try
476 // {
477 // using namespace CryptoPP;
478 // AutoSeededRandomPool rng;
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800479
Yingdi Yu2e57a582014-02-20 23:34:43 -0800480 // //Read private key
481 // ByteQueue bytes;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700482 // FileSource file(m_impl->transformName(keyURI, ".pub").string().c_str(), true, new Base64Decoder);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800483 // file.TransferTo(bytes);
484 // bytes.MessageEnd();
485 // RSA::PublicKey publicKey;
486 // publicKey.Load(bytes);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800487
Yingdi Yu2e57a582014-02-20 23:34:43 -0800488 // OBufferStream os;
489 // RSAES_PKCS1v15_Encryptor encryptor(publicKey);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800490
Yingdi Yu2e57a582014-02-20 23:34:43 -0800491 // StringSource(data, dataLength, true, new PK_EncryptorFilter(rng, encryptor, new FileSink(os)));
492 // return os.buf();
493 // }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700494 // catch (const CryptoPP::Exception& e){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800495 // throw Error(e.what());
496 // }
497 // }
498 // else
499 // {
500 // throw Error("Symmetric encryption is not implemented!");
Yingdi Yu99b2a002015-08-12 12:47:44 -0700501 // // if (!doesKeyExistInTpm(keyName, KeyClass::SYMMETRIC))
Yingdi Yu7036ce22014-06-19 18:53:37 -0700502 // // throw Error("symmetric key doesn't exist");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800503
Yingdi Yu2e57a582014-02-20 23:34:43 -0800504 // // try{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700505 // // string keyBits;
506 // // string symKeyFileName = m_impl->transformName(keyURI, ".key");
507 // // FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800508
Yingdi Yu7036ce22014-06-19 18:53:37 -0700509 // // using CryptoPP::AES;
510 // // AutoSeededRandomPool rnd;
511 // // byte iv[AES::BLOCKSIZE];
512 // // rnd.GenerateBlock(iv, AES::BLOCKSIZE);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800513
Yingdi Yu7036ce22014-06-19 18:53:37 -0700514 // // CFB_Mode<AES>::Encryption encryptor;
515 // // encryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800516
Yingdi Yu7036ce22014-06-19 18:53:37 -0700517 // // OBufferStream os;
518 // // StringSource(data, dataLength, true, new StreamTransformationFilter(encryptor, new FileSink(os)));
519 // // return os.buf();
Yingdi Yu99b2a002015-08-12 12:47:44 -0700520 // // } catch (const CryptoPP::Exception& e){
Yingdi Yu7036ce22014-06-19 18:53:37 -0700521 // // throw Error(e.what());
Yingdi Yu2e57a582014-02-20 23:34:43 -0800522 // // }
523 // }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800524}
525
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800526void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700527SecTpmFile::generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800528{
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700529 BOOST_THROW_EXCEPTION(Error("SecTpmFile::generateSymmetricKeyInTpm is not supported"));
Yingdi Yu2e57a582014-02-20 23:34:43 -0800530 // string keyURI = keyName.toUri();
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800531
Yingdi Yu99b2a002015-08-12 12:47:44 -0700532 // if (doesKeyExistInTpm(keyName, KeyClass::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 Yu99b2a002015-08-12 12:47:44 -0700540 // case KeyType::AES:
Yingdi Yu2e57a582014-02-20 23:34:43 -0800541 // {
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 // }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700556 // } catch (const 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();
Yingdi Yu99b2a002015-08-12 12:47:44 -0700565 if (keyClass == KeyClass::PUBLIC) {
566 return boost::filesystem::exists(m_impl->transformName(keyURI, ".pub"));
567 }
568 if (keyClass == KeyClass::PRIVATE) {
569 return boost::filesystem::exists(m_impl->transformName(keyURI, ".pri"));
570 }
571 if (keyClass == KeyClass::SYMMETRIC) {
572 return boost::filesystem::exists(m_impl->transformName(keyURI, ".key"));
573 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800574 return false;
575}
576
Yingdi Yu4b752752014-02-18 12:24:03 -0800577bool
578SecTpmFile::generateRandomBlock(uint8_t* res, size_t size)
579{
Yingdi Yu99b2a002015-08-12 12:47:44 -0700580 try {
581 CryptoPP::AutoSeededRandomPool rng;
582 rng.GenerateBlock(res, size);
583 return true;
584 }
585 catch (const CryptoPP::Exception& e) {
586 return false;
587 }
Yingdi Yu4b752752014-02-18 12:24:03 -0800588}
589
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700590} // namespace security
Yingdi Yufc40d872014-02-18 12:56:04 -0800591} // namespace ndn