blob: 69b5f22a8c0f69b76d4477ea900d2afb771087d0 [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 */
Yingdi Yuf56c68f2014-04-24 21:50:13 -070031class SecTpm : noncopyable
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070032{
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 Yuf56c68f2014-04-24 21:50:13 -070045 ~SecTpm()
46 {
47 }
Jeff Thompson7b79eb62013-09-12 18:48:29 -070048
Jeff Thompson7b79eb62013-09-12 18:48:29 -070049 /**
Yingdi Yube4150e2014-02-18 13:02:46 -080050 * @brief set password of TPM
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070051 *
Yingdi Yube4150e2014-02-18 13:02:46 -080052 * Password is used to unlock TPM when it is locked.
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070053 * You should be cautious when using this method, because remembering password is kind of
54 * dangerous.
Yingdi Yube4150e2014-02-18 13:02:46 -080055 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -070056 * @param password The password
57 * @param passwordLength The length of password
Yingdi Yube4150e2014-02-18 13:02:46 -080058 */
59 virtual void
60 setTpmPassword(const uint8_t* password, size_t passwordLength) = 0;
61
62 /**
63 * @brief reset password of TPM
64 */
65 virtual void
66 resetTpmPassword() = 0;
67
68 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070069 * @brief Set inTerminal flag to @param inTerminal
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070070 *
Yingdi Yube4150e2014-02-18 13:02:46 -080071 * If the inTerminal flag is set, and password is not set, TPM may ask for password via terminal.
72 * inTerminal flag is set by default.
Yingdi Yube4150e2014-02-18 13:02:46 -080073 */
74 virtual void
75 setInTerminal(bool inTerminal) = 0;
76
77 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070078 * @brief Get value of inTerminal flag
Yingdi Yube4150e2014-02-18 13:02:46 -080079 */
80 virtual bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -070081 getInTerminal() const = 0;
Yingdi Yube4150e2014-02-18 13:02:46 -080082
83 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070084 * @brief Check if TPM is locked
Yingdi Yube4150e2014-02-18 13:02:46 -080085 */
86 virtual bool
Yingdi Yuf56c68f2014-04-24 21:50:13 -070087 isLocked() = 0;
Yingdi Yube4150e2014-02-18 13:02:46 -080088
89 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070090 * @brief Unlock the TPM
Yingdi Yube4150e2014-02-18 13:02:46 -080091 *
92 * @param password The password.
93 * @param passwordLength The password size. 0 indicates no password.
94 * @param usePassword True if we want to use the supplied password to unlock the TPM.
Yingdi Yu2e57a582014-02-20 23:34:43 -080095 * @return true if TPM is unlocked, otherwise false.
Yingdi Yube4150e2014-02-18 13:02:46 -080096 */
Yingdi Yu2e57a582014-02-20 23:34:43 -080097 virtual bool
Yingdi Yube4150e2014-02-18 13:02:46 -080098 unlockTpm(const char* password, size_t passwordLength, bool usePassword) = 0;
99
100 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800101 * @brief Generate a pair of asymmetric keys.
102 *
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700103 * @param keyName The name of the key pair.
104 * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
105 * @param keySize The size of the key pair.
Yingdi Yufc40d872014-02-18 12:56:04 -0800106 * @throws SecTpm::Error if fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700107 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700108 virtual void
Yingdi Yu31b4af22014-01-14 14:13:00 -0800109 generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700110
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800111 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800112 * @brief Delete a key pair of asymmetric keys.
113 *
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800114 * @param keyName The name of the key pair.
115 */
116 virtual void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700117 deleteKeyPairInTpm(const Name& keyName) = 0;
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700118
119 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800120 * @brief Get a public key.
121 *
122 * @param keyName The public key name.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800123 * @return The public key.
124 * @throws SecTpm::Error if public key does not exist in TPM.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700125 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700126 virtual shared_ptr<PublicKey>
Yingdi Yu31b4af22014-01-14 14:13:00 -0800127 getPublicKeyFromTpm(const Name& keyName) = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700128
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700129 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800130 * @brief Sign data.
131 *
132 * @param data Pointer to the byte array to be signed.
Jeff Thompson4c11b9f2013-09-13 11:05:28 -0700133 * @param dataLength The length of data.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700134 * @param keyName The name of the signing key.
135 * @param digestAlgorithm the digest algorithm.
Yingdi Yu3c5887c2014-01-21 18:19:49 -0800136 * @return The signature block.
Yingdi Yufc40d872014-02-18 12:56:04 -0800137 * @throws SecTpm::Error if signing fails.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700138 */
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800139 virtual Block
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700140 signInTpm(const uint8_t* data, size_t dataLength,
141 const Name& keyName,
142 DigestAlgorithm digestAlgorithm) = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700143
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700144 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800145 * @brief Decrypt data.
146 *
147 * @param data Pointer to the byte arry to be decrypted.
148 * @param dataLength The length of data.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700149 * @param keyName The name of the decrypting key.
Yingdi Yufc40d872014-02-18 12:56:04 -0800150 * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric encryption.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700151 * @return The decrypted data.
Yingdi Yufc40d872014-02-18 12:56:04 -0800152 * @throws SecTpm::Error if decryption fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700153 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700154 virtual ConstBufferPtr
Yingdi Yufc40d872014-02-18 12:56:04 -0800155 decryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric) = 0;
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700156
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700157 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800158 * @brief Encrypt data.
159 *
160 * @param data Pointer to the byte arry to be decrypted.
161 * @param dataLength The length of data.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700162 * @param keyName The name of the encrypting key.
Yingdi Yufc40d872014-02-18 12:56:04 -0800163 * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric encryption.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700164 * @return The encrypted data.
Yingdi Yufc40d872014-02-18 12:56:04 -0800165 * @throws SecTpm::Error if encryption fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700166 */
Alexander Afanasyev64a3d812014-01-05 23:35:05 -0800167 virtual ConstBufferPtr
Yingdi Yufc40d872014-02-18 12:56:04 -0800168 encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric) = 0;
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700169
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700170 /**
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700171 * @brief Generate a symmetric key.
Yingdi Yufc40d872014-02-18 12:56:04 -0800172 *
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700173 * @param keyName The name of the key.
174 * @param keyType The type of the key, e.g. KEY_TYPE_AES.
175 * @param keySize The size of the key.
Yingdi Yu2e57a582014-02-20 23:34:43 -0800176 * @throws SecTpm::Error if key generating fails.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700177 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700178 virtual void
Yingdi Yub4bb85a2014-01-16 10:11:04 -0800179 generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700180
181 /**
Yingdi Yufc40d872014-02-18 12:56:04 -0800182 * @brief Check if a particular key exists.
183 *
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700184 * @param keyName The name of the key.
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700185 * @param keyClass The class of the key, e.g. KEY_CLASS_PUBLIC, KEY_CLASS_PRIVATE.
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700186 * @return True if the key exists, otherwise false.
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700187 */
188 virtual bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700189 doesKeyExistInTpm(const Name& keyName, KeyClass keyClass) = 0;
Yingdi Yu4b752752014-02-18 12:24:03 -0800190
191 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700192 * @brief Generate a random block
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700193 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700194 * @param res The pointer to the generated block
195 * @param size The random block size
196 * @return true for success, otherwise false
Yingdi Yu4b752752014-02-18 12:24:03 -0800197 */
198 virtual bool
199 generateRandomBlock(uint8_t* res, size_t size) = 0;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800200
201 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700202 * @brief Add the application into the ACL of a particular key
Yingdi Yu2e57a582014-02-20 23:34:43 -0800203 *
204 * @param keyName the name of key
205 * @param keyClass the class of key, e.g. Private Key
206 * @param appPath the absolute path to the application
207 * @param acl the new acl of the key
208 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700209 virtual void
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700210 addAppToAcl(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl) = 0;
Yingdi Yu2e57a582014-02-20 23:34:43 -0800211
212 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700213 * @brief Export a private key in PKCS#5 format
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700214 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700215 * @param keyName The private key name
216 * @param password The password to encrypt the private key
217 * @return The private key info (in PKCS8 format) if exist
218 * @throws SecTpm::Error if private key cannot be exported
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800219 */
220 ConstBufferPtr
Yingdi Yu5e96e002014-04-23 18:32:15 -0700221 exportPrivateKeyPkcs5FromTpm(const Name& keyName, const std::string& password);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800222
223 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700224 * @brief Import a private key in PKCS#5 formatted @param buffer of size @param bufferSize
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700225 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800226 * Also recover the public key and installed it in TPM.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700227 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700228 * @param keyName The private key name
229 * @param buffer Pointer to the first byte of the buffer containing PKCS#5-encoded
230 * private key info
231 * @param bufferSize Size of the buffer
232 * @param password The password to encrypt the private key
233 * @return false if import fails
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800234 */
235 bool
Yingdi Yu5e96e002014-04-23 18:32:15 -0700236 importPrivateKeyPkcs5IntoTpm(const Name& keyName,
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700237 const uint8_t* buffer, size_t bufferSize,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700238 const std::string& password);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800239
240protected:
241 /**
Yingdi Yu5e96e002014-04-23 18:32:15 -0700242 * @brief Export a private key in PKCS#8 format.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700243 *
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800244 * @param keyName The private key name.
Yingdi Yu5e96e002014-04-23 18:32:15 -0700245 * @return The private key info (in PKCS#8 format) if exist, otherwise a NULL pointer.
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800246 */
247 virtual ConstBufferPtr
Yingdi Yu5e96e002014-04-23 18:32:15 -0700248 exportPrivateKeyPkcs8FromTpm(const Name& keyName) = 0;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800249
250 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700251 * @brief Import a private key from PKCS#8 formatted @param buffer of size @param bufferSize
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700252 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700253 * @param keyName The private key name.
254 * @param buffer Pointer to the first byte of the buffer containing PKCS#8-encoded
255 * private key info
256 * @param bufferSize Size of the buffer
257 * @return false if import fails
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800258 */
259 virtual bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700260 importPrivateKeyPkcs8IntoTpm(const Name& keyName, const uint8_t* buffer, size_t bufferSize) = 0;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800261
262 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700263 * @brief Import a public key in PKCS#1 formatted @param buffer of size @param bufferSize
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700264 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700265 * @param keyName The public key name
266 * @param buffer Pointer to the first byte of the buffer containing PKCS#1-encoded
267 * private key info
268 * @param bufferSize Size of the buffer
269 * @return false if import fails
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800270 */
271 virtual bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700272 importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buffer, size_t bufferSize) = 0;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800273
274 /**
Yingdi Yube4150e2014-02-18 13:02:46 -0800275 * @brief Get import/export password.
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800276 *
277 * @param password On return, the password.
278 * @param prompt Prompt for password, i.e., "Password for key:"
279 * @return true if password has been obtained.
280 */
281 inline virtual bool
Yingdi Yube4150e2014-02-18 13:02:46 -0800282 getImpExpPassWord(std::string& password, const std::string& prompt);
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700283};
284
Yingdi Yuf8fc8de2014-02-25 15:45:39 -0800285inline bool
Yingdi Yube4150e2014-02-18 13:02:46 -0800286SecTpm::getImpExpPassWord(std::string& password, const std::string& prompt)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800287{
288 int result = false;
289
290 char* pw0 = NULL;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700291
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800292 pw0 = getpass(prompt.c_str());
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700293 if (!pw0)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800294 return false;
295 std::string password1 = pw0;
296 memset(pw0, 0, strlen(pw0));
297
298 pw0 = getpass("Confirm:");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700299 if (!pw0)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800300 {
301 char* pw1 = const_cast<char*>(password1.c_str());
302 memset(pw1, 0, password1.size());
303 return false;
304 }
305
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700306 if (!password1.compare(pw0))
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800307 {
308 result = true;
309 password.swap(password1);
310 }
311
312 char* pw1 = const_cast<char*>(password1.c_str());
313 memset(pw1, 0, password1.size());
Yingdi Yube4150e2014-02-18 13:02:46 -0800314 memset(pw0, 0, strlen(pw0));
315
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700316 if (password.empty())
Yingdi Yube4150e2014-02-18 13:02:46 -0800317 return false;
318
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800319 return result;
320}
321
Yingdi Yufc40d872014-02-18 12:56:04 -0800322} // namespace ndn
Jeff Thompson7b79eb62013-09-12 18:48:29 -0700323
Yingdi Yufc40d872014-02-18 12:56:04 -0800324#endif //NDN_SECURITY_SEC_TPM_HPP