00001
00002
00003
00004
00005
00006
00007
00008 #include <botan/libstate.h>
00009 #include <botan/charset.h>
00010 #include <botan/engine.h>
00011 #include <botan/cpuid.h>
00012 #include <botan/internal/defalloc.h>
00013 #include <botan/internal/core_engine.h>
00014 #include <botan/internal/mutex.h>
00015 #include <botan/internal/mux_noop.h>
00016 #include <botan/internal/stl_util.h>
00017 #include <botan/internal/mlock.h>
00018 #include <algorithm>
00019
00020 #if defined(BOTAN_HAS_SELFTESTS)
00021 #include <botan/selftest.h>
00022 #endif
00023
00024 #if defined(BOTAN_HAS_MUTEX_PTHREAD)
00025 #include <botan/internal/mux_pthr.h>
00026 #elif defined(BOTAN_HAS_MUTEX_WIN32)
00027 #include <botan/internal/mux_win32.h>
00028 #elif defined(BOTAN_HAS_MUTEX_QT)
00029 #include <botan/internal/mux_qt.h>
00030 #endif
00031
00032 #if defined(BOTAN_HAS_ALLOC_MMAP)
00033 #include <botan/internal/mmap_mem.h>
00034 #endif
00035
00036 #if defined(BOTAN_HAS_ENGINE_ASSEMBLER)
00037 #include <botan/internal/asm_engine.h>
00038 #endif
00039
00040 #if defined(BOTAN_HAS_ENGINE_AES_ISA)
00041 #include <botan/internal/aes_isa_engine.h>
00042 #endif
00043
00044 #if defined(BOTAN_HAS_ENGINE_SIMD)
00045 #include <botan/internal/simd_engine.h>
00046 #endif
00047
00048 #if defined(BOTAN_HAS_ENGINE_GNU_MP)
00049 #include <botan/internal/gnump_engine.h>
00050 #endif
00051
00052 #if defined(BOTAN_HAS_ENGINE_OPENSSL)
00053 #include <botan/internal/openssl_engine.h>
00054 #endif
00055
00056 namespace Botan {
00057
00058
00059
00060
00061 Mutex* Library_State::get_mutex() const
00062 {
00063 return mutex_factory->make();
00064 }
00065
00066
00067
00068
00069 Allocator* Library_State::get_allocator(const std::string& type) const
00070 {
00071 Mutex_Holder lock(allocator_lock);
00072
00073 if(type != "")
00074 return search_map<std::string, Allocator*>(alloc_factory, type, 0);
00075
00076 if(!cached_default_allocator)
00077 {
00078 cached_default_allocator =
00079 search_map<std::string, Allocator*>(alloc_factory,
00080 default_allocator_name, 0);
00081 }
00082
00083 return cached_default_allocator;
00084 }
00085
00086
00087
00088
00089 void Library_State::add_allocator(Allocator* allocator)
00090 {
00091 Mutex_Holder lock(allocator_lock);
00092
00093 allocator->init();
00094
00095 allocators.push_back(allocator);
00096 alloc_factory[allocator->type()] = allocator;
00097 }
00098
00099
00100
00101
00102 void Library_State::set_default_allocator(const std::string& type)
00103 {
00104 Mutex_Holder lock(allocator_lock);
00105
00106 if(type == "")
00107 return;
00108
00109 default_allocator_name = type;
00110 cached_default_allocator = 0;
00111 }
00112
00113
00114
00115
00116 std::string Library_State::get(const std::string& section,
00117 const std::string& key) const
00118 {
00119 Mutex_Holder lock(config_lock);
00120
00121 return search_map<std::string, std::string>(config,
00122 section + "/" + key, "");
00123 }
00124
00125
00126
00127
00128 bool Library_State::is_set(const std::string& section,
00129 const std::string& key) const
00130 {
00131 Mutex_Holder lock(config_lock);
00132
00133 return search_map(config, section + "/" + key, false, true);
00134 }
00135
00136
00137
00138
00139 void Library_State::set(const std::string& section, const std::string& key,
00140 const std::string& value, bool overwrite)
00141 {
00142 Mutex_Holder lock(config_lock);
00143
00144 std::string full_key = section + "/" + key;
00145
00146 std::map<std::string, std::string>::const_iterator i =
00147 config.find(full_key);
00148
00149 if(overwrite || i == config.end() || i->second == "")
00150 config[full_key] = value;
00151 }
00152
00153
00154
00155
00156 void Library_State::add_alias(const std::string& key, const std::string& value)
00157 {
00158 set("alias", key, value);
00159 }
00160
00161
00162
00163
00164 std::string Library_State::deref_alias(const std::string& key) const
00165 {
00166 std::string result = key;
00167 while(is_set("alias", result))
00168 result = get("alias", result);
00169 return result;
00170 }
00171
00172
00173
00174
00175 Algorithm_Factory& Library_State::algorithm_factory() const
00176 {
00177 if(!m_algorithm_factory)
00178 throw Invalid_State("Uninitialized in Library_State::algorithm_factory");
00179 return *m_algorithm_factory;
00180 }
00181
00182
00183
00184
00185 RandomNumberGenerator& Library_State::global_rng()
00186 {
00187 Mutex_Holder lock(global_rng_lock);
00188
00189 if(!global_rng_ptr)
00190 global_rng_ptr = make_global_rng(algorithm_factory(),
00191 global_rng_lock);
00192
00193 return *global_rng_ptr;
00194 }
00195
00196
00197
00198
00199 void Library_State::initialize(bool thread_safe)
00200 {
00201 CPUID::initialize();
00202
00203 if(mutex_factory)
00204 throw Invalid_State("Library_State has already been initialized");
00205
00206 if(!thread_safe)
00207 {
00208 mutex_factory = new Noop_Mutex_Factory;
00209 }
00210 else
00211 {
00212 #if defined(BOTAN_HAS_MUTEX_PTHREAD)
00213 mutex_factory = new Pthread_Mutex_Factory;
00214 #elif defined(BOTAN_HAS_MUTEX_WIN32)
00215 mutex_factory = new Win32_Mutex_Factory;
00216 #elif defined(BOTAN_HAS_MUTEX_QT)
00217 mutex_factory Qt_Mutex_Factory;
00218 #else
00219 throw Invalid_State("Could not find a thread-safe mutex object to use");
00220 #endif
00221 }
00222
00223 allocator_lock = get_mutex();
00224 config_lock = get_mutex();
00225 global_rng_lock = get_mutex();
00226
00227 default_allocator_name = has_mlock() ? "locking" : "malloc";
00228
00229 add_allocator(new Malloc_Allocator);
00230 add_allocator(new Locking_Allocator(get_mutex()));
00231
00232 #if defined(BOTAN_HAS_ALLOC_MMAP)
00233 add_allocator(new MemoryMapping_Allocator(get_mutex()));
00234 #endif
00235
00236 load_default_config();
00237
00238 m_algorithm_factory = new Algorithm_Factory(*mutex_factory);
00239
00240 #if defined(BOTAN_HAS_ENGINE_GNU_MP)
00241 algorithm_factory().add_engine(new GMP_Engine);
00242 #endif
00243
00244 #if defined(BOTAN_HAS_ENGINE_OPENSSL)
00245 algorithm_factory().add_engine(new OpenSSL_Engine);
00246 #endif
00247
00248 #if defined(BOTAN_HAS_ENGINE_AES_ISA)
00249 algorithm_factory().add_engine(new AES_ISA_Engine);
00250 #endif
00251
00252 #if defined(BOTAN_HAS_ENGINE_SIMD)
00253 algorithm_factory().add_engine(new SIMD_Engine);
00254 #endif
00255
00256 #if defined(BOTAN_HAS_ENGINE_ASSEMBLER)
00257 algorithm_factory().add_engine(new Assembler_Engine);
00258 #endif
00259
00260 algorithm_factory().add_engine(new Core_Engine);
00261
00262 #if defined(BOTAN_HAS_SELFTESTS)
00263 confirm_startup_self_tests(algorithm_factory());
00264 #endif
00265 }
00266
00267
00268
00269
00270 Library_State::Library_State()
00271 {
00272 mutex_factory = 0;
00273 allocator_lock = config_lock = 0;
00274 cached_default_allocator = 0;
00275 m_algorithm_factory = 0;
00276
00277 global_rng_lock = 0;
00278 global_rng_ptr = 0;
00279 }
00280
00281
00282
00283
00284 Library_State::~Library_State()
00285 {
00286 delete m_algorithm_factory;
00287 delete global_rng_ptr;
00288
00289 cached_default_allocator = 0;
00290
00291 for(u32bit j = 0; j != allocators.size(); ++j)
00292 {
00293 allocators[j]->destroy();
00294 delete allocators[j];
00295 }
00296
00297 delete global_rng_lock;
00298 delete allocator_lock;
00299 delete mutex_factory;
00300 delete config_lock;
00301 }
00302
00303 }