blob: f15962ca53d4de20bc44aee27990d746c70409fd [file] [log] [blame]
Yingdi Yu0b60e7a2015-07-16 21:05:11 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento8aad3722017-09-16 20:57:28 -04002/*
Yingdi Yufe4733a2015-10-22 14:24:12 -07003 * Copyright (c) 2013-2017 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
22#include "back-end.hpp"
23#include "key-handle.hpp"
24#include "tpm.hpp"
Davide Pesavento8aad3722017-09-16 20:57:28 -040025#include "../pib/key.hpp"
26#include "../transform/buffer-source.hpp"
27#include "../transform/digest-filter.hpp"
28#include "../transform/stream-sink.hpp"
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070029#include "../../encoding/buffer-stream.hpp"
30#include "../../util/random.hpp"
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070031
32namespace ndn {
33namespace security {
34namespace tpm {
35
36BackEnd::~BackEnd() = default;
37
38bool
39BackEnd::hasKey(const Name& keyName) const
40{
41 return doHasKey(keyName);
42}
43
44unique_ptr<KeyHandle>
45BackEnd::getKeyHandle(const Name& keyName) const
46{
47 return doGetKeyHandle(keyName);
48}
49
50unique_ptr<KeyHandle>
51BackEnd::createKey(const Name& identity, const KeyParams& params)
52{
53 // key name checking
54 switch (params.getKeyIdType()) {
55 case KeyIdType::USER_SPECIFIED: { // keyId is pre-set.
56 Name keyName = v2::constructKeyName(identity, params.getKeyId());
57 if (hasKey(keyName)) {
58 BOOST_THROW_EXCEPTION(Tpm::Error("Key `" + keyName.toUri() + "` already exists"));
59 }
60 break;
61 }
62 case KeyIdType::SHA256: {
63 // KeyName will be assigned in setKeyName after key is generated
64 break;
65 }
66 case KeyIdType::RANDOM: {
67 Name keyName;
68 name::Component keyId;
69 do {
70 keyId = name::Component::fromNumber(random::generateSecureWord64());
Yingdi Yufe4733a2015-10-22 14:24:12 -070071 keyName = v2::constructKeyName(identity, keyId);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070072 } while (hasKey(keyName));
73
74 const_cast<KeyParams&>(params).setKeyId(keyId);
75 break;
76 }
77 default: {
78 BOOST_THROW_EXCEPTION(Error("Unsupported key id type"));
79 }
80 }
81
82 return doCreateKey(identity, params);
83}
84
85void
86BackEnd::deleteKey(const Name& keyName)
87{
88 doDeleteKey(keyName);
89}
90
91ConstBufferPtr
92BackEnd::exportKey(const Name& keyName, const char* pw, size_t pwLen)
93{
94 if (!hasKey(keyName)) {
95 BOOST_THROW_EXCEPTION(Error("Key `" + keyName.toUri() + "` does not exist"));
96 }
97 return doExportKey(keyName, pw, pwLen);
98}
99
100void
101BackEnd::importKey(const Name& keyName, const uint8_t* pkcs8, size_t pkcs8Len, const char* pw, size_t pwLen)
102{
103 if (hasKey(keyName)) {
104 BOOST_THROW_EXCEPTION(Error("Key `" + keyName.toUri() + "` already exists"));
105 }
106 doImportKey(keyName, pkcs8, pkcs8Len, pw, pwLen);
107}
108
109void
110BackEnd::setKeyName(KeyHandle& keyHandle, const Name& identity, const KeyParams& params)
111{
112 name::Component keyId;
Davide Pesavento864e8e82017-10-04 23:41:14 -0400113
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700114 switch (params.getKeyIdType()) {
Davide Pesavento864e8e82017-10-04 23:41:14 -0400115 case KeyIdType::USER_SPECIFIED: {
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700116 keyId = params.getKeyId();
117 break;
Davide Pesavento864e8e82017-10-04 23:41:14 -0400118 }
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700119 case KeyIdType::SHA256: {
120 using namespace transform;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700121 OBufferStream os;
Davide Pesavento864e8e82017-10-04 23:41:14 -0400122 bufferSource(*keyHandle.derivePublicKey()) >>
123 digestFilter(DigestAlgorithm::SHA256) >>
124 streamSink(os);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700125 keyId = name::Component(os.buf());
126 break;
127 }
128 case KeyIdType::RANDOM: {
129 BOOST_ASSERT(!params.getKeyId().empty());
130 keyId = params.getKeyId();
131 break;
132 }
133 default: {
Davide Pesavento864e8e82017-10-04 23:41:14 -0400134 BOOST_THROW_EXCEPTION(Error("Unsupported key id type"));
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700135 }
136 }
137
138 keyHandle.setKeyName(v2::constructKeyName(identity, keyId));
139}
140
Yingdi Yufe4733a2015-10-22 14:24:12 -0700141bool
142BackEnd::isTerminalMode() const
143{
144 return true;
145}
146
147void
148BackEnd::setTerminalMode(bool isTerminal) const
149{
150}
151
152bool
153BackEnd::isTpmLocked() const
154{
155 return false;
156}
157
158bool
159BackEnd::unlockTpm(const char* pw, size_t pwLen) const
160{
161 return !isTpmLocked();
162}
163
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700164} // namespace tpm
165} // namespace security
166} // namespace ndn