blob: 5c20f715c9fb52d66bd174ebadf40d0021e5ff4f [file] [log] [blame]
Yingdi Yu0b60e7a2015-07-16 21:05:11 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesaventodb4da5e2018-06-15 11:37:52 -04002/*
Davide Pesavento923ba442019-02-12 22:00:38 -05003 * Copyright (c) 2013-2019 Regents of the University of California.
Yingdi Yu0b60e7a2015-07-16 21:05:11 -07004 *
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
Davide Pesavento7e780642018-11-24 15:51:34 -050022#include "ndn-cxx/security/tpm/back-end-mem.hpp"
23#include "ndn-cxx/security/tpm/key-handle-mem.hpp"
24#include "ndn-cxx/security/transform/private-key.hpp"
25#include "ndn-cxx/encoding/buffer-stream.hpp"
Davide Pesaventodb4da5e2018-06-15 11:37:52 -040026
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070027#include <unordered_map>
28
laqinfan56a812d2019-06-03 15:33:58 -050029#include <boost/lexical_cast.hpp>
30
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070031namespace ndn {
32namespace security {
33namespace tpm {
34
35using transform::PrivateKey;
36
37class BackEndMem::Impl
38{
39public:
40 std::unordered_map<Name, shared_ptr<PrivateKey>> keys;
41};
42
Yingdi Yufe4733a2015-10-22 14:24:12 -070043BackEndMem::BackEndMem(const std::string&)
laqinfan56a812d2019-06-03 15:33:58 -050044 : m_impl(make_unique<Impl>())
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070045{
46}
47
48BackEndMem::~BackEndMem() = default;
49
Yingdi Yufe4733a2015-10-22 14:24:12 -070050const std::string&
51BackEndMem::getScheme()
52{
53 static std::string scheme = "tpm-memory";
54 return scheme;
55}
56
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070057bool
58BackEndMem::doHasKey(const Name& keyName) const
59{
60 return (m_impl->keys.count(keyName) > 0);
61}
62
63unique_ptr<KeyHandle>
64BackEndMem::doGetKeyHandle(const Name& keyName) const
65{
66 auto it = m_impl->keys.find(keyName);
67 if (it == m_impl->keys.end())
68 return nullptr;
69 return make_unique<KeyHandleMem>(it->second);
70}
71
72unique_ptr<KeyHandle>
73BackEndMem::doCreateKey(const Name& identityName, const KeyParams& params)
74{
laqinfan56a812d2019-06-03 15:33:58 -050075 switch (params.getKeyType()) {
76 case KeyType::RSA:
77 case KeyType::EC:
78 case KeyType::HMAC:
79 break;
80 default:
81 NDN_THROW(Error("Memory-based TPM does not support creating a key of type " +
82 boost::lexical_cast<std::string>(params.getKeyType())));
83 }
84
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070085 shared_ptr<PrivateKey> key(transform::generatePrivateKey(params).release());
86 unique_ptr<KeyHandle> keyHandle = make_unique<KeyHandleMem>(key);
87
laqinfan56a812d2019-06-03 15:33:58 -050088 Name keyName;
89 if (params.getKeyType() == KeyType::HMAC) {
90 keyName = constructHmacKeyName(*key, identityName, params);
91 }
92 else {
93 keyName = constructAsymmetricKeyName(*keyHandle, identityName, params);
94 }
95 keyHandle->setKeyName(keyName);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070096
laqinfan56a812d2019-06-03 15:33:58 -050097 m_impl->keys[keyName] = std::move(key);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070098 return keyHandle;
99}
100
101void
102BackEndMem::doDeleteKey(const Name& keyName)
103{
104 m_impl->keys.erase(keyName);
105}
106
107ConstBufferPtr
108BackEndMem::doExportKey(const Name& keyName, const char* pw, size_t pwLen)
109{
110 OBufferStream os;
111 m_impl->keys[keyName]->savePkcs8(os, pw, pwLen);
112 return os.buf();
113}
114
115void
116BackEndMem::doImportKey(const Name& keyName, const uint8_t* buf, size_t size, const char* pw, size_t pwLen)
117{
laqinfan56a812d2019-06-03 15:33:58 -0500118 auto key = make_shared<PrivateKey>();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700119 try {
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700120 key->loadPkcs8(buf, size, pw, pwLen);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700121 }
Davide Pesavento923ba442019-02-12 22:00:38 -0500122 catch (const PrivateKey::Error&) {
123 NDN_THROW_NESTED(Error("Cannot import private key"));
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700124 }
laqinfan56a812d2019-06-03 15:33:58 -0500125 doImportKey(keyName, std::move(key));
126}
127
128void
129BackEndMem::doImportKey(const Name& keyName, shared_ptr<transform::PrivateKey> key)
130{
131 m_impl->keys[keyName] = std::move(key);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700132}
133
134} // namespace tpm
135} // namespace security
136} // namespace ndn