blob: 2ce3d6613303465065b68d631b6097bacf6a6284 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Yingdi Yu8dceb1d2014-02-18 12:45:10 -08002/**
Yingdi Yu99b2a002015-08-12 12:47:44 -07003 * Copyright (c) 2013-2016 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070020 *
21 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080022 */
23
24#include "sec-tpm.hpp"
25
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070026#include "../encoding/oid.hpp"
27#include "../encoding/buffer-stream.hpp"
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070028#include "v1/cryptopp.hpp"
Alexander Afanasyeva2ada222015-01-22 18:34:16 -080029#include <unistd.h>
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080030
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080031namespace ndn {
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070032namespace security {
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080033
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070034SecTpm::SecTpm(const std::string& location)
Yingdi Yu41546342014-11-30 23:37:53 -080035 : m_location(location)
36{
37}
38
39SecTpm::~SecTpm()
40{
41}
42
43std::string
44SecTpm::getTpmLocator()
45{
Alexander Afanasyev07113802015-01-15 19:14:36 -080046 return this->getScheme() + ":" + m_location;
Yingdi Yu41546342014-11-30 23:37:53 -080047}
48
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080049ConstBufferPtr
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070050SecTpm::exportPrivateKeyPkcs5FromTpm(const Name& keyName, const std::string& passwordStr)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080051{
Yingdi Yu2e57a582014-02-20 23:34:43 -080052 using namespace CryptoPP;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070053
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080054 uint8_t salt[8] = {0};
55 uint8_t iv[8] = {0};
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070056
Yingdi Yu2e57a582014-02-20 23:34:43 -080057 // derive key
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070058 if (!generateRandomBlock(salt, 8) || !generateRandomBlock(iv, 8))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -070059 BOOST_THROW_EXCEPTION(Error("Cannot generate salt or iv"));
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080060
Yingdi Yu2e57a582014-02-20 23:34:43 -080061 uint32_t iterationCount = 2048;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070062
Yingdi Yu2e57a582014-02-20 23:34:43 -080063 PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
Yingdi Yu99b2a002015-08-12 12:47:44 -070064 size_t derivedLen = 24; // For DES-EDE3-CBC-PAD
Yingdi Yu2e57a582014-02-20 23:34:43 -080065 byte derived[24] = {0};
66 byte purpose = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070067
Yingdi Yu99b2a002015-08-12 12:47:44 -070068 try {
69 keyGenerator.DeriveKey(derived, derivedLen, purpose,
70 reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(),
71 salt, 8, iterationCount);
72 }
73 catch (const CryptoPP::Exception& e) {
74 BOOST_THROW_EXCEPTION(Error("Cannot derived the encryption key"));
75 }
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080076
Yingdi Yu99b2a002015-08-12 12:47:44 -070077 // encrypt
Yingdi Yu2e57a582014-02-20 23:34:43 -080078 CBC_Mode< DES_EDE3 >::Encryption e;
79 e.SetKeyWithIV(derived, derivedLen, iv);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070080
Yingdi Yu5e96e002014-04-23 18:32:15 -070081 ConstBufferPtr pkcs8PrivateKey = exportPrivateKeyPkcs8FromTpm(keyName);
Yingdi Yu9d9d5992014-06-25 12:25:16 -070082
Yingdi Yu99b2a002015-08-12 12:47:44 -070083 if (pkcs8PrivateKey == nullptr)
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -070084 BOOST_THROW_EXCEPTION(Error("Cannot export the private key, #1"));
Yingdi Yu2e57a582014-02-20 23:34:43 -080085
86 OBufferStream encryptedOs;
Yingdi Yu99b2a002015-08-12 12:47:44 -070087 try {
88 StringSource stringSource(pkcs8PrivateKey->buf(), pkcs8PrivateKey->size(), true,
89 new StreamTransformationFilter(e, new FileSink(encryptedOs)));
90 }
91 catch (const CryptoPP::Exception& e) {
92 BOOST_THROW_EXCEPTION(Error("Cannot export the private key, #2"));
93 }
Yingdi Yu2e57a582014-02-20 23:34:43 -080094
Yingdi Yu99b2a002015-08-12 12:47:44 -070095 // encode
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070096 Oid pbes2Id("1.2.840.113549.1.5.13");
97 Oid pbkdf2Id("1.2.840.113549.1.5.12");
98 Oid pbes2encsId("1.2.840.113549.3.7");
Yingdi Yu2e57a582014-02-20 23:34:43 -080099
100 OBufferStream pkcs8Os;
Yingdi Yu99b2a002015-08-12 12:47:44 -0700101 try {
102 FileSink sink(pkcs8Os);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700103
Yingdi Yu99b2a002015-08-12 12:47:44 -0700104 // EncryptedPrivateKeyInfo ::= SEQUENCE {
105 // encryptionAlgorithm EncryptionAlgorithmIdentifier,
106 // encryptedData OCTET STRING }
107 DERSequenceEncoder encryptedPrivateKeyInfo(sink);
108 {
109 // EncryptionAlgorithmIdentifier ::= SEQUENCE {
110 // algorithm OBJECT IDENTIFIER {{PBES2-id}},
111 // parameters SEQUENCE {{PBES2-params}} }
112 DERSequenceEncoder encryptionAlgorithm(encryptedPrivateKeyInfo);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800113 {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700114 pbes2Id.encode(encryptionAlgorithm);
115 // PBES2-params ::= SEQUENCE {
116 // keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
117 // encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} }
118 DERSequenceEncoder pbes2Params(encryptionAlgorithm);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800119 {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700120 // AlgorithmIdentifier ::= SEQUENCE {
121 // algorithm OBJECT IDENTIFIER {{PBKDF2-id}},
122 // parameters SEQUENCE {{PBKDF2-params}} }
123 DERSequenceEncoder pbes2KDFs(pbes2Params);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800124 {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700125 pbkdf2Id.encode(pbes2KDFs);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800126 // AlgorithmIdentifier ::= SEQUENCE {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700127 // salt OCTET STRING,
128 // iterationCount INTEGER (1..MAX),
129 // keyLength INTEGER (1..MAX) OPTIONAL,
130 // prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 }
131 DERSequenceEncoder pbkdf2Params(pbes2KDFs);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800132 {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700133 DEREncodeOctetString(pbkdf2Params, salt, 8);
134 DEREncodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800135 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700136 pbkdf2Params.MessageEnd();
Yingdi Yu2e57a582014-02-20 23:34:43 -0800137 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700138 pbes2KDFs.MessageEnd();
139
140 // AlgorithmIdentifier ::= SEQUENCE {
141 // algorithm OBJECT IDENTIFIER {{DES-EDE3-CBC-PAD}},
142 // parameters OCTET STRING} {{iv}} }
143 DERSequenceEncoder pbes2Encs(pbes2Params);
144 {
145 pbes2encsId.encode(pbes2Encs);
146 DEREncodeOctetString(pbes2Encs, iv, 8);
147 }
148 pbes2Encs.MessageEnd();
Yingdi Yu2e57a582014-02-20 23:34:43 -0800149 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700150 pbes2Params.MessageEnd();
Yingdi Yu2e57a582014-02-20 23:34:43 -0800151 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700152 encryptionAlgorithm.MessageEnd();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700153
Yingdi Yu99b2a002015-08-12 12:47:44 -0700154 DEREncodeOctetString(encryptedPrivateKeyInfo,
155 encryptedOs.buf()->buf(), encryptedOs.buf()->size());
Yingdi Yu2e57a582014-02-20 23:34:43 -0800156 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700157 encryptedPrivateKeyInfo.MessageEnd();
158
159 return pkcs8Os.buf();
160 }
161 catch (const CryptoPP::Exception& e) {
162 BOOST_THROW_EXCEPTION(Error("Cannot export the private key, #3"));
163 }
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800164}
165
166bool
Yingdi Yu5e96e002014-04-23 18:32:15 -0700167SecTpm::importPrivateKeyPkcs5IntoTpm(const Name& keyName,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700168 const uint8_t* buf, size_t size,
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700169 const std::string& passwordStr)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800170{
Yingdi Yu2e57a582014-02-20 23:34:43 -0800171 using namespace CryptoPP;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700172
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700173 Oid pbes2Id;
174 Oid pbkdf2Id;
Yingdi Yu2e57a582014-02-20 23:34:43 -0800175 SecByteBlock saltBlock;
176 uint32_t iterationCount;
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700177 Oid pbes2encsId;
Yingdi Yu2e57a582014-02-20 23:34:43 -0800178 SecByteBlock ivBlock;
179 SecByteBlock encryptedDataBlock;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700180
Yingdi Yu99b2a002015-08-12 12:47:44 -0700181 try {
182 // decode some decoding processes are not necessary for now,
183 // because we assume only one encryption scheme.
184 StringSource source(buf, size, true);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700185
Yingdi Yu99b2a002015-08-12 12:47:44 -0700186 // EncryptedPrivateKeyInfo ::= SEQUENCE {
187 // encryptionAlgorithm EncryptionAlgorithmIdentifier,
188 // encryptedData OCTET STRING }
189 BERSequenceDecoder encryptedPrivateKeyInfo(source);
190 {
191 // EncryptionAlgorithmIdentifier ::= SEQUENCE {
192 // algorithm OBJECT IDENTIFIER {{PBES2-id}},
193 // parameters SEQUENCE {{PBES2-params}} }
194 BERSequenceDecoder encryptionAlgorithm(encryptedPrivateKeyInfo);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800195 {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700196 pbes2Id.decode(encryptionAlgorithm);
197 // PBES2-params ::= SEQUENCE {
198 // keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
199 // encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} }
200 BERSequenceDecoder pbes2Params(encryptionAlgorithm);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800201 {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700202 // AlgorithmIdentifier ::= SEQUENCE {
203 // algorithm OBJECT IDENTIFIER {{PBKDF2-id}},
204 // parameters SEQUENCE {{PBKDF2-params}} }
205 BERSequenceDecoder pbes2KDFs(pbes2Params);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800206 {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700207 pbkdf2Id.decode(pbes2KDFs);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800208 // AlgorithmIdentifier ::= SEQUENCE {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700209 // salt OCTET STRING,
210 // iterationCount INTEGER (1..MAX),
211 // keyLength INTEGER (1..MAX) OPTIONAL,
212 // prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 }
213 BERSequenceDecoder pbkdf2Params(pbes2KDFs);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800214 {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700215 BERDecodeOctetString(pbkdf2Params, saltBlock);
216 BERDecodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800217 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700218 pbkdf2Params.MessageEnd();
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800219 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700220 pbes2KDFs.MessageEnd();
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800221
Yingdi Yu99b2a002015-08-12 12:47:44 -0700222 // AlgorithmIdentifier ::= SEQUENCE {
223 // algorithm OBJECT IDENTIFIER {{DES-EDE3-CBC-PAD}},
224 // parameters OCTET STRING} {{iv}} }
225 BERSequenceDecoder pbes2Encs(pbes2Params);
226 {
227 pbes2encsId.decode(pbes2Encs);
228 BERDecodeOctetString(pbes2Encs, ivBlock);
229 }
230 pbes2Encs.MessageEnd();
231 }
232 pbes2Params.MessageEnd();
Yingdi Yu2e57a582014-02-20 23:34:43 -0800233 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700234 encryptionAlgorithm.MessageEnd();
235
236 BERDecodeOctetString(encryptedPrivateKeyInfo, encryptedDataBlock);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800237 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700238 encryptedPrivateKeyInfo.MessageEnd();
239 }
240 catch (const CryptoPP::Exception& e) {
241 return false;
242 }
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800243
Yingdi Yu2e57a582014-02-20 23:34:43 -0800244 PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
245 size_t derivedLen = 24; //For DES-EDE3-CBC-PAD
246 byte derived[24] = {0};
247 byte purpose = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700248
Yingdi Yu99b2a002015-08-12 12:47:44 -0700249 try {
250 keyGenerator.DeriveKey(derived, derivedLen,
251 purpose,
252 reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(),
253 saltBlock.BytePtr(), saltBlock.size(),
254 iterationCount);
255 }
256 catch (const CryptoPP::Exception& e) {
257 return false;
258 }
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800259
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700260 //decrypt
261 CBC_Mode< DES_EDE3 >::Decryption d;
262 d.SetKeyWithIV(derived, derivedLen, ivBlock.BytePtr());
263
264 OBufferStream privateKeyOs;
Yingdi Yu99b2a002015-08-12 12:47:44 -0700265 try {
266 StringSource encryptedSource(encryptedDataBlock.BytePtr(), encryptedDataBlock.size(), true,
267 new StreamTransformationFilter(d, new FileSink(privateKeyOs)));
268 }
269 catch (const CryptoPP::Exception& e) {
270 return false;
271 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700272
Yingdi Yu5e96e002014-04-23 18:32:15 -0700273 if (!importPrivateKeyPkcs8IntoTpm(keyName,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700274 privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()))
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800275 return false;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700276
Yingdi Yu99b2a002015-08-12 12:47:44 -0700277 // determine key type
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700278 StringSource privateKeySource(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size(), true);
279
Yingdi Yu99b2a002015-08-12 12:47:44 -0700280 KeyType publicKeyType = KeyType::NONE;
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700281 SecByteBlock rawKeyBits;
282 // PrivateKeyInfo ::= SEQUENCE {
283 // INTEGER,
284 // SEQUENCE,
285 // OCTECT STRING}
286 BERSequenceDecoder privateKeyInfo(privateKeySource);
287 {
288 uint32_t versionNum;
289 BERDecodeUnsigned<uint32_t>(privateKeyInfo, versionNum, INTEGER);
290 BERSequenceDecoder sequenceDecoder(privateKeyInfo);
291 {
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700292 Oid keyTypeOid;
293 keyTypeOid.decode(sequenceDecoder);
294 if (keyTypeOid == oid::RSA)
Yingdi Yu99b2a002015-08-12 12:47:44 -0700295 publicKeyType = KeyType::RSA;
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700296 else if (keyTypeOid == oid::ECDSA)
Yingdi Yu99b2a002015-08-12 12:47:44 -0700297 publicKeyType = KeyType::EC;
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700298 else
299 return false; // Unsupported key type;
300 }
301 }
302
303
Yingdi Yu99b2a002015-08-12 12:47:44 -0700304 // derive public key
Yingdi Yu2e57a582014-02-20 23:34:43 -0800305 OBufferStream publicKeyOs;
306
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700307 try {
308 switch (publicKeyType) {
Yingdi Yu99b2a002015-08-12 12:47:44 -0700309 case KeyType::RSA: {
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700310 RSA::PrivateKey privateKey;
311 privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref());
312 RSAFunction publicKey(privateKey);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700313
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700314 FileSink publicKeySink(publicKeyOs);
315 publicKey.DEREncode(publicKeySink);
316 publicKeySink.MessageEnd();
317 break;
318 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700319
320 case KeyType::EC: {
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700321 ECDSA<ECP, SHA256>::PrivateKey privateKey;
322 privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref());
323
324 ECDSA<ECP, SHA256>::PublicKey publicKey;
325 privateKey.MakePublicKey(publicKey);
326 publicKey.AccessGroupParameters().SetEncodeAsOID(true);
327
328 FileSink publicKeySink(publicKeyOs);
329 publicKey.DEREncode(publicKeySink);
330 publicKeySink.MessageEnd();
331 break;
332 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700333
334 default:
335 return false;
Yingdi Yu2e57a582014-02-20 23:34:43 -0800336 }
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700337 }
Yingdi Yu99b2a002015-08-12 12:47:44 -0700338 catch (const CryptoPP::Exception& e) {
339 return false;
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700340 }
Yingdi Yu2e57a582014-02-20 23:34:43 -0800341
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700342 if (!importPublicKeyPkcs1IntoTpm(keyName, publicKeyOs.buf()->buf(), publicKeyOs.buf()->size()))
Yingdi Yu2e57a582014-02-20 23:34:43 -0800343 return false;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700344
Yingdi Yu2e57a582014-02-20 23:34:43 -0800345 return true;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800346}
347
Yingdi Yu7036ce22014-06-19 18:53:37 -0700348bool
349SecTpm::getImpExpPassWord(std::string& password, const std::string& prompt)
350{
351 bool isInitialized = false;
352
Alexander Afanasyevcf3a6672015-02-01 20:33:22 -0800353#ifdef NDN_CXX_HAVE_GETPASS
Yingdi Yu99b2a002015-08-12 12:47:44 -0700354 char* pw0 = nullptr;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700355
356 pw0 = getpass(prompt.c_str());
Yingdi Yu99b2a002015-08-12 12:47:44 -0700357 if (pw0 == nullptr)
Yingdi Yu7036ce22014-06-19 18:53:37 -0700358 return false;
359 std::string password1 = pw0;
360 memset(pw0, 0, strlen(pw0));
361
362 pw0 = getpass("Confirm:");
Yingdi Yu99b2a002015-08-12 12:47:44 -0700363 if (pw0 == nullptr) {
364 std::fill(password1.begin(), password1.end(), 0);
365 return false;
366 }
Yingdi Yu7036ce22014-06-19 18:53:37 -0700367
Yingdi Yu99b2a002015-08-12 12:47:44 -0700368 if (password1.compare(pw0) == 0) {
369 isInitialized = true;
370 password.swap(password1);
371 }
Yingdi Yu7036ce22014-06-19 18:53:37 -0700372
373 std::fill(password1.begin(), password1.end(), 0);
374 memset(pw0, 0, strlen(pw0));
375
376 if (password.empty())
377 return false;
378
Alexander Afanasyeva2ada222015-01-22 18:34:16 -0800379#endif // NDN_CXX_HAVE_GETPASS
380
Yingdi Yu7036ce22014-06-19 18:53:37 -0700381 return isInitialized;
382}
383
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700384} // namespace security
Yingdi Yufc40d872014-02-18 12:56:04 -0800385} // namespace ndn