NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.5: NDN, CCN, CCNx, content centric networks
API Documentation
back-end-file.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2019 Regents of the University of California.
4  *
5  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6  *
7  * 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.
20  */
21 
27 
28 #include <cstdlib>
29 #include <fstream>
30 #include <sys/stat.h>
31 
32 #include <boost/filesystem.hpp>
33 #include <boost/lexical_cast.hpp>
34 
35 namespace ndn {
36 namespace security {
37 namespace tpm {
38 
39 namespace fs = boost::filesystem;
41 
43 {
44 public:
45  explicit
46  Impl(const std::string& dir)
47  {
48  if (!dir.empty()) {
49  m_keystorePath = fs::path(dir);
50  }
51 #ifdef NDN_CXX_HAVE_TESTS
52  else if (std::getenv("TEST_HOME") != nullptr) {
53  m_keystorePath = fs::path(std::getenv("TEST_HOME")) / ".ndn";
54  }
55 #endif // NDN_CXX_HAVE_TESTS
56  else if (std::getenv("HOME") != nullptr) {
57  m_keystorePath = fs::path(std::getenv("HOME")) / ".ndn";
58  }
59  else {
60  m_keystorePath = fs::current_path() / ".ndn";
61  }
62 
63  m_keystorePath /= "ndnsec-key-file";
64  fs::create_directories(m_keystorePath);
65  }
66 
67  fs::path
68  toFileName(const Name& keyName) const
69  {
70  std::ostringstream os;
71  {
72  using namespace transform;
73  bufferSource(keyName.wireEncode().wire(), keyName.wireEncode().size())
75  >> hexEncode()
76  >> streamSink(os);
77  }
78  return m_keystorePath / (os.str() + ".privkey");
79  }
80 
81 private:
82  fs::path m_keystorePath;
83 };
84 
85 BackEndFile::BackEndFile(const std::string& location)
86  : m_impl(make_unique<Impl>(location))
87 {
88 }
89 
90 BackEndFile::~BackEndFile() = default;
91 
92 const std::string&
94 {
95  static std::string scheme = "tpm-file";
96  return scheme;
97 }
98 
99 bool
100 BackEndFile::doHasKey(const Name& keyName) const
101 {
102  if (!fs::exists(m_impl->toFileName(keyName)))
103  return false;
104 
105  try {
106  loadKey(keyName);
107  return true;
108  }
109  catch (const std::runtime_error&) {
110  return false;
111  }
112 }
113 
114 unique_ptr<KeyHandle>
115 BackEndFile::doGetKeyHandle(const Name& keyName) const
116 {
117  if (!doHasKey(keyName))
118  return nullptr;
119 
120  return make_unique<KeyHandleMem>(loadKey(keyName));
121 }
122 
123 unique_ptr<KeyHandle>
124 BackEndFile::doCreateKey(const Name& identityName, const KeyParams& params)
125 {
126  switch (params.getKeyType()) {
127  case KeyType::RSA:
128  case KeyType::EC:
129  break;
130  default:
131  NDN_THROW(std::invalid_argument("File-based TPM does not support creating a key of type " +
132  boost::lexical_cast<std::string>(params.getKeyType())));
133  }
134 
135  shared_ptr<PrivateKey> key(transform::generatePrivateKey(params).release());
136  unique_ptr<KeyHandle> keyHandle = make_unique<KeyHandleMem>(key);
137 
138  Name keyName = constructAsymmetricKeyName(*keyHandle, identityName, params);
139  keyHandle->setKeyName(keyName);
140 
141  try {
142  saveKey(keyName, *key);
143  return keyHandle;
144  }
145  catch (const std::runtime_error&) {
146  NDN_THROW_NESTED(Error("Cannot write key to file"));
147  }
148 }
149 
150 void
151 BackEndFile::doDeleteKey(const Name& keyName)
152 {
153  auto keyPath = m_impl->toFileName(keyName);
154  if (!fs::exists(keyPath))
155  return;
156 
157  try {
158  fs::remove(keyPath);
159  }
160  catch (const fs::filesystem_error&) {
161  NDN_THROW_NESTED(Error("Cannot remove key file"));
162  }
163 }
164 
166 BackEndFile::doExportKey(const Name& keyName, const char* pw, size_t pwLen)
167 {
168  unique_ptr<PrivateKey> key;
169  try {
170  key = loadKey(keyName);
171  }
172  catch (const PrivateKey::Error&) {
173  NDN_THROW_NESTED(Error("Cannot export private key"));
174  }
175 
176  OBufferStream os;
177  key->savePkcs8(os, pw, pwLen);
178  return os.buf();
179 }
180 
181 void
182 BackEndFile::doImportKey(const Name& keyName, const uint8_t* buf, size_t size, const char* pw, size_t pwLen)
183 {
184  try {
185  PrivateKey key;
186  key.loadPkcs8(buf, size, pw, pwLen);
187  saveKey(keyName, key);
188  }
189  catch (const PrivateKey::Error&) {
190  NDN_THROW_NESTED(Error("Cannot import private key"));
191  }
192 }
193 
194 void
195 BackEndFile::doImportKey(const Name& keyName, shared_ptr<transform::PrivateKey> key)
196 {
197  try {
198  saveKey(keyName, *key);
199  }
200  catch (const PrivateKey::Error&) {
201  NDN_THROW_NESTED(Error("Cannot import private key"));
202  }
203 }
204 
205 unique_ptr<PrivateKey>
206 BackEndFile::loadKey(const Name& keyName) const
207 {
208  std::ifstream is(m_impl->toFileName(keyName).string());
209  auto key = make_unique<PrivateKey>();
210  key->loadPkcs1Base64(is);
211  return key;
212 }
213 
214 void
215 BackEndFile::saveKey(const Name& keyName, const PrivateKey& key)
216 {
217  std::string fileName = m_impl->toFileName(keyName).string();
218  std::ofstream os(fileName);
219  key.savePkcs1Base64(os);
220 
221  // set file permission
222  ::chmod(fileName.data(), 0000400);
223 }
224 
225 } // namespace tpm
226 } // namespace security
227 } // namespace ndn
buf
const uint8_t * buf
Definition: verification-helpers.cpp:47
transform
ndn::DigestAlgorithm::SHA256
@ SHA256
ndn::security::transform::generatePrivateKey
unique_ptr< PrivateKey > generatePrivateKey(const KeyParams &keyParams)
Generate a private key according to keyParams.
Definition: private-key.cpp:536
ndn::security::tpm::BackEnd::Error
Tpm::Error Error
Definition: back-end.hpp:39
ndn::security::transform::bufferSource
BufferSource bufferSource
Definition: buffer-source.hpp:73
NDN_THROW_NESTED
#define NDN_THROW_NESTED(e)
Definition: exception.hpp:71
ndn::KeyType::EC
@ EC
Elliptic Curve key (e.g. for ECDSA), supports sign/verify operations.
ndn::Name
Represents an absolute name.
Definition: name.hpp:44
ns3::ndn::Name
Name
Definition: ndn-common.cpp:25
ndn::security::tpm::BackEndFile::~BackEndFile
~BackEndFile() final
ndn::security::transform::hexEncode
unique_ptr< Transform > hexEncode(bool useUpperCase)
Definition: hex-encode.cpp:70
ndn::Name::wireEncode
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
Definition: name.cpp:117
private-key.hpp
NDN_THROW
#define NDN_THROW(e)
Definition: exception.hpp:61
ndn::security::tpm::BackEndFile::Impl
Definition: back-end-file.cpp:43
ndn::security::tpm::BackEnd::constructAsymmetricKeyName
Name constructAsymmetricKeyName(const KeyHandle &key, const Name &identity, const KeyParams &params) const
Construct and return the name of a RSA or EC key, based on identity and params.
Definition: back-end.cpp:114
ndn::security::tpm::BackEndFile::Impl::Impl
Impl(const std::string &dir)
Definition: back-end-file.cpp:46
ndn::security::tpm::BackEndFile::Impl::toFileName
fs::path toFileName(const Name &keyName) const
Definition: back-end-file.cpp:68
transform::PrivateKey
ndn::security::tpm::BackEndFile::BackEndFile
BackEndFile(const std::string &location="")
Create file-based TPM backend.
Definition: back-end-file.cpp:85
transform.hpp
ndn::security::transform::digestFilter
unique_ptr< Transform > digestFilter(DigestAlgorithm algo)
Definition: digest-filter.cpp:76
key-handle-mem.hpp
ndn::security::transform::streamSink
unique_ptr< Sink > streamSink(std::ostream &os)
Definition: stream-sink.cpp:53
buffer-stream.hpp
back-end-file.hpp
ndn::KeyType::RSA
@ RSA
RSA key, supports sign/verify and encrypt/decrypt operations.
ndn::ConstBufferPtr
shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:126
ndn::security::tpm::BackEndFile::getScheme
static const std::string & getScheme()
Definition: back-end-file.cpp:93
ndn
Copyright (c) 2011-2015 Regents of the University of California.
Definition: ndn-strategy-choice-helper.hpp:34