aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2008-12-12 17:41:47 +0000
committerlloyd <[email protected]>2008-12-12 17:41:47 +0000
commit05134b3f0a8589410e09c463a9866a8b40e5c3e9 (patch)
tree6404a5e790c24496372b4dc0bc18417327268488
parente41b96f756ac44f700ce70b30c57bfc4dd037537 (diff)
Fix a memory leak in PKCS #8 load_key and encrypt_key that would
occur because PKCS #5 v2.0 doesn't support empty passphrases (though maybe it should?). In this case pbe->set_key would throw an exception, causing the stack to be unwound without the (dynamically created) PBE object being deleted. Use auto_ptr to hold the PBE*, then .release() it when passing it to the Pipe (since Pipe takes ownership of its Filters). Noticed when looking at valgrind analysis of monotone's sync command.
-rw-r--r--doc/log.txt3
-rw-r--r--src/pubkey/pubkey/pkcs8.cpp14
2 files changed, 12 insertions, 5 deletions
diff --git a/doc/log.txt b/doc/log.txt
index 2d66df996..6ea97a8d4 100644
--- a/doc/log.txt
+++ b/doc/log.txt
@@ -1,4 +1,7 @@
+* 1.8.1-pre, 2009-??-??
+ - Fix memory leak in PKCS8 load_key and encrypt_key
+
* 1.8.0, 2008-12-08
- Fix compilation on Solaris with GCC
diff --git a/src/pubkey/pubkey/pkcs8.cpp b/src/pubkey/pubkey/pkcs8.cpp
index a79a616a2..179be57fe 100644
--- a/src/pubkey/pubkey/pkcs8.cpp
+++ b/src/pubkey/pubkey/pkcs8.cpp
@@ -87,7 +87,7 @@ SecureVector<byte> PKCS8_decode(DataSource& source, const User_Interface& ui,
if(is_encrypted)
{
DataSource_Memory params(pbe_alg_id.parameters);
- PBE* pbe = get_pbe(pbe_alg_id.oid, params);
+ std::auto_ptr<PBE> pbe(get_pbe(pbe_alg_id.oid, params));
User_Interface::UI_Result result = User_Interface::OK;
const std::string passphrase =
@@ -97,7 +97,8 @@ SecureVector<byte> PKCS8_decode(DataSource& source, const User_Interface& ui,
break;
pbe->set_key(passphrase);
- Pipe decryptor(pbe);
+ Pipe decryptor(pbe.release());
+
decryptor.process_msg(key_data, key_data.size());
key = decryptor.read_all();
}
@@ -172,17 +173,20 @@ void encrypt_key(const Private_Key& key,
encode(key, raw_key, RAW_BER);
raw_key.end_msg();
- PBE* pbe = get_pbe(((pbe_algo != "") ? pbe_algo : DEFAULT_PBE));
+ std::auto_ptr<PBE> pbe(get_pbe(((pbe_algo != "") ? pbe_algo : DEFAULT_PBE)));
+
pbe->new_params(rng);
pbe->set_key(pass);
- Pipe key_encrytor(pbe);
+ AlgorithmIdentifier pbe_algid(pbe->get_oid(), pbe->encode_params());
+
+ Pipe key_encrytor(pbe.release());
key_encrytor.process_msg(raw_key);
SecureVector<byte> enc_key =
DER_Encoder()
.start_cons(SEQUENCE)
- .encode(AlgorithmIdentifier(pbe->get_oid(), pbe->encode_params()))
+ .encode(pbe_algid)
.encode(key_encrytor.read_all(), OCTET_STRING)
.end_cons()
.get_contents();