# # # add_file "lazy_rng.hh" # content [1f39ec488a4ff5c0566404f56284708d32f5a190] # # patch "Makefile.am" # from [1fa5708e37b84429937048bcf960fff5c77064d3] # to [24a49b6a2886c1adcfbf6ecda1183626cce5d15b] # # patch "app_state.cc" # from [3a362dd33a8f16581de40e22a6239647b9bad32d] # to [a45a76aca10a1575343c85ed2a90cad93c32b20f] # # patch "app_state.hh" # from [e57895ea6314242a40799597824f87686be9d754] # to [2275ee20981badbd2d6adcce90364f431d1c1bef] # # patch "database.cc" # from [5aedd286b29568349b0eed1e72dc0e8f978c75ea] # to [efc69590fa7fed3244b661212115dbf0cce2c1ab] # # patch "database.hh" # from [0b96f942511c38e878487ad7ad095111cf49680d] # to [51cdb3af0f01006863c7a58b0de71570f80e8cea] # # patch "key_store.cc" # from [a58d0322098751fe096cbb1b316f4dd370f14532] # to [f1bd7b63a19c3321ecb4f1ffa0a8de4cff1b2f11] # ============================================================ --- lazy_rng.hh 1f39ec488a4ff5c0566404f56284708d32f5a190 +++ lazy_rng.hh 1f39ec488a4ff5c0566404f56284708d32f5a190 @@ -0,0 +1,40 @@ +// Copyright (C) 2002 Graydon Hoare +// +// This program is made available under the GNU GPL version 2.0 or +// greater. See the accompanying file COPYING for details. +// +// This program is distributed WITHOUT ANY WARRANTY; without even the +// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. + +#ifndef __LAZY_RNG_HH__ +#define __LAZY_RNG_HH__ + +// This class instantiates a Botan::RandomNumberGenerator the first time +// its get() method is called. Subsequent calls return the same object. +// It is expected that callers will not hang on to the reference. + +#include + +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7) +#include + +class lazy_rng +{ + Botan::RandomNumberGenerator * rng; + +public: + lazy_rng() : rng(0) {} + ~lazy_rng() { delete rng; } + + Botan::RandomNumberGenerator & get() { + if (!rng) + rng = Botan::RandomNumberGenerator::make_rng(); + + return *rng; + } +}; + +#endif /* botan >= 1.7.7 */ + +#endif /* lazy_rng.hh */ ============================================================ --- Makefile.am 1fa5708e37b84429937048bcf960fff5c77064d3 +++ Makefile.am 24a49b6a2886c1adcfbf6ecda1183626cce5d15b @@ -77,7 +77,7 @@ MOST_SOURCES = \ asciik.cc asciik.hh \ dates.cc dates.hh \ \ - lru_writeback_cache.hh hybrid_map.hh \ + lru_writeback_cache.hh hybrid_map.hh lazy_rng.hh \ \ cleanup.hh unit_tests.hh \ cycle_detector.hh randomfile.hh adler32.hh \ ============================================================ --- app_state.cc 3a362dd33a8f16581de40e22a6239647b9bad32d +++ app_state.cc a45a76aca10a1575343c85ed2a90cad93c32b20f @@ -14,6 +14,7 @@ #include "app_state.hh" #include "database.hh" +#include "lazy_rng.hh" using boost::shared_ptr; @@ -25,11 +26,10 @@ app_state::app_state() app_state::app_state() : _hidden(new app_state_private()), lua(this), mtn_automate_allowed(false) -{ #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7) - rng = shared_ptr( - Botan::RandomNumberGenerator::make_rng()); + , rng(new lazy_rng()) #endif +{ } app_state::~app_state() ============================================================ --- app_state.hh e57895ea6314242a40799597824f87686be9d754 +++ app_state.hh 2275ee20981badbd2d6adcce90364f431d1c1bef @@ -11,14 +11,8 @@ // PURPOSE. #include +#include -#include -#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7) -#include -#else -#include -#endif - #include "options.hh" #include "lua_hooks.hh" @@ -28,6 +22,8 @@ class database_impl; class app_state_private; class database_impl; +class lazy_rng; + class app_state { boost::shared_ptr _hidden; @@ -43,7 +39,7 @@ public: bool mtn_automate_allowed; #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7) - boost::shared_ptr rng; + boost::shared_ptr rng; #endif }; ============================================================ --- database.cc 5aedd286b29568349b0eed1e72dc0e8f978c75ea +++ database.cc efc69590fa7fed3244b661212115dbf0cce2c1ab @@ -19,13 +19,15 @@ #include "vector.hh" #include +#include -#include #include #include #include #include #include +#include "lazy_rng.hh" + #include #include "lexical_cast.hh" @@ -446,10 +448,10 @@ database::database(app_state & app) database::database(app_state & app) : lua(app.lua) -{ #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7) - rng = app.rng; + , rng(app.rng) #endif +{ boost::shared_ptr & i = app.lookup_db(app.opts.dbname); if (!i) @@ -2949,7 +2951,7 @@ database::encrypt_rsa(rsa_keypair_id con #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7) ct = encryptor->encrypt( reinterpret_cast(plaintext.data()), - plaintext.size(), *rng); + plaintext.size(), rng->get()); #else ct = encryptor->encrypt( reinterpret_cast(plaintext.data()), ============================================================ --- database.hh 0b96f942511c38e878487ad7ad095111cf49680d +++ database.hh 51cdb3af0f01006863c7a58b0de71570f80e8cea @@ -13,12 +13,8 @@ #include "vector.hh" #include #include +#include -#include -#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7) -#include -#endif - #include "rev_types.hh" #include "cert.hh" @@ -29,6 +25,7 @@ class rev_height; class key_store; class outdated_indicator; class rev_height; +class lazy_rng; typedef std::pair var_key; @@ -442,7 +439,7 @@ private: boost::shared_ptr imp; lua_hooks & lua; #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7) - boost::shared_ptr rng; + boost::shared_ptr rng; #endif }; ============================================================ --- key_store.cc a58d0322098751fe096cbb1b316f4dd370f14532 +++ key_store.cc f1bd7b63a19c3321ecb4f1ffa0a8de4cff1b2f11 @@ -18,7 +18,7 @@ #include "constants.hh" #include "ssh_agent.hh" #include "safe_map.hh" - +#include "lazy_rng.hh" #include "botan_pipe_cache.hh" using std::make_pair; @@ -52,7 +52,7 @@ struct key_store_state map hashes; #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7) - boost::shared_ptr rng; + boost::shared_ptr rng; #endif // These are used to cache keys and signers (if the hook allows). @@ -169,7 +169,7 @@ key_store::get_rng() Botan::RandomNumberGenerator & key_store::get_rng() { - return *s->rng; + return s->rng->get(); } #endif @@ -403,7 +403,7 @@ key_store_state::decrypt_private_key(rsa { Botan::DataSource_Memory ds(kp.priv()); #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7) - pkcs8_key.reset(Botan::PKCS8::load_key(ds, *rng, "")); + pkcs8_key.reset(Botan::PKCS8::load_key(ds, rng->get(), "")); #else pkcs8_key.reset(Botan::PKCS8::load_key(ds, "")); #endif @@ -426,7 +426,7 @@ key_store_state::decrypt_private_key(rsa { Botan::DataSource_Memory ds(kp.priv()); #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7) - pkcs8_key.reset(Botan::PKCS8::load_key(ds, *rng, phrase())); + pkcs8_key.reset(Botan::PKCS8::load_key(ds, rng->get(), phrase())); #else pkcs8_key.reset(Botan::PKCS8::load_key(ds, phrase())); #endif @@ -503,7 +503,8 @@ key_store::create_key_pair(database & db // okay, now we can create the key P(F("generating key-pair '%s'") % id); #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7) - RSA_PrivateKey priv(*s->rng, static_cast(constants::keylen)); + RSA_PrivateKey priv(s->rng->get(), + static_cast(constants::keylen)); #else RSA_PrivateKey priv(static_cast(constants::keylen)); #endif @@ -516,7 +517,7 @@ key_store::create_key_pair(database & db if ((*maybe_passphrase)().length()) Botan::PKCS8::encrypt_key(priv, *unfiltered_pipe, #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7) - *s->rng, + s->rng->get(), #endif (*maybe_passphrase)(), "PBE-PKCS5v20(SHA-1,TripleDES/CBC)", @@ -568,7 +569,7 @@ key_store::change_key_passphrase(rsa_key unfiltered_pipe->start_msg(); Botan::PKCS8::encrypt_key(*priv, *unfiltered_pipe, #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7) - *s->rng, + s->rng->get(), #endif new_phrase(), "PBE-PKCS5v20(SHA-1,TripleDES/CBC)", @@ -688,7 +689,7 @@ key_store::make_signature(database & db, #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7) sig = signer->sign_message( reinterpret_cast(tosign.data()), - tosign.size(), *s->rng); + tosign.size(), s->rng->get()); #else sig = signer->sign_message( reinterpret_cast(tosign.data()), @@ -749,7 +750,7 @@ key_store::export_key_for_agent(rsa_keyp Botan::PKCS8::encrypt_key(*priv, p, #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7) - *s->rng, + s->rng->get(), #endif new_phrase(), "PBE-PKCS5v20(SHA-1,TripleDES/CBC)"); @@ -800,7 +801,7 @@ key_store_state::migrate_old_key_pair Botan::DataSource_Memory ds(Botan::PEM_Code::encode(arc4_decrypt, "PRIVATE KEY")); #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7) - pkcs8_key.reset(Botan::PKCS8::load_key(ds, *rng)); + pkcs8_key.reset(Botan::PKCS8::load_key(ds, rng->get())); #else pkcs8_key.reset(Botan::PKCS8::load_key(ds)); #endif @@ -827,7 +828,7 @@ key_store_state::migrate_old_key_pair unfiltered_pipe->start_msg(); Botan::PKCS8::encrypt_key(*priv_key, *unfiltered_pipe, #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7) - *rng, + rng->get(), #endif phrase(), "PBE-PKCS5v20(SHA-1,TripleDES/CBC)",