blob: bb7e44b727b01d592c03e981b81989c92d67bde0 [file] [log] [blame]
Jeff Thompson25b4e612013-10-10 16:03:24 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Jeff Thompson7b79eb62013-09-12 18:48:29 -07002/**
Jeff Thompson7687dc02013-09-13 11:54:07 -07003 * Copyright (C) 2013 Regents of the University of California.
Jeff Thompson7b79eb62013-09-12 18:48:29 -07004 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
Jeff Thompson7687dc02013-09-13 11:54:07 -07005 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompson7b79eb62013-09-12 18:48:29 -07006 * See COPYING for copyright and distribution information.
7 */
8
Yingdi Yufc40d872014-02-18 12:56:04 -08009#ifndef NDN_SECURITY_SEC_TPM_HPP
10#define NDN_SECURITY_SEC_TPM_HPP
Jeff Thompson7b79eb62013-09-12 18:48:29 -070011
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080012#include "../common.hpp"
Yingdi Yu4f324632014-01-15 18:10:03 -080013#include "security-common.hpp"
14#include "../name.hpp"
15#include "../data.hpp"
16#include "public-key.hpp"
Jeff Thompson7b79eb62013-09-12 18:48:29 -070017
18namespace ndn {
19
Yingdi Yufc40d872014-02-18 12:56:04 -080020/**
21 * @brief SecTpm is the base class of the TPM classes.
22 *
23 * It specifies the interfaces of private/secret key related operations.
24 */
Yingdi Yu31b4af22014-01-14 14:13:00 -080025class SecTpm {
Jeff Thompsona50703f2013-09-17 14:24:15 -070026public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070027 class Error : public std::runtime_error
28 {
29 public:
30 explicit
31 Error(const std::string& what)
32 : std::runtime_error(what)
33 {
34 }
35 };
Alexander Afanasyeve64788e2014-01-05 22:38:21 -080036
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070037 virtual
Yingdi Yu31b4af22014-01-14 14:13:00 -080038 ~SecTpm() {}
Jeff Thompson7b79eb62013-09-12 18:48:29 -070039
Jeff Thompson7b79eb62013-09-12 18:48:29 -070040 /**
Yingdi Yube4150e2014-02-18 13:02:46 -080041 * @brief set password of TPM
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070042 *
Yingdi Yube4150e2014-02-18 13:02:46 -080043 * Password is used to unlock TPM when it is locked.
44 * You should be cautious when using this method, because remembering password is kind of dangerous.
45 *
46 * @param password The password.
47 * @param passwordLength The length of password.
48 */
49 virtual void
50 setTpmPassword(const uint8_t* password, size_t passwordLength) = 0;
51
52 /**
53 * @brief reset password of TPM
54 */
55 virtual void
56 resetTpmPassword() = 0;
57
58 /**
59 * @brief set inTerminal flag
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070060 *
Yingdi Yube4150e2014-02-18 13:02:46 -080061 * If the inTerminal flag is set, and password is not set, TPM may ask for password via terminal.
62 * inTerminal flag is set by default.
63 *
64 * @param inTerminal.
65 */
66 virtual void
67 setInTerminal(bool inTerminal) = 0;
68
69 /**
70 * @brief get inTerminal flag
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070071 *
Yingdi Yube4150e2014-02-18 13:02:46 -080072 * @return inTerminal flag.
73 */
74 virtual bool
75 getInTerminal() = 0;
76
77 /**
78 * @brief check if TPM is locked.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070079 *
Yingdi Yube4150e2014-02-18 13:02:46 -080080 * @return true if locked, false otherwise
81 */
82 virtual bool
83 locked() = 0;
84
85 /**
86 * @brief Unlock the TPM.
87 *
88 * @param password The password.
89 * @param passwordLength The password size. 0 indicates no password.
90 * @param usePassword True if we want to use the supplied password to unlock the TPM.
Yingdi Yu2e57a582014-02-20 23:34:43 -080091 * @return true if TPM is unlocked, otherwise false.
Yingdi Yube4150e2014-02-18 13:02:46 -080092 */
Yingdi Yu2e57a582014-02-20 23:34:43 -080093 virtual bool
Yingdi Yube4150e2014-02-18 13:02:46 -080094 unlockTpm(const char* password, size_t passwordLength, bool usePassword) = 0;
95
96 /**
Yingdi Yufc40d872014-02-18 12:56:04 -080097 * @brief Generate a pair of asymmetric keys.
98 *
Jeff Thompson6c314bc2013-09-23 18:09:38 -070099 * @param keyName The name of the key pair.
100 * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
101 * @param keySize The size of the key pair.
Yingdi Yufc40d872014-02-18 12:56:04 -0800102 * @throws SecTpm::Error if fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700103 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700104 virtual void
Yingdi Yu31b4af22014-01-14 14:13:00 -0800105 generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700106
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800107 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800108 * @brief Delete a key pair of asymmetric keys.
109 *
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800110 * @param keyName The name of the key pair.
111 */
112 virtual void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700113 deleteKeyPairInTpm(const Name& keyName) = 0;
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700114
115 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800116 * @brief Get a public key.
117 *
118 * @param keyName The public key name.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800119 * @return The public key.
120 * @throws SecTpm::Error if public key does not exist in TPM.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700121 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700122 virtual shared_ptr<PublicKey>
Yingdi Yu31b4af22014-01-14 14:13:00 -0800123 getPublicKeyFromTpm(const Name& keyName) = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700124
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700125 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800126 * @brief Sign data.
127 *
128 * @param data Pointer to the byte array to be signed.
Jeff Thompson4c11b9f2013-09-13 11:05:28 -0700129 * @param dataLength The length of data.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700130 * @param keyName The name of the signing key.
131 * @param digestAlgorithm the digest algorithm.
Yingdi Yu3c5887c2014-01-21 18:19:49 -0800132 * @return The signature block.
Yingdi Yufc40d872014-02-18 12:56:04 -0800133 * @throws SecTpm::Error if signing fails.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700134 */
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800135 virtual Block
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700136 signInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, DigestAlgorithm digestAlgorithm) = 0;
137
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700138 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800139 * @brief Decrypt data.
140 *
141 * @param data Pointer to the byte arry to be decrypted.
142 * @param dataLength The length of data.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700143 * @param keyName The name of the decrypting key.
Yingdi Yufc40d872014-02-18 12:56:04 -0800144 * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric encryption.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700145 * @return The decrypted data.
Yingdi Yufc40d872014-02-18 12:56:04 -0800146 * @throws SecTpm::Error if decryption fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700147 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700148 virtual ConstBufferPtr
Yingdi Yufc40d872014-02-18 12:56:04 -0800149 decryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric) = 0;
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700150
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700151 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800152 * @brief Encrypt data.
153 *
154 * @param data Pointer to the byte arry to be decrypted.
155 * @param dataLength The length of data.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700156 * @param keyName The name of the encrypting key.
Yingdi Yufc40d872014-02-18 12:56:04 -0800157 * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric encryption.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700158 * @return The encrypted data.
Yingdi Yufc40d872014-02-18 12:56:04 -0800159 * @throws SecTpm::Error if encryption fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700160 */
Alexander Afanasyev64a3d812014-01-05 23:35:05 -0800161 virtual ConstBufferPtr
Yingdi Yufc40d872014-02-18 12:56:04 -0800162 encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric) = 0;
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700163
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700164 /**
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700165 * @brief Generate a symmetric key.
Yingdi Yufc40d872014-02-18 12:56:04 -0800166 *
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700167 * @param keyName The name of the key.
168 * @param keyType The type of the key, e.g. KEY_TYPE_AES.
169 * @param keySize The size of the key.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800170 * @throws SecTpm::Error if key generating fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700171 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700172 virtual void
Yingdi Yub4bb85a2014-01-16 10:11:04 -0800173 generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700174
175 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800176 * @brief Check if a particular key exists.
177 *
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700178 * @param keyName The name of the key.
179 * @param keyClass The class of the key, e.g. KEY_CLASS_PUBLIC, KEY_CLASS_PRIVATE, or KEY_CLASS_SYMMETRIC.
180 * @return True if the key exists, otherwise false.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700181 */
182 virtual bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700183 doesKeyExistInTpm(const Name& keyName, KeyClass keyClass) = 0;
Yingdi Yu4b752752014-02-18 12:24:03 -0800184
185 /**
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800186 * @brief Generate a random block.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700187 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800188 * @param res The pointer to the generated block.
189 * @param size The random block size.
Yingdi Yu4b752752014-02-18 12:24:03 -0800190 * @return true for success, otherwise false.
191 */
192 virtual bool
193 generateRandomBlock(uint8_t* res, size_t size) = 0;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800194
195 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800196 * @brief Add the application into the ACL of a particular key.
197 *
198 * @param keyName the name of key
199 * @param keyClass the class of key, e.g. Private Key
200 * @param appPath the absolute path to the application
201 * @param acl the new acl of the key
202 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700203 virtual void
Yingdi Yu2e57a582014-02-20 23:34:43 -0800204 addAppToACL(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl) = 0;
205
206 /**
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800207 * @brief Export a private key in PKCS#8 format.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700208 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800209 * @param keyName The private key name.
210 * @param password The password to encrypt the private key.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800211 * @return The private key info (in PKCS8 format) if exist.
212 * @throws SecTpm::Error if private key cannot be exported.
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800213 */
214 ConstBufferPtr
Yingdi Yube4150e2014-02-18 13:02:46 -0800215 exportPrivateKeyPkcs8FromTpm(const Name& keyName, const std::string& password);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800216
217 /**
218 * @brief Import a private key in PKCS#8 format.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700219 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800220 * Also recover the public key and installed it in TPM.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700221 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800222 * @param keyName The private key name.
223 * @param key The encoded private key info.
224 * @param password The password to encrypt the private key.
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800225 * @return False if import fails.
226 */
227 bool
Yingdi Yube4150e2014-02-18 13:02:46 -0800228 importPrivateKeyPkcs8IntoTpm(const Name& keyName, const uint8_t* buf, size_t size, const std::string& password);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800229
230protected:
231 /**
232 * @brief Export a private key in PKCS#1 format.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700233 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800234 * @param keyName The private key name.
235 * @return The private key info (in PKCS#1 format) if exist, otherwise a NULL pointer.
236 */
237 virtual ConstBufferPtr
238 exportPrivateKeyPkcs1FromTpm(const Name& keyName) = 0;
239
240 /**
241 * @brief Import a private key in PKCS#1 format.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700242 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800243 * @param keyName The private key name.
244 * @param key The encoded private key info.
245 * @return False if import fails.
246 */
247 virtual bool
248 importPrivateKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size) = 0;
249
250 /**
251 * @brief Import a public key in PKCS#1 format.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700252 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800253 * @param keyName The public key name.
254 * @param key The encoded public key info.
255 * @return False if import fails.
256 */
257 virtual bool
258 importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size) = 0;
259
260
261 /**
Yingdi Yube4150e2014-02-18 13:02:46 -0800262 * @brief Get import/export password.
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800263 *
264 * @param password On return, the password.
265 * @param prompt Prompt for password, i.e., "Password for key:"
266 * @return true if password has been obtained.
267 */
268 inline virtual bool
Yingdi Yube4150e2014-02-18 13:02:46 -0800269 getImpExpPassWord(std::string& password, const std::string& prompt);
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700270};
271
Yingdi Yuf8fc8de2014-02-25 15:45:39 -0800272inline bool
Yingdi Yube4150e2014-02-18 13:02:46 -0800273SecTpm::getImpExpPassWord(std::string& password, const std::string& prompt)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800274{
275 int result = false;
276
277 char* pw0 = NULL;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700278
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800279 pw0 = getpass(prompt.c_str());
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700280 if (!pw0)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800281 return false;
282 std::string password1 = pw0;
283 memset(pw0, 0, strlen(pw0));
284
285 pw0 = getpass("Confirm:");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700286 if (!pw0)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800287 {
288 char* pw1 = const_cast<char*>(password1.c_str());
289 memset(pw1, 0, password1.size());
290 return false;
291 }
292
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700293 if (!password1.compare(pw0))
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800294 {
295 result = true;
296 password.swap(password1);
297 }
298
299 char* pw1 = const_cast<char*>(password1.c_str());
300 memset(pw1, 0, password1.size());
Yingdi Yube4150e2014-02-18 13:02:46 -0800301 memset(pw0, 0, strlen(pw0));
302
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700303 if (password.empty())
Yingdi Yube4150e2014-02-18 13:02:46 -0800304 return false;
305
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800306 return result;
307}
308
Yingdi Yufc40d872014-02-18 12:56:04 -0800309} // namespace ndn
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700310
Yingdi Yufc40d872014-02-18 12:56:04 -0800311#endif //NDN_SECURITY_SEC_TPM_HPP