17 SecTpm::exportPrivateKeyPkcs5FromTpm(
const Name& keyName,
const string& passwordStr)
19 using namespace CryptoPP;
21 uint8_t salt[8] = {0};
25 if (!generateRandomBlock(salt, 8) || !generateRandomBlock(iv, 8))
26 throw Error(
"Cannot generate salt or iv");
28 uint32_t iterationCount = 2048;
30 PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
31 size_t derivedLen = 24;
32 byte derived[24] = {0};
37 keyGenerator.DeriveKey(derived, derivedLen, purpose,
38 reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(),
39 salt, 8, iterationCount);
41 catch (CryptoPP::Exception& e)
43 throw Error(
"Cannot derived the encryption key");
47 CBC_Mode< DES_EDE3 >::Encryption e;
48 e.SetKeyWithIV(derived, derivedLen, iv);
50 ConstBufferPtr pkcs8PrivateKey = exportPrivateKeyPkcs8FromTpm(keyName);
51 if (!static_cast<bool>(pkcs8PrivateKey))
52 throw Error(
"Cannot export the private key, #1");
57 StringSource stringSource(pkcs8PrivateKey->buf(), pkcs8PrivateKey->size(),
true,
58 new StreamTransformationFilter(e,
new FileSink(encryptedOs)));
60 catch (CryptoPP::Exception& e)
62 throw Error(
"Cannot export the private key, #2");
66 OID pbes2Id(
"1.2.840.113549.1.5.13");
67 OID pbkdf2Id(
"1.2.840.113549.1.5.12");
68 OID pbes2encsId(
"1.2.840.113549.3.7");
73 FileSink sink(pkcs8Os);
78 DERSequenceEncoder encryptedPrivateKeyInfo(sink);
83 DERSequenceEncoder encryptionAlgorithm(encryptedPrivateKeyInfo);
85 pbes2Id.
encode(encryptionAlgorithm);
89 DERSequenceEncoder pbes2Params(encryptionAlgorithm);
94 DERSequenceEncoder pbes2KDFs(pbes2Params);
96 pbkdf2Id.
encode(pbes2KDFs);
102 DERSequenceEncoder pbkdf2Params(pbes2KDFs);
104 DEREncodeOctetString(pbkdf2Params, salt, 8);
105 DEREncodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER);
107 pbkdf2Params.MessageEnd();
109 pbes2KDFs.MessageEnd();
114 DERSequenceEncoder pbes2Encs(pbes2Params);
116 pbes2encsId.
encode(pbes2Encs);
117 DEREncodeOctetString(pbes2Encs, iv, 8);
119 pbes2Encs.MessageEnd();
121 pbes2Params.MessageEnd();
123 encryptionAlgorithm.MessageEnd();
125 DEREncodeOctetString(encryptedPrivateKeyInfo,
126 encryptedOs.buf()->buf(), encryptedOs.buf()->size());
128 encryptedPrivateKeyInfo.MessageEnd();
130 return pkcs8Os.buf();
132 catch (CryptoPP::Exception& e)
134 throw Error(
"Cannot export the private key, #3");
139 SecTpm::importPrivateKeyPkcs5IntoTpm(
const Name& keyName,
140 const uint8_t* buf,
size_t size,
141 const string& passwordStr)
143 using namespace CryptoPP;
147 SecByteBlock saltBlock;
148 uint32_t iterationCount;
150 SecByteBlock ivBlock;
151 SecByteBlock encryptedDataBlock;
157 StringSource source(buf, size,
true);
162 BERSequenceDecoder encryptedPrivateKeyInfo(source);
167 BERSequenceDecoder encryptionAlgorithm(encryptedPrivateKeyInfo);
169 pbes2Id.decode(encryptionAlgorithm);
173 BERSequenceDecoder pbes2Params(encryptionAlgorithm);
178 BERSequenceDecoder pbes2KDFs(pbes2Params);
180 pbkdf2Id.decode(pbes2KDFs);
186 BERSequenceDecoder pbkdf2Params(pbes2KDFs);
188 BERDecodeOctetString(pbkdf2Params, saltBlock);
189 BERDecodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER);
191 pbkdf2Params.MessageEnd();
193 pbes2KDFs.MessageEnd();
198 BERSequenceDecoder pbes2Encs(pbes2Params);
200 pbes2encsId.decode(pbes2Encs);
201 BERDecodeOctetString(pbes2Encs, ivBlock);
203 pbes2Encs.MessageEnd();
205 pbes2Params.MessageEnd();
207 encryptionAlgorithm.MessageEnd();
209 BERDecodeOctetString(encryptedPrivateKeyInfo, encryptedDataBlock);
211 encryptedPrivateKeyInfo.MessageEnd();
213 catch (CryptoPP::Exception& e)
219 PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
220 size_t derivedLen = 24;
221 byte derived[24] = {0};
226 keyGenerator.DeriveKey(derived, derivedLen,
228 reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(),
229 saltBlock.BytePtr(), saltBlock.size(),
232 catch (CryptoPP::Exception& e)
238 CBC_Mode< DES_EDE3 >::Decryption d;
239 d.SetKeyWithIV(derived, derivedLen, ivBlock.BytePtr());
244 StringSource encryptedSource(encryptedDataBlock.BytePtr(), encryptedDataBlock.size(),
true,
245 new StreamTransformationFilter(d,
new FileSink(privateKeyOs)));
247 catch (CryptoPP::Exception& e)
252 if (!importPrivateKeyPkcs8IntoTpm(keyName,
253 privateKeyOs.buf()->buf(), privateKeyOs.buf()->
size()))
261 RSA::PrivateKey privateKey;
262 privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref());
263 RSAFunction publicKey(privateKey);
265 FileSink publicKeySink(publicKeyOs);
266 publicKey.DEREncode(publicKeySink);
267 publicKeySink.MessageEnd();
269 catch (CryptoPP::Exception& e)
274 if (!importPublicKeyPkcs1IntoTpm(keyName, publicKeyOs.buf()->buf(), publicKeyOs.buf()->
size()))
Class implementing interface similar to ostringstream, but to construct ndn::Buffer.
ptr_lib::shared_ptr< const Buffer > ConstBufferPtr
size_t size() const
Get the number of components.
A Name holds an array of Name::Component and represents an NDN name.
void encode(CryptoPP::BufferedTransformation &out) const