diff options
Diffstat (limited to 'src/core/libstate.cpp')
-rw-r--r-- | src/core/libstate.cpp | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/src/core/libstate.cpp b/src/core/libstate.cpp new file mode 100644 index 000000000..df9d2b519 --- /dev/null +++ b/src/core/libstate.cpp @@ -0,0 +1,294 @@ +/************************************************* +* Library Internal/Global State Source File * +* (C) 1999-2008 Jack Lloyd * +*************************************************/ + +#include <botan/libstate.h> +#include <botan/modules.h> +#include <botan/engine.h> +#include <botan/stl_util.h> +#include <botan/mutex.h> +#include <botan/charset.h> +#include <botan/lookup.h> +#include <algorithm> + +#if defined(BOTAN_HAS_SELFTEST) + #include <botan/selftest.h> +#endif + +namespace Botan { + +/************************************************* +* Botan's global state * +*************************************************/ +namespace { + +Library_State* global_lib_state = 0; + +} + +/************************************************* +* Access the global state object * +*************************************************/ +Library_State& global_state() + { + if(!global_lib_state) + LibraryInitializer::initialize(); + return (*global_lib_state); + } + +/************************************************* +* Set a new global state object * +*************************************************/ +void set_global_state(Library_State* new_state) + { + delete swap_global_state(new_state); + } + +/************************************************* +* Swap two global state objects * +*************************************************/ +Library_State* swap_global_state(Library_State* new_state) + { + Library_State* old_state = global_lib_state; + global_lib_state = new_state; + return old_state; + } + +/************************************************* +* Increment the Engine iterator * +*************************************************/ +Engine* Library_State::Engine_Iterator::next() + { + return lib.get_engine_n(n++); + } + +/************************************************* +* Get a new mutex object * +*************************************************/ +Mutex* Library_State::get_mutex() const + { + return mutex_factory->make(); + } + +/************************************************* +* Get an allocator by its name * +*************************************************/ +Allocator* Library_State::get_allocator(const std::string& type) const + { + Mutex_Holder lock(allocator_lock); + + if(type != "") + return search_map<std::string, Allocator*>(alloc_factory, type, 0); + + if(!cached_default_allocator) + { + std::string chosen = this->option("base/default_allocator"); + + if(chosen == "") + chosen = "malloc"; + + cached_default_allocator = + search_map<std::string, Allocator*>(alloc_factory, chosen, 0); + } + + return cached_default_allocator; + } + +/************************************************* +* Create a new name to object mapping * +*************************************************/ +void Library_State::add_allocator(Allocator* allocator) + { + Mutex_Holder lock(allocator_lock); + + allocator->init(); + + allocators.push_back(allocator); + alloc_factory[allocator->type()] = allocator; + } + +/************************************************* +* Set the default allocator type * +*************************************************/ +void Library_State::set_default_allocator(const std::string& type) + { + Mutex_Holder lock(allocator_lock); + + if(type == "") + return; + + this->set("conf", "base/default_allocator", type); + cached_default_allocator = 0; + } + +/************************************************* +* Get an engine out of the list * +*************************************************/ +Engine* Library_State::get_engine_n(u32bit n) const + { + Mutex_Holder lock(engine_lock); + + if(n >= engines.size()) + return 0; + return engines[n]; + } + +/************************************************* +* Add a new engine to the list * +*************************************************/ +void Library_State::add_engine(Engine* engine) + { + Mutex_Holder lock(engine_lock); + engines.insert(engines.begin(), engine); + } + +/************************************************* +* Get a configuration value * +*************************************************/ +std::string Library_State::get(const std::string& section, + const std::string& key) const + { + Mutex_Holder lock(config_lock); + + return search_map<std::string, std::string>(config, + section + "/" + key, ""); + } + +/************************************************* +* See if a particular option has been set * +*************************************************/ +bool Library_State::is_set(const std::string& section, + const std::string& key) const + { + Mutex_Holder lock(config_lock); + + return search_map(config, section + "/" + key, false, true); + } + +/************************************************* +* Set a configuration value * +*************************************************/ +void Library_State::set(const std::string& section, const std::string& key, + const std::string& value, bool overwrite) + { + Mutex_Holder lock(config_lock); + + std::string full_key = section + "/" + key; + + std::map<std::string, std::string>::const_iterator i = + config.find(full_key); + + if(overwrite || i == config.end() || i->second == "") + config[full_key] = value; + } + +/************************************************* +* Add an alias * +*************************************************/ +void Library_State::add_alias(const std::string& key, const std::string& value) + { + set("alias", key, value); + } + +/************************************************* +* Dereference an alias to a fixed name * +*************************************************/ +std::string Library_State::deref_alias(const std::string& key) const + { + std::string result = key; + while(is_set("alias", result)) + result = get("alias", result); + return result; + } + +/************************************************* +* Set/Add an option * +*************************************************/ +void Library_State::set_option(const std::string key, + const std::string& value) + { + set("conf", key, value); + } + +/************************************************* +* Get an option value * +*************************************************/ +std::string Library_State::option(const std::string& key) const + { + return get("conf", key); + } + +/************************************************* +* Load a set of modules * +*************************************************/ +void Library_State::initialize(const InitializerOptions& args, + Modules& modules) + { + if(mutex_factory) + throw Invalid_State("Library_State has already been initialized"); + + mutex_factory = modules.mutex_factory(args.thread_safe()); + + if(!mutex_factory) + throw Invalid_State("Could not acquire a mutex module at init"); + + allocator_lock = get_mutex(); + engine_lock = get_mutex(); + config_lock = get_mutex(); + + cached_default_allocator = 0; + + std::vector<Allocator*> mod_allocs = modules.allocators(); + for(u32bit j = 0; j != mod_allocs.size(); ++j) + add_allocator(mod_allocs[j]); + + set_default_allocator(modules.default_allocator()); + + load_default_config(); + + std::vector<Engine*> mod_engines = modules.engines(); + for(u32bit j = 0; j != mod_engines.size(); ++j) + engines.push_back(mod_engines[j]); + +#if defined(BOTAN_HAS_SELFTEST) + if(args.fips_mode() || args.self_test()) + { + if(!passes_self_tests()) + throw Self_Test_Failure("Initialization self-tests"); + } +#endif + } + +/************************************************* +* Library_State Constructor * +*************************************************/ +Library_State::Library_State() + { + mutex_factory = 0; + allocator_lock = engine_lock = config_lock = 0; + cached_default_allocator = 0; + } + +/************************************************* +* Library_State Destructor * +*************************************************/ +Library_State::~Library_State() + { + std::for_each(engines.begin(), engines.end(), del_fun<Engine>()); + + cached_default_allocator = 0; + + for(u32bit j = 0; j != allocators.size(); ++j) + { + allocators[j]->destroy(); + delete allocators[j]; + } + + delete allocator_lock; + delete engine_lock; + delete mutex_factory; + delete config_lock; + } + +} |