Botan: src/libstate/libstate.cpp Source File

Botan 1.10.17

libstate.cpp
Go to the documentation of this file.
1 /*
2 * Library Internal/Global State
3 * (C) 1999-2010 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7
8 #include <botan/libstate.h>
9 #include <botan/charset.h>
10 #include <botan/engine.h>
11 #include <botan/cpuid.h>
12 #include <botan/internal/defalloc.h>
13 #include <botan/internal/core_engine.h>
14 #include <botan/internal/mutex.h>
15 #include <botan/internal/mux_noop.h>
16 #include <botan/internal/stl_util.h>
17 #include <botan/internal/mlock.h>
18 #include <algorithm>
19
20 #if defined(BOTAN_HAS_SELFTESTS)
21 #include <botan/selftest.h>
22 #endif
23
24 #if defined(BOTAN_HAS_MUTEX_PTHREAD)
25 #include <botan/internal/mux_pthr.h>
26 #elif defined(BOTAN_HAS_MUTEX_WIN32)
27 #include <botan/internal/mux_win32.h>
28 #endif
29
30 #if defined(BOTAN_HAS_ALLOC_MMAP)
31 #include <botan/internal/mmap_mem.h>
32 #endif
33
34 #if defined(BOTAN_HAS_ENGINE_ASSEMBLER)
35 #include <botan/internal/asm_engine.h>
36 #endif
37
38 #if defined(BOTAN_HAS_ENGINE_AES_ISA)
39 #include <botan/internal/aes_isa_engine.h>
40 #endif
41
42 #if defined(BOTAN_HAS_ENGINE_SIMD)
43 #include <botan/internal/simd_engine.h>
44 #endif
45
46 #if defined(BOTAN_HAS_ENGINE_GNU_MP)
47 #include <botan/internal/gnump_engine.h>
48 #endif
49
50 #if defined(BOTAN_HAS_ENGINE_OPENSSL)
51 #include <botan/internal/openssl_engine.h>
52 #endif
53
54 namespace Botan {
55
56 /*
57 * Get a new mutex object
58 */
59 Mutex* Library_State::get_mutex() const
60 {
61 return mutex_factory->make();
62 }
63
64 /*
65 * Get an allocator by its name
66 */
67 Allocator* Library_State::get_allocator(const std::string& type) const
68 {
69 Mutex_Holder lock(allocator_lock);
70
71 if(type != "")
72 return search_map<std::string, Allocator*>(alloc_factory, type, 0);
73
74 if(!cached_default_allocator)
75 {
76 cached_default_allocator =
77 search_map<std::string, Allocator*>(alloc_factory,
78 default_allocator_name, 0);
79 }
80
81 return cached_default_allocator;
82 }
83
84 /*
85 * Create a new name to object mapping
86 */
87 void Library_State::add_allocator(Allocator* allocator)
88 {
89 Mutex_Holder lock(allocator_lock);
90
91 allocator->init();
92
93 allocators.push_back(allocator);
94 alloc_factory[allocator->type()] = allocator;
95 }
96
97 /*
98 * Set the default allocator type
99 */
100 void Library_State::set_default_allocator(const std::string& type)
101 {
102 Mutex_Holder lock(allocator_lock);
103
104 if(type == "")
105 return;
106
107 default_allocator_name = type;
108 cached_default_allocator = 0;
109 }
110
111 /*
112 * Get a configuration value
113 */
114 std::string Library_State::get(const std::string& section,
115 const std::string& key) const
116 {
117 Mutex_Holder lock(config_lock);
118
119 return search_map<std::string, std::string>(config,
120 section + "/" + key, "");
121 }
122
123 /*
124 * See if a particular option has been set
125 */
126 bool Library_State::is_set(const std::string& section,
127 const std::string& key) const
128 {
129 Mutex_Holder lock(config_lock);
130
131 return config.count(section + "/" + key) != 0;
132 }
133
134 /*
135 * Set a configuration value
136 */
137 void Library_State::set(const std::string& section, const std::string& key,
138 const std::string& value, bool overwrite)
139 {
140 Mutex_Holder lock(config_lock);
141
142 std::string full_key = section + "/" + key;
143
144 std::map<std::string, std::string>::const_iterator i =
145 config.find(full_key);
146
147 if(overwrite || i == config.end() || i->second == "")
148 config[full_key] = value;
149 }
150
151 /*
152 * Add an alias
153 */
154 void Library_State::add_alias(const std::string& key, const std::string& value)
155 {
156 set("alias", key, value);
157 }
158
159 /*
160 * Dereference an alias to a fixed name
161 */
162 std::string Library_State::deref_alias(const std::string& key) const
163 {
164 std::string result = key;
165 while(is_set("alias", result))
166 result = get("alias", result);
167 return result;
168 }
169
170 /*
171 * Return a reference to the Algorithm_Factory
172 */
173 Algorithm_Factory& Library_State::algorithm_factory() const
174 {
175 if(!m_algorithm_factory)
176 throw Invalid_State("Uninitialized in Library_State::algorithm_factory");
177 return *m_algorithm_factory;
178 }
179
180 /*
181 * Return a reference to the global PRNG
182 */
183 RandomNumberGenerator& Library_State::global_rng()
184 {
185 Mutex_Holder lock(global_rng_lock);
186
187 if(!global_rng_ptr)
188 global_rng_ptr = make_global_rng(algorithm_factory(),
189 global_rng_lock);
190
191 return *global_rng_ptr;
192 }
193
194 /*
195 * Load a set of modules
196 */
197 void Library_State::initialize(bool thread_safe)
198 {
199 CPUID::initialize();
200
201 if(mutex_factory)
202 throw Invalid_State("Library_State has already been initialized");
203
204 if(!thread_safe)
205 {
206 mutex_factory = new Noop_Mutex_Factory;
207 }
208 else
209 {
210 #if defined(BOTAN_HAS_MUTEX_PTHREAD)
211 mutex_factory = new Pthread_Mutex_Factory;
212 #elif defined(BOTAN_HAS_MUTEX_WIN32)
213 mutex_factory = new Win32_Mutex_Factory;
214 #else
215 throw Invalid_State("Could not find a thread-safe mutex object to use");
216 #endif
217 }
218
219 allocator_lock = get_mutex();
220 config_lock = get_mutex();
221 global_rng_lock = get_mutex();
222
223 default_allocator_name = has_mlock() ? "locking" : "malloc";
224
225 add_allocator(new Malloc_Allocator);
226 add_allocator(new Locking_Allocator(get_mutex()));
227
228 #if defined(BOTAN_HAS_ALLOC_MMAP)
229 add_allocator(new MemoryMapping_Allocator(get_mutex()));
230 #endif
231
232 load_default_config();
233
234 m_algorithm_factory = new Algorithm_Factory(*mutex_factory);
235
236 #if defined(BOTAN_HAS_ENGINE_GNU_MP)
237 algorithm_factory().add_engine(new GMP_Engine);
238 #endif
239
240 #if defined(BOTAN_HAS_ENGINE_OPENSSL)
241 algorithm_factory().add_engine(new OpenSSL_Engine);
242 #endif
243
244 #if defined(BOTAN_HAS_ENGINE_AES_ISA)
245 algorithm_factory().add_engine(new AES_ISA_Engine);
246 #endif
247
248 #if defined(BOTAN_HAS_ENGINE_SIMD)
249 algorithm_factory().add_engine(new SIMD_Engine);
250 #endif
251
252 #if defined(BOTAN_HAS_ENGINE_ASSEMBLER)
253 algorithm_factory().add_engine(new Assembler_Engine);
254 #endif
255
256 algorithm_factory().add_engine(new Core_Engine);
257
258 #if defined(BOTAN_HAS_SELFTESTS)
259 confirm_startup_self_tests(algorithm_factory());
260 #endif
261 }
262
263 /*
264 * Library_State Constructor
265 */
266 Library_State::Library_State()
267 {
268 mutex_factory = 0;
269 allocator_lock = config_lock = 0;
270 cached_default_allocator = 0;
271 m_algorithm_factory = 0;
272
273 global_rng_lock = 0;
274 global_rng_ptr = 0;
275 }
276
277 /*
278 * Library_State Destructor
279 */
280 Library_State::~Library_State()
281 {
282 delete m_algorithm_factory;
283 delete global_rng_ptr;
284
285 cached_default_allocator = 0;
286
287 for(size_t i = 0; i != allocators.size(); ++i)
288 {
289 allocators[i]->destroy();
290 delete allocators[i];
291 }
292
293 delete global_rng_lock;
294 delete allocator_lock;
295 delete mutex_factory;
296 delete config_lock;
297 }
298
299 }
Botan::Locking_Allocator
Definition: defalloc.h:30
Botan::Library_State::global_rng
RandomNumberGenerator & global_rng()
Definition: libstate.cpp:183
Botan::Algorithm_Factory
Definition: algo_factory.h:34
Botan::RandomNumberGenerator
Definition: rng.h:20
Botan::Library_State::algorithm_factory
Algorithm_Factory & algorithm_factory() const
Definition: libstate.cpp:173
Botan::Allocator
Definition: allocate.h:19
Botan::confirm_startup_self_tests
void confirm_startup_self_tests(Algorithm_Factory &af)
Definition: selftest.cpp:226
Botan::Invalid_State
Definition: exceptn.h:25
Botan::Library_State::is_set
bool is_set(const std::string &section, const std::string &key) const
Definition: libstate.cpp:126
Botan::has_mlock
bool has_mlock()
Definition: mlock.cpp:19
Botan::Library_State::set_default_allocator
void set_default_allocator(const std::string &name)
Definition: libstate.cpp:100
Botan::Library_State::get_allocator
Allocator * get_allocator(const std::string &name="") const
Definition: libstate.cpp:67
Botan::Mutex_Factory::make
virtual Mutex * make()=0
Botan::SIMD_Engine
Definition: simd_engine.h:18
Botan::Allocator::init
virtual void init()
Definition: allocate.h:53
Botan::Library_State::initialize
void initialize(bool thread_safe)
Definition: libstate.cpp:197
Botan::Win32_Mutex_Factory
Definition: mux_win32.h:19
Botan::Noop_Mutex_Factory
Definition: mux_noop.h:18
Botan::Library_State::get
std::string get(const std::string &section, const std::string &key) const
Definition: libstate.cpp:114
Botan::OpenSSL_Engine
Definition: openssl_engine.h:18
Botan
Definition: algo_base.h:14
Botan::Allocator::type
virtual std::string type() const =0
Botan::AES_ISA_Engine
Definition: aes_isa_engine.h:19
Botan::Mutex
Definition: mutex.h:18
Botan::Mutex_Holder
Definition: mutex.h:50
Botan::Library_State::add_allocator
void add_allocator(Allocator *alloc)
Definition: libstate.cpp:87
Botan::GMP_Engine
Definition: gnump_engine.h:18
Botan::Algorithm_Factory::add_engine
void add_engine(Engine *engine)
Definition: algo_factory.cpp:129
Botan::Library_State::deref_alias
std::string deref_alias(const std::string &alias) const
Definition: libstate.cpp:162
Botan::CPUID::initialize
static void initialize()
Definition: cpuid.cpp:196
Botan::Assembler_Engine
Definition: asm_engine.h:18
Botan::Malloc_Allocator
Definition: defalloc.h:18
Botan::Library_State::set
void set(const std::string &section, const std::string &key, const std::string &value, bool overwrite=true)
Definition: libstate.cpp:137
Botan::Pthread_Mutex_Factory
Definition: mux_pthr.h:18
Botan::Library_State::add_alias
void add_alias(const std::string &key, const std::string &value)
Definition: libstate.cpp:154
Botan::Library_State::Library_State
Library_State()
Definition: libstate.cpp:266
Botan::MemoryMapping_Allocator
Definition: mmap_mem.h:21
Botan::Core_Engine
Definition: core_engine.h:18
Botan::Library_State::~Library_State
~Library_State()
Definition: libstate.cpp:280
Botan::Library_State::get_mutex
Mutex * get_mutex() const
Definition: libstate.cpp:59