blob: a4bb6543c346709f4495c9618ca3cf49ef253ebf [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 Afanasyev4c9a3d52017-01-03 17:45:19 -08003 * Copyright (c) 2013-2017 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 Afanasyev4c9a3d52017-01-03 17:45:19 -080028#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 Afanasyev4c9a3d52017-01-03 17:45:19 -080033#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 {
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070041namespace security {
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -080042namespace v1 {
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080043
Yingdi Yu7036ce22014-06-19 18:53:37 -070044using std::string;
45using std::ostringstream;
46using std::ofstream;
47
Alexander Afanasyev07113802015-01-15 19:14:36 -080048const std::string SecTpmFile::SCHEME("tpm-file");
Yingdi Yu41546342014-11-30 23:37:53 -080049
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070050class SecTpmFile::Impl
51{
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080052public:
Yingdi Yu7036ce22014-06-19 18:53:37 -070053 explicit
Yingdi Yu4b752752014-02-18 12:24:03 -080054 Impl(const string& dir)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080055 {
Alexander Afanasyev57e00362016-06-23 13:22:54 -070056 boost::filesystem::path actualDir;
57 if (dir.empty()) {
58#ifdef NDN_CXX_HAVE_TESTS
59 if (getenv("TEST_HOME") != nullptr) {
60 actualDir = boost::filesystem::path(getenv("TEST_HOME")) / ".ndn";
61 }
62 else
63#endif // NDN_CXX_HAVE_TESTS
64 if (getenv("HOME") != nullptr) {
65 actualDir = boost::filesystem::path(getenv("HOME")) / ".ndn";
66 }
67 else {
68 actualDir = boost::filesystem::path(".") / ".ndn";
69 }
70 }
71 else {
72 actualDir = boost::filesystem::path(dir);
73 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070074
Alexander Afanasyev57e00362016-06-23 13:22:54 -070075 m_keystorePath = actualDir / "ndnsec-tpm-file";
Yingdi Yu7036ce22014-06-19 18:53:37 -070076 boost::filesystem::create_directories(m_keystorePath);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -080077 }
78
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080079 boost::filesystem::path
Yingdi Yu7036ce22014-06-19 18:53:37 -070080 transformName(const string& keyName, const string& extension)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080081 {
82 using namespace CryptoPP;
83 string digest;
84 SHA256 hash;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070085 StringSource src(keyName,
86 true,
87 new HashFilter(hash,
88 new Base64Encoder(new CryptoPP::StringSink(digest))));
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080089
90 boost::algorithm::trim(digest);
91 std::replace(digest.begin(), digest.end(), '/', '%');
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070092
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080093 return m_keystorePath / (digest + extension);
94 }
95
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070096 string
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080097 maintainMapping(const string& keyName)
98 {
Yingdi Yu7036ce22014-06-19 18:53:37 -070099 string keyFileName = transformName(keyName, "").string();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700100
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800101 ofstream outfile;
102 string dirFile = (m_keystorePath / "mapping.txt").string();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700103
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800104 outfile.open(dirFile.c_str(), std::ios_base::app);
105 outfile << keyName << ' ' << keyFileName << '\n';
106 outfile.close();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700107
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800108 return keyFileName;
109 }
110
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800111public:
112 boost::filesystem::path m_keystorePath;
113};
114
Yingdi Yu4b752752014-02-18 12:24:03 -0800115
Yingdi Yu41546342014-11-30 23:37:53 -0800116SecTpmFile::SecTpmFile(const string& location)
117 : SecTpm(location)
118 , m_impl(new Impl(location))
Yingdi Yube4150e2014-02-18 13:02:46 -0800119 , m_inTerminal(false)
Yingdi Yu7036ce22014-06-19 18:53:37 -0700120{
121}
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800122
Yingdi Yu41546342014-11-30 23:37:53 -0800123SecTpmFile::~SecTpmFile()
124{
125}
126
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800127void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700128SecTpmFile::generateKeyPairInTpm(const Name& keyName, const KeyParams& params)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800129{
130 string keyURI = keyName.toUri();
131
Yingdi Yu99b2a002015-08-12 12:47:44 -0700132 if (doesKeyExistInTpm(keyName, KeyClass::PUBLIC))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700133 BOOST_THROW_EXCEPTION(Error("public key exists"));
Yingdi Yu99b2a002015-08-12 12:47:44 -0700134 if (doesKeyExistInTpm(keyName, KeyClass::PRIVATE))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700135 BOOST_THROW_EXCEPTION(Error("private key exists"));
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800136
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800137 string keyFileName = m_impl->maintainMapping(keyURI);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800138
Yingdi Yu99b2a002015-08-12 12:47:44 -0700139 try {
140 switch (params.getKeyType()) {
141 case KeyType::RSA: {
142 using namespace CryptoPP;
Yingdi Yu4b752752014-02-18 12:24:03 -0800143
Yingdi Yu99b2a002015-08-12 12:47:44 -0700144 const RsaKeyParams& rsaParams = static_cast<const RsaKeyParams&>(params);
145 AutoSeededRandomPool rng;
146 InvertibleRSAFunction privateKey;
147 privateKey.Initialize(rng, rsaParams.getKeySize());
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700148
Yingdi Yu99b2a002015-08-12 12:47:44 -0700149 string privateKeyFileName = keyFileName + ".pri";
150 Base64Encoder privateKeySink(new FileSink(privateKeyFileName.c_str()));
151 privateKey.DEREncode(privateKeySink);
152 privateKeySink.MessageEnd();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700153
Yingdi Yu99b2a002015-08-12 12:47:44 -0700154 RSAFunction publicKey(privateKey);
155 string publicKeyFileName = keyFileName + ".pub";
156 Base64Encoder publicKeySink(new FileSink(publicKeyFileName.c_str()));
157 publicKey.DEREncode(publicKeySink);
158 publicKeySink.MessageEnd();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700159
Yingdi Yu99b2a002015-08-12 12:47:44 -0700160 // set file permission
161 chmod(privateKeyFileName.c_str(), 0000400);
162 chmod(publicKeyFileName.c_str(), 0000444);
163 return;
164 }
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700165
Yingdi Yu99b2a002015-08-12 12:47:44 -0700166 case KeyType::EC: {
167 using namespace CryptoPP;
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700168
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700169 const EcKeyParams& ecParams = static_cast<const EcKeyParams&>(params);
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700170
Yingdi Yu99b2a002015-08-12 12:47:44 -0700171 CryptoPP::OID curveName;
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700172 switch (ecParams.getKeySize()) {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700173 case 256:
174 curveName = ASN1::secp256r1();
175 break;
176 case 384:
177 curveName = ASN1::secp384r1();
178 break;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700179 default:
Yingdi Yu99b2a002015-08-12 12:47:44 -0700180 curveName = ASN1::secp256r1();
181 break;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700182 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700183
184 AutoSeededRandomPool rng;
185
186 ECDSA<ECP, SHA256>::PrivateKey privateKey;
187 DL_GroupParameters_EC<ECP> cryptoParams(curveName);
188 cryptoParams.SetEncodeAsOID(true);
189 privateKey.Initialize(rng, cryptoParams);
190
191 ECDSA<ECP, SHA256>::PublicKey publicKey;
192 privateKey.MakePublicKey(publicKey);
193 publicKey.AccessGroupParameters().SetEncodeAsOID(true);
194
195 string privateKeyFileName = keyFileName + ".pri";
196 Base64Encoder privateKeySink(new FileSink(privateKeyFileName.c_str()));
197 privateKey.DEREncode(privateKeySink);
198 privateKeySink.MessageEnd();
199
200 string publicKeyFileName = keyFileName + ".pub";
201 Base64Encoder publicKeySink(new FileSink(publicKeyFileName.c_str()));
202 publicKey.Save(publicKeySink);
203 publicKeySink.MessageEnd();
204
205 // set file permission
206 chmod(privateKeyFileName.c_str(), 0000400);
207 chmod(publicKeyFileName.c_str(), 0000444);
208 return;
209 }
210
211 default:
212 BOOST_THROW_EXCEPTION(Error("Unsupported key type"));
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800213 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700214 }
215 catch (const KeyParams::Error& e) {
216 BOOST_THROW_EXCEPTION(Error(e.what()));
217 }
218 catch (const CryptoPP::Exception& e) {
219 BOOST_THROW_EXCEPTION(Error(e.what()));
220 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800221}
222
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800223void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700224SecTpmFile::deleteKeyPairInTpm(const Name& keyName)
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800225{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700226 boost::filesystem::path publicKeyPath(m_impl->transformName(keyName.toUri(), ".pub"));
227 boost::filesystem::path privateKeyPath(m_impl->transformName(keyName.toUri(), ".pri"));
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800228
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700229 if (boost::filesystem::exists(publicKeyPath))
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800230 boost::filesystem::remove(publicKeyPath);
231
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700232 if (boost::filesystem::exists(privateKeyPath))
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800233 boost::filesystem::remove(privateKeyPath);
234}
235
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800236shared_ptr<PublicKey>
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700237SecTpmFile::getPublicKeyFromTpm(const Name& keyName)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800238{
239 string keyURI = keyName.toUri();
240
Yingdi Yu99b2a002015-08-12 12:47:44 -0700241 if (!doesKeyExistInTpm(keyName, KeyClass::PUBLIC))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700242 BOOST_THROW_EXCEPTION(Error("Public Key does not exist"));
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800243
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800244 ostringstream os;
Yingdi Yu99b2a002015-08-12 12:47:44 -0700245 try {
246 using namespace CryptoPP;
247 FileSource(m_impl->transformName(keyURI, ".pub").string().c_str(),
248 true,
249 new Base64Decoder(new FileSink(os)));
250 }
251 catch (const CryptoPP::Exception& e) {
252 BOOST_THROW_EXCEPTION(Error(e.what()));
253 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800254
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800255 return make_shared<PublicKey>(reinterpret_cast<const uint8_t*>(os.str().c_str()),
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700256 os.str().size());
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800257}
258
Yingdi Yu41546342014-11-30 23:37:53 -0800259std::string
260SecTpmFile::getScheme()
261{
262 return SCHEME;
263}
264
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800265ConstBufferPtr
Yingdi Yu5e96e002014-04-23 18:32:15 -0700266SecTpmFile::exportPrivateKeyPkcs8FromTpm(const Name& keyName)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800267{
268 OBufferStream privateKeyOs;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700269 CryptoPP::FileSource(m_impl->transformName(keyName.toUri(), ".pri").string().c_str(), true,
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800270 new CryptoPP::Base64Decoder(new CryptoPP::FileSink(privateKeyOs)));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700271
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800272 return privateKeyOs.buf();
273}
274
275bool
Yingdi Yu5e96e002014-04-23 18:32:15 -0700276SecTpmFile::importPrivateKeyPkcs8IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800277{
Yingdi Yu99b2a002015-08-12 12:47:44 -0700278 try {
279 using namespace CryptoPP;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700280
Yingdi Yu99b2a002015-08-12 12:47:44 -0700281 string keyFileName = m_impl->maintainMapping(keyName.toUri());
282 keyFileName.append(".pri");
283 StringSource(buf, size,
284 true,
285 new Base64Encoder(new FileSink(keyFileName.c_str())));
286 return true;
287 }
288 catch (const CryptoPP::Exception& e) {
289 return false;
290 }
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800291}
292
293bool
294SecTpmFile::importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
295{
Yingdi Yu99b2a002015-08-12 12:47:44 -0700296 try {
297 using namespace CryptoPP;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700298
Yingdi Yu99b2a002015-08-12 12:47:44 -0700299 string keyFileName = m_impl->maintainMapping(keyName.toUri());
300 keyFileName.append(".pub");
301 StringSource(buf, size,
302 true,
303 new Base64Encoder(new FileSink(keyFileName.c_str())));
304 return true;
305 }
306 catch (const CryptoPP::Exception& e) {
307 return false;
308 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800309}
310
311Block
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700312SecTpmFile::signInTpm(const uint8_t* data, size_t dataLength,
313 const Name& keyName, DigestAlgorithm digestAlgorithm)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800314{
315 string keyURI = keyName.toUri();
316
Yingdi Yu99b2a002015-08-12 12:47:44 -0700317 if (!doesKeyExistInTpm(keyName, KeyClass::PRIVATE))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700318 BOOST_THROW_EXCEPTION(Error("private key doesn't exist"));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700319
Yingdi Yu99b2a002015-08-12 12:47:44 -0700320 try {
321 using namespace CryptoPP;
322 AutoSeededRandomPool rng;
Yingdi Yu4b752752014-02-18 12:24:03 -0800323
Yingdi Yu99b2a002015-08-12 12:47:44 -0700324 // Read public key
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800325 shared_ptr<PublicKey> pubkeyPtr;
Yingdi Yu99b2a002015-08-12 12:47:44 -0700326 pubkeyPtr = getPublicKeyFromTpm(keyName);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700327
Yingdi Yu99b2a002015-08-12 12:47:44 -0700328 switch (pubkeyPtr->getKeyType()) {
329 case KeyType::RSA: {
330 // Read private key
331 ByteQueue bytes;
332 FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
333 true, new Base64Decoder);
334 file.TransferTo(bytes);
335 bytes.MessageEnd();
336 RSA::PrivateKey privateKey;
337 privateKey.Load(bytes);
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700338
Yingdi Yu99b2a002015-08-12 12:47:44 -0700339 // Sign message
340 switch (digestAlgorithm) {
341 case DigestAlgorithm::SHA256: {
342 RSASS<PKCS1v15, SHA256>::Signer signer(privateKey);
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700343
Yingdi Yu99b2a002015-08-12 12:47:44 -0700344 OBufferStream os;
345 StringSource(data, dataLength,
346 true,
347 new SignerFilter(rng, signer, new FileSink(os)));
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700348
Yingdi Yu99b2a002015-08-12 12:47:44 -0700349 return Block(tlv::SignatureValue, os.buf());
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700350 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700351
352 default:
353 BOOST_THROW_EXCEPTION(Error("Unsupported digest algorithm"));
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700354 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700355 }
356
357 case KeyType::EC: {
358 // Read private key
359 ByteQueue bytes;
360 FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
361 true, new Base64Decoder);
362 file.TransferTo(bytes);
363 bytes.MessageEnd();
364
365 // Sign message
366 switch (digestAlgorithm) {
367 case DigestAlgorithm::SHA256: {
368 ECDSA<ECP, SHA256>::PrivateKey privateKey;
369 privateKey.Load(bytes);
370 ECDSA<ECP, SHA256>::Signer signer(privateKey);
371
372 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, sizeof(buf), DSA_DER,
379 os.buf()->buf(), os.buf()->size(),
380 DSA_P1363);
381
382 shared_ptr<Buffer> sigBuffer = make_shared<Buffer>(buf, bufSize);
383
384 return Block(tlv::SignatureValue, sigBuffer);
385 }
386
387 default:
388 BOOST_THROW_EXCEPTION(Error("Unsupported digest algorithm"));
389 }
390 }
391
392 default:
393 BOOST_THROW_EXCEPTION(Error("Unsupported key type"));
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800394 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700395 }
396 catch (const CryptoPP::Exception& e) {
397 BOOST_THROW_EXCEPTION(Error(e.what()));
398 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800399}
400
401
402ConstBufferPtr
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700403SecTpmFile::decryptInTpm(const uint8_t* data, size_t dataLength,
404 const Name& keyName, bool isSymmetric)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800405{
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700406 BOOST_THROW_EXCEPTION(Error("SecTpmFile::decryptInTpm is not supported"));
Yingdi Yu2e57a582014-02-20 23:34:43 -0800407 // string keyURI = keyName.toUri();
408 // if (!isSymmetric)
409 // {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700410 // if (!doesKeyExistInTpm(keyName, KeyClass::PRIVATE))
Yingdi Yu2e57a582014-02-20 23:34:43 -0800411 // throw Error("private key doesn't exist");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800412
Yingdi Yu2e57a582014-02-20 23:34:43 -0800413 // try{
414 // using namespace CryptoPP;
415 // AutoSeededRandomPool rng;
Yingdi Yu4b752752014-02-18 12:24:03 -0800416
Yingdi Yu2e57a582014-02-20 23:34:43 -0800417 // //Read private key
418 // ByteQueue bytes;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700419 // FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(), true, new Base64Decoder);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800420 // file.TransferTo(bytes);
421 // bytes.MessageEnd();
422 // RSA::PrivateKey privateKey;
423 // privateKey.Load(bytes);
424 // RSAES_PKCS1v15_Decryptor decryptor(privateKey);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700425
Yingdi Yu2e57a582014-02-20 23:34:43 -0800426 // OBufferStream os;
427 // StringSource(data, dataLength, true, new PK_DecryptorFilter(rng, decryptor, new FileSink(os)));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700428
Yingdi Yu2e57a582014-02-20 23:34:43 -0800429 // return os.buf();
430 // }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700431 // catch (const CryptoPP::Exception& e){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800432 // throw Error(e.what());
433 // }
434 // }
435 // else
436 // {
437 // throw Error("Symmetric encryption is not implemented!");
Yingdi Yu99b2a002015-08-12 12:47:44 -0700438 // // if (!doesKeyExistInTpm(keyName, KeyClass::SYMMETRIC))
Yingdi Yu7036ce22014-06-19 18:53:37 -0700439 // // throw Error("symmetric key doesn't exist");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800440
Yingdi Yu2e57a582014-02-20 23:34:43 -0800441 // // try{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700442 // // string keyBits;
443 // // string symKeyFileName = m_impl->transformName(keyURI, ".key");
444 // // FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700445
Yingdi Yu7036ce22014-06-19 18:53:37 -0700446 // // using CryptoPP::AES;
447 // // AutoSeededRandomPool rnd;
448 // // byte iv[AES::BLOCKSIZE];
449 // // rnd.GenerateBlock(iv, AES::BLOCKSIZE);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800450
Yingdi Yu7036ce22014-06-19 18:53:37 -0700451 // // CFB_Mode<AES>::Decryption decryptor;
452 // // decryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700453
Yingdi Yu7036ce22014-06-19 18:53:37 -0700454 // // OBufferStream os;
455 // // StringSource(data, dataLength, true, new StreamTransformationFilter(decryptor,new FileSink(os)));
456 // // return os.buf();
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800457
Yingdi Yu99b2a002015-08-12 12:47:44 -0700458 // // }
459 // // catch (const CryptoPP::Exception& e){
Yingdi Yu7036ce22014-06-19 18:53:37 -0700460 // // throw Error(e.what());
Yingdi Yu2e57a582014-02-20 23:34:43 -0800461 // // }
462 // }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800463}
464
465ConstBufferPtr
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700466SecTpmFile::encryptInTpm(const uint8_t* data, size_t dataLength,
467 const Name& keyName, bool isSymmetric)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800468{
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700469 BOOST_THROW_EXCEPTION(Error("SecTpmFile::encryptInTpm is not supported"));
Yingdi Yu2e57a582014-02-20 23:34:43 -0800470 // string keyURI = keyName.toUri();
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800471
Yingdi Yu2e57a582014-02-20 23:34:43 -0800472 // if (!isSymmetric)
473 // {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700474 // if (!doesKeyExistInTpm(keyName, KeyClass::PUBLIC))
Yingdi Yu2e57a582014-02-20 23:34:43 -0800475 // throw Error("public key doesn't exist");
476 // try
477 // {
478 // using namespace CryptoPP;
479 // AutoSeededRandomPool rng;
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800480
Yingdi Yu2e57a582014-02-20 23:34:43 -0800481 // //Read private key
482 // ByteQueue bytes;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700483 // FileSource file(m_impl->transformName(keyURI, ".pub").string().c_str(), true, new Base64Decoder);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800484 // file.TransferTo(bytes);
485 // bytes.MessageEnd();
486 // RSA::PublicKey publicKey;
487 // publicKey.Load(bytes);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800488
Yingdi Yu2e57a582014-02-20 23:34:43 -0800489 // OBufferStream os;
490 // RSAES_PKCS1v15_Encryptor encryptor(publicKey);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800491
Yingdi Yu2e57a582014-02-20 23:34:43 -0800492 // StringSource(data, dataLength, true, new PK_EncryptorFilter(rng, encryptor, new FileSink(os)));
493 // return os.buf();
494 // }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700495 // catch (const CryptoPP::Exception& e){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800496 // throw Error(e.what());
497 // }
498 // }
499 // else
500 // {
501 // throw Error("Symmetric encryption is not implemented!");
Yingdi Yu99b2a002015-08-12 12:47:44 -0700502 // // if (!doesKeyExistInTpm(keyName, KeyClass::SYMMETRIC))
Yingdi Yu7036ce22014-06-19 18:53:37 -0700503 // // throw Error("symmetric key doesn't exist");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800504
Yingdi Yu2e57a582014-02-20 23:34:43 -0800505 // // try{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700506 // // string keyBits;
507 // // string symKeyFileName = m_impl->transformName(keyURI, ".key");
508 // // FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800509
Yingdi Yu7036ce22014-06-19 18:53:37 -0700510 // // using CryptoPP::AES;
511 // // AutoSeededRandomPool rnd;
512 // // byte iv[AES::BLOCKSIZE];
513 // // rnd.GenerateBlock(iv, AES::BLOCKSIZE);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800514
Yingdi Yu7036ce22014-06-19 18:53:37 -0700515 // // CFB_Mode<AES>::Encryption encryptor;
516 // // encryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800517
Yingdi Yu7036ce22014-06-19 18:53:37 -0700518 // // OBufferStream os;
519 // // StringSource(data, dataLength, true, new StreamTransformationFilter(encryptor, new FileSink(os)));
520 // // return os.buf();
Yingdi Yu99b2a002015-08-12 12:47:44 -0700521 // // } catch (const CryptoPP::Exception& e){
Yingdi Yu7036ce22014-06-19 18:53:37 -0700522 // // throw Error(e.what());
Yingdi Yu2e57a582014-02-20 23:34:43 -0800523 // // }
524 // }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800525}
526
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800527void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700528SecTpmFile::generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800529{
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700530 BOOST_THROW_EXCEPTION(Error("SecTpmFile::generateSymmetricKeyInTpm is not supported"));
Yingdi Yu2e57a582014-02-20 23:34:43 -0800531 // string keyURI = keyName.toUri();
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800532
Yingdi Yu99b2a002015-08-12 12:47:44 -0700533 // if (doesKeyExistInTpm(keyName, KeyClass::SYMMETRIC))
Yingdi Yu2e57a582014-02-20 23:34:43 -0800534 // throw Error("symmetric key exists");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800535
Yingdi Yu2e57a582014-02-20 23:34:43 -0800536 // string keyFileName = m_impl->maintainMapping(keyURI);
537 // string symKeyFileName = keyFileName + ".key";
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800538
Yingdi Yu2e57a582014-02-20 23:34:43 -0800539 // try{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700540 // switch (keyType){
Yingdi Yu99b2a002015-08-12 12:47:44 -0700541 // case KeyType::AES:
Yingdi Yu2e57a582014-02-20 23:34:43 -0800542 // {
543 // using namespace CryptoPP;
544 // AutoSeededRandomPool rng;
Yingdi Yu4b752752014-02-18 12:24:03 -0800545
Yingdi Yu2e57a582014-02-20 23:34:43 -0800546 // SecByteBlock key(0x00, keySize);
547 // rng.GenerateBlock(key, keySize);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700548
Yingdi Yu2e57a582014-02-20 23:34:43 -0800549 // StringSource(key, key.size(), true, new HexEncoder(new FileSink(symKeyFileName.c_str())));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700550
Yingdi Yu2e57a582014-02-20 23:34:43 -0800551 // chmod(symKeyFileName.c_str(), 0000400);
552 // return;
553 // }
554 // default:
555 // throw Error("Unsupported symmetric key type!");
556 // }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700557 // } catch (const CryptoPP::Exception& e){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800558 // throw Error(e.what());
559 // }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800560}
561
562bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700563SecTpmFile::doesKeyExistInTpm(const Name& keyName, KeyClass keyClass)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800564{
565 string keyURI = keyName.toUri();
Yingdi Yu99b2a002015-08-12 12:47:44 -0700566 if (keyClass == KeyClass::PUBLIC) {
567 return boost::filesystem::exists(m_impl->transformName(keyURI, ".pub"));
568 }
569 if (keyClass == KeyClass::PRIVATE) {
570 return boost::filesystem::exists(m_impl->transformName(keyURI, ".pri"));
571 }
572 if (keyClass == KeyClass::SYMMETRIC) {
573 return boost::filesystem::exists(m_impl->transformName(keyURI, ".key"));
574 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800575 return false;
576}
577
Yingdi Yu4b752752014-02-18 12:24:03 -0800578bool
579SecTpmFile::generateRandomBlock(uint8_t* res, size_t size)
580{
Yingdi Yu99b2a002015-08-12 12:47:44 -0700581 try {
582 CryptoPP::AutoSeededRandomPool rng;
583 rng.GenerateBlock(res, size);
584 return true;
585 }
586 catch (const CryptoPP::Exception& e) {
587 return false;
588 }
Yingdi Yu4b752752014-02-18 12:24:03 -0800589}
590
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -0800591} // namespace v1
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700592} // namespace security
Yingdi Yufc40d872014-02-18 12:56:04 -0800593} // namespace ndn