1
/*************************************************
2
* Library Internal/Global State Source File *
3
* (C) 1999-2007 The Botan Project *
4
*************************************************/
6
#include <botan/libstate.h>
7
#include <botan/config.h>
8
#include <botan/modules.h>
9
#include <botan/engine.h>
10
#include <botan/x509stat.h>
11
#include <botan/stl_util.h>
12
#include <botan/mutex.h>
13
#include <botan/timers.h>
14
#include <botan/charset.h>
19
/*************************************************
20
* Botan's global state *
21
*************************************************/
24
Library_State* global_lib_state = 0;
28
/*************************************************
29
* Access the global state object *
30
*************************************************/
31
Library_State& global_state()
34
throw Invalid_State("Library was not initialized correctly");
35
return (*global_lib_state);
38
/*************************************************
39
* Set a new global state object *
40
*************************************************/
41
void set_global_state(Library_State* new_state)
43
delete swap_global_state(new_state);
46
/*************************************************
47
* Swap two global state objects *
48
*************************************************/
49
Library_State* swap_global_state(Library_State* new_state)
51
Library_State* old_state = global_lib_state;
52
global_lib_state = new_state;
56
/*************************************************
57
* Increment the Engine iterator *
58
*************************************************/
59
Engine* Library_State::Engine_Iterator::next()
61
return lib.get_engine_n(n++);
64
/*************************************************
65
* Get a new mutex object *
66
*************************************************/
67
Mutex* Library_State::get_mutex() const
69
return mutex_factory->make();
72
/*************************************************
73
* Get a persistent named mutex object *
74
*************************************************/
75
Mutex* Library_State::get_named_mutex(const std::string& name)
77
Mutex* mux = search_map<std::string, Mutex*>(locks, name, 0);
80
return (locks[name] = get_mutex());
83
/*************************************************
84
* Get an allocator by its name *
85
*************************************************/
86
Allocator* Library_State::get_allocator(const std::string& type) const
88
Named_Mutex_Holder lock("allocator");
91
return search_map<std::string, Allocator*>(alloc_factory, type, 0);
93
if(!cached_default_allocator)
95
std::string chosen = config().option("base/default_allocator");
100
cached_default_allocator =
101
search_map<std::string, Allocator*>(alloc_factory, chosen, 0);
104
return cached_default_allocator;
107
/*************************************************
108
* Create a new name to object mapping *
109
*************************************************/
110
void Library_State::add_allocator(Allocator* allocator)
112
Named_Mutex_Holder lock("allocator");
116
allocators.push_back(allocator);
117
alloc_factory[allocator->type()] = allocator;
120
/*************************************************
121
* Set the default allocator type *
122
*************************************************/
123
void Library_State::set_default_allocator(const std::string& type) const
125
Named_Mutex_Holder lock("allocator");
130
config().set("conf", "base/default_allocator", type);
131
cached_default_allocator = 0;
134
/*************************************************
135
* Set the high resolution clock implementation *
136
*************************************************/
137
void Library_State::set_timer(Timer* new_timer)
146
/*************************************************
147
* Read a high resolution clock *
148
*************************************************/
149
u64bit Library_State::system_clock() const
151
return (timer) ? timer->clock() : 0;
154
/*************************************************
155
* Set the global PRNG *
156
*************************************************/
157
void Library_State::set_prng(RandomNumberGenerator* new_rng)
159
Named_Mutex_Holder lock("rng");
165
/*************************************************
166
* Get bytes from the global PRNG *
167
*************************************************/
168
void Library_State::randomize(byte out[], u32bit length)
170
Named_Mutex_Holder lock("rng");
172
rng->randomize(out, length);
175
/*************************************************
176
* Add a new entropy source to use *
177
*************************************************/
178
void Library_State::add_entropy_source(EntropySource* src, bool last_in_list)
180
Named_Mutex_Holder lock("rng");
183
entropy_sources.push_back(src);
185
entropy_sources.insert(entropy_sources.begin(), src);
188
/*************************************************
189
* Add some bytes of entropy to the global PRNG *
190
*************************************************/
191
void Library_State::add_entropy(const byte in[], u32bit length)
193
Named_Mutex_Holder lock("rng");
195
rng->add_entropy(in, length);
198
/*************************************************
199
* Add some bytes of entropy to the global PRNG *
200
*************************************************/
201
void Library_State::add_entropy(EntropySource& source, bool slow_poll)
203
Named_Mutex_Holder lock("rng");
205
rng->add_entropy(source, slow_poll);
208
/*************************************************
209
* Gather entropy for our PRNG object *
210
*************************************************/
211
u32bit Library_State::seed_prng(bool slow_poll, u32bit bits_to_get)
213
Named_Mutex_Holder lock("rng");
216
for(u32bit j = 0; j != entropy_sources.size(); ++j)
218
bits += rng->add_entropy(*(entropy_sources[j]), slow_poll);
220
if(bits_to_get && bits >= bits_to_get)
227
/*************************************************
228
* Get an engine out of the list *
229
*************************************************/
230
Engine* Library_State::get_engine_n(u32bit n) const
232
Named_Mutex_Holder lock("engine");
234
if(n >= engines.size())
239
/*************************************************
240
* Add a new engine to the list *
241
*************************************************/
242
void Library_State::add_engine(Engine* engine)
244
Named_Mutex_Holder lock("engine");
245
engines.insert(engines.begin(), engine);
248
/*************************************************
249
* Set the character set transcoder object *
250
*************************************************/
251
void Library_State::set_transcoder(class Charset_Transcoder* transcoder)
254
delete this->transcoder;
255
this->transcoder = transcoder;
258
/*************************************************
259
* Transcode a string from one charset to another *
260
*************************************************/
261
std::string Library_State::transcode(const std::string str,
263
Character_Set from) const
266
throw Invalid_State("Library_State::transcode: No transcoder set");
268
return transcoder->transcode(str, to, from);
271
/*************************************************
272
* Set the X509 global state class *
273
*************************************************/
274
void Library_State::set_x509_state(X509_GlobalState* new_x509_state_obj)
276
delete x509_state_obj;
277
x509_state_obj = new_x509_state_obj;
280
/*************************************************
281
* Get the X509 global state class *
282
*************************************************/
283
X509_GlobalState& Library_State::x509_state()
286
x509_state_obj = new X509_GlobalState();
288
return (*x509_state_obj);
291
/*************************************************
292
* Set the UI object state *
293
*************************************************/
294
void Library_State::set_ui(UI* new_ui)
300
/*************************************************
301
* Send a pulse to the UI object *
302
*************************************************/
303
void Library_State::pulse(Pulse_Type pulse_type) const
306
ui->pulse(pulse_type);
309
/*************************************************
310
* Set the configuration object *
311
*************************************************/
312
Config& Library_State::config() const
315
throw Invalid_State("Library_State::config(): No config set");
317
return (*config_obj);
320
/*************************************************
322
*************************************************/
323
void Library_State::load(Modules& modules)
325
set_timer(modules.timer());
326
set_transcoder(modules.transcoder());
328
std::vector<Allocator*> mod_allocs = modules.allocators();
329
for(u32bit j = 0; j != mod_allocs.size(); j++)
330
add_allocator(mod_allocs[j]);
332
set_default_allocator(modules.default_allocator());
334
std::vector<Engine*> mod_engines = modules.engines();
335
for(u32bit j = 0; j != mod_engines.size(); ++j)
337
Named_Mutex_Holder lock("engine");
338
engines.push_back(mod_engines[j]);
341
std::vector<EntropySource*> sources = modules.entropy_sources();
342
for(u32bit j = 0; j != sources.size(); ++j)
343
add_entropy_source(sources[j]);
346
/*************************************************
347
* Library_State Constructor *
348
*************************************************/
349
Library_State::Library_State(Mutex_Factory* mutex_factory)
352
throw Exception("Library_State: no mutex found");
354
this->mutex_factory = mutex_factory;
355
this->timer = new Timer();
356
this->transcoder = 0;
357
this->config_obj = new Config();
359
locks["settings"] = get_mutex();
360
locks["allocator"] = get_mutex();
361
locks["rng"] = get_mutex();
362
locks["engine"] = get_mutex();
364
cached_default_allocator = 0;
369
/*************************************************
370
* Library_State Destructor *
371
*************************************************/
372
Library_State::~Library_State()
374
delete x509_state_obj;
381
std::for_each(entropy_sources.begin(), entropy_sources.end(),
382
del_fun<EntropySource>());
383
std::for_each(engines.begin(), engines.end(), del_fun<Engine>());
385
cached_default_allocator = 0;
387
for(u32bit j = 0; j != allocators.size(); j++)
389
allocators[j]->destroy();
390
delete allocators[j];
393
std::for_each(locks.begin(), locks.end(),
394
delete2nd<std::map<std::string, Mutex*>::value_type>);
396
delete mutex_factory;