blob: b6ea71e76900edcd2bedfddb4771c524b6afbd84 [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/**
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07003 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
5 *
6 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
8 *
9 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
11 *
12 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
Jeff Thompson7b79eb62013-09-12 18:48:29 -070013 */
14
Yingdi Yufc40d872014-02-18 12:56:04 -080015#ifndef NDN_SECURITY_SEC_TPM_HPP
16#define NDN_SECURITY_SEC_TPM_HPP
Jeff Thompson7b79eb62013-09-12 18:48:29 -070017
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080018#include "../common.hpp"
Yingdi Yu4f324632014-01-15 18:10:03 -080019#include "security-common.hpp"
20#include "../name.hpp"
21#include "../data.hpp"
22#include "public-key.hpp"
Jeff Thompson7b79eb62013-09-12 18:48:29 -070023
24namespace ndn {
25
Yingdi Yufc40d872014-02-18 12:56:04 -080026/**
27 * @brief SecTpm is the base class of the TPM classes.
28 *
29 * It specifies the interfaces of private/secret key related operations.
30 */
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070031class SecTpm
32{
Jeff Thompsona50703f2013-09-17 14:24:15 -070033public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070034 class Error : public std::runtime_error
35 {
36 public:
37 explicit
38 Error(const std::string& what)
39 : std::runtime_error(what)
40 {
41 }
42 };
Alexander Afanasyeve64788e2014-01-05 22:38:21 -080043
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070044 virtual
Yingdi Yu31b4af22014-01-14 14:13:00 -080045 ~SecTpm() {}
Jeff Thompson7b79eb62013-09-12 18:48:29 -070046
Jeff Thompson7b79eb62013-09-12 18:48:29 -070047 /**
Yingdi Yube4150e2014-02-18 13:02:46 -080048 * @brief set password of TPM
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070049 *
Yingdi Yube4150e2014-02-18 13:02:46 -080050 * Password is used to unlock TPM when it is locked.
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070051 * You should be cautious when using this method, because remembering password is kind of
52 * dangerous.
Yingdi Yube4150e2014-02-18 13:02:46 -080053 *
54 * @param password The password.
55 * @param passwordLength The length of password.
56 */
57 virtual void
58 setTpmPassword(const uint8_t* password, size_t passwordLength) = 0;
59
60 /**
61 * @brief reset password of TPM
62 */
63 virtual void
64 resetTpmPassword() = 0;
65
66 /**
67 * @brief set inTerminal flag
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070068 *
Yingdi Yube4150e2014-02-18 13:02:46 -080069 * If the inTerminal flag is set, and password is not set, TPM may ask for password via terminal.
70 * inTerminal flag is set by default.
71 *
72 * @param inTerminal.
73 */
74 virtual void
75 setInTerminal(bool inTerminal) = 0;
76
77 /**
78 * @brief get inTerminal flag
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070079 *
Yingdi Yube4150e2014-02-18 13:02:46 -080080 * @return inTerminal flag.
81 */
82 virtual bool
83 getInTerminal() = 0;
84
85 /**
86 * @brief check if TPM is locked.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070087 *
Yingdi Yube4150e2014-02-18 13:02:46 -080088 * @return true if locked, false otherwise
89 */
90 virtual bool
91 locked() = 0;
92
93 /**
94 * @brief Unlock the TPM.
95 *
96 * @param password The password.
97 * @param passwordLength The password size. 0 indicates no password.
98 * @param usePassword True if we want to use the supplied password to unlock the TPM.
Yingdi Yu2e57a582014-02-20 23:34:43 -080099 * @return true if TPM is unlocked, otherwise false.
Yingdi Yube4150e2014-02-18 13:02:46 -0800100 */
Yingdi Yu2e57a582014-02-20 23:34:43 -0800101 virtual bool
Yingdi Yube4150e2014-02-18 13:02:46 -0800102 unlockTpm(const char* password, size_t passwordLength, bool usePassword) = 0;
103
104 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800105 * @brief Generate a pair of asymmetric keys.
106 *
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700107 * @param keyName The name of the key pair.
108 * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
109 * @param keySize The size of the key pair.
Yingdi Yufc40d872014-02-18 12:56:04 -0800110 * @throws SecTpm::Error if fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700111 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700112 virtual void
Yingdi Yu31b4af22014-01-14 14:13:00 -0800113 generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700114
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800115 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800116 * @brief Delete a key pair of asymmetric keys.
117 *
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800118 * @param keyName The name of the key pair.
119 */
120 virtual void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700121 deleteKeyPairInTpm(const Name& keyName) = 0;
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700122
123 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800124 * @brief Get a public key.
125 *
126 * @param keyName The public key name.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800127 * @return The public key.
128 * @throws SecTpm::Error if public key does not exist in TPM.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700129 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700130 virtual shared_ptr<PublicKey>
Yingdi Yu31b4af22014-01-14 14:13:00 -0800131 getPublicKeyFromTpm(const Name& keyName) = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700132
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700133 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800134 * @brief Sign data.
135 *
136 * @param data Pointer to the byte array to be signed.
Jeff Thompson4c11b9f2013-09-13 11:05:28 -0700137 * @param dataLength The length of data.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700138 * @param keyName The name of the signing key.
139 * @param digestAlgorithm the digest algorithm.
Yingdi Yu3c5887c2014-01-21 18:19:49 -0800140 * @return The signature block.
Yingdi Yufc40d872014-02-18 12:56:04 -0800141 * @throws SecTpm::Error if signing fails.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700142 */
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800143 virtual Block
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700144 signInTpm(const uint8_t* data, size_t dataLength,
145 const Name& keyName,
146 DigestAlgorithm digestAlgorithm) = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700147
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700148 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800149 * @brief Decrypt data.
150 *
151 * @param data Pointer to the byte arry to be decrypted.
152 * @param dataLength The length of data.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700153 * @param keyName The name of the decrypting key.
Yingdi Yufc40d872014-02-18 12:56:04 -0800154 * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric encryption.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700155 * @return The decrypted data.
Yingdi Yufc40d872014-02-18 12:56:04 -0800156 * @throws SecTpm::Error if decryption fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700157 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700158 virtual ConstBufferPtr
Yingdi Yufc40d872014-02-18 12:56:04 -0800159 decryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric) = 0;
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700160
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700161 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800162 * @brief Encrypt data.
163 *
164 * @param data Pointer to the byte arry to be decrypted.
165 * @param dataLength The length of data.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700166 * @param keyName The name of the encrypting key.
Yingdi Yufc40d872014-02-18 12:56:04 -0800167 * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric encryption.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700168 * @return The encrypted data.
Yingdi Yufc40d872014-02-18 12:56:04 -0800169 * @throws SecTpm::Error if encryption fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700170 */
Alexander Afanasyev64a3d812014-01-05 23:35:05 -0800171 virtual ConstBufferPtr
Yingdi Yufc40d872014-02-18 12:56:04 -0800172 encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric) = 0;
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700173
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700174 /**
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700175 * @brief Generate a symmetric key.
Yingdi Yufc40d872014-02-18 12:56:04 -0800176 *
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700177 * @param keyName The name of the key.
178 * @param keyType The type of the key, e.g. KEY_TYPE_AES.
179 * @param keySize The size of the key.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800180 * @throws SecTpm::Error if key generating fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700181 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700182 virtual void
Yingdi Yub4bb85a2014-01-16 10:11:04 -0800183 generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700184
185 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800186 * @brief Check if a particular key exists.
187 *
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700188 * @param keyName The name of the key.
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700189 * @param keyClass The class of the key, e.g. KEY_CLASS_PUBLIC, KEY_CLASS_PRIVATE.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700190 * @return True if the key exists, otherwise false.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700191 */
192 virtual bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700193 doesKeyExistInTpm(const Name& keyName, KeyClass keyClass) = 0;
Yingdi Yu4b752752014-02-18 12:24:03 -0800194
195 /**
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800196 * @brief Generate a random block.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700197 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800198 * @param res The pointer to the generated block.
199 * @param size The random block size.
Yingdi Yu4b752752014-02-18 12:24:03 -0800200 * @return true for success, otherwise false.
201 */
202 virtual bool
203 generateRandomBlock(uint8_t* res, size_t size) = 0;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800204
205 /**
Yingdi Yu2e57a582014-02-20 23:34:43 -0800206 * @brief Add the application into the ACL of a particular key.
207 *
208 * @param keyName the name of key
209 * @param keyClass the class of key, e.g. Private Key
210 * @param appPath the absolute path to the application
211 * @param acl the new acl of the key
212 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700213 virtual void
Yingdi Yu2e57a582014-02-20 23:34:43 -0800214 addAppToACL(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl) = 0;
215
216 /**
Yingdi Yu5e96e002014-04-23 18:32:15 -0700217 * @brief Export a private key in PKCS#5 format.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700218 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800219 * @param keyName The private key name.
220 * @param password The password to encrypt the private key.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800221 * @return The private key info (in PKCS8 format) if exist.
222 * @throws SecTpm::Error if private key cannot be exported.
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800223 */
224 ConstBufferPtr
Yingdi Yu5e96e002014-04-23 18:32:15 -0700225 exportPrivateKeyPkcs5FromTpm(const Name& keyName, const std::string& password);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800226
227 /**
Yingdi Yu5e96e002014-04-23 18:32:15 -0700228 * @brief Import a private key in PKCS#5 format.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700229 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800230 * Also recover the public key and installed it in TPM.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700231 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800232 * @param keyName The private key name.
233 * @param key The encoded private key info.
234 * @param password The password to encrypt the private key.
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800235 * @return False if import fails.
236 */
237 bool
Yingdi Yu5e96e002014-04-23 18:32:15 -0700238 importPrivateKeyPkcs5IntoTpm(const Name& keyName,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700239 const uint8_t* buf, size_t size,
240 const std::string& password);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800241
242protected:
243 /**
Yingdi Yu5e96e002014-04-23 18:32:15 -0700244 * @brief Export a private key in PKCS#8 format.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700245 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800246 * @param keyName The private key name.
Yingdi Yu5e96e002014-04-23 18:32:15 -0700247 * @return The private key info (in PKCS#8 format) if exist, otherwise a NULL pointer.
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800248 */
249 virtual ConstBufferPtr
Yingdi Yu5e96e002014-04-23 18:32:15 -0700250 exportPrivateKeyPkcs8FromTpm(const Name& keyName) = 0;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800251
252 /**
Yingdi Yu5e96e002014-04-23 18:32:15 -0700253 * @brief Import a private key in PKCS#8 format.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700254 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800255 * @param keyName The private key name.
256 * @param key The encoded private key info.
257 * @return False if import fails.
258 */
259 virtual bool
Yingdi Yu5e96e002014-04-23 18:32:15 -0700260 importPrivateKeyPkcs8IntoTpm(const Name& keyName, const uint8_t* buf, size_t size) = 0;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800261
262 /**
263 * @brief Import a public key in PKCS#1 format.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700264 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800265 * @param keyName The public key name.
266 * @param key The encoded public key info.
267 * @return False if import fails.
268 */
269 virtual bool
270 importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size) = 0;
271
272
273 /**
Yingdi Yube4150e2014-02-18 13:02:46 -0800274 * @brief Get import/export password.
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800275 *
276 * @param password On return, the password.
277 * @param prompt Prompt for password, i.e., "Password for key:"
278 * @return true if password has been obtained.
279 */
280 inline virtual bool
Yingdi Yube4150e2014-02-18 13:02:46 -0800281 getImpExpPassWord(std::string& password, const std::string& prompt);
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700282};
283
Yingdi Yuf8fc8de2014-02-25 15:45:39 -0800284inline bool
Yingdi Yube4150e2014-02-18 13:02:46 -0800285SecTpm::getImpExpPassWord(std::string& password, const std::string& prompt)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800286{
287 int result = false;
288
289 char* pw0 = NULL;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700290
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800291 pw0 = getpass(prompt.c_str());
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700292 if (!pw0)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800293 return false;
294 std::string password1 = pw0;
295 memset(pw0, 0, strlen(pw0));
296
297 pw0 = getpass("Confirm:");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700298 if (!pw0)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800299 {
300 char* pw1 = const_cast<char*>(password1.c_str());
301 memset(pw1, 0, password1.size());
302 return false;
303 }
304
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700305 if (!password1.compare(pw0))
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800306 {
307 result = true;
308 password.swap(password1);
309 }
310
311 char* pw1 = const_cast<char*>(password1.c_str());
312 memset(pw1, 0, password1.size());
Yingdi Yube4150e2014-02-18 13:02:46 -0800313 memset(pw0, 0, strlen(pw0));
314
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700315 if (password.empty())
Yingdi Yube4150e2014-02-18 13:02:46 -0800316 return false;
317
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800318 return result;
319}
320
Yingdi Yufc40d872014-02-18 12:56:04 -0800321} // namespace ndn
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700322
Yingdi Yufc40d872014-02-18 12:56:04 -0800323#endif //NDN_SECURITY_SEC_TPM_HPP