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-2018 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 
34 namespace ndn {
35 namespace security {
36 namespace tpm {
37 
39 
41 {
42 public:
43  explicit
44  Impl(const std::string& dir)
45  {
46  if (!dir.empty()) {
47  keystorePath = boost::filesystem::path(dir);
48  }
49 #ifdef NDN_CXX_HAVE_TESTS
50  else if (std::getenv("TEST_HOME") != nullptr) {
51  keystorePath = boost::filesystem::path(std::getenv("TEST_HOME")) / ".ndn";
52  }
53 #endif // NDN_CXX_HAVE_TESTS
54  else if (std::getenv("HOME") != nullptr) {
55  keystorePath = boost::filesystem::path(std::getenv("HOME")) / ".ndn";
56  }
57  else {
58  keystorePath = boost::filesystem::current_path() / ".ndn";
59  }
60 
61  keystorePath /= "ndnsec-key-file";
62  boost::filesystem::create_directories(keystorePath);
63  }
64 
65  boost::filesystem::path
66  toFileName(const Name& keyName)
67  {
68  std::stringstream os;
69  {
70  using namespace transform;
71  bufferSource(keyName.wireEncode().wire(), keyName.wireEncode().size()) >>
73  }
74  return keystorePath / (os.str() + ".privkey");
75  }
76 
77 public:
78  boost::filesystem::path keystorePath;
79 };
80 
81 BackEndFile::BackEndFile(const std::string& location)
82  : m_impl(new Impl(location))
83 {
84 }
85 
86 BackEndFile::~BackEndFile() = default;
87 
88 const std::string&
90 {
91  static std::string scheme = "tpm-file";
92  return scheme;
93 }
94 
95 bool
96 BackEndFile::doHasKey(const Name& keyName) const
97 {
98  if (!boost::filesystem::exists(m_impl->toFileName(keyName)))
99  return false;
100 
101  try {
102  loadKey(keyName);
103  return true;
104  }
105  catch (const std::runtime_error&) {
106  return false;
107  }
108 }
109 
110 unique_ptr<KeyHandle>
111 BackEndFile::doGetKeyHandle(const Name& keyName) const
112 {
113  if (!doHasKey(keyName))
114  return nullptr;
115 
116  return make_unique<KeyHandleMem>(loadKey(keyName));
117 }
118 
119 unique_ptr<KeyHandle>
120 BackEndFile::doCreateKey(const Name& identityName, const KeyParams& params)
121 {
122  shared_ptr<PrivateKey> key(transform::generatePrivateKey(params).release());
123  unique_ptr<KeyHandle> keyHandle = make_unique<KeyHandleMem>(key);
124 
125  setKeyName(*keyHandle, identityName, params);
126 
127  try {
128  saveKey(keyHandle->getKeyName(), *key);
129  return keyHandle;
130  }
131  catch (const std::runtime_error& e) {
132  BOOST_THROW_EXCEPTION(Error("Cannot write key to file: "s + e.what()));
133  }
134 }
135 
136 void
137 BackEndFile::doDeleteKey(const Name& keyName)
138 {
139  boost::filesystem::path keyPath(m_impl->toFileName(keyName));
140  if (!boost::filesystem::exists(keyPath))
141  return;
142 
143  try {
144  boost::filesystem::remove(keyPath);
145  }
146  catch (const boost::filesystem::filesystem_error& e) {
147  BOOST_THROW_EXCEPTION(Error("Cannot remove key file: "s + e.what()));
148  }
149 }
150 
152 BackEndFile::doExportKey(const Name& keyName, const char* pw, size_t pwLen)
153 {
154  unique_ptr<PrivateKey> key;
155  try {
156  key = loadKey(keyName);
157  }
158  catch (const PrivateKey::Error& e) {
159  BOOST_THROW_EXCEPTION(Error("Cannot export private key: "s + e.what()));
160  }
161 
162  OBufferStream os;
163  key->savePkcs8(os, pw, pwLen);
164  return os.buf();
165 }
166 
167 void
168 BackEndFile::doImportKey(const Name& keyName, const uint8_t* buf, size_t size, const char* pw, size_t pwLen)
169 {
170  try {
171  PrivateKey key;
172  key.loadPkcs8(buf, size, pw, pwLen);
173  saveKey(keyName, key);
174  }
175  catch (const PrivateKey::Error& e) {
176  BOOST_THROW_EXCEPTION(Error("Cannot import private key: "s + e.what()));
177  }
178 }
179 
180 unique_ptr<PrivateKey>
181 BackEndFile::loadKey(const Name& keyName) const
182 {
183  std::ifstream is(m_impl->toFileName(keyName).string());
184  auto key = make_unique<PrivateKey>();
185  key->loadPkcs1Base64(is);
186  return key;
187 }
188 
189 void
190 BackEndFile::saveKey(const Name& keyName, const PrivateKey& key)
191 {
192  std::string fileName = m_impl->toFileName(keyName).string();
193  std::ofstream os(fileName);
194  key.savePkcs1Base64(os);
195 
196  // set file permission
197  ::chmod(fileName.data(), 0000400);
198 }
199 
200 } // namespace tpm
201 } // namespace security
202 } // namespace ndn
Copyright (c) 2011-2015 Regents of the University of California.
unique_ptr< Transform > hexEncode(bool useUpperCase)
Definition: hex-encode.cpp:70
boost::filesystem::path keystorePath
unique_ptr< PrivateKey > generatePrivateKey(const KeyParams &keyParams)
Generate a private key according to keyParams.
static const std::string & getScheme()
unique_ptr< Sink > streamSink(std::ostream &os)
Definition: stream-sink.cpp:53
BackEndFile(const std::string &location="")
Create file-based TPM backend.
unique_ptr< Transform > digestFilter(DigestAlgorithm algo)
Use the SHA256 hash of the public key as the key id.
Represents an absolute name.
Definition: name.hpp:43
static void setKeyName(KeyHandle &keyHandle, const Name &identity, const KeyParams &params)
Set the key name in keyHandle according to identity and params.
Definition: back-end.cpp:110
boost::filesystem::path toFileName(const Name &keyName)
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
Definition: name.cpp:125
shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:126