security: Consistent exception handling.
Change-Id: Ia29963e96028e591e9c4fc4a68a472f794b17e52
diff --git a/src/security/sec-tpm.cpp b/src/security/sec-tpm.cpp
index f93169d..56c39b8 100644
--- a/src/security/sec-tpm.cpp
+++ b/src/security/sec-tpm.cpp
@@ -26,224 +26,260 @@
ConstBufferPtr
SecTpm::exportPrivateKeyPkcs8FromTpm(const Name& keyName, const string& passwordStr)
{
+ using namespace CryptoPP;
+
uint8_t salt[8] = {0};
uint8_t iv[8] = {0};
- try{
- using namespace CryptoPP;
+ // derive key
+ if(!generateRandomBlock(salt, 8) || !generateRandomBlock(iv, 8))
+ throw Error("Cannot generate salt or iv");
- // derive key
- if(!generateRandomBlock(salt, 8))
- return shared_ptr<Buffer>();
-
- if(!generateRandomBlock(iv, 8))
- return shared_ptr<Buffer>();
-
- uint32_t iterationCount = 2048;
-
- PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
- size_t derivedLen = 24; //For DES-EDE3-CBC-PAD
- byte derived[24] = {0};
- byte purpose = 0;
-
- keyGenerator.DeriveKey(derived, derivedLen,
- purpose,
- reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(),
- salt, 8,
- iterationCount);
-
- //encrypt
- CBC_Mode< DES_EDE3 >::Encryption e;
- e.SetKeyWithIV(derived, derivedLen, iv);
-
- string encrypted;
- OBufferStream encryptedOs;
- ConstBufferPtr pkcs1PrivateKey = exportPrivateKeyPkcs1FromTpm(keyName);
- StringSource stringSource(pkcs1PrivateKey->buf(), pkcs1PrivateKey->size(), true,
- new StreamTransformationFilter(e, new FileSink(encryptedOs)));
-
- //encode
- OID pbes2Id("1.2.840.113549.1.5.13");
- OID pbkdf2Id("1.2.840.113549.1.5.12");
- OID pbes2encsId("1.2.840.113549.3.7");
-
- OBufferStream pkcs8Os;
- FileSink sink(pkcs8Os);
+ uint32_t iterationCount = 2048;
- // EncryptedPrivateKeyInfo ::= SEQUENCE {
- // encryptionAlgorithm EncryptionAlgorithmIdentifier,
- // encryptedData OCTET STRING }
- DERSequenceEncoder encryptedPrivateKeyInfo(sink);
+ PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
+ size_t derivedLen = 24; //For DES-EDE3-CBC-PAD
+ byte derived[24] = {0};
+ byte purpose = 0;
+
+ try
{
- // EncryptionAlgorithmIdentifier ::= SEQUENCE {
- // algorithm OBJECT IDENTIFIER {{PBES2-id}},
- // parameters SEQUENCE {{PBES2-params}} }
- DERSequenceEncoder encryptionAlgorithm(encryptedPrivateKeyInfo);
- {
- pbes2Id.encode(encryptionAlgorithm);
- // PBES2-params ::= SEQUENCE {
- // keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
- // encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} }
- DERSequenceEncoder pbes2Params(encryptionAlgorithm);
- {
- // AlgorithmIdentifier ::= SEQUENCE {
- // algorithm OBJECT IDENTIFIER {{PBKDF2-id}},
- // parameters SEQUENCE {{PBKDF2-params}} }
- DERSequenceEncoder pbes2KDFs(pbes2Params);
- {
- pbkdf2Id.encode(pbes2KDFs);
- // AlgorithmIdentifier ::= SEQUENCE {
- // salt OCTET STRING,
- // iterationCount INTEGER (1..MAX),
- // keyLength INTEGER (1..MAX) OPTIONAL,
- // prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 }
- DERSequenceEncoder pbkdf2Params(pbes2KDFs);
- {
- DEREncodeOctetString(pbkdf2Params, salt, 8);
- DEREncodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER);
- }
- pbkdf2Params.MessageEnd();
- }
- pbes2KDFs.MessageEnd();
-
- // AlgorithmIdentifier ::= SEQUENCE {
- // algorithm OBJECT IDENTIFIER {{DES-EDE3-CBC-PAD}},
- // parameters OCTET STRING} {{iv}} }
- DERSequenceEncoder pbes2Encs(pbes2Params);
- {
- pbes2encsId.encode(pbes2Encs);
- DEREncodeOctetString(pbes2Encs, iv, 8);
- }
- pbes2Encs.MessageEnd();
- }
- pbes2Params.MessageEnd();
- }
- encryptionAlgorithm.MessageEnd();
-
- DEREncodeOctetString(encryptedPrivateKeyInfo, encryptedOs.buf()->buf(), encryptedOs.buf()->size());
+ keyGenerator.DeriveKey(derived, derivedLen, purpose,
+ reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(),
+ salt, 8, iterationCount);
}
- encryptedPrivateKeyInfo.MessageEnd();
+ catch(CryptoPP::Exception& e)
+ {
+ throw Error("Cannot derived the encryption key");
+ }
- return pkcs8Os.buf();
- }catch(...){
- return shared_ptr<Buffer>();
- }
+ //encrypt
+ CBC_Mode< DES_EDE3 >::Encryption e;
+ e.SetKeyWithIV(derived, derivedLen, iv);
+
+ ConstBufferPtr pkcs1PrivateKey = exportPrivateKeyPkcs1FromTpm(keyName);
+ if(!static_cast<bool>(pkcs1PrivateKey))
+ throw Error("Cannot export the private key, #1");
+
+ OBufferStream encryptedOs;
+ try
+ {
+ StringSource stringSource(pkcs1PrivateKey->buf(), pkcs1PrivateKey->size(), true,
+ new StreamTransformationFilter(e, new FileSink(encryptedOs)));
+ }
+ catch(CryptoPP::Exception& e)
+ {
+ throw Error("Cannot export the private key, #2");
+ }
+
+ //encode
+ OID pbes2Id("1.2.840.113549.1.5.13");
+ OID pbkdf2Id("1.2.840.113549.1.5.12");
+ OID pbes2encsId("1.2.840.113549.3.7");
+
+ OBufferStream pkcs8Os;
+ try
+ {
+ FileSink sink(pkcs8Os);
+
+ // EncryptedPrivateKeyInfo ::= SEQUENCE {
+ // encryptionAlgorithm EncryptionAlgorithmIdentifier,
+ // encryptedData OCTET STRING }
+ DERSequenceEncoder encryptedPrivateKeyInfo(sink);
+ {
+ // EncryptionAlgorithmIdentifier ::= SEQUENCE {
+ // algorithm OBJECT IDENTIFIER {{PBES2-id}},
+ // parameters SEQUENCE {{PBES2-params}} }
+ DERSequenceEncoder encryptionAlgorithm(encryptedPrivateKeyInfo);
+ {
+ pbes2Id.encode(encryptionAlgorithm);
+ // PBES2-params ::= SEQUENCE {
+ // keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
+ // encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} }
+ DERSequenceEncoder pbes2Params(encryptionAlgorithm);
+ {
+ // AlgorithmIdentifier ::= SEQUENCE {
+ // algorithm OBJECT IDENTIFIER {{PBKDF2-id}},
+ // parameters SEQUENCE {{PBKDF2-params}} }
+ DERSequenceEncoder pbes2KDFs(pbes2Params);
+ {
+ pbkdf2Id.encode(pbes2KDFs);
+ // AlgorithmIdentifier ::= SEQUENCE {
+ // salt OCTET STRING,
+ // iterationCount INTEGER (1..MAX),
+ // keyLength INTEGER (1..MAX) OPTIONAL,
+ // prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 }
+ DERSequenceEncoder pbkdf2Params(pbes2KDFs);
+ {
+ DEREncodeOctetString(pbkdf2Params, salt, 8);
+ DEREncodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER);
+ }
+ pbkdf2Params.MessageEnd();
+ }
+ pbes2KDFs.MessageEnd();
+
+ // AlgorithmIdentifier ::= SEQUENCE {
+ // algorithm OBJECT IDENTIFIER {{DES-EDE3-CBC-PAD}},
+ // parameters OCTET STRING} {{iv}} }
+ DERSequenceEncoder pbes2Encs(pbes2Params);
+ {
+ pbes2encsId.encode(pbes2Encs);
+ DEREncodeOctetString(pbes2Encs, iv, 8);
+ }
+ pbes2Encs.MessageEnd();
+ }
+ pbes2Params.MessageEnd();
+ }
+ encryptionAlgorithm.MessageEnd();
+
+ DEREncodeOctetString(encryptedPrivateKeyInfo, encryptedOs.buf()->buf(), encryptedOs.buf()->size());
+ }
+ encryptedPrivateKeyInfo.MessageEnd();
+
+ return pkcs8Os.buf();
+ }
+ catch(CryptoPP::Exception& e)
+ {
+ throw Error("Cannot export the private key, #3");
+ }
}
bool
SecTpm::importPrivateKeyPkcs8IntoTpm(const Name& keyName, const uint8_t* buf, size_t size, const string& passwordStr)
{
- try{
- using namespace CryptoPP;
-
- OID pbes2Id;
- OID pbkdf2Id;
- SecByteBlock saltBlock;
- uint32_t iterationCount;
- OID pbes2encsId;
- SecByteBlock ivBlock;
- SecByteBlock encryptedDataBlock;
-
- //decode some decoding processes are not necessary for now, because we assume only one encryption scheme.
- StringSource source(buf, size, true);
-
- // EncryptedPrivateKeyInfo ::= SEQUENCE {
- // encryptionAlgorithm EncryptionAlgorithmIdentifier,
- // encryptedData OCTET STRING }
- BERSequenceDecoder encryptedPrivateKeyInfo(source);
+ using namespace CryptoPP;
+
+ OID pbes2Id;
+ OID pbkdf2Id;
+ SecByteBlock saltBlock;
+ uint32_t iterationCount;
+ OID pbes2encsId;
+ SecByteBlock ivBlock;
+ SecByteBlock encryptedDataBlock;
+
+ try
{
- // EncryptionAlgorithmIdentifier ::= SEQUENCE {
- // algorithm OBJECT IDENTIFIER {{PBES2-id}},
- // parameters SEQUENCE {{PBES2-params}} }
- BERSequenceDecoder encryptionAlgorithm(encryptedPrivateKeyInfo);
+ //decode some decoding processes are not necessary for now, because we assume only one encryption scheme.
+ StringSource source(buf, size, true);
+
+ // EncryptedPrivateKeyInfo ::= SEQUENCE {
+ // encryptionAlgorithm EncryptionAlgorithmIdentifier,
+ // encryptedData OCTET STRING }
+ BERSequenceDecoder encryptedPrivateKeyInfo(source);
{
- pbes2Id.decode(encryptionAlgorithm);
- // PBES2-params ::= SEQUENCE {
- // keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
- // encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} }
- BERSequenceDecoder pbes2Params(encryptionAlgorithm);
+ // EncryptionAlgorithmIdentifier ::= SEQUENCE {
+ // algorithm OBJECT IDENTIFIER {{PBES2-id}},
+ // parameters SEQUENCE {{PBES2-params}} }
+ BERSequenceDecoder encryptionAlgorithm(encryptedPrivateKeyInfo);
{
- // AlgorithmIdentifier ::= SEQUENCE {
- // algorithm OBJECT IDENTIFIER {{PBKDF2-id}},
- // parameters SEQUENCE {{PBKDF2-params}} }
- BERSequenceDecoder pbes2KDFs(pbes2Params);
+ pbes2Id.decode(encryptionAlgorithm);
+ // PBES2-params ::= SEQUENCE {
+ // keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
+ // encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} }
+ BERSequenceDecoder pbes2Params(encryptionAlgorithm);
{
- pbkdf2Id.decode(pbes2KDFs);
// AlgorithmIdentifier ::= SEQUENCE {
- // salt OCTET STRING,
- // iterationCount INTEGER (1..MAX),
- // keyLength INTEGER (1..MAX) OPTIONAL,
- // prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 }
- BERSequenceDecoder pbkdf2Params(pbes2KDFs);
+ // algorithm OBJECT IDENTIFIER {{PBKDF2-id}},
+ // parameters SEQUENCE {{PBKDF2-params}} }
+ BERSequenceDecoder pbes2KDFs(pbes2Params);
{
- BERDecodeOctetString(pbkdf2Params, saltBlock);
- BERDecodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER);
+ pbkdf2Id.decode(pbes2KDFs);
+ // AlgorithmIdentifier ::= SEQUENCE {
+ // salt OCTET STRING,
+ // iterationCount INTEGER (1..MAX),
+ // keyLength INTEGER (1..MAX) OPTIONAL,
+ // prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 }
+ BERSequenceDecoder pbkdf2Params(pbes2KDFs);
+ {
+ BERDecodeOctetString(pbkdf2Params, saltBlock);
+ BERDecodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER);
+ }
+ pbkdf2Params.MessageEnd();
}
- pbkdf2Params.MessageEnd();
+ pbes2KDFs.MessageEnd();
+
+ // AlgorithmIdentifier ::= SEQUENCE {
+ // algorithm OBJECT IDENTIFIER {{DES-EDE3-CBC-PAD}},
+ // parameters OCTET STRING} {{iv}} }
+ BERSequenceDecoder pbes2Encs(pbes2Params);
+ {
+ pbes2encsId.decode(pbes2Encs);
+ BERDecodeOctetString(pbes2Encs, ivBlock);
+ }
+ pbes2Encs.MessageEnd();
}
- pbes2KDFs.MessageEnd();
-
- // AlgorithmIdentifier ::= SEQUENCE {
- // algorithm OBJECT IDENTIFIER {{DES-EDE3-CBC-PAD}},
- // parameters OCTET STRING} {{iv}} }
- BERSequenceDecoder pbes2Encs(pbes2Params);
- {
- pbes2encsId.decode(pbes2Encs);
- BERDecodeOctetString(pbes2Encs, ivBlock);
- }
- pbes2Encs.MessageEnd();
+ pbes2Params.MessageEnd();
}
- pbes2Params.MessageEnd();
- }
- encryptionAlgorithm.MessageEnd();
+ encryptionAlgorithm.MessageEnd();
- BERDecodeOctetString(encryptedPrivateKeyInfo, encryptedDataBlock);
+ BERDecodeOctetString(encryptedPrivateKeyInfo, encryptedDataBlock);
+ }
+ encryptedPrivateKeyInfo.MessageEnd();
}
- encryptedPrivateKeyInfo.MessageEnd();
+ catch(CryptoPP::Exception& e)
+ {
+ return false;
+ }
- PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
- size_t derivedLen = 24; //For DES-EDE3-CBC-PAD
- byte derived[24] = {0};
- byte purpose = 0;
-
- keyGenerator.DeriveKey(derived, derivedLen,
- purpose,
- reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(),
- saltBlock.BytePtr(), saltBlock.size(),
- iterationCount);
-
+ PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
+ size_t derivedLen = 24; //For DES-EDE3-CBC-PAD
+ byte derived[24] = {0};
+ byte purpose = 0;
+
+ try
+ {
+ keyGenerator.DeriveKey(derived, derivedLen,
+ purpose,
+ reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(),
+ saltBlock.BytePtr(), saltBlock.size(),
+ iterationCount);
+ }
+ catch(CryptoPP::Exception& e)
+ {
+ return false;
+ }
- //decrypt
- CBC_Mode< DES_EDE3 >::Decryption d;
- d.SetKeyWithIV(derived, derivedLen, ivBlock.BytePtr());
-
- OBufferStream privateKeyOs;
- StringSource encryptedSource(encryptedDataBlock.BytePtr(), encryptedDataBlock.size(), true,
- new StreamTransformationFilter(d, new FileSink(privateKeyOs)));
-
- if(!importPrivateKeyPkcs1IntoTpm(keyName, privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()))
+ //decrypt
+ CBC_Mode< DES_EDE3 >::Decryption d;
+ d.SetKeyWithIV(derived, derivedLen, ivBlock.BytePtr());
+
+ OBufferStream privateKeyOs;
+ try
+ {
+ StringSource encryptedSource(encryptedDataBlock.BytePtr(), encryptedDataBlock.size(), true,
+ new StreamTransformationFilter(d, new FileSink(privateKeyOs)));
+ }
+ catch(CryptoPP::Exception& e)
+ {
return false;
-
- //derive public key
- RSA::PrivateKey privateKey;
- privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref());
+ }
- RSAFunction publicKey(privateKey);
-
- OBufferStream publicKeyOs;
- FileSink publicKeySink(publicKeyOs);
- publicKey.DEREncode(publicKeySink);
- publicKeySink.MessageEnd();
-
- if(!importPublicKeyPkcs1IntoTpm(keyName, publicKeyOs.buf()->buf(), publicKeyOs.buf()->size()))
- return false;
-
- return true;
- }catch(std::runtime_error& e){
- cerr << e.what() << endl;
+ if(!importPrivateKeyPkcs1IntoTpm(keyName, privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()))
return false;
- }
+
+ //derive public key
+ OBufferStream publicKeyOs;
+
+ try
+ {
+ RSA::PrivateKey privateKey;
+ privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref());
+ RSAFunction publicKey(privateKey);
+
+ FileSink publicKeySink(publicKeyOs);
+ publicKey.DEREncode(publicKeySink);
+ publicKeySink.MessageEnd();
+ }
+ catch(CryptoPP::Exception& e)
+ {
+ return false;
+ }
+
+ if(!importPublicKeyPkcs1IntoTpm(keyName, publicKeyOs.buf()->buf(), publicKeyOs.buf()->size()))
+ return false;
+
+ return true;
}