diff options
author | lloyd <[email protected]> | 2008-12-12 17:41:47 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2008-12-12 17:41:47 +0000 |
commit | 05134b3f0a8589410e09c463a9866a8b40e5c3e9 (patch) | |
tree | 6404a5e790c24496372b4dc0bc18417327268488 | |
parent | e41b96f756ac44f700ce70b30c57bfc4dd037537 (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.txt | 3 | ||||
-rw-r--r-- | src/pubkey/pubkey/pkcs8.cpp | 14 |
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(); |