Botan  1.10.9
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 */
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 */
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 */
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 */
197 void 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 }
RandomNumberGenerator & global_rng()
Definition: libstate.cpp:183
void confirm_startup_self_tests(Algorithm_Factory &af)
Definition: selftest.cpp:226
bool has_mlock()
Definition: mlock.cpp:19
void set_default_allocator(const std::string &name)
Definition: libstate.cpp:100
Mutex * get_mutex() const
Definition: libstate.cpp:59
Algorithm_Factory & algorithm_factory() const
Definition: libstate.cpp:173
virtual Mutex * make()=0
virtual void init()
Definition: allocate.h:53
Allocator * get_allocator(const std::string &name="") const
Definition: libstate.cpp:67
void initialize(bool thread_safe)
Definition: libstate.cpp:197
bool is_set(const std::string &section, const std::string &key) const
Definition: libstate.cpp:126
std::string deref_alias(const std::string &alias) const
Definition: libstate.cpp:162
virtual std::string type() const =0
void add_allocator(Allocator *alloc)
Definition: libstate.cpp:87
void add_engine(Engine *engine)
static void initialize()
Definition: cpuid.cpp:190
void set(const std::string &section, const std::string &key, const std::string &value, bool overwrite=true)
Definition: libstate.cpp:137
void add_alias(const std::string &key, const std::string &value)
Definition: libstate.cpp:154
std::string get(const std::string &section, const std::string &key) const
Definition: libstate.cpp:114