blob: 5d836eee1290dee4af3a77e5fc70baabec0e203c [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 Afanasyeve64788e2014-01-05 22:38:21 -080027 struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
28
Jeff Thompson7b79eb62013-09-12 18:48:29 -070029 virtual
Yingdi Yu31b4af22014-01-14 14:13:00 -080030 ~SecTpm() {}
Jeff Thompson7b79eb62013-09-12 18:48:29 -070031
Jeff Thompson7b79eb62013-09-12 18:48:29 -070032 /**
Yingdi Yube4150e2014-02-18 13:02:46 -080033 * @brief set password of TPM
34 *
35 * Password is used to unlock TPM when it is locked.
36 * You should be cautious when using this method, because remembering password is kind of dangerous.
37 *
38 * @param password The password.
39 * @param passwordLength The length of password.
40 */
41 virtual void
42 setTpmPassword(const uint8_t* password, size_t passwordLength) = 0;
43
44 /**
45 * @brief reset password of TPM
46 */
47 virtual void
48 resetTpmPassword() = 0;
49
50 /**
51 * @brief set inTerminal flag
52 *
53 * If the inTerminal flag is set, and password is not set, TPM may ask for password via terminal.
54 * inTerminal flag is set by default.
55 *
56 * @param inTerminal.
57 */
58 virtual void
59 setInTerminal(bool inTerminal) = 0;
60
61 /**
62 * @brief get inTerminal flag
63 *
64 * @return inTerminal flag.
65 */
66 virtual bool
67 getInTerminal() = 0;
68
69 /**
70 * @brief check if TPM is locked.
71 *
72 * @return true if locked, false otherwise
73 */
74 virtual bool
75 locked() = 0;
76
77 /**
78 * @brief Unlock the TPM.
79 *
80 * @param password The password.
81 * @param passwordLength The password size. 0 indicates no password.
82 * @param usePassword True if we want to use the supplied password to unlock the TPM.
83 */
84 virtual void
85 unlockTpm(const char* password, size_t passwordLength, bool usePassword) = 0;
86
87 /**
Yingdi Yufc40d872014-02-18 12:56:04 -080088 * @brief Generate a pair of asymmetric keys.
89 *
Jeff Thompson6c314bc2013-09-23 18:09:38 -070090 * @param keyName The name of the key pair.
91 * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
92 * @param keySize The size of the key pair.
Yingdi Yufc40d872014-02-18 12:56:04 -080093 * @throws SecTpm::Error if fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -070094 */
95 virtual void
Yingdi Yu31b4af22014-01-14 14:13:00 -080096 generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
Yingdi Yu28fd32f2014-01-28 19:03:03 -080097
98 /**
Yingdi Yufc40d872014-02-18 12:56:04 -080099 * @brief Delete a key pair of asymmetric keys.
100 *
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800101 * @param keyName The name of the key pair.
102 */
103 virtual void
104 deleteKeyPairInTpm(const Name &keyName) = 0;
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700105
106 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800107 * @brief Get a public key.
108 *
109 * @param keyName The public key name.
110 * @return The public key if exists, otherwise a NULL pointer.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700111 */
Yingdi Yufc40d872014-02-18 12:56:04 -0800112 virtual shared_ptr<PublicKey>
Yingdi Yu31b4af22014-01-14 14:13:00 -0800113 getPublicKeyFromTpm(const Name& keyName) = 0;
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700114
115 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800116 * @brief Sign data.
117 *
118 * @param data Pointer to the byte array to be signed.
Jeff Thompson4c11b9f2013-09-13 11:05:28 -0700119 * @param dataLength The length of data.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700120 * @param keyName The name of the signing key.
121 * @param digestAlgorithm the digest algorithm.
Yingdi Yu3c5887c2014-01-21 18:19:49 -0800122 * @return The signature block.
Yingdi Yufc40d872014-02-18 12:56:04 -0800123 * @throws SecTpm::Error if signing fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700124 */
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800125 virtual Block
Yingdi Yub4bb85a2014-01-16 10:11:04 -0800126 signInTpm(const uint8_t *data, size_t dataLength, const Name& keyName, DigestAlgorithm digestAlgorithm) = 0;
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800127
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700128 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800129 * @brief Decrypt data.
130 *
131 * @param data Pointer to the byte arry to be decrypted.
132 * @param dataLength The length of data.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700133 * @param keyName The name of the decrypting key.
Yingdi Yufc40d872014-02-18 12:56:04 -0800134 * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric encryption.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700135 * @return The decrypted data.
Yingdi Yufc40d872014-02-18 12:56:04 -0800136 * @throws SecTpm::Error if decryption fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700137 */
Alexander Afanasyev64a3d812014-01-05 23:35:05 -0800138 virtual ConstBufferPtr
Yingdi Yufc40d872014-02-18 12:56:04 -0800139 decryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric) = 0;
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700140
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700141 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800142 * @brief Encrypt data.
143 *
144 * @param data Pointer to the byte arry to be decrypted.
145 * @param dataLength The length of data.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700146 * @param keyName The name of the encrypting key.
Yingdi Yufc40d872014-02-18 12:56:04 -0800147 * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric encryption.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700148 * @return The encrypted data.
Yingdi Yufc40d872014-02-18 12:56:04 -0800149 * @throws SecTpm::Error if encryption fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700150 */
Alexander Afanasyev64a3d812014-01-05 23:35:05 -0800151 virtual ConstBufferPtr
Yingdi Yufc40d872014-02-18 12:56:04 -0800152 encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric) = 0;
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700153
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700154 /**
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700155 * @brief Generate a symmetric key.
Yingdi Yufc40d872014-02-18 12:56:04 -0800156 *
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700157 * @param keyName The name of the key.
158 * @param keyType The type of the key, e.g. KEY_TYPE_AES.
159 * @param keySize The size of the key.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700160 */
161 virtual void
Yingdi Yub4bb85a2014-01-16 10:11:04 -0800162 generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700163
164 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800165 * @brief Check if a particular key exists.
166 *
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700167 * @param keyName The name of the key.
168 * @param keyClass The class of the key, e.g. KEY_CLASS_PUBLIC, KEY_CLASS_PRIVATE, or KEY_CLASS_SYMMETRIC.
169 * @return True if the key exists, otherwise false.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700170 */
171 virtual bool
Yingdi Yub4bb85a2014-01-16 10:11:04 -0800172 doesKeyExistInTpm(const Name& keyName, KeyClass keyClass) = 0;
Yingdi Yu4b752752014-02-18 12:24:03 -0800173
174 /**
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800175 * @brief Generate a random block.
Yingdi Yu4b752752014-02-18 12:24:03 -0800176 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800177 * @param res The pointer to the generated block.
178 * @param size The random block size.
Yingdi Yu4b752752014-02-18 12:24:03 -0800179 * @return true for success, otherwise false.
180 */
181 virtual bool
182 generateRandomBlock(uint8_t* res, size_t size) = 0;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800183
184 /**
185 * @brief Export a private key in PKCS#8 format.
186 *
187 * @param keyName The private key name.
188 * @param password The password to encrypt the private key.
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800189 * @return The private key info (in PKCS8 format) if exist, otherwise a NULL pointer.
190 */
191 ConstBufferPtr
Yingdi Yube4150e2014-02-18 13:02:46 -0800192 exportPrivateKeyPkcs8FromTpm(const Name& keyName, const std::string& password);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800193
194 /**
195 * @brief Import a private key in PKCS#8 format.
196 *
197 * Also recover the public key and installed it in TPM.
198 *
199 * @param keyName The private key name.
200 * @param key The encoded private key info.
201 * @param password The password to encrypt the private key.
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800202 * @return False if import fails.
203 */
204 bool
Yingdi Yube4150e2014-02-18 13:02:46 -0800205 importPrivateKeyPkcs8IntoTpm(const Name& keyName, const uint8_t* buf, size_t size, const std::string& password);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800206
207protected:
208 /**
209 * @brief Export a private key in PKCS#1 format.
210 *
211 * @param keyName The private key name.
212 * @return The private key info (in PKCS#1 format) if exist, otherwise a NULL pointer.
213 */
214 virtual ConstBufferPtr
215 exportPrivateKeyPkcs1FromTpm(const Name& keyName) = 0;
216
217 /**
218 * @brief Import a private key in PKCS#1 format.
219 *
220 * @param keyName The private key name.
221 * @param key The encoded private key info.
222 * @return False if import fails.
223 */
224 virtual bool
225 importPrivateKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size) = 0;
226
227 /**
228 * @brief Import a public key in PKCS#1 format.
229 *
230 * @param keyName The public key name.
231 * @param key The encoded public key info.
232 * @return False if import fails.
233 */
234 virtual bool
235 importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size) = 0;
236
237
238 /**
Yingdi Yube4150e2014-02-18 13:02:46 -0800239 * @brief Get import/export password.
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800240 *
241 * @param password On return, the password.
242 * @param prompt Prompt for password, i.e., "Password for key:"
243 * @return true if password has been obtained.
244 */
245 inline virtual bool
Yingdi Yube4150e2014-02-18 13:02:46 -0800246 getImpExpPassWord(std::string& password, const std::string& prompt);
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700247};
248
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800249bool
Yingdi Yube4150e2014-02-18 13:02:46 -0800250SecTpm::getImpExpPassWord(std::string& password, const std::string& prompt)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800251{
252 int result = false;
253
254 char* pw0 = NULL;
255
256 pw0 = getpass(prompt.c_str());
257 if(!pw0)
258 return false;
259 std::string password1 = pw0;
260 memset(pw0, 0, strlen(pw0));
261
262 pw0 = getpass("Confirm:");
263 if(!pw0)
264 {
265 char* pw1 = const_cast<char*>(password1.c_str());
266 memset(pw1, 0, password1.size());
267 return false;
268 }
269
270 if(!password1.compare(pw0))
271 {
272 result = true;
273 password.swap(password1);
274 }
275
276 char* pw1 = const_cast<char*>(password1.c_str());
277 memset(pw1, 0, password1.size());
Yingdi Yube4150e2014-02-18 13:02:46 -0800278 memset(pw0, 0, strlen(pw0));
279
280 if(password.empty())
281 return false;
282
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800283 return result;
284}
285
Yingdi Yufc40d872014-02-18 12:56:04 -0800286} // namespace ndn
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700287
Yingdi Yufc40d872014-02-18 12:56:04 -0800288#endif //NDN_SECURITY_SEC_TPM_HPP