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
54namespace Botan {
55
56/*
57* Get a new mutex object
58*/
60 {
61 return mutex_factory->make();
62 }
63
64/*
65* Get an allocator by its name
66*/
67Allocator* 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 =
78 default_allocator_name, 0);
79 }
80
81 return cached_default_allocator;
82 }
83
84/*
85* Create a new name to object mapping
86*/
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*/
100void 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*/
114std::string Library_State::get(const std::string& section,
115 const std::string& key) const
116 {
117 Mutex_Holder lock(config_lock);
118
120 section + "/" + key, "");
121 }
122
123/*
124* See if a particular option has been set
125*/
126bool 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*/
137void 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*/
154void 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*/
162std::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*/
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*/
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*/
197void Library_State::initialize(bool thread_safe)
198 {
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
227
228#if defined(BOTAN_HAS_ALLOC_MMAP)
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)
238#endif
239
240#if defined(BOTAN_HAS_ENGINE_OPENSSL)
242#endif
243
244#if defined(BOTAN_HAS_ENGINE_AES_ISA)
246#endif
247
248#if defined(BOTAN_HAS_ENGINE_SIMD)
250#endif
251
252#if defined(BOTAN_HAS_ENGINE_ASSEMBLER)
254#endif
255
257
258#if defined(BOTAN_HAS_SELFTESTS)
260#endif
261 }
262
263/*
264* Library_State Constructor
265*/
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*/
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}
void add_engine(Engine *engine)
Algorithm_Factory(Mutex_Factory &mf)
virtual void init()
Definition allocate.h:53
virtual std::string type() const =0
static void initialize()
Definition cpuid.cpp:196
Algorithm_Factory & algorithm_factory() const
Definition libstate.cpp:173
RandomNumberGenerator & global_rng()
Definition libstate.cpp:183
void set_default_allocator(const std::string &name)
Definition libstate.cpp:100
void add_alias(const std::string &key, const std::string &value)
Definition libstate.cpp:154
bool is_set(const std::string &section, const std::string &key) const
Definition libstate.cpp:126
void add_allocator(Allocator *alloc)
Definition libstate.cpp:87
Allocator * get_allocator(const std::string &name="") const
Definition libstate.cpp:67
std::string deref_alias(const std::string &alias) const
Definition libstate.cpp:162
void initialize(bool thread_safe)
Definition libstate.cpp:197
Mutex * get_mutex() const
Definition libstate.cpp:59
std::string get(const std::string &section, const std::string &key) const
Definition libstate.cpp:114
void set(const std::string &section, const std::string &key, const std::string &value, bool overwrite=true)
Definition libstate.cpp:137
Locking_Allocator(Mutex *mutex)
Definition defalloc.h:36
MemoryMapping_Allocator(Mutex *mutex)
Definition mmap_mem.h:27
bool has_mlock()
Definition mlock.cpp:19
V search_map(const std::map< K, V > &mapping, const K &key, const V &null_result=V())
Definition stl_util.h:43
void confirm_startup_self_tests(Algorithm_Factory &af)
Definition selftest.cpp:226
Invalid_State(const std::string &err)
Definition exceptn.h:27