diff options
-rw-r--r-- | src/libstate/algo_factory.cpp | 37 | ||||
-rw-r--r-- | src/libstate/algo_factory.h | 6 | ||||
-rw-r--r-- | src/libstate/engine/def_engine/def_eng.h | 7 | ||||
-rw-r--r-- | src/libstate/engine/def_engine/lookup_hash.cpp | 33 | ||||
-rw-r--r-- | src/libstate/engine/engine.cpp | 17 | ||||
-rw-r--r-- | src/libstate/engine/engine.h | 19 | ||||
-rw-r--r-- | src/libstate/engine/gnump/eng_gmp.h | 2 | ||||
-rw-r--r-- | src/libstate/engine/openssl/eng_ossl.h | 7 | ||||
-rw-r--r-- | src/libstate/engine/openssl/ossl_md.cpp | 5 | ||||
-rw-r--r-- | src/libstate/libstate.cpp | 2 | ||||
-rw-r--r-- | src/libstate/lookup.cpp | 70 |
11 files changed, 129 insertions, 76 deletions
diff --git a/src/libstate/algo_factory.cpp b/src/libstate/algo_factory.cpp index 4e5bfea85..c7f10a68a 100644 --- a/src/libstate/algo_factory.cpp +++ b/src/libstate/algo_factory.cpp @@ -17,8 +17,6 @@ Algorithm_Factory::~Algorithm_Factory() { std::for_each(engines.begin(), engines.end(), del_fun<Engine>()); engines.clear(); - - delete mutex; } /** @@ -26,8 +24,7 @@ Algorithm_Factory::~Algorithm_Factory() */ void Algorithm_Factory::add_engine(Engine* engine) { - Mutex_Holder lock(mutex); - engines.insert(engines.begin(), engine); + engines.push_back(engine); } /************************************************* @@ -35,25 +32,41 @@ void Algorithm_Factory::add_engine(Engine* engine) *************************************************/ Engine* Algorithm_Factory::get_engine_n(u32bit n) const { - Mutex_Holder lock(mutex); - if(n >= engines.size()) return 0; return engines[n]; } -const HashFunction* Algorithm_Factory::prototype_hash_function(const std::string& algo_spec) +/** +* Return the prototypical object cooresponding to this request +*/ +const HashFunction* +Algorithm_Factory::prototype_hash_function(const SCAN_Name& request) { - Mutex_Holder lock(mutex); - for(u32bit i = 0; i != engines.size(); ++i) { - const HashFunction* algo = engines[i]->hash(algo_spec); - if(algo) - return algo; + if(request.provider_allowed(engines[i]->provider_name())) + { + const HashFunction* algo = + engines[i]->prototype_hash_function(request, *this); + + if(algo) + return algo; + } } return 0; } +/** +* Return a new object cooresponding to this request +*/ +HashFunction* Algorithm_Factory::make_hash_function(const SCAN_Name& request) + { + const HashFunction* prototype = prototype_hash_function(request); + if(prototype) + return prototype->clone(); + return 0; + } + } diff --git a/src/libstate/algo_factory.h b/src/libstate/algo_factory.h index 5a00f3b55..57b94fbb3 100644 --- a/src/libstate/algo_factory.h +++ b/src/libstate/algo_factory.h @@ -6,6 +6,7 @@ #ifndef BOTAN_ALGORITHM_FACTORY_H__ #define BOTAN_ALGORITHM_FACTORY_H__ +#include <botan/scan_name.h> #include <botan/mutex.h> #include <botan/hash.h> #include <string> @@ -19,10 +20,10 @@ namespace Botan { class BOTAN_DLL Algorithm_Factory { public: - Algorithm_Factory(Mutex* m) : mutex(m) {} ~Algorithm_Factory(); - const HashFunction* prototype_hash_function(const std::string& algo_spec); + const HashFunction* prototype_hash_function(const SCAN_Name& request); + HashFunction* make_hash_function(const SCAN_Name& request); void add_engine(class Engine*); @@ -40,7 +41,6 @@ class BOTAN_DLL Algorithm_Factory private: class Engine* get_engine_n(u32bit) const; - Mutex* mutex; std::vector<class Engine*> engines; }; diff --git a/src/libstate/engine/def_engine/def_eng.h b/src/libstate/engine/def_engine/def_eng.h index 377333856..490ef1def 100644 --- a/src/libstate/engine/def_engine/def_eng.h +++ b/src/libstate/engine/def_engine/def_eng.h @@ -16,6 +16,8 @@ namespace Botan { class BOTAN_DLL Default_Engine : public Engine { public: + std::string provider_name() const { return "core"; } + #if defined(BOTAN_HAS_IF_PUBLIC_KEY_FAMILY) IF_Operation* if_op(const BigInt&, const BigInt&, const BigInt&, const BigInt&, const BigInt&, const BigInt&, @@ -61,7 +63,10 @@ class BOTAN_DLL Default_Engine : public Engine private: BlockCipher* find_block_cipher(const std::string&) const; StreamCipher* find_stream_cipher(const std::string&) const; - HashFunction* find_hash(const std::string&) const; + + HashFunction* find_hash(const SCAN_Name& requst, + Algorithm_Factory&) const; + MessageAuthenticationCode* find_mac(const std::string&) const; }; diff --git a/src/libstate/engine/def_engine/lookup_hash.cpp b/src/libstate/engine/def_engine/lookup_hash.cpp index 78f084395..55ee922f9 100644 --- a/src/libstate/engine/def_engine/lookup_hash.cpp +++ b/src/libstate/engine/def_engine/lookup_hash.cpp @@ -4,8 +4,8 @@ *************************************************/ #include <botan/def_eng.h> -#include <botan/lookup.h> #include <botan/scan_name.h> +#include <botan/algo_factory.h> #include <memory> #if defined(BOTAN_HAS_ADLER32) @@ -95,10 +95,9 @@ namespace Botan { * Look for an algorithm with this name * *************************************************/ HashFunction* -Default_Engine::find_hash(const std::string& algo_spec) const +Default_Engine::find_hash(const SCAN_Name& request, + Algorithm_Factory& af) const { - SCAN_Name request(algo_spec); - #if defined(BOTAN_HAS_ADLER32) if(request.algo_name() == "Adler32") return new Adler32; @@ -192,15 +191,33 @@ Default_Engine::find_hash(const std::string& algo_spec) const #endif #if defined(BOTAN_HAS_PARALLEL_HASH) - if(request.algo_name() == "Parallel" && request.arg_count() > 0) + + if(request.algo_name() == "Parallel") { - std::vector<HashFunction*> hashes; + std::vector<const HashFunction*> hash_prototypes; + + /* First pass, just get the prototypes (no memory allocation). Then + if all were found, replace each prototype with a newly created clone + */ + for(size_t i = 0; i != request.arg_count(); ++i) + { + SCAN_Name hash_request(request.argument(i), + request.providers_string()); - for(u32bit i = 0; i != request.arg_count(); ++i) - hashes.push_back(get_hash(request.argument(i))); + const HashFunction* hash = af.prototype_hash_function(hash_request); + if(!hash) + return 0; + + hash_prototypes.push_back(hash); + } + + std::vector<HashFunction*> hashes; + for(size_t i = 0; i != hash_prototypes.size(); ++i) + hashes.push_back(hash_prototypes[i]->clone()); return new Parallel(hashes); } + #endif return 0; diff --git a/src/libstate/engine/engine.cpp b/src/libstate/engine/engine.cpp index c55ff2a78..cbc2c9599 100644 --- a/src/libstate/engine/engine.cpp +++ b/src/libstate/engine/engine.cpp @@ -84,10 +84,21 @@ const StreamCipher* Engine::stream_cipher(const std::string& name) const /************************************************* * Acquire a HashFunction * *************************************************/ -const HashFunction* Engine::hash(const std::string& name) const +const HashFunction* +Engine::prototype_hash_function(const SCAN_Name& request, + Algorithm_Factory& af) const { - return lookup_algo(cache_of_hf, global_state().deref_alias(name), - this, &Engine::find_hash); + // This needs to respect provider settings + HashFunction* algo = cache_of_hf->get(request.as_string()); + if(algo) + return algo; + + // cache miss: do full search + algo = find_hash(request, af); + if(algo) + cache_of_hf->add(algo, request.as_string()); + + return algo; } /************************************************* diff --git a/src/libstate/engine/engine.h b/src/libstate/engine/engine.h index 9e83ce97f..0f61fe1e2 100644 --- a/src/libstate/engine/engine.h +++ b/src/libstate/engine/engine.h @@ -6,14 +6,14 @@ #ifndef BOTAN_ENGINE_H__ #define BOTAN_ENGINE_H__ +#include <botan/scan_name.h> +#include <botan/mutex.h> + #include <botan/block_cipher.h> #include <botan/stream_cipher.h> #include <botan/hash.h> #include <botan/mac.h> -#include <botan/mutex.h> -#include <botan/pow_mod.h> -#include <botan/basefilt.h> #include <utility> #include <map> @@ -49,6 +49,10 @@ namespace Botan { +class Algorithm_Factory; +class Keyed_Filter; +class Modular_Exponentiator; + /************************************************* * Engine Base Class * *************************************************/ @@ -117,7 +121,10 @@ class BOTAN_DLL Engine const BlockCipher* block_cipher(const std::string&) const; const StreamCipher* stream_cipher(const std::string&) const; - const HashFunction* hash(const std::string&) const; + + const HashFunction* prototype_hash_function(const SCAN_Name& request, + Algorithm_Factory& af) const; + const MessageAuthenticationCode* mac(const std::string&) const; virtual bool can_add_algorithms() { return false; } @@ -127,6 +134,8 @@ class BOTAN_DLL Engine void add_algorithm(HashFunction*) const; void add_algorithm(MessageAuthenticationCode*) const; + virtual std::string provider_name() const = 0; + Engine(); virtual ~Engine(); private: @@ -136,7 +145,7 @@ class BOTAN_DLL Engine virtual StreamCipher* find_stream_cipher(const std::string&) const { return 0; } - virtual HashFunction* find_hash(const std::string&) const + virtual HashFunction* find_hash(const SCAN_Name&, Algorithm_Factory&) const { return 0; } virtual MessageAuthenticationCode* find_mac(const std::string&) const diff --git a/src/libstate/engine/gnump/eng_gmp.h b/src/libstate/engine/gnump/eng_gmp.h index a0ff2661c..8edaae374 100644 --- a/src/libstate/engine/gnump/eng_gmp.h +++ b/src/libstate/engine/gnump/eng_gmp.h @@ -16,6 +16,8 @@ namespace Botan { class BOTAN_DLL GMP_Engine : public Engine { public: + std::string provider_name() const { return "gmp"; } + #if defined(BOTAN_HAS_IF_PUBLIC_KEY_FAMILY) IF_Operation* if_op(const BigInt&, const BigInt&, const BigInt&, const BigInt&, const BigInt&, const BigInt&, diff --git a/src/libstate/engine/openssl/eng_ossl.h b/src/libstate/engine/openssl/eng_ossl.h index c63179459..6eb5700d6 100644 --- a/src/libstate/engine/openssl/eng_ossl.h +++ b/src/libstate/engine/openssl/eng_ossl.h @@ -16,6 +16,11 @@ namespace Botan { class BOTAN_DLL OpenSSL_Engine : public Engine { public: + /** + * Return the provider name ("openssl") + */ + std::string provider_name() const { return "openssl"; } + #if defined(BOTAN_HAS_IF_PUBLIC_KEY_FAMILY) IF_Operation* if_op(const BigInt&, const BigInt&, const BigInt&, const BigInt&, const BigInt&, const BigInt&, @@ -45,7 +50,7 @@ class BOTAN_DLL OpenSSL_Engine : public Engine private: BlockCipher* find_block_cipher(const std::string&) const; StreamCipher* find_stream_cipher(const std::string&) const; - HashFunction* find_hash(const std::string&) const; + HashFunction* find_hash(const SCAN_Name&, Algorithm_Factory&) const; }; } diff --git a/src/libstate/engine/openssl/ossl_md.cpp b/src/libstate/engine/openssl/ossl_md.cpp index d009e4c42..04ef59f99 100644 --- a/src/libstate/engine/openssl/ossl_md.cpp +++ b/src/libstate/engine/openssl/ossl_md.cpp @@ -91,10 +91,9 @@ EVP_HashFunction::~EVP_HashFunction() /************************************************* * Look for an algorithm with this name * *************************************************/ -HashFunction* OpenSSL_Engine::find_hash(const std::string& algo_spec) const +HashFunction* OpenSSL_Engine::find_hash(const SCAN_Name& request, + Algorithm_Factory&) const { - SCAN_Name request(algo_spec); - if(request.algo_name() == "SHA-160") return new EVP_HashFunction(EVP_sha1(), "SHA-160"); diff --git a/src/libstate/libstate.cpp b/src/libstate/libstate.cpp index bc0f6794b..1b32f2e86 100644 --- a/src/libstate/libstate.cpp +++ b/src/libstate/libstate.cpp @@ -227,7 +227,7 @@ void Library_State::initialize(const InitializerOptions& args, load_default_config(); - algorithm_factory = new Algorithm_Factory(get_mutex()); + algorithm_factory = new Algorithm_Factory; std::vector<Engine*> mod_engines = modules.engines(); for(u32bit j = 0; j != mod_engines.size(); ++j) diff --git a/src/libstate/lookup.cpp b/src/libstate/lookup.cpp index dd18420b5..d8fab625b 100644 --- a/src/libstate/lookup.cpp +++ b/src/libstate/lookup.cpp @@ -10,6 +10,37 @@ namespace Botan { /************************************************* +* Acquire a hash function * +*************************************************/ +const HashFunction* retrieve_hash(Library_State& libstate, + const std::string& name) + { + return libstate.algo_factory().prototype_hash_function(name); + } + +/************************************************* +* Get a hash function by name * +*************************************************/ +HashFunction* get_hash(const std::string& algo_spec) + { + const HashFunction* hash = + global_state().algo_factory().prototype_hash_function(algo_spec); + + if(hash) + return hash->clone(); + + throw Algorithm_Not_Found(algo_spec); + } + +/************************************************* +* Query if Botan has the named hash function * +*************************************************/ +bool have_hash(const std::string& algo_spec) + { + return global_state().algo_factory().prototype_hash_function(algo_spec); + } + +/************************************************* * Get a block cipher by name * *************************************************/ BlockCipher* get_block_cipher(const std::string& name) @@ -32,17 +63,6 @@ StreamCipher* get_stream_cipher(const std::string& name) } /************************************************* -* Get a hash function by name * -*************************************************/ -HashFunction* get_hash(const std::string& name) - { - const HashFunction* hash = retrieve_hash(global_state(), name); - if(hash) - return hash->clone(); - throw Algorithm_Not_Found(name); - } - -/************************************************* * Get a MAC by name * *************************************************/ MessageAuthenticationCode* get_mac(const std::string& name) @@ -86,14 +106,6 @@ bool have_stream_cipher(const std::string& name) } /************************************************* -* Query if Botan has the named hash function * -*************************************************/ -bool have_hash(const std::string& name) - { - return (retrieve_hash(global_state(), name) != 0); - } - -/************************************************* * Query if Botan has the named MAC * *************************************************/ bool have_mac(const std::string& name) @@ -213,7 +225,6 @@ u32bit keylength_multiple_of(const std::string& name) throw Algorithm_Not_Found(name); } - /************************************************* * Acquire a block cipher * *************************************************/ @@ -251,25 +262,6 @@ const StreamCipher* retrieve_stream_cipher(Library_State& libstate, } /************************************************* -* Acquire a hash function * -*************************************************/ -const HashFunction* retrieve_hash(Library_State& libstate, - const std::string& name) - { - //return libstate.algo_factory().prototype_hash_function(name); - Algorithm_Factory::Engine_Iterator i(libstate.algo_factory()); - - while(const Engine* engine = i.next()) - { - const HashFunction* algo = engine->hash(name); - if(algo) - return algo; - } - - return 0; - } - -/************************************************* * Acquire an authentication code * *************************************************/ const MessageAuthenticationCode* retrieve_mac(Library_State& libstate, |