blob: 8acb1b59b925716fb67ccbb979db3232039ad2e6 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Jeff Thompson7b79eb62013-09-12 18:48:29 -07002/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * 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.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070020 *
21 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
Jeff Thompson7b79eb62013-09-12 18:48:29 -070022 */
23
Yingdi Yufc40d872014-02-18 12:56:04 -080024#ifndef NDN_SECURITY_SEC_TPM_HPP
25#define NDN_SECURITY_SEC_TPM_HPP
Jeff Thompson7b79eb62013-09-12 18:48:29 -070026
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080027#include "../common.hpp"
Yingdi Yu4f324632014-01-15 18:10:03 -080028#include "security-common.hpp"
29#include "../name.hpp"
30#include "../data.hpp"
31#include "public-key.hpp"
Jeff Thompson7b79eb62013-09-12 18:48:29 -070032
33namespace ndn {
34
Yingdi Yufc40d872014-02-18 12:56:04 -080035/**
36 * @brief SecTpm is the base class of the TPM classes.
37 *
38 * It specifies the interfaces of private/secret key related operations.
39 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -070040class SecTpm : noncopyable
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070041{
Jeff Thompsona50703f2013-09-17 14:24:15 -070042public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070043 class Error : public std::runtime_error
44 {
45 public:
46 explicit
47 Error(const std::string& what)
48 : std::runtime_error(what)
49 {
50 }
51 };
Alexander Afanasyeve64788e2014-01-05 22:38:21 -080052
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070053 virtual
Yingdi Yuf56c68f2014-04-24 21:50:13 -070054 ~SecTpm()
55 {
56 }
Jeff Thompson7b79eb62013-09-12 18:48:29 -070057
Jeff Thompson7b79eb62013-09-12 18:48:29 -070058 /**
Yingdi Yube4150e2014-02-18 13:02:46 -080059 * @brief set password of TPM
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070060 *
Yingdi Yube4150e2014-02-18 13:02:46 -080061 * Password is used to unlock TPM when it is locked.
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070062 * You should be cautious when using this method, because remembering password is kind of
63 * dangerous.
Yingdi Yube4150e2014-02-18 13:02:46 -080064 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -070065 * @param password The password
66 * @param passwordLength The length of password
Yingdi Yube4150e2014-02-18 13:02:46 -080067 */
68 virtual void
69 setTpmPassword(const uint8_t* password, size_t passwordLength) = 0;
70
71 /**
72 * @brief reset password of TPM
73 */
74 virtual void
75 resetTpmPassword() = 0;
76
77 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070078 * @brief Set inTerminal flag to @param inTerminal
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070079 *
Yingdi Yube4150e2014-02-18 13:02:46 -080080 * If the inTerminal flag is set, and password is not set, TPM may ask for password via terminal.
81 * inTerminal flag is set by default.
Yingdi Yube4150e2014-02-18 13:02:46 -080082 */
83 virtual void
84 setInTerminal(bool inTerminal) = 0;
85
86 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070087 * @brief Get value of inTerminal flag
Yingdi Yube4150e2014-02-18 13:02:46 -080088 */
89 virtual bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -070090 getInTerminal() const = 0;
Yingdi Yube4150e2014-02-18 13:02:46 -080091
92 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070093 * @brief Check if TPM is locked
Yingdi Yube4150e2014-02-18 13:02:46 -080094 */
95 virtual bool
Yingdi Yuf56c68f2014-04-24 21:50:13 -070096 isLocked() = 0;
Yingdi Yube4150e2014-02-18 13:02:46 -080097
98 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070099 * @brief Unlock the TPM
Yingdi Yube4150e2014-02-18 13:02:46 -0800100 *
101 * @param password The password.
102 * @param passwordLength The password size. 0 indicates no password.
103 * @param usePassword True if we want to use the supplied password to unlock the TPM.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800104 * @return true if TPM is unlocked, otherwise false.
Yingdi Yube4150e2014-02-18 13:02:46 -0800105 */
Yingdi Yu2e57a582014-02-20 23:34:43 -0800106 virtual bool
Yingdi Yube4150e2014-02-18 13:02:46 -0800107 unlockTpm(const char* password, size_t passwordLength, bool usePassword) = 0;
108
109 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800110 * @brief Generate a pair of asymmetric keys.
111 *
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700112 * @param keyName The name of the key pair.
113 * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
114 * @param keySize The size of the key pair.
Yingdi Yufc40d872014-02-18 12:56:04 -0800115 * @throws SecTpm::Error if fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700116 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700117 virtual void
Yingdi Yu31b4af22014-01-14 14:13:00 -0800118 generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700119
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800120 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800121 * @brief Delete a key pair of asymmetric keys.
122 *
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800123 * @param keyName The name of the key pair.
124 */
125 virtual void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700126 deleteKeyPairInTpm(const Name& keyName) = 0;
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700127
128 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800129 * @brief Get a public key.
130 *
131 * @param keyName The public key name.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800132 * @return The public key.
133 * @throws SecTpm::Error if public key does not exist in TPM.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700134 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700135 virtual shared_ptr<PublicKey>
Yingdi Yu31b4af22014-01-14 14:13:00 -0800136 getPublicKeyFromTpm(const Name& keyName) = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700137
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700138 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800139 * @brief Sign data.
140 *
141 * @param data Pointer to the byte array to be signed.
Jeff Thompson4c11b9f2013-09-13 11:05:28 -0700142 * @param dataLength The length of data.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700143 * @param keyName The name of the signing key.
144 * @param digestAlgorithm the digest algorithm.
Yingdi Yu3c5887c2014-01-21 18:19:49 -0800145 * @return The signature block.
Yingdi Yufc40d872014-02-18 12:56:04 -0800146 * @throws SecTpm::Error if signing fails.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700147 */
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800148 virtual Block
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700149 signInTpm(const uint8_t* data, size_t dataLength,
150 const Name& keyName,
151 DigestAlgorithm digestAlgorithm) = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700152
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700153 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800154 * @brief Decrypt data.
155 *
156 * @param data Pointer to the byte arry to be decrypted.
157 * @param dataLength The length of data.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700158 * @param keyName The name of the decrypting key.
Yingdi Yufc40d872014-02-18 12:56:04 -0800159 * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric encryption.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700160 * @return The decrypted data.
Yingdi Yufc40d872014-02-18 12:56:04 -0800161 * @throws SecTpm::Error if decryption fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700162 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700163 virtual ConstBufferPtr
Yingdi Yufc40d872014-02-18 12:56:04 -0800164 decryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric) = 0;
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700165
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700166 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800167 * @brief Encrypt data.
168 *
169 * @param data Pointer to the byte arry to be decrypted.
170 * @param dataLength The length of data.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700171 * @param keyName The name of the encrypting key.
Yingdi Yufc40d872014-02-18 12:56:04 -0800172 * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric encryption.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700173 * @return The encrypted data.
Yingdi Yufc40d872014-02-18 12:56:04 -0800174 * @throws SecTpm::Error if encryption fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700175 */
Alexander Afanasyev64a3d812014-01-05 23:35:05 -0800176 virtual ConstBufferPtr
Yingdi Yufc40d872014-02-18 12:56:04 -0800177 encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric) = 0;
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700178
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700179 /**
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700180 * @brief Generate a symmetric key.
Yingdi Yufc40d872014-02-18 12:56:04 -0800181 *
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700182 * @param keyName The name of the key.
183 * @param keyType The type of the key, e.g. KEY_TYPE_AES.
184 * @param keySize The size of the key.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800185 * @throws SecTpm::Error if key generating fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700186 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700187 virtual void
Yingdi Yub4bb85a2014-01-16 10:11:04 -0800188 generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700189
190 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800191 * @brief Check if a particular key exists.
192 *
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700193 * @param keyName The name of the key.
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700194 * @param keyClass The class of the key, e.g. KEY_CLASS_PUBLIC, KEY_CLASS_PRIVATE.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700195 * @return True if the key exists, otherwise false.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700196 */
197 virtual bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700198 doesKeyExistInTpm(const Name& keyName, KeyClass keyClass) = 0;
Yingdi Yu4b752752014-02-18 12:24:03 -0800199
200 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700201 * @brief Generate a random block
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700202 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700203 * @param res The pointer to the generated block
204 * @param size The random block size
205 * @return true for success, otherwise false
Yingdi Yu4b752752014-02-18 12:24:03 -0800206 */
207 virtual bool
208 generateRandomBlock(uint8_t* res, size_t size) = 0;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800209
210 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700211 * @brief Add the application into the ACL of a particular key
Yingdi Yu2e57a582014-02-20 23:34:43 -0800212 *
213 * @param keyName the name of key
214 * @param keyClass the class of key, e.g. Private Key
215 * @param appPath the absolute path to the application
216 * @param acl the new acl of the key
217 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700218 virtual void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700219 addAppToAcl(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl) = 0;
Yingdi Yu2e57a582014-02-20 23:34:43 -0800220
221 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700222 * @brief Export a private key in PKCS#5 format
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700223 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700224 * @param keyName The private key name
225 * @param password The password to encrypt the private key
226 * @return The private key info (in PKCS8 format) if exist
227 * @throws SecTpm::Error if private key cannot be exported
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800228 */
229 ConstBufferPtr
Yingdi Yu5e96e002014-04-23 18:32:15 -0700230 exportPrivateKeyPkcs5FromTpm(const Name& keyName, const std::string& password);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800231
232 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700233 * @brief Import a private key in PKCS#5 formatted @param buffer of size @param bufferSize
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700234 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800235 * Also recover the public key and installed it in TPM.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700236 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700237 * @param keyName The private key name
238 * @param buffer Pointer to the first byte of the buffer containing PKCS#5-encoded
239 * private key info
240 * @param bufferSize Size of the buffer
241 * @param password The password to encrypt the private key
242 * @return false if import fails
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800243 */
244 bool
Yingdi Yu5e96e002014-04-23 18:32:15 -0700245 importPrivateKeyPkcs5IntoTpm(const Name& keyName,
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700246 const uint8_t* buffer, size_t bufferSize,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700247 const std::string& password);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800248
249protected:
250 /**
Yingdi Yu5e96e002014-04-23 18:32:15 -0700251 * @brief Export a private key in PKCS#8 format.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700252 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800253 * @param keyName The private key name.
Yingdi Yu5e96e002014-04-23 18:32:15 -0700254 * @return The private key info (in PKCS#8 format) if exist, otherwise a NULL pointer.
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800255 */
256 virtual ConstBufferPtr
Yingdi Yu5e96e002014-04-23 18:32:15 -0700257 exportPrivateKeyPkcs8FromTpm(const Name& keyName) = 0;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800258
259 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700260 * @brief Import a private key from PKCS#8 formatted @param buffer of size @param bufferSize
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700261 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700262 * @param keyName The private key name.
263 * @param buffer Pointer to the first byte of the buffer containing PKCS#8-encoded
264 * private key info
265 * @param bufferSize Size of the buffer
266 * @return false if import fails
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800267 */
268 virtual bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700269 importPrivateKeyPkcs8IntoTpm(const Name& keyName, const uint8_t* buffer, size_t bufferSize) = 0;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800270
271 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700272 * @brief Import a public key in PKCS#1 formatted @param buffer of size @param bufferSize
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700273 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700274 * @param keyName The public key name
275 * @param buffer Pointer to the first byte of the buffer containing PKCS#1-encoded
276 * private key info
277 * @param bufferSize Size of the buffer
278 * @return false if import fails
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800279 */
280 virtual bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700281 importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buffer, size_t bufferSize) = 0;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800282
283 /**
Yingdi Yube4150e2014-02-18 13:02:46 -0800284 * @brief Get import/export password.
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800285 *
286 * @param password On return, the password.
287 * @param prompt Prompt for password, i.e., "Password for key:"
288 * @return true if password has been obtained.
289 */
290 inline virtual bool
Yingdi Yube4150e2014-02-18 13:02:46 -0800291 getImpExpPassWord(std::string& password, const std::string& prompt);
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700292};
293
Yingdi Yuf8fc8de2014-02-25 15:45:39 -0800294inline bool
Yingdi Yube4150e2014-02-18 13:02:46 -0800295SecTpm::getImpExpPassWord(std::string& password, const std::string& prompt)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800296{
297 int result = false;
298
299 char* pw0 = NULL;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700300
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800301 pw0 = getpass(prompt.c_str());
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700302 if (!pw0)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800303 return false;
304 std::string password1 = pw0;
305 memset(pw0, 0, strlen(pw0));
306
307 pw0 = getpass("Confirm:");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700308 if (!pw0)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800309 {
310 char* pw1 = const_cast<char*>(password1.c_str());
311 memset(pw1, 0, password1.size());
312 return false;
313 }
314
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700315 if (!password1.compare(pw0))
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800316 {
317 result = true;
318 password.swap(password1);
319 }
320
321 char* pw1 = const_cast<char*>(password1.c_str());
322 memset(pw1, 0, password1.size());
Yingdi Yube4150e2014-02-18 13:02:46 -0800323 memset(pw0, 0, strlen(pw0));
324
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700325 if (password.empty())
Yingdi Yube4150e2014-02-18 13:02:46 -0800326 return false;
327
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800328 return result;
329}
330
Yingdi Yufc40d872014-02-18 12:56:04 -0800331} // namespace ndn
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700332
Yingdi Yufc40d872014-02-18 12:56:04 -0800333#endif //NDN_SECURITY_SEC_TPM_HPP