Don't DES-encrypt priv keys without a passphrase

Per https://www.openssl.org/docs/crypto/pem.html, specifying to encrypt
a private key with DES *without* providing a passphrase causes OpenSSL
to prompt for the passphrase to use on the console -- which is
problematic for GUI applications which generally lack a console.

This modifies the behavior of RSAKeyImpl::save() so that DES encryption
of private keys will not be attempted unless the passphrase argument is
non-empty. This will also suppress OpenSSL's prompting for that
passphrase on the console.

Also added a case to the test suite.
This commit is contained in:
John Nelson 2014-10-13 13:33:22 -06:00
parent 50f1f12cab
commit 18ffcdd7c3
3 changed files with 27 additions and 2 deletions

View File

@ -256,7 +256,7 @@ void RSAKeyImpl::save(const std::string& publicKeyFile, const std::string& priva
{
int rc = 0;
if (privateKeyPassphrase.empty())
rc = PEM_write_bio_RSAPrivateKey(bio, _pRSA, EVP_des_ede3_cbc(), 0, 0, 0, 0);
rc = PEM_write_bio_RSAPrivateKey(bio, _pRSA, 0, 0, 0, 0, 0);
else
rc = PEM_write_bio_RSAPrivateKey(bio, _pRSA, EVP_des_ede3_cbc(),
reinterpret_cast<unsigned char*>(const_cast<char*>(privateKeyPassphrase.c_str())),
@ -298,7 +298,7 @@ void RSAKeyImpl::save(std::ostream* pPublicKeyStream, std::ostream* pPrivateKeyS
if (!bio) throw Poco::IOException("Cannot create BIO for writing public key");
int rc = 0;
if (privateKeyPassphrase.empty())
rc = PEM_write_bio_RSAPrivateKey(bio, _pRSA, EVP_des_ede3_cbc(), 0, 0, 0, 0);
rc = PEM_write_bio_RSAPrivateKey(bio, _pRSA, 0, 0, 0, 0, 0);
else
rc = PEM_write_bio_RSAPrivateKey(bio, _pRSA, EVP_des_ede3_cbc(),
reinterpret_cast<unsigned char*>(const_cast<char*>(privateKeyPassphrase.c_str())),

View File

@ -108,6 +108,29 @@ void RSATest::testNewKeys()
}
void RSATest::testNewKeysNoPassphrase()
{
RSAKey key(RSAKey::KL_1024, RSAKey::EXP_SMALL);
std::ostringstream strPub;
std::ostringstream strPriv;
key.save(&strPub, &strPriv);
std::string pubKey = strPub.str();
std::string privKey = strPriv.str();
// now do the round trip
std::istringstream iPub(pubKey);
std::istringstream iPriv(privKey);
RSAKey key2(&iPub, &iPriv);
std::istringstream iPriv2(privKey);
RSAKey key3(0, &iPriv2);
std::ostringstream strPub3;
key3.save(&strPub3);
std::string pubFromPrivate = strPub3.str();
assert (pubFromPrivate == pubKey);
}
void RSATest::testSign()
{
std::string msg("Test this sign message");
@ -244,6 +267,7 @@ CppUnit::Test* RSATest::suite()
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("RSATest");
CppUnit_addTest(pSuite, RSATest, testNewKeys);
CppUnit_addTest(pSuite, RSATest, testNewKeysNoPassphrase);
CppUnit_addTest(pSuite, RSATest, testSign);
CppUnit_addTest(pSuite, RSATest, testSignSha256);
CppUnit_addTest(pSuite, RSATest, testSignManipulated);

View File

@ -27,6 +27,7 @@ public:
~RSATest();
void testNewKeys();
void testNewKeysNoPassphrase();
void testSign();
void testSignSha256();
void testSignManipulated();