back-end.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2021 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 
23 
30 #include "ndn-cxx/util/random.hpp"
31 
32 #include <boost/lexical_cast.hpp>
33 
34 namespace ndn {
35 namespace security {
36 namespace tpm {
37 
38 BackEnd::~BackEnd() = default;
39 
40 bool
41 BackEnd::hasKey(const Name& keyName) const
42 {
43  return doHasKey(keyName);
44 }
45 
46 unique_ptr<KeyHandle>
47 BackEnd::getKeyHandle(const Name& keyName) const
48 {
49  return doGetKeyHandle(keyName);
50 }
51 
52 unique_ptr<KeyHandle>
53 BackEnd::createKey(const Name& identity, const KeyParams& params)
54 {
55  if (params.getKeyType() == KeyType::HMAC) {
56  return doCreateKey(identity, params);
57  }
58 
59  switch (params.getKeyIdType()) {
61  // check that the provided key id isn't already taken
62  Name keyName = constructKeyName(identity, params.getKeyId());
63  if (hasKey(keyName)) {
64  NDN_THROW(Error("Key `" + keyName.toUri() + "` already exists"));
65  }
66  break;
67  }
68  case KeyIdType::SHA256:
69  case KeyIdType::RANDOM:
70  // key id will be determined after key is generated
71  break;
72  default:
73  NDN_THROW(std::invalid_argument("Unsupported key id type " +
74  boost::lexical_cast<std::string>(params.getKeyIdType())));
75  }
76 
77  return doCreateKey(identity, params);
78 }
79 
80 void
81 BackEnd::deleteKey(const Name& keyName)
82 {
83  doDeleteKey(keyName);
84 }
85 
87 BackEnd::exportKey(const Name& keyName, const char* pw, size_t pwLen)
88 {
89  if (!hasKey(keyName)) {
90  NDN_THROW(Error("Key `" + keyName.toUri() + "` does not exist"));
91  }
92  return doExportKey(keyName, pw, pwLen);
93 }
94 
95 void
96 BackEnd::importKey(const Name& keyName, span<const uint8_t> pkcs8, const char* pw, size_t pwLen)
97 {
98  if (hasKey(keyName)) {
99  NDN_THROW(Error("Key `" + keyName.toUri() + "` already exists"));
100  }
101  doImportKey(keyName, pkcs8, pw, pwLen);
102 }
103 
104 void
105 BackEnd::importKey(const Name& keyName, shared_ptr<transform::PrivateKey> key)
106 {
107  if (hasKey(keyName)) {
108  NDN_THROW(Error("Key `" + keyName.toUri() + "` already exists"));
109  }
110  doImportKey(keyName, std::move(key));
111 }
112 
113 Name
114 BackEnd::constructAsymmetricKeyName(const KeyHandle& keyHandle, const Name& identity,
115  const KeyParams& params) const
116 {
117  switch (params.getKeyIdType()) {
119  return constructKeyName(identity, params.getKeyId());
120  }
121  case KeyIdType::SHA256: {
122  using namespace transform;
123  OBufferStream os;
124  bufferSource(*keyHandle.derivePublicKey()) >>
126  streamSink(os);
127  return constructKeyName(identity, name::Component(os.buf()));
128  }
129  case KeyIdType::RANDOM: {
130  Name keyName;
131  do {
133  keyName = constructKeyName(identity, keyId);
134  } while (hasKey(keyName));
135  return keyName;
136  }
137  default: {
138  NDN_THROW(Error("Unsupported key id type " + boost::lexical_cast<std::string>(params.getKeyIdType())));
139  }
140  }
141 }
142 
143 Name
145  const KeyParams& params) const
146 {
147  return Name(identity).append(name::Component(key.getKeyDigest(DigestAlgorithm::SHA256)));
148 }
149 
150 bool
152 {
153  return true;
154 }
155 
156 void
157 BackEnd::setTerminalMode(bool isTerminal) const
158 {
159 }
160 
161 bool
163 {
164  return false;
165 }
166 
167 bool
168 BackEnd::unlockTpm(const char* pw, size_t pwLen) const
169 {
170  return !isTpmLocked();
171 }
172 
173 } // namespace tpm
174 } // namespace security
175 } // namespace ndn
Base class for key parameters.
Definition: key-params.hpp:36
KeyIdType getKeyIdType() const
Definition: key-params.hpp:54
KeyType getKeyType() const
Definition: key-params.hpp:48
const name::Component & getKeyId() const
Definition: key-params.hpp:60
Represents an absolute name.
Definition: name.hpp:44
void toUri(std::ostream &os, name::UriFormat format=name::UriFormat::DEFAULT) const
Write URI representation of the name to the output stream.
Definition: name.cpp:349
An output stream that writes to a Buffer.
shared_ptr< Buffer > buf()
Return a shared pointer to the underlying buffer.
Represents a name component.
static Component fromNumber(uint64_t number, uint32_t type=tlv::GenericNameComponent)
Create a component encoded as NonNegativeInteger.
unique_ptr< KeyHandle > createKey(const Name &identityName, const KeyParams &params)
Create a key for identityName according to params.
Definition: back-end.cpp:53
void importKey(const Name &keyName, span< const uint8_t > pkcs8, const char *pw, size_t pwLen)
Import a private key in encrypted PKCS #8 format.
Definition: back-end.cpp:96
virtual bool unlockTpm(const char *pw, size_t pwLen) const
Unlock the TPM.
Definition: back-end.cpp:168
bool hasKey(const Name &keyName) const
Check if the key with name keyName exists in the TPM.
Definition: back-end.cpp:41
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
virtual bool isTerminalMode() const
Check if the TPM is in terminal mode.
Definition: back-end.cpp:151
virtual void setTerminalMode(bool isTerminal) const
Set the terminal mode of the TPM.
Definition: back-end.cpp:157
void deleteKey(const Name &keyName)
Delete the key with name keyName.
Definition: back-end.cpp:81
virtual bool isTpmLocked() const
Check if the TPM is locked.
Definition: back-end.cpp:162
ConstBufferPtr exportKey(const Name &keyName, const char *pw, size_t pwLen)
Get the private key with name keyName in encrypted PKCS #8 format.
Definition: back-end.cpp:87
unique_ptr< KeyHandle > getKeyHandle(const Name &keyName) const
Get the handle of the key with name keyName.
Definition: back-end.cpp:47
Name constructHmacKeyName(const transform::PrivateKey &key, const Name &identity, const KeyParams &params) const
Construct and return the name of a HMAC key, based on identity and params.
Definition: back-end.cpp:144
Abstraction of TPM key handle.
Definition: key-handle.hpp:38
ConstBufferPtr derivePublicKey() const
Definition: key-handle.cpp:50
Abstraction of private key in crypto transformation.
Definition: private-key.hpp:39
ConstBufferPtr getKeyDigest(DigestAlgorithm algo) const
Returns a digest of the private key.
#define NDN_THROW(e)
Definition: exception.hpp:61
uint64_t generateSecureWord64()
Generate a cryptographically secure random integer from the range [0, 2^64)
Definition: random.cpp:39
unique_ptr< Transform > digestFilter(DigestAlgorithm algo)
unique_ptr< Sink > streamSink(std::ostream &os)
Definition: stream-sink.cpp:53
Name constructKeyName(const Name &identity, const name::Component &keyId)
Construct key name based on the appropriate naming conventions.
Definition: key.cpp:129
@ Name
Definition: tlv.hpp:71
Definition: data.cpp:25
shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:139
@ HMAC
HMAC key, supports sign/verify operations.
@ RANDOM
Use a 64-bit random number as key id.
@ USER_SPECIFIED
User-specified key id.
@ SHA256
Use the SHA-256 hash of the public key as key id.