blob: adb5938532893faacb38140f5adb9abbea86d5cd [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
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 Afanasyev57e00362016-06-23 13:22:54 -070054 boost::filesystem::path actualDir;
55 if (dir.empty()) {
56#ifdef NDN_CXX_HAVE_TESTS
57 if (getenv("TEST_HOME") != nullptr) {
58 actualDir = boost::filesystem::path(getenv("TEST_HOME")) / ".ndn";
59 }
60 else
61#endif // NDN_CXX_HAVE_TESTS
62 if (getenv("HOME") != nullptr) {
63 actualDir = boost::filesystem::path(getenv("HOME")) / ".ndn";
64 }
65 else {
66 actualDir = boost::filesystem::path(".") / ".ndn";
67 }
68 }
69 else {
70 actualDir = boost::filesystem::path(dir);
71 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070072
Alexander Afanasyev57e00362016-06-23 13:22:54 -070073 m_keystorePath = actualDir / "ndnsec-tpm-file";
Yingdi Yu7036ce22014-06-19 18:53:37 -070074 boost::filesystem::create_directories(m_keystorePath);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080075 }
76
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080077 boost::filesystem::path
Yingdi Yu7036ce22014-06-19 18:53:37 -070078 transformName(const string& keyName, const string& extension)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080079 {
80 using namespace CryptoPP;
81 string digest;
82 SHA256 hash;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070083 StringSource src(keyName,
84 true,
85 new HashFilter(hash,
86 new Base64Encoder(new CryptoPP::StringSink(digest))));
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080087
88 boost::algorithm::trim(digest);
89 std::replace(digest.begin(), digest.end(), '/', '%');
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070090
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080091 return m_keystorePath / (digest + extension);
92 }
93
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070094 string
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080095 maintainMapping(const string& keyName)
96 {
Yingdi Yu7036ce22014-06-19 18:53:37 -070097 string keyFileName = transformName(keyName, "").string();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070098
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080099 ofstream outfile;
100 string dirFile = (m_keystorePath / "mapping.txt").string();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700101
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800102 outfile.open(dirFile.c_str(), std::ios_base::app);
103 outfile << keyName << ' ' << keyFileName << '\n';
104 outfile.close();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700105
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800106 return keyFileName;
107 }
108
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800109public:
110 boost::filesystem::path m_keystorePath;
111};
112
Yingdi Yu4b752752014-02-18 12:24:03 -0800113
Yingdi Yu41546342014-11-30 23:37:53 -0800114SecTpmFile::SecTpmFile(const string& location)
115 : SecTpm(location)
116 , m_impl(new Impl(location))
Yingdi Yube4150e2014-02-18 13:02:46 -0800117 , m_inTerminal(false)
Yingdi Yu7036ce22014-06-19 18:53:37 -0700118{
119}
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800120
Yingdi Yu41546342014-11-30 23:37:53 -0800121SecTpmFile::~SecTpmFile()
122{
123}
124
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800125void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700126SecTpmFile::generateKeyPairInTpm(const Name& keyName, const KeyParams& params)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800127{
128 string keyURI = keyName.toUri();
129
Yingdi Yu99b2a002015-08-12 12:47:44 -0700130 if (doesKeyExistInTpm(keyName, KeyClass::PUBLIC))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700131 BOOST_THROW_EXCEPTION(Error("public key exists"));
Yingdi Yu99b2a002015-08-12 12:47:44 -0700132 if (doesKeyExistInTpm(keyName, KeyClass::PRIVATE))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700133 BOOST_THROW_EXCEPTION(Error("private key exists"));
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800134
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800135 string keyFileName = m_impl->maintainMapping(keyURI);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800136
Yingdi Yu99b2a002015-08-12 12:47:44 -0700137 try {
138 switch (params.getKeyType()) {
139 case KeyType::RSA: {
140 using namespace CryptoPP;
Yingdi Yu4b752752014-02-18 12:24:03 -0800141
Yingdi Yu99b2a002015-08-12 12:47:44 -0700142 const RsaKeyParams& rsaParams = static_cast<const RsaKeyParams&>(params);
143 AutoSeededRandomPool rng;
144 InvertibleRSAFunction privateKey;
145 privateKey.Initialize(rng, rsaParams.getKeySize());
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700146
Yingdi Yu99b2a002015-08-12 12:47:44 -0700147 string privateKeyFileName = keyFileName + ".pri";
148 Base64Encoder privateKeySink(new FileSink(privateKeyFileName.c_str()));
149 privateKey.DEREncode(privateKeySink);
150 privateKeySink.MessageEnd();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700151
Yingdi Yu99b2a002015-08-12 12:47:44 -0700152 RSAFunction publicKey(privateKey);
153 string publicKeyFileName = keyFileName + ".pub";
154 Base64Encoder publicKeySink(new FileSink(publicKeyFileName.c_str()));
155 publicKey.DEREncode(publicKeySink);
156 publicKeySink.MessageEnd();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700157
Yingdi Yu99b2a002015-08-12 12:47:44 -0700158 // set file permission
159 chmod(privateKeyFileName.c_str(), 0000400);
160 chmod(publicKeyFileName.c_str(), 0000444);
161 return;
162 }
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700163
Yingdi Yu99b2a002015-08-12 12:47:44 -0700164 case KeyType::EC: {
165 using namespace CryptoPP;
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700166
Yingdi Yu99b2a002015-08-12 12:47:44 -0700167 const EcdsaKeyParams& ecdsaParams = static_cast<const EcdsaKeyParams&>(params);
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700168
Yingdi Yu99b2a002015-08-12 12:47:44 -0700169 CryptoPP::OID curveName;
170 switch (ecdsaParams.getKeySize()) {
171 case 256:
172 curveName = ASN1::secp256r1();
173 break;
174 case 384:
175 curveName = ASN1::secp384r1();
176 break;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700177 default:
Yingdi Yu99b2a002015-08-12 12:47:44 -0700178 curveName = ASN1::secp256r1();
179 break;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700180 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700181
182 AutoSeededRandomPool rng;
183
184 ECDSA<ECP, SHA256>::PrivateKey privateKey;
185 DL_GroupParameters_EC<ECP> cryptoParams(curveName);
186 cryptoParams.SetEncodeAsOID(true);
187 privateKey.Initialize(rng, cryptoParams);
188
189 ECDSA<ECP, SHA256>::PublicKey publicKey;
190 privateKey.MakePublicKey(publicKey);
191 publicKey.AccessGroupParameters().SetEncodeAsOID(true);
192
193 string privateKeyFileName = keyFileName + ".pri";
194 Base64Encoder privateKeySink(new FileSink(privateKeyFileName.c_str()));
195 privateKey.DEREncode(privateKeySink);
196 privateKeySink.MessageEnd();
197
198 string publicKeyFileName = keyFileName + ".pub";
199 Base64Encoder publicKeySink(new FileSink(publicKeyFileName.c_str()));
200 publicKey.Save(publicKeySink);
201 publicKeySink.MessageEnd();
202
203 // set file permission
204 chmod(privateKeyFileName.c_str(), 0000400);
205 chmod(publicKeyFileName.c_str(), 0000444);
206 return;
207 }
208
209 default:
210 BOOST_THROW_EXCEPTION(Error("Unsupported key type"));
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800211 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700212 }
213 catch (const KeyParams::Error& e) {
214 BOOST_THROW_EXCEPTION(Error(e.what()));
215 }
216 catch (const CryptoPP::Exception& e) {
217 BOOST_THROW_EXCEPTION(Error(e.what()));
218 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800219}
220
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800221void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700222SecTpmFile::deleteKeyPairInTpm(const Name& keyName)
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800223{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700224 boost::filesystem::path publicKeyPath(m_impl->transformName(keyName.toUri(), ".pub"));
225 boost::filesystem::path privateKeyPath(m_impl->transformName(keyName.toUri(), ".pri"));
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800226
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700227 if (boost::filesystem::exists(publicKeyPath))
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800228 boost::filesystem::remove(publicKeyPath);
229
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700230 if (boost::filesystem::exists(privateKeyPath))
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800231 boost::filesystem::remove(privateKeyPath);
232}
233
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800234shared_ptr<PublicKey>
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700235SecTpmFile::getPublicKeyFromTpm(const Name& keyName)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800236{
237 string keyURI = keyName.toUri();
238
Yingdi Yu99b2a002015-08-12 12:47:44 -0700239 if (!doesKeyExistInTpm(keyName, KeyClass::PUBLIC))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700240 BOOST_THROW_EXCEPTION(Error("Public Key does not exist"));
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800241
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800242 ostringstream os;
Yingdi Yu99b2a002015-08-12 12:47:44 -0700243 try {
244 using namespace CryptoPP;
245 FileSource(m_impl->transformName(keyURI, ".pub").string().c_str(),
246 true,
247 new Base64Decoder(new FileSink(os)));
248 }
249 catch (const CryptoPP::Exception& e) {
250 BOOST_THROW_EXCEPTION(Error(e.what()));
251 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800252
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700253 return make_shared<PublicKey>(reinterpret_cast<const uint8_t*>(os.str().c_str()),
254 os.str().size());
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800255}
256
Yingdi Yu41546342014-11-30 23:37:53 -0800257std::string
258SecTpmFile::getScheme()
259{
260 return SCHEME;
261}
262
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800263ConstBufferPtr
Yingdi Yu5e96e002014-04-23 18:32:15 -0700264SecTpmFile::exportPrivateKeyPkcs8FromTpm(const Name& keyName)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800265{
266 OBufferStream privateKeyOs;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700267 CryptoPP::FileSource(m_impl->transformName(keyName.toUri(), ".pri").string().c_str(), true,
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800268 new CryptoPP::Base64Decoder(new CryptoPP::FileSink(privateKeyOs)));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700269
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800270 return privateKeyOs.buf();
271}
272
273bool
Yingdi Yu5e96e002014-04-23 18:32:15 -0700274SecTpmFile::importPrivateKeyPkcs8IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800275{
Yingdi Yu99b2a002015-08-12 12:47:44 -0700276 try {
277 using namespace CryptoPP;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700278
Yingdi Yu99b2a002015-08-12 12:47:44 -0700279 string keyFileName = m_impl->maintainMapping(keyName.toUri());
280 keyFileName.append(".pri");
281 StringSource(buf, size,
282 true,
283 new Base64Encoder(new FileSink(keyFileName.c_str())));
284 return true;
285 }
286 catch (const CryptoPP::Exception& e) {
287 return false;
288 }
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800289}
290
291bool
292SecTpmFile::importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
293{
Yingdi Yu99b2a002015-08-12 12:47:44 -0700294 try {
295 using namespace CryptoPP;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700296
Yingdi Yu99b2a002015-08-12 12:47:44 -0700297 string keyFileName = m_impl->maintainMapping(keyName.toUri());
298 keyFileName.append(".pub");
299 StringSource(buf, size,
300 true,
301 new Base64Encoder(new FileSink(keyFileName.c_str())));
302 return true;
303 }
304 catch (const CryptoPP::Exception& e) {
305 return false;
306 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800307}
308
309Block
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700310SecTpmFile::signInTpm(const uint8_t* data, size_t dataLength,
311 const Name& keyName, DigestAlgorithm digestAlgorithm)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800312{
313 string keyURI = keyName.toUri();
314
Yingdi Yu99b2a002015-08-12 12:47:44 -0700315 if (!doesKeyExistInTpm(keyName, KeyClass::PRIVATE))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700316 BOOST_THROW_EXCEPTION(Error("private key doesn't exist"));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700317
Yingdi Yu99b2a002015-08-12 12:47:44 -0700318 try {
319 using namespace CryptoPP;
320 AutoSeededRandomPool rng;
Yingdi Yu4b752752014-02-18 12:24:03 -0800321
Yingdi Yu99b2a002015-08-12 12:47:44 -0700322 // Read public key
323 shared_ptr<PublicKey> pubkeyPtr;
324 pubkeyPtr = getPublicKeyFromTpm(keyName);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700325
Yingdi Yu99b2a002015-08-12 12:47:44 -0700326 switch (pubkeyPtr->getKeyType()) {
327 case KeyType::RSA: {
328 // Read private key
329 ByteQueue bytes;
330 FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
331 true, new Base64Decoder);
332 file.TransferTo(bytes);
333 bytes.MessageEnd();
334 RSA::PrivateKey privateKey;
335 privateKey.Load(bytes);
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700336
Yingdi Yu99b2a002015-08-12 12:47:44 -0700337 // Sign message
338 switch (digestAlgorithm) {
339 case DigestAlgorithm::SHA256: {
340 RSASS<PKCS1v15, SHA256>::Signer signer(privateKey);
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700341
Yingdi Yu99b2a002015-08-12 12:47:44 -0700342 OBufferStream os;
343 StringSource(data, dataLength,
344 true,
345 new SignerFilter(rng, signer, new FileSink(os)));
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700346
Yingdi Yu99b2a002015-08-12 12:47:44 -0700347 return Block(tlv::SignatureValue, os.buf());
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700348 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700349
350 default:
351 BOOST_THROW_EXCEPTION(Error("Unsupported digest algorithm"));
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700352 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700353 }
354
355 case KeyType::EC: {
356 // 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();
362
363 // Sign message
364 switch (digestAlgorithm) {
365 case DigestAlgorithm::SHA256: {
366 ECDSA<ECP, SHA256>::PrivateKey privateKey;
367 privateKey.Load(bytes);
368 ECDSA<ECP, SHA256>::Signer signer(privateKey);
369
370 OBufferStream os;
371 StringSource(data, dataLength,
372 true,
373 new SignerFilter(rng, signer, new FileSink(os)));
374
375 uint8_t buf[200];
376 size_t bufSize = DSAConvertSignatureFormat(buf, sizeof(buf), DSA_DER,
377 os.buf()->buf(), os.buf()->size(),
378 DSA_P1363);
379
380 shared_ptr<Buffer> sigBuffer = make_shared<Buffer>(buf, bufSize);
381
382 return Block(tlv::SignatureValue, sigBuffer);
383 }
384
385 default:
386 BOOST_THROW_EXCEPTION(Error("Unsupported digest algorithm"));
387 }
388 }
389
390 default:
391 BOOST_THROW_EXCEPTION(Error("Unsupported key type"));
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800392 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700393 }
394 catch (const CryptoPP::Exception& e) {
395 BOOST_THROW_EXCEPTION(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{
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700404 BOOST_THROW_EXCEPTION(Error("SecTpmFile::decryptInTpm is not supported"));
Yingdi Yu2e57a582014-02-20 23:34:43 -0800405 // string keyURI = keyName.toUri();
406 // if (!isSymmetric)
407 // {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700408 // if (!doesKeyExistInTpm(keyName, KeyClass::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 // }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700429 // catch (const 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!");
Yingdi Yu99b2a002015-08-12 12:47:44 -0700436 // // if (!doesKeyExistInTpm(keyName, KeyClass::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
Yingdi Yu99b2a002015-08-12 12:47:44 -0700456 // // }
457 // // catch (const 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{
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700467 BOOST_THROW_EXCEPTION(Error("SecTpmFile::encryptInTpm is not supported"));
Yingdi Yu2e57a582014-02-20 23:34:43 -0800468 // string keyURI = keyName.toUri();
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800469
Yingdi Yu2e57a582014-02-20 23:34:43 -0800470 // if (!isSymmetric)
471 // {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700472 // if (!doesKeyExistInTpm(keyName, KeyClass::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 // }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700493 // catch (const 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!");
Yingdi Yu99b2a002015-08-12 12:47:44 -0700500 // // if (!doesKeyExistInTpm(keyName, KeyClass::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();
Yingdi Yu99b2a002015-08-12 12:47:44 -0700519 // // } catch (const 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
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800525void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700526SecTpmFile::generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800527{
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700528 BOOST_THROW_EXCEPTION(Error("SecTpmFile::generateSymmetricKeyInTpm is not supported"));
Yingdi Yu2e57a582014-02-20 23:34:43 -0800529 // string keyURI = keyName.toUri();
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800530
Yingdi Yu99b2a002015-08-12 12:47:44 -0700531 // if (doesKeyExistInTpm(keyName, KeyClass::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 Yu99b2a002015-08-12 12:47:44 -0700539 // case KeyType::AES:
Yingdi Yu2e57a582014-02-20 23:34:43 -0800540 // {
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 // }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700555 // } catch (const 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();
Yingdi Yu99b2a002015-08-12 12:47:44 -0700564 if (keyClass == KeyClass::PUBLIC) {
565 return boost::filesystem::exists(m_impl->transformName(keyURI, ".pub"));
566 }
567 if (keyClass == KeyClass::PRIVATE) {
568 return boost::filesystem::exists(m_impl->transformName(keyURI, ".pri"));
569 }
570 if (keyClass == KeyClass::SYMMETRIC) {
571 return boost::filesystem::exists(m_impl->transformName(keyURI, ".key"));
572 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800573 return false;
574}
575
Yingdi Yu4b752752014-02-18 12:24:03 -0800576bool
577SecTpmFile::generateRandomBlock(uint8_t* res, size_t size)
578{
Yingdi Yu99b2a002015-08-12 12:47:44 -0700579 try {
580 CryptoPP::AutoSeededRandomPool rng;
581 rng.GenerateBlock(res, size);
582 return true;
583 }
584 catch (const CryptoPP::Exception& e) {
585 return false;
586 }
Yingdi Yu4b752752014-02-18 12:24:03 -0800587}
588
Yingdi Yufc40d872014-02-18 12:56:04 -0800589} // namespace ndn