~ubuntu-branches/debian/sid/botan/sid

« back to all changes in this revision

Viewing changes to src/libstate.cpp

  • Committer: Package Import Robot
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2018-03-01 22:23:25 UTC
  • mfrom: (1.2.2)
  • Revision ID: package-import@ubuntu.com-20180301222325-7p7vc45gu3hta34d
Tags: 2.4.0-2
* Don't remove .doctrees from the manual if it doesn't exist.
* Don't specify parallel to debhelper.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*************************************************
2
 
* Library Internal/Global State Source File      *
3
 
* (C) 1999-2007 The Botan Project                *
4
 
*************************************************/
5
 
 
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>
15
 
#include <algorithm>
16
 
 
17
 
namespace Botan {
18
 
 
19
 
/*************************************************
20
 
* Botan's global state                           *
21
 
*************************************************/
22
 
namespace {
23
 
 
24
 
Library_State* global_lib_state = 0;
25
 
 
26
 
}
27
 
 
28
 
/*************************************************
29
 
* Access the global state object                 *
30
 
*************************************************/
31
 
Library_State& global_state()
32
 
   {
33
 
   if(!global_lib_state)
34
 
      throw Invalid_State("Library was not initialized correctly");
35
 
   return (*global_lib_state);
36
 
   }
37
 
 
38
 
/*************************************************
39
 
* Set a new global state object                  *
40
 
*************************************************/
41
 
void set_global_state(Library_State* new_state)
42
 
   {
43
 
   delete swap_global_state(new_state);
44
 
   }
45
 
 
46
 
/*************************************************
47
 
* Swap two global state objects                  *
48
 
*************************************************/
49
 
Library_State* swap_global_state(Library_State* new_state)
50
 
   {
51
 
   Library_State* old_state = global_lib_state;
52
 
   global_lib_state = new_state;
53
 
   return old_state;
54
 
   }
55
 
 
56
 
/*************************************************
57
 
* Increment the Engine iterator                  *
58
 
*************************************************/
59
 
Engine* Library_State::Engine_Iterator::next()
60
 
   {
61
 
   return lib.get_engine_n(n++);
62
 
   }
63
 
 
64
 
/*************************************************
65
 
* Get a new mutex object                         *
66
 
*************************************************/
67
 
Mutex* Library_State::get_mutex() const
68
 
   {
69
 
   return mutex_factory->make();
70
 
   }
71
 
 
72
 
/*************************************************
73
 
* Get a persistent named mutex object            *
74
 
*************************************************/
75
 
Mutex* Library_State::get_named_mutex(const std::string& name)
76
 
   {
77
 
   Mutex* mux = search_map<std::string, Mutex*>(locks, name, 0);
78
 
   if(mux)
79
 
      return mux;
80
 
   return (locks[name] = get_mutex());
81
 
   }
82
 
 
83
 
/*************************************************
84
 
* Get an allocator by its name                   *
85
 
*************************************************/
86
 
Allocator* Library_State::get_allocator(const std::string& type) const
87
 
   {
88
 
   Named_Mutex_Holder lock("allocator");
89
 
 
90
 
   if(type != "")
91
 
      return search_map<std::string, Allocator*>(alloc_factory, type, 0);
92
 
 
93
 
   if(!cached_default_allocator)
94
 
      {
95
 
      std::string chosen = config().option("base/default_allocator");
96
 
 
97
 
      if(chosen == "")
98
 
         chosen = "malloc";
99
 
 
100
 
      cached_default_allocator =
101
 
         search_map<std::string, Allocator*>(alloc_factory, chosen, 0);
102
 
      }
103
 
 
104
 
   return cached_default_allocator;
105
 
   }
106
 
 
107
 
/*************************************************
108
 
* Create a new name to object mapping            *
109
 
*************************************************/
110
 
void Library_State::add_allocator(Allocator* allocator)
111
 
   {
112
 
   Named_Mutex_Holder lock("allocator");
113
 
 
114
 
   allocator->init();
115
 
 
116
 
   allocators.push_back(allocator);
117
 
   alloc_factory[allocator->type()] = allocator;
118
 
   }
119
 
 
120
 
/*************************************************
121
 
* Set the default allocator type                 *
122
 
*************************************************/
123
 
void Library_State::set_default_allocator(const std::string& type) const
124
 
   {
125
 
   Named_Mutex_Holder lock("allocator");
126
 
 
127
 
   if(type == "")
128
 
      return;
129
 
 
130
 
   config().set("conf", "base/default_allocator", type);
131
 
   cached_default_allocator = 0;
132
 
   }
133
 
 
134
 
/*************************************************
135
 
* Set the high resolution clock implementation   *
136
 
*************************************************/
137
 
void Library_State::set_timer(Timer* new_timer)
138
 
   {
139
 
   if(new_timer)
140
 
      {
141
 
      delete timer;
142
 
      timer = new_timer;
143
 
      }
144
 
   }
145
 
 
146
 
/*************************************************
147
 
* Read a high resolution clock                   *
148
 
*************************************************/
149
 
u64bit Library_State::system_clock() const
150
 
   {
151
 
   return (timer) ? timer->clock() : 0;
152
 
   }
153
 
 
154
 
/*************************************************
155
 
* Set the global PRNG                            *
156
 
*************************************************/
157
 
void Library_State::set_prng(RandomNumberGenerator* new_rng)
158
 
   {
159
 
   Named_Mutex_Holder lock("rng");
160
 
 
161
 
   delete rng;
162
 
   rng = new_rng;
163
 
   }
164
 
 
165
 
/*************************************************
166
 
* Get bytes from the global PRNG                 *
167
 
*************************************************/
168
 
void Library_State::randomize(byte out[], u32bit length)
169
 
   {
170
 
   Named_Mutex_Holder lock("rng");
171
 
 
172
 
   rng->randomize(out, length);
173
 
   }
174
 
 
175
 
/*************************************************
176
 
* Add a new entropy source to use                *
177
 
*************************************************/
178
 
void Library_State::add_entropy_source(EntropySource* src, bool last_in_list)
179
 
   {
180
 
   Named_Mutex_Holder lock("rng");
181
 
 
182
 
   if(last_in_list)
183
 
      entropy_sources.push_back(src);
184
 
   else
185
 
      entropy_sources.insert(entropy_sources.begin(), src);
186
 
   }
187
 
 
188
 
/*************************************************
189
 
* Add some bytes of entropy to the global PRNG   *
190
 
*************************************************/
191
 
void Library_State::add_entropy(const byte in[], u32bit length)
192
 
   {
193
 
   Named_Mutex_Holder lock("rng");
194
 
 
195
 
   rng->add_entropy(in, length);
196
 
   }
197
 
 
198
 
/*************************************************
199
 
* Add some bytes of entropy to the global PRNG   *
200
 
*************************************************/
201
 
void Library_State::add_entropy(EntropySource& source, bool slow_poll)
202
 
   {
203
 
   Named_Mutex_Holder lock("rng");
204
 
 
205
 
   rng->add_entropy(source, slow_poll);
206
 
   }
207
 
 
208
 
/*************************************************
209
 
* Gather entropy for our PRNG object             *
210
 
*************************************************/
211
 
u32bit Library_State::seed_prng(bool slow_poll, u32bit bits_to_get)
212
 
   {
213
 
   Named_Mutex_Holder lock("rng");
214
 
 
215
 
   u32bit bits = 0;
216
 
   for(u32bit j = 0; j != entropy_sources.size(); ++j)
217
 
      {
218
 
      bits += rng->add_entropy(*(entropy_sources[j]), slow_poll);
219
 
 
220
 
      if(bits_to_get && bits >= bits_to_get)
221
 
         return bits;
222
 
      }
223
 
 
224
 
   return bits;
225
 
   }
226
 
 
227
 
/*************************************************
228
 
* Get an engine out of the list                  *
229
 
*************************************************/
230
 
Engine* Library_State::get_engine_n(u32bit n) const
231
 
   {
232
 
   Named_Mutex_Holder lock("engine");
233
 
 
234
 
   if(n >= engines.size())
235
 
      return 0;
236
 
   return engines[n];
237
 
   }
238
 
 
239
 
/*************************************************
240
 
* Add a new engine to the list                   *
241
 
*************************************************/
242
 
void Library_State::add_engine(Engine* engine)
243
 
   {
244
 
   Named_Mutex_Holder lock("engine");
245
 
   engines.insert(engines.begin(), engine);
246
 
   }
247
 
 
248
 
/*************************************************
249
 
* Set the character set transcoder object        *
250
 
*************************************************/
251
 
void Library_State::set_transcoder(class Charset_Transcoder* transcoder)
252
 
   {
253
 
   if(this->transcoder)
254
 
      delete this->transcoder;
255
 
   this->transcoder = transcoder;
256
 
   }
257
 
 
258
 
/*************************************************
259
 
* Transcode a string from one charset to another *
260
 
*************************************************/
261
 
std::string Library_State::transcode(const std::string str,
262
 
                                     Character_Set to,
263
 
                                     Character_Set from) const
264
 
   {
265
 
   if(!transcoder)
266
 
      throw Invalid_State("Library_State::transcode: No transcoder set");
267
 
 
268
 
   return transcoder->transcode(str, to, from);
269
 
   }
270
 
 
271
 
/*************************************************
272
 
* Set the X509 global state class                *
273
 
*************************************************/
274
 
void Library_State::set_x509_state(X509_GlobalState* new_x509_state_obj)
275
 
   {
276
 
   delete x509_state_obj;
277
 
   x509_state_obj = new_x509_state_obj;
278
 
   }
279
 
 
280
 
/*************************************************
281
 
* Get the X509 global state class                *
282
 
*************************************************/
283
 
X509_GlobalState& Library_State::x509_state()
284
 
   {
285
 
   if(!x509_state_obj)
286
 
      x509_state_obj = new X509_GlobalState();
287
 
 
288
 
   return (*x509_state_obj);
289
 
   }
290
 
 
291
 
/*************************************************
292
 
* Set the UI object state                        *
293
 
*************************************************/
294
 
void Library_State::set_ui(UI* new_ui)
295
 
   {
296
 
   delete ui;
297
 
   ui = new_ui;
298
 
   }
299
 
 
300
 
/*************************************************
301
 
* Send a pulse to the UI object                  *
302
 
*************************************************/
303
 
void Library_State::pulse(Pulse_Type pulse_type) const
304
 
   {
305
 
   if(ui)
306
 
      ui->pulse(pulse_type);
307
 
   }
308
 
 
309
 
/*************************************************
310
 
* Set the configuration object                   *
311
 
*************************************************/
312
 
Config& Library_State::config() const
313
 
   {
314
 
   if(!config_obj)
315
 
      throw Invalid_State("Library_State::config(): No config set");
316
 
 
317
 
   return (*config_obj);
318
 
   }
319
 
 
320
 
/*************************************************
321
 
* Load modules                                   *
322
 
*************************************************/
323
 
void Library_State::load(Modules& modules)
324
 
   {
325
 
   set_timer(modules.timer());
326
 
   set_transcoder(modules.transcoder());
327
 
 
328
 
   std::vector<Allocator*> mod_allocs = modules.allocators();
329
 
   for(u32bit j = 0; j != mod_allocs.size(); j++)
330
 
      add_allocator(mod_allocs[j]);
331
 
 
332
 
   set_default_allocator(modules.default_allocator());
333
 
 
334
 
   std::vector<Engine*> mod_engines = modules.engines();
335
 
   for(u32bit j = 0; j != mod_engines.size(); ++j)
336
 
      {
337
 
      Named_Mutex_Holder lock("engine");
338
 
      engines.push_back(mod_engines[j]);
339
 
      }
340
 
 
341
 
   std::vector<EntropySource*> sources = modules.entropy_sources();
342
 
   for(u32bit j = 0; j != sources.size(); ++j)
343
 
      add_entropy_source(sources[j]);
344
 
   }
345
 
 
346
 
/*************************************************
347
 
* Library_State Constructor                      *
348
 
*************************************************/
349
 
Library_State::Library_State(Mutex_Factory* mutex_factory)
350
 
   {
351
 
   if(!mutex_factory)
352
 
      throw Exception("Library_State: no mutex found");
353
 
 
354
 
   this->mutex_factory = mutex_factory;
355
 
   this->timer = new Timer();
356
 
   this->transcoder = 0;
357
 
   this->config_obj = new Config();
358
 
 
359
 
   locks["settings"] = get_mutex();
360
 
   locks["allocator"] = get_mutex();
361
 
   locks["rng"] = get_mutex();
362
 
   locks["engine"] = get_mutex();
363
 
   rng = 0;
364
 
   cached_default_allocator = 0;
365
 
   x509_state_obj = 0;
366
 
   ui = 0;
367
 
   }
368
 
 
369
 
/*************************************************
370
 
* Library_State Destructor                       *
371
 
*************************************************/
372
 
Library_State::~Library_State()
373
 
   {
374
 
   delete x509_state_obj;
375
 
   delete transcoder;
376
 
   delete rng;
377
 
   delete timer;
378
 
   delete config_obj;
379
 
   delete ui;
380
 
 
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>());
384
 
 
385
 
   cached_default_allocator = 0;
386
 
 
387
 
   for(u32bit j = 0; j != allocators.size(); j++)
388
 
      {
389
 
      allocators[j]->destroy();
390
 
      delete allocators[j];
391
 
      }
392
 
 
393
 
   std::for_each(locks.begin(), locks.end(),
394
 
                 delete2nd<std::map<std::string, Mutex*>::value_type>);
395
 
 
396
 
   delete mutex_factory;
397
 
   }
398
 
 
399
 
}