blob: 306a062540d6bf074ca75ab200c2032cfa85946e [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
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700130 if (doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700131 BOOST_THROW_EXCEPTION(Error("public key exists"));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700132 if (doesKeyExistInTpm(keyName, KEY_CLASS_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 Yu4b8c6a22014-04-15 23:00:54 -0700137 try
138 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700139 switch (params.getKeyType())
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700140 {
141 case KEY_TYPE_RSA:
142 {
143 using namespace CryptoPP;
Yingdi Yu4b752752014-02-18 12:24:03 -0800144
Yingdi Yu7036ce22014-06-19 18:53:37 -0700145 const RsaKeyParams& rsaParams = static_cast<const RsaKeyParams&>(params);
146 AutoSeededRandomPool rng;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700147 InvertibleRSAFunction privateKey;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700148 privateKey.Initialize(rng, rsaParams.getKeySize());
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700149
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700150 string privateKeyFileName = keyFileName + ".pri";
151 Base64Encoder privateKeySink(new FileSink(privateKeyFileName.c_str()));
152 privateKey.DEREncode(privateKeySink);
153 privateKeySink.MessageEnd();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700154
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700155 RSAFunction publicKey(privateKey);
156 string publicKeyFileName = keyFileName + ".pub";
157 Base64Encoder publicKeySink(new FileSink(publicKeyFileName.c_str()));
158 publicKey.DEREncode(publicKeySink);
159 publicKeySink.MessageEnd();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700160
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700161 /*set file permission*/
162 chmod(privateKeyFileName.c_str(), 0000400);
163 chmod(publicKeyFileName.c_str(), 0000444);
164 return;
165 }
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700166 case KEY_TYPE_ECDSA:
167 {
168 using namespace CryptoPP;
169
170 const EcdsaKeyParams& ecdsaParams = static_cast<const EcdsaKeyParams&>(params);
171
Alexander Afanasyev07113802015-01-15 19:14:36 -0800172 CryptoPP::OID curveName;
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700173 switch (ecdsaParams.getKeySize())
174 {
175 case 256:
176 curveName = ASN1::secp256r1();
177 break;
178 case 384:
179 curveName = ASN1::secp384r1();
180 break;
181 default:
182 curveName = ASN1::secp256r1();
183 }
184
185 AutoSeededRandomPool rng;
186
187 ECDSA<ECP, SHA256>::PrivateKey privateKey;
188 DL_GroupParameters_EC<ECP> cryptoParams(curveName);
189 cryptoParams.SetEncodeAsOID(true);
190 privateKey.Initialize(rng, cryptoParams);
191
192 ECDSA<ECP, SHA256>::PublicKey publicKey;
193 privateKey.MakePublicKey(publicKey);
194 publicKey.AccessGroupParameters().SetEncodeAsOID(true);
195
196 string privateKeyFileName = keyFileName + ".pri";
197 Base64Encoder privateKeySink(new FileSink(privateKeyFileName.c_str()));
198 privateKey.DEREncode(privateKeySink);
199 privateKeySink.MessageEnd();
200
201 string publicKeyFileName = keyFileName + ".pub";
202 Base64Encoder publicKeySink(new FileSink(publicKeyFileName.c_str()));
203 publicKey.Save(publicKeySink);
204 publicKeySink.MessageEnd();
205
206 /*set file permission*/
207 chmod(privateKeyFileName.c_str(), 0000400);
208 chmod(publicKeyFileName.c_str(), 0000444);
209 return;
210 }
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700211 default:
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700212 BOOST_THROW_EXCEPTION(Error("Unsupported key type"));
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700213 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800214 }
Yingdi Yu7036ce22014-06-19 18:53:37 -0700215 catch (KeyParams::Error& e)
216 {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700217 BOOST_THROW_EXCEPTION(Error(e.what()));
Yingdi Yu7036ce22014-06-19 18:53:37 -0700218 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700219 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700220 {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700221 BOOST_THROW_EXCEPTION(Error(e.what()));
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700222 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800223}
224
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800225void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700226SecTpmFile::deleteKeyPairInTpm(const Name& keyName)
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800227{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700228 boost::filesystem::path publicKeyPath(m_impl->transformName(keyName.toUri(), ".pub"));
229 boost::filesystem::path privateKeyPath(m_impl->transformName(keyName.toUri(), ".pri"));
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800230
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700231 if (boost::filesystem::exists(publicKeyPath))
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800232 boost::filesystem::remove(publicKeyPath);
233
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700234 if (boost::filesystem::exists(privateKeyPath))
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800235 boost::filesystem::remove(privateKeyPath);
236}
237
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800238shared_ptr<PublicKey>
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700239SecTpmFile::getPublicKeyFromTpm(const Name& keyName)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800240{
241 string keyURI = keyName.toUri();
242
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700243 if (!doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700244 BOOST_THROW_EXCEPTION(Error("Public Key does not exist"));
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800245
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800246 ostringstream os;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700247 try
248 {
249 using namespace CryptoPP;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700250 FileSource(m_impl->transformName(keyURI, ".pub").string().c_str(),
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700251 true,
252 new Base64Decoder(new FileSink(os)));
253 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700254 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700255 {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700256 BOOST_THROW_EXCEPTION(Error(e.what()));
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700257 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800258
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700259 return make_shared<PublicKey>(reinterpret_cast<const uint8_t*>(os.str().c_str()),
260 os.str().size());
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800261}
262
Yingdi Yu41546342014-11-30 23:37:53 -0800263std::string
264SecTpmFile::getScheme()
265{
266 return SCHEME;
267}
268
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800269ConstBufferPtr
Yingdi Yu5e96e002014-04-23 18:32:15 -0700270SecTpmFile::exportPrivateKeyPkcs8FromTpm(const Name& keyName)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800271{
272 OBufferStream privateKeyOs;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700273 CryptoPP::FileSource(m_impl->transformName(keyName.toUri(), ".pri").string().c_str(), true,
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800274 new CryptoPP::Base64Decoder(new CryptoPP::FileSink(privateKeyOs)));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700275
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800276 return privateKeyOs.buf();
277}
278
279bool
Yingdi Yu5e96e002014-04-23 18:32:15 -0700280SecTpmFile::importPrivateKeyPkcs8IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800281{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700282 try
283 {
284 using namespace CryptoPP;
285
286 string keyFileName = m_impl->maintainMapping(keyName.toUri());
287 keyFileName.append(".pri");
288 StringSource(buf, size,
289 true,
290 new Base64Encoder(new FileSink(keyFileName.c_str())));
291 return true;
292 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700293 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700294 {
295 return false;
296 }
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800297}
298
299bool
300SecTpmFile::importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
301{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700302 try
303 {
304 using namespace CryptoPP;
305
306 string keyFileName = m_impl->maintainMapping(keyName.toUri());
307 keyFileName.append(".pub");
308 StringSource(buf, size,
309 true,
310 new Base64Encoder(new FileSink(keyFileName.c_str())));
311 return true;
312 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700313 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700314 {
315 return false;
316 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800317}
318
319Block
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700320SecTpmFile::signInTpm(const uint8_t* data, size_t dataLength,
321 const Name& keyName, DigestAlgorithm digestAlgorithm)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800322{
323 string keyURI = keyName.toUri();
324
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700325 if (!doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700326 BOOST_THROW_EXCEPTION(Error("private key doesn't exist"));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700327
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700328 try
329 {
330 using namespace CryptoPP;
331 AutoSeededRandomPool rng;
Yingdi Yu4b752752014-02-18 12:24:03 -0800332
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700333 //Read public key
334 shared_ptr<PublicKey> pubkeyPtr;
335 pubkeyPtr = getPublicKeyFromTpm(keyName);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700336
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700337 switch (pubkeyPtr->getKeyType())
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700338 {
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700339 case KEY_TYPE_RSA:
340 {
341 //Read private key
342 ByteQueue bytes;
343 FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
344 true, new Base64Decoder);
345 file.TransferTo(bytes);
346 bytes.MessageEnd();
347 RSA::PrivateKey privateKey;
348 privateKey.Load(bytes);
349
350 //Sign message
351 switch (digestAlgorithm)
352 {
353 case DIGEST_ALGORITHM_SHA256:
354 {
355 RSASS<PKCS1v15, SHA256>::Signer signer(privateKey);
356
357 OBufferStream os;
358 StringSource(data, dataLength,
359 true,
360 new SignerFilter(rng, signer, new FileSink(os)));
361
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600362 return Block(tlv::SignatureValue, os.buf());
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700363 }
364 default:
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700365 BOOST_THROW_EXCEPTION(Error("Unsupported digest algorithm"));
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700366 }
367 }
368 case KEY_TYPE_ECDSA:
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700369 {
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700370 //Read private key
371 ByteQueue bytes;
372 FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
373 true, new Base64Decoder);
374 file.TransferTo(bytes);
375 bytes.MessageEnd();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700376
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700377 //Sign message
378 switch (digestAlgorithm)
379 {
380 case DIGEST_ALGORITHM_SHA256:
381 {
382 ECDSA<ECP, SHA256>::PrivateKey privateKey;
383 privateKey.Load(bytes);
384 ECDSA<ECP, SHA256>::Signer signer(privateKey);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700385
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700386 OBufferStream os;
387 StringSource(data, dataLength,
388 true,
389 new SignerFilter(rng, signer, new FileSink(os)));
390
391 uint8_t buf[200];
392 size_t bufSize = DSAConvertSignatureFormat(buf, 200, DSA_DER,
393 os.buf()->buf(), os.buf()->size(),
394 DSA_P1363);
395
396 shared_ptr<Buffer> sigBuffer = make_shared<Buffer>(buf, bufSize);
397
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600398 return Block(tlv::SignatureValue, sigBuffer);
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700399 }
400 default:
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700401 BOOST_THROW_EXCEPTION(Error("Unsupported digest algorithm"));
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700402 }
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700403 }
404 default:
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700405 BOOST_THROW_EXCEPTION(Error("Unsupported key type"));
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700406 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800407 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700408 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700409 {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700410 BOOST_THROW_EXCEPTION(Error(e.what()));
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700411 }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800412}
413
414
415ConstBufferPtr
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700416SecTpmFile::decryptInTpm(const uint8_t* data, size_t dataLength,
417 const Name& keyName, bool isSymmetric)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800418{
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700419 BOOST_THROW_EXCEPTION(Error("SecTpmFile::decryptInTpm is not supported"));
Yingdi Yu2e57a582014-02-20 23:34:43 -0800420 // string keyURI = keyName.toUri();
421 // if (!isSymmetric)
422 // {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700423 // if (!doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
Yingdi Yu2e57a582014-02-20 23:34:43 -0800424 // throw Error("private key doesn't exist");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800425
Yingdi Yu2e57a582014-02-20 23:34:43 -0800426 // try{
427 // using namespace CryptoPP;
428 // AutoSeededRandomPool rng;
Yingdi Yu4b752752014-02-18 12:24:03 -0800429
Yingdi Yu2e57a582014-02-20 23:34:43 -0800430 // //Read private key
431 // ByteQueue bytes;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700432 // FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(), true, new Base64Decoder);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800433 // file.TransferTo(bytes);
434 // bytes.MessageEnd();
435 // RSA::PrivateKey privateKey;
436 // privateKey.Load(bytes);
437 // RSAES_PKCS1v15_Decryptor decryptor(privateKey);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700438
Yingdi Yu2e57a582014-02-20 23:34:43 -0800439 // OBufferStream os;
440 // StringSource(data, dataLength, true, new PK_DecryptorFilter(rng, decryptor, new FileSink(os)));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700441
Yingdi Yu2e57a582014-02-20 23:34:43 -0800442 // return os.buf();
443 // }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700444 // catch (CryptoPP::Exception& e){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800445 // throw Error(e.what());
446 // }
447 // }
448 // else
449 // {
450 // throw Error("Symmetric encryption is not implemented!");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700451 // // if (!doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
Yingdi Yu7036ce22014-06-19 18:53:37 -0700452 // // throw Error("symmetric key doesn't exist");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800453
Yingdi Yu2e57a582014-02-20 23:34:43 -0800454 // // try{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700455 // // string keyBits;
456 // // string symKeyFileName = m_impl->transformName(keyURI, ".key");
457 // // FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700458
Yingdi Yu7036ce22014-06-19 18:53:37 -0700459 // // using CryptoPP::AES;
460 // // AutoSeededRandomPool rnd;
461 // // byte iv[AES::BLOCKSIZE];
462 // // rnd.GenerateBlock(iv, AES::BLOCKSIZE);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800463
Yingdi Yu7036ce22014-06-19 18:53:37 -0700464 // // CFB_Mode<AES>::Decryption decryptor;
465 // // decryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700466
Yingdi Yu7036ce22014-06-19 18:53:37 -0700467 // // OBufferStream os;
468 // // StringSource(data, dataLength, true, new StreamTransformationFilter(decryptor,new FileSink(os)));
469 // // return os.buf();
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800470
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700471 // // }catch (CryptoPP::Exception& e){
Yingdi Yu7036ce22014-06-19 18:53:37 -0700472 // // throw Error(e.what());
Yingdi Yu2e57a582014-02-20 23:34:43 -0800473 // // }
474 // }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800475}
476
477ConstBufferPtr
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700478SecTpmFile::encryptInTpm(const uint8_t* data, size_t dataLength,
479 const Name& keyName, bool isSymmetric)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800480{
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700481 BOOST_THROW_EXCEPTION(Error("SecTpmFile::encryptInTpm is not supported"));
Yingdi Yu2e57a582014-02-20 23:34:43 -0800482 // string keyURI = keyName.toUri();
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800483
Yingdi Yu2e57a582014-02-20 23:34:43 -0800484 // if (!isSymmetric)
485 // {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700486 // if (!doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC))
Yingdi Yu2e57a582014-02-20 23:34:43 -0800487 // throw Error("public key doesn't exist");
488 // try
489 // {
490 // using namespace CryptoPP;
491 // AutoSeededRandomPool rng;
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800492
Yingdi Yu2e57a582014-02-20 23:34:43 -0800493 // //Read private key
494 // ByteQueue bytes;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700495 // FileSource file(m_impl->transformName(keyURI, ".pub").string().c_str(), true, new Base64Decoder);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800496 // file.TransferTo(bytes);
497 // bytes.MessageEnd();
498 // RSA::PublicKey publicKey;
499 // publicKey.Load(bytes);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800500
Yingdi Yu2e57a582014-02-20 23:34:43 -0800501 // OBufferStream os;
502 // RSAES_PKCS1v15_Encryptor encryptor(publicKey);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800503
Yingdi Yu2e57a582014-02-20 23:34:43 -0800504 // StringSource(data, dataLength, true, new PK_EncryptorFilter(rng, encryptor, new FileSink(os)));
505 // return os.buf();
506 // }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700507 // catch (CryptoPP::Exception& e){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800508 // throw Error(e.what());
509 // }
510 // }
511 // else
512 // {
513 // throw Error("Symmetric encryption is not implemented!");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700514 // // if (!doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
Yingdi Yu7036ce22014-06-19 18:53:37 -0700515 // // throw Error("symmetric key doesn't exist");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800516
Yingdi Yu2e57a582014-02-20 23:34:43 -0800517 // // try{
Yingdi Yu7036ce22014-06-19 18:53:37 -0700518 // // string keyBits;
519 // // string symKeyFileName = m_impl->transformName(keyURI, ".key");
520 // // FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800521
Yingdi Yu7036ce22014-06-19 18:53:37 -0700522 // // using CryptoPP::AES;
523 // // AutoSeededRandomPool rnd;
524 // // byte iv[AES::BLOCKSIZE];
525 // // rnd.GenerateBlock(iv, AES::BLOCKSIZE);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800526
Yingdi Yu7036ce22014-06-19 18:53:37 -0700527 // // CFB_Mode<AES>::Encryption encryptor;
528 // // encryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800529
Yingdi Yu7036ce22014-06-19 18:53:37 -0700530 // // OBufferStream os;
531 // // StringSource(data, dataLength, true, new StreamTransformationFilter(encryptor, new FileSink(os)));
532 // // return os.buf();
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700533 // // }catch (CryptoPP::Exception& e){
Yingdi Yu7036ce22014-06-19 18:53:37 -0700534 // // throw Error(e.what());
Yingdi Yu2e57a582014-02-20 23:34:43 -0800535 // // }
536 // }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800537}
538
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800539void
Yingdi Yu7036ce22014-06-19 18:53:37 -0700540SecTpmFile::generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800541{
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700542 BOOST_THROW_EXCEPTION(Error("SecTpmFile::generateSymmetricKeyInTpm is not supported"));
Yingdi Yu2e57a582014-02-20 23:34:43 -0800543 // string keyURI = keyName.toUri();
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800544
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700545 // if (doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
Yingdi Yu2e57a582014-02-20 23:34:43 -0800546 // throw Error("symmetric key exists");
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800547
Yingdi Yu2e57a582014-02-20 23:34:43 -0800548 // string keyFileName = m_impl->maintainMapping(keyURI);
549 // string symKeyFileName = keyFileName + ".key";
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800550
Yingdi Yu2e57a582014-02-20 23:34:43 -0800551 // try{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700552 // switch (keyType){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800553 // case KEY_TYPE_AES:
554 // {
555 // using namespace CryptoPP;
556 // AutoSeededRandomPool rng;
Yingdi Yu4b752752014-02-18 12:24:03 -0800557
Yingdi Yu2e57a582014-02-20 23:34:43 -0800558 // SecByteBlock key(0x00, keySize);
559 // rng.GenerateBlock(key, keySize);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700560
Yingdi Yu2e57a582014-02-20 23:34:43 -0800561 // StringSource(key, key.size(), true, new HexEncoder(new FileSink(symKeyFileName.c_str())));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700562
Yingdi Yu2e57a582014-02-20 23:34:43 -0800563 // chmod(symKeyFileName.c_str(), 0000400);
564 // return;
565 // }
566 // default:
567 // throw Error("Unsupported symmetric key type!");
568 // }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700569 // }catch (CryptoPP::Exception& e){
Yingdi Yu2e57a582014-02-20 23:34:43 -0800570 // throw Error(e.what());
571 // }
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800572}
573
574bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700575SecTpmFile::doesKeyExistInTpm(const Name& keyName, KeyClass keyClass)
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800576{
577 string keyURI = keyName.toUri();
578 if (keyClass == KEY_CLASS_PUBLIC)
579 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700580 if (boost::filesystem::exists(m_impl->transformName(keyURI, ".pub")))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800581 return true;
582 else
583 return false;
584 }
585 if (keyClass == KEY_CLASS_PRIVATE)
586 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700587 if (boost::filesystem::exists(m_impl->transformName(keyURI, ".pri")))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800588 return true;
589 else
590 return false;
591 }
592 if (keyClass == KEY_CLASS_SYMMETRIC)
593 {
Yingdi Yu7036ce22014-06-19 18:53:37 -0700594 if (boost::filesystem::exists(m_impl->transformName(keyURI, ".key")))
Yingdi Yu2d9c50f2014-01-21 18:25:00 -0800595 return true;
596 else
597 return false;
598 }
599 return false;
600}
601
Yingdi Yu4b752752014-02-18 12:24:03 -0800602bool
603SecTpmFile::generateRandomBlock(uint8_t* res, size_t size)
604{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700605 try
606 {
607 CryptoPP::AutoSeededRandomPool rng;
608 rng.GenerateBlock(res, size);
609 return true;
610 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700611 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700612 {
613 return false;
614 }
Yingdi Yu4b752752014-02-18 12:24:03 -0800615}
616
Yingdi Yufc40d872014-02-18 12:56:04 -0800617} // namespace ndn