NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.3: 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; -*- */
22 #include "back-end-file.hpp"
23 #include "key-handle-mem.hpp"
24 #include "../transform.hpp"
25 #include "../transform/private-key.hpp"
26 #include "../../encoding/buffer-stream.hpp"
27 #include <unordered_map>
28 #include <fstream>
29 #include <cstdlib>
30 #include <boost/filesystem.hpp>
31 
32 namespace ndn {
33 namespace security {
34 namespace tpm {
35 
37 
39 {
40 public:
41  explicit
42  Impl(const std::string& dir)
43  {
44  if (!dir.empty()) {
45  keystorePath = boost::filesystem::path(dir);
46  }
47 #ifdef NDN_CXX_HAVE_TESTS
48  else if (getenv("TEST_HOME") != nullptr) {
49  keystorePath = boost::filesystem::path(getenv("TEST_HOME")) / ".ndn";
50  }
51 #endif // NDN_CXX_HAVE_TESTS
52  else if (getenv("HOME") != nullptr) {
53  keystorePath = boost::filesystem::path(getenv("HOME")) / ".ndn";
54  }
55  else {
56  keystorePath = boost::filesystem::current_path() / ".ndn";
57  }
58 
59  keystorePath /= "ndnsec-key-file";
60  boost::filesystem::create_directories(keystorePath);
61  }
62 
63  boost::filesystem::path
64  toFileName(const Name& keyName)
65  {
66  std::stringstream os;
67  {
68  using namespace transform;
69  bufferSource(keyName.wireEncode().wire(), keyName.wireEncode().size()) >>
71  }
72  return keystorePath / (os.str() + ".privkey");
73  }
74 
75 public:
76  boost::filesystem::path keystorePath;
77 };
78 
79 BackEndFile::BackEndFile(const std::string& location)
80  : m_impl(new Impl(location))
81 {
82 }
83 
84 BackEndFile::~BackEndFile() = default;
85 
86 const std::string&
88 {
89  static std::string scheme = "tpm-file";
90  return scheme;
91 }
92 
93 bool
94 BackEndFile::doHasKey(const Name& keyName) const
95 {
96  if (!boost::filesystem::exists(m_impl->toFileName(keyName)))
97  return false;
98 
99  try {
100  loadKey(keyName);
101  return true;
102  }
103  catch (const std::runtime_error&) {
104  return false;
105  }
106 }
107 
108 unique_ptr<KeyHandle>
109 BackEndFile::doGetKeyHandle(const Name& keyName) const
110 {
111  if (!doHasKey(keyName))
112  return nullptr;
113 
114  return make_unique<KeyHandleMem>(loadKey(keyName));
115 }
116 
117 unique_ptr<KeyHandle>
118 BackEndFile::doCreateKey(const Name& identityName, const KeyParams& params)
119 {
120  shared_ptr<PrivateKey> key(transform::generatePrivateKey(params).release());
121  unique_ptr<KeyHandle> keyHandle = make_unique<KeyHandleMem>(key);
122 
123  setKeyName(*keyHandle, identityName, params);
124 
125  try {
126  saveKey(keyHandle->getKeyName(), key);
127  return keyHandle;
128  }
129  catch (const std::runtime_error& e) {
130  BOOST_THROW_EXCEPTION(Error(std::string("Cannot write key to disk: ") + e.what()));
131  }
132 }
133 
134 void
135 BackEndFile::doDeleteKey(const Name& keyName)
136 {
137  boost::filesystem::path keyPath(m_impl->toFileName(keyName));
138 
139  if (boost::filesystem::exists(keyPath)) {
140  try {
141  boost::filesystem::remove(keyPath);
142  }
143  catch (const boost::filesystem::filesystem_error&) {
144  BOOST_THROW_EXCEPTION(Error("Cannot delete key"));
145  }
146  }
147 }
148 
150 BackEndFile::doExportKey(const Name& keyName, const char* pw, size_t pwLen)
151 {
152  shared_ptr<PrivateKey> key;
153  try {
154  key = loadKey(keyName);
155  }
156  catch (const PrivateKey::Error&) {
157  BOOST_THROW_EXCEPTION(Error("Cannot export private key"));
158  }
159  OBufferStream os;
160  key->savePkcs8(os, pw, pwLen);
161  return os.buf();
162 }
163 
164 void
165 BackEndFile::doImportKey(const Name& keyName, const uint8_t* buf, size_t size, const char* pw, size_t pwLen)
166 {
167  try {
168  auto key = make_shared<PrivateKey>();
169  key->loadPkcs8(buf, size, pw, pwLen);
170  saveKey(keyName, key);
171  }
172  catch (const PrivateKey::Error&) {
173  BOOST_THROW_EXCEPTION(Error("Cannot import private key"));
174  }
175 }
176 
177 shared_ptr<PrivateKey>
178 BackEndFile::loadKey(const Name& keyName) const
179 {
180  auto key = make_shared<PrivateKey>();
181  std::fstream is(m_impl->toFileName(keyName).string(), std::ios_base::in);
182  key->loadPkcs1Base64(is);
183  return key;
184 }
185 
186 void
187 BackEndFile::saveKey(const Name& keyName, shared_ptr<PrivateKey> key)
188 {
189  std::string fileName = m_impl->toFileName(keyName).string();
190  std::fstream os(fileName, std::ios_base::out);
191  key->savePkcs1Base64(os);
192 
193  // set file permission
194  chmod(fileName.c_str(), 0000400);
195 }
196 
197 } // namespace tpm
198 } // namespace security
199 } // namespace ndn
Copyright (c) 2011-2015 Regents of the University of California.
unique_ptr< Transform > hexEncode(bool useUpperCase)
Definition: hex-encode.cpp:69
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
Definition: name.cpp:131
boost::filesystem::path keystorePath
unique_ptr< PrivateKey > generatePrivateKey(const KeyParams &keyParams)
Generate a private key according to keyParams.
Catch-all error for security policy errors that don&#39;t fit in other categories.
Definition: base.hpp:79
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:42
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)
shared_ptr< Buffer > buf()
Flush written data to the stream and return shared pointer to the underlying buffer.
Base class of key parameters.
Definition: key-params.hpp:35
implements an output stream that constructs ndn::Buffer
shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:89