blob: 14b57566813b86ab3fd05675aed660d6594d9e04 [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 */
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070025class SecTpm
26{
Jeff Thompsona50703f2013-09-17 14:24:15 -070027public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070028 class Error : public std::runtime_error
29 {
30 public:
31 explicit
32 Error(const std::string& what)
33 : std::runtime_error(what)
34 {
35 }
36 };
Alexander Afanasyeve64788e2014-01-05 22:38:21 -080037
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070038 virtual
Yingdi Yu31b4af22014-01-14 14:13:00 -080039 ~SecTpm() {}
Jeff Thompson7b79eb62013-09-12 18:48:29 -070040
Jeff Thompson7b79eb62013-09-12 18:48:29 -070041 /**
Yingdi Yube4150e2014-02-18 13:02:46 -080042 * @brief set password of TPM
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070043 *
Yingdi Yube4150e2014-02-18 13:02:46 -080044 * Password is used to unlock TPM when it is locked.
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070045 * You should be cautious when using this method, because remembering password is kind of
46 * dangerous.
Yingdi Yube4150e2014-02-18 13:02:46 -080047 *
48 * @param password The password.
49 * @param passwordLength The length of password.
50 */
51 virtual void
52 setTpmPassword(const uint8_t* password, size_t passwordLength) = 0;
53
54 /**
55 * @brief reset password of TPM
56 */
57 virtual void
58 resetTpmPassword() = 0;
59
60 /**
61 * @brief set inTerminal flag
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070062 *
Yingdi Yube4150e2014-02-18 13:02:46 -080063 * If the inTerminal flag is set, and password is not set, TPM may ask for password via terminal.
64 * inTerminal flag is set by default.
65 *
66 * @param inTerminal.
67 */
68 virtual void
69 setInTerminal(bool inTerminal) = 0;
70
71 /**
72 * @brief get inTerminal flag
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070073 *
Yingdi Yube4150e2014-02-18 13:02:46 -080074 * @return inTerminal flag.
75 */
76 virtual bool
77 getInTerminal() = 0;
78
79 /**
80 * @brief check if TPM is locked.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070081 *
Yingdi Yube4150e2014-02-18 13:02:46 -080082 * @return true if locked, false otherwise
83 */
84 virtual bool
85 locked() = 0;
86
87 /**
88 * @brief Unlock the TPM.
89 *
90 * @param password The password.
91 * @param passwordLength The password size. 0 indicates no password.
92 * @param usePassword True if we want to use the supplied password to unlock the TPM.
Yingdi Yu2e57a582014-02-20 23:34:43 -080093 * @return true if TPM is unlocked, otherwise false.
Yingdi Yube4150e2014-02-18 13:02:46 -080094 */
Yingdi Yu2e57a582014-02-20 23:34:43 -080095 virtual bool
Yingdi Yube4150e2014-02-18 13:02:46 -080096 unlockTpm(const char* password, size_t passwordLength, bool usePassword) = 0;
97
98 /**
Yingdi Yufc40d872014-02-18 12:56:04 -080099 * @brief Generate a pair of asymmetric keys.
100 *
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700101 * @param keyName The name of the key pair.
102 * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
103 * @param keySize The size of the key pair.
Yingdi Yufc40d872014-02-18 12:56:04 -0800104 * @throws SecTpm::Error if fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700105 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700106 virtual void
Yingdi Yu31b4af22014-01-14 14:13:00 -0800107 generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700108
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800109 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800110 * @brief Delete a key pair of asymmetric keys.
111 *
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800112 * @param keyName The name of the key pair.
113 */
114 virtual void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700115 deleteKeyPairInTpm(const Name& keyName) = 0;
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700116
117 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800118 * @brief Get a public key.
119 *
120 * @param keyName The public key name.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800121 * @return The public key.
122 * @throws SecTpm::Error if public key does not exist in TPM.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700123 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700124 virtual shared_ptr<PublicKey>
Yingdi Yu31b4af22014-01-14 14:13:00 -0800125 getPublicKeyFromTpm(const Name& keyName) = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700126
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700127 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800128 * @brief Sign data.
129 *
130 * @param data Pointer to the byte array to be signed.
Jeff Thompson4c11b9f2013-09-13 11:05:28 -0700131 * @param dataLength The length of data.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700132 * @param keyName The name of the signing key.
133 * @param digestAlgorithm the digest algorithm.
Yingdi Yu3c5887c2014-01-21 18:19:49 -0800134 * @return The signature block.
Yingdi Yufc40d872014-02-18 12:56:04 -0800135 * @throws SecTpm::Error if signing fails.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700136 */
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800137 virtual Block
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700138 signInTpm(const uint8_t* data, size_t dataLength,
139 const Name& keyName,
140 DigestAlgorithm digestAlgorithm) = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700141
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700142 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800143 * @brief Decrypt data.
144 *
145 * @param data Pointer to the byte arry to be decrypted.
146 * @param dataLength The length of data.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700147 * @param keyName The name of the decrypting key.
Yingdi Yufc40d872014-02-18 12:56:04 -0800148 * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric encryption.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700149 * @return The decrypted data.
Yingdi Yufc40d872014-02-18 12:56:04 -0800150 * @throws SecTpm::Error if decryption fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700151 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700152 virtual ConstBufferPtr
Yingdi Yufc40d872014-02-18 12:56:04 -0800153 decryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric) = 0;
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700154
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700155 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800156 * @brief Encrypt data.
157 *
158 * @param data Pointer to the byte arry to be decrypted.
159 * @param dataLength The length of data.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700160 * @param keyName The name of the encrypting key.
Yingdi Yufc40d872014-02-18 12:56:04 -0800161 * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric encryption.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700162 * @return The encrypted data.
Yingdi Yufc40d872014-02-18 12:56:04 -0800163 * @throws SecTpm::Error if encryption fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700164 */
Alexander Afanasyev64a3d812014-01-05 23:35:05 -0800165 virtual ConstBufferPtr
Yingdi Yufc40d872014-02-18 12:56:04 -0800166 encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric) = 0;
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700167
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700168 /**
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700169 * @brief Generate a symmetric key.
Yingdi Yufc40d872014-02-18 12:56:04 -0800170 *
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700171 * @param keyName The name of the key.
172 * @param keyType The type of the key, e.g. KEY_TYPE_AES.
173 * @param keySize The size of the key.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800174 * @throws SecTpm::Error if key generating fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700175 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700176 virtual void
Yingdi Yub4bb85a2014-01-16 10:11:04 -0800177 generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700178
179 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800180 * @brief Check if a particular key exists.
181 *
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700182 * @param keyName The name of the key.
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700183 * @param keyClass The class of the key, e.g. KEY_CLASS_PUBLIC, KEY_CLASS_PRIVATE.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700184 * @return True if the key exists, otherwise false.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700185 */
186 virtual bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700187 doesKeyExistInTpm(const Name& keyName, KeyClass keyClass) = 0;
Yingdi Yu4b752752014-02-18 12:24:03 -0800188
189 /**
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800190 * @brief Generate a random block.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700191 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800192 * @param res The pointer to the generated block.
193 * @param size The random block size.
Yingdi Yu4b752752014-02-18 12:24:03 -0800194 * @return true for success, otherwise false.
195 */
196 virtual bool
197 generateRandomBlock(uint8_t* res, size_t size) = 0;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800198
199 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800200 * @brief Add the application into the ACL of a particular key.
201 *
202 * @param keyName the name of key
203 * @param keyClass the class of key, e.g. Private Key
204 * @param appPath the absolute path to the application
205 * @param acl the new acl of the key
206 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700207 virtual void
Yingdi Yu2e57a582014-02-20 23:34:43 -0800208 addAppToACL(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl) = 0;
209
210 /**
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800211 * @brief Export a private key in PKCS#8 format.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700212 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800213 * @param keyName The private key name.
214 * @param password The password to encrypt the private key.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800215 * @return The private key info (in PKCS8 format) if exist.
216 * @throws SecTpm::Error if private key cannot be exported.
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800217 */
218 ConstBufferPtr
Yingdi Yube4150e2014-02-18 13:02:46 -0800219 exportPrivateKeyPkcs8FromTpm(const Name& keyName, const std::string& password);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800220
221 /**
222 * @brief Import a private key in PKCS#8 format.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700223 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800224 * Also recover the public key and installed it in TPM.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700225 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800226 * @param keyName The private key name.
227 * @param key The encoded private key info.
228 * @param password The password to encrypt the private key.
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800229 * @return False if import fails.
230 */
231 bool
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700232 importPrivateKeyPkcs8IntoTpm(const Name& keyName,
233 const uint8_t* buf, size_t size,
234 const std::string& password);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800235
236protected:
237 /**
238 * @brief Export a private key in PKCS#1 format.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700239 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800240 * @param keyName The private key name.
241 * @return The private key info (in PKCS#1 format) if exist, otherwise a NULL pointer.
242 */
243 virtual ConstBufferPtr
244 exportPrivateKeyPkcs1FromTpm(const Name& keyName) = 0;
245
246 /**
247 * @brief Import a private key in PKCS#1 format.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700248 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800249 * @param keyName The private key name.
250 * @param key The encoded private key info.
251 * @return False if import fails.
252 */
253 virtual bool
254 importPrivateKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size) = 0;
255
256 /**
257 * @brief Import a public key in PKCS#1 format.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700258 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800259 * @param keyName The public key name.
260 * @param key The encoded public key info.
261 * @return False if import fails.
262 */
263 virtual bool
264 importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size) = 0;
265
266
267 /**
Yingdi Yube4150e2014-02-18 13:02:46 -0800268 * @brief Get import/export password.
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800269 *
270 * @param password On return, the password.
271 * @param prompt Prompt for password, i.e., "Password for key:"
272 * @return true if password has been obtained.
273 */
274 inline virtual bool
Yingdi Yube4150e2014-02-18 13:02:46 -0800275 getImpExpPassWord(std::string& password, const std::string& prompt);
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700276};
277
Yingdi Yuf8fc8de2014-02-25 15:45:39 -0800278inline bool
Yingdi Yube4150e2014-02-18 13:02:46 -0800279SecTpm::getImpExpPassWord(std::string& password, const std::string& prompt)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800280{
281 int result = false;
282
283 char* pw0 = NULL;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700284
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800285 pw0 = getpass(prompt.c_str());
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700286 if (!pw0)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800287 return false;
288 std::string password1 = pw0;
289 memset(pw0, 0, strlen(pw0));
290
291 pw0 = getpass("Confirm:");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700292 if (!pw0)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800293 {
294 char* pw1 = const_cast<char*>(password1.c_str());
295 memset(pw1, 0, password1.size());
296 return false;
297 }
298
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700299 if (!password1.compare(pw0))
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800300 {
301 result = true;
302 password.swap(password1);
303 }
304
305 char* pw1 = const_cast<char*>(password1.c_str());
306 memset(pw1, 0, password1.size());
Yingdi Yube4150e2014-02-18 13:02:46 -0800307 memset(pw0, 0, strlen(pw0));
308
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700309 if (password.empty())
Yingdi Yube4150e2014-02-18 13:02:46 -0800310 return false;
311
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800312 return result;
313}
314
Yingdi Yufc40d872014-02-18 12:56:04 -0800315} // namespace ndn
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700316
Yingdi Yufc40d872014-02-18 12:56:04 -0800317#endif //NDN_SECURITY_SEC_TPM_HPP