blob: 620a2cc0ec99ef7c184da8fbb3daec7e70ee69f7 [file] [log] [blame]
Yingdi Yu0b60e7a2015-07-16 21:05:11 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento82d6a4c2017-12-23 19:47:20 -05002/*
Davide Pesavento3b101d02018-07-21 22:44:09 -04003 * Copyright (c) 2013-2018 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#ifndef NDN_SECURITY_TPM_TPM_HPP
23#define NDN_SECURITY_TPM_TPM_HPP
24
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070025#include "key-handle.hpp"
Davide Pesavento82d6a4c2017-12-23 19:47:20 -050026#include "../key-params.hpp"
27#include "../../name.hpp"
Davide Pesavento794f6872017-05-15 23:33:38 -040028
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070029#include <unordered_map>
30
31namespace ndn {
32namespace security {
Yingdi Yufe4733a2015-10-22 14:24:12 -070033
34namespace v2 {
35class KeyChain;
36} // namespace v2
37
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070038namespace tpm {
39
40class BackEnd;
41
42/**
43 * @brief represents the front-end of TPM
44 *
45 * The TPM (Trusted Platform Module) stores the private portion of a user's cryptography keys.
46 * The format and location of stored information is indicated by the TpmLocator.
47 * The TPM is designed to work with a PIB (Public Information Base) which stores public keys and
48 * related information such as certificate.
49 *
50 * The TPM also provides functionalities of crypto transformation, such as signing and decryption.
51 *
52 * A TPM consists of a unified front-end interface and a back-end implementation. The front-end
53 * cache the handles of private keys which is provided by the back-end implementation.
54 *
Yingdi Yufe4733a2015-10-22 14:24:12 -070055 * @note Tpm instance is created and managed only by v2::KeyChain. v2::KeyChain::getTpm()
56 * returns a const reference to the managed Tpm instance, through which it is possible to
57 * check existence of private keys, get public keys for the private keys, sign, and decrypt
58 * the supplied buffers using managed private keys.
59 *
60 * @throw BackEnd::Error Failure with the underlying implementation having non-semantic errors
61 * @throw Tpm::Error Failure with semantic error in the underlying implementation
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070062 */
63class Tpm : noncopyable
64{
65public:
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070066 class Error : public std::runtime_error
67 {
68 public:
Junxiao Shi68b53852018-07-25 13:56:38 -060069 using std::runtime_error::runtime_error;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070070 };
71
72public:
73 ~Tpm();
74
75 std::string
76 getTpmLocator() const;
77
78 /**
Davide Pesavento92856862017-05-15 21:35:08 -040079 * @brief Check if a private key exists.
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070080 *
81 * @param keyName The key name
82 * @return true if the key exists
83 */
84 bool
85 hasKey(const Name& keyName) const;
86
87 /**
Davide Pesavento92856862017-05-15 21:35:08 -040088 * @return The public portion of an asymmetric key with name @p keyName,
89 * or nullptr if the key does not exist,
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070090 *
Davide Pesavento92856862017-05-15 21:35:08 -040091 * The public key is in PKCS#8 format.
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070092 */
93 ConstBufferPtr
94 getPublicKey(const Name& keyName) const;
95
96 /**
Davide Pesavento92856862017-05-15 21:35:08 -040097 * @brief Sign blob using the key with name @p keyName and using the digest @p digestAlgorithm.
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070098 *
Davide Pesavento92856862017-05-15 21:35:08 -040099 * @return The signature, or nullptr if the key does not exist.
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700100 */
101 ConstBufferPtr
102 sign(const uint8_t* buf, size_t size, const Name& keyName, DigestAlgorithm digestAlgorithm) const;
103
104 /**
Davide Pesavento92856862017-05-15 21:35:08 -0400105 * @brief Decrypt blob using the key with name @p keyName.
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700106 *
Davide Pesavento92856862017-05-15 21:35:08 -0400107 * @return The decrypted data, or nullptr if the key does not exist.
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700108 */
109 ConstBufferPtr
110 decrypt(const uint8_t* buf, size_t size, const Name& keyName) const;
111
Yingdi Yufe4733a2015-10-22 14:24:12 -0700112public: // Management
113 /**
Davide Pesavento92856862017-05-15 21:35:08 -0400114 * @brief Check if the TPM is in terminal mode.
Yingdi Yufe4733a2015-10-22 14:24:12 -0700115 */
116 bool
117 isTerminalMode() const;
118
119 /**
Davide Pesavento92856862017-05-15 21:35:08 -0400120 * @brief Set the terminal mode of the TPM.
Yingdi Yufe4733a2015-10-22 14:24:12 -0700121 *
Davide Pesavento92856862017-05-15 21:35:08 -0400122 * When in terminal mode, the TPM will not ask user permission from GUI.
Yingdi Yufe4733a2015-10-22 14:24:12 -0700123 */
124 void
125 setTerminalMode(bool isTerminal) const;
126
127 /**
Davide Pesavento92856862017-05-15 21:35:08 -0400128 * @return true if the TPM is locked, otherwise false.
Yingdi Yufe4733a2015-10-22 14:24:12 -0700129 */
130 bool
131 isTpmLocked() const;
132
133 /**
Davide Pesavento92856862017-05-15 21:35:08 -0400134 * @brief Unlock the TPM.
Yingdi Yufe4733a2015-10-22 14:24:12 -0700135 *
Davide Pesavento92856862017-05-15 21:35:08 -0400136 * @param password The password to unlock the TPM.
Yingdi Yufe4733a2015-10-22 14:24:12 -0700137 * @param passwordLength The password size.
138 */
139 bool
140 unlockTpm(const char* password, size_t passwordLength) const;
141
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700142NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Davide Pesavento3b101d02018-07-21 22:44:09 -0400143 /**
Davide Pesavento92856862017-05-15 21:35:08 -0400144 * @brief Create a new TPM instance with the specified @p location.
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700145 *
146 * @param scheme The scheme for the TPM
147 * @param location The location for the TPM
148 * @param impl The back-end implementation
149 */
150 Tpm(const std::string& scheme, const std::string& location, unique_ptr<BackEnd> impl);
151
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700152 /**
153 * @brief Create key for @p identityName according to @p params.
154 *
155 * The created key is named as: /<identityName>/[keyId]/KEY
156 *
Davide Pesavento92856862017-05-15 21:35:08 -0400157 * @return The key name.
158 * @throw Tpm::Error the key already exists or @p params is invalid.
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700159 */
160 Name
161 createKey(const Name& identityName, const KeyParams& params);
162
163 /**
164 * @brief Delete a key pair with name @p keyName.
165 */
166 void
167 deleteKey(const Name& keyName);
168
169 /**
Davide Pesavento92856862017-05-15 21:35:08 -0400170 * @brief Export a private key.
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700171 *
Davide Pesavento92856862017-05-15 21:35:08 -0400172 * Export a private key in encrypted PKCS #8 format.
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700173 *
Davide Pesavento92856862017-05-15 21:35:08 -0400174 * @param keyName The private key name
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700175 * @param pw The password to encrypt the private key
176 * @param pwLen The length of the password
Davide Pesavento92856862017-05-15 21:35:08 -0400177 * @return The encoded private key wrapper.
Davide Pesavento82d6a4c2017-12-23 19:47:20 -0500178 * @throw BackEnd::Error The key does not exist or it could not be exported.
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700179 */
180 ConstBufferPtr
Davide Pesavento794f6872017-05-15 23:33:38 -0400181 exportPrivateKey(const Name& keyName, const char* pw, size_t pwLen) const;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700182
183 /**
Davide Pesavento92856862017-05-15 21:35:08 -0400184 * @brief Import a private key.
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700185 *
186 * @param keyName The private key name
187 * @param pkcs8 The private key wrapper
188 * @param pkcs8Len The length of the private key wrapper
189 * @param pw The password to encrypt the private key
190 * @param pwLen The length of the password
Davide Pesavento82d6a4c2017-12-23 19:47:20 -0500191 * @throw BackEnd::Error The key could not be imported.
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700192 */
Davide Pesavento82d6a4c2017-12-23 19:47:20 -0500193 void
Davide Pesavento92856862017-05-15 21:35:08 -0400194 importPrivateKey(const Name& keyName, const uint8_t* pkcs8, size_t pkcs8Len,
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700195 const char* pw, size_t pwLen);
196
197 /**
Davide Pesavento92856862017-05-15 21:35:08 -0400198 * @brief Clear the key cache.
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700199 *
Davide Pesavento82d6a4c2017-12-23 19:47:20 -0500200 * An empty cache can force Tpm to do key lookup in the back-end.
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700201 */
202 void
203 clearKeyCache()
204 {
205 m_keys.clear();
206 }
207
208private:
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700209 /**
Davide Pesavento92856862017-05-15 21:35:08 -0400210 * @brief Internal KeyHandle lookup.
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700211 *
212 * @return A pointer to the handle of key @p keyName if it exists, otherwise nullptr.
213 */
214 const KeyHandle*
215 findKey(const Name& keyName) const;
216
217private:
218 std::string m_scheme;
219 std::string m_location;
220
221 mutable std::unordered_map<Name, unique_ptr<KeyHandle>> m_keys;
222
Davide Pesavento794f6872017-05-15 23:33:38 -0400223 const unique_ptr<BackEnd> m_backEnd;
Yingdi Yufe4733a2015-10-22 14:24:12 -0700224
225 friend class v2::KeyChain;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700226};
227
228} // namespace tpm
229
230using tpm::Tpm;
231
232} // namespace security
233} // namespace ndn
234
235#endif // NDN_SECURITY_TPM_TPM_HPP