curl: For SSL features, depend on thread-safety provided by our crypto plugins
[strongswan.git] / src / libstrongswan / plugins / openssl / openssl_plugin.c
1 /*
2 * Copyright (C) 2008-2013 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include <library.h>
18 #include <utils/debug.h>
19 #include <threading/thread.h>
20 #include <threading/mutex.h>
21 #include <threading/thread_value.h>
22
23 #include <openssl/err.h>
24 #include <openssl/evp.h>
25 #include <openssl/conf.h>
26 #include <openssl/rand.h>
27 #include <openssl/crypto.h>
28 #ifndef OPENSSL_NO_ENGINE
29 #include <openssl/engine.h>
30 #endif
31
32 #include "openssl_plugin.h"
33 #include "openssl_util.h"
34 #include "openssl_crypter.h"
35 #include "openssl_hasher.h"
36 #include "openssl_sha1_prf.h"
37 #include "openssl_diffie_hellman.h"
38 #include "openssl_ec_diffie_hellman.h"
39 #include "openssl_rsa_private_key.h"
40 #include "openssl_rsa_public_key.h"
41 #include "openssl_ec_private_key.h"
42 #include "openssl_ec_public_key.h"
43 #include "openssl_x509.h"
44 #include "openssl_crl.h"
45 #include "openssl_pkcs7.h"
46 #include "openssl_pkcs12.h"
47 #include "openssl_rng.h"
48 #include "openssl_hmac.h"
49 #include "openssl_gcm.h"
50
51 #ifndef FIPS_MODE
52 #define FIPS_MODE 0
53 #endif
54
55 typedef struct private_openssl_plugin_t private_openssl_plugin_t;
56
57 /**
58 * private data of openssl_plugin
59 */
60 struct private_openssl_plugin_t {
61
62 /**
63 * public functions
64 */
65 openssl_plugin_t public;
66 };
67
68 /**
69 * Array of static mutexs, with CRYPTO_num_locks() mutex
70 */
71 static mutex_t **mutex = NULL;
72
73 /**
74 * Locking callback for static locks
75 */
76 static void locking_function(int mode, int type, const char *file, int line)
77 {
78 if (mutex)
79 {
80 if (mode & CRYPTO_LOCK)
81 {
82 mutex[type]->lock(mutex[type]);
83 }
84 else
85 {
86 mutex[type]->unlock(mutex[type]);
87 }
88 }
89 }
90
91 /**
92 * Implementation of dynlock
93 */
94 struct CRYPTO_dynlock_value {
95 mutex_t *mutex;
96 };
97
98 /**
99 * Callback to create a dynamic lock
100 */
101 static struct CRYPTO_dynlock_value *create_function(const char *file, int line)
102 {
103 struct CRYPTO_dynlock_value *lock;
104
105 lock = malloc_thing(struct CRYPTO_dynlock_value);
106 lock->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
107 return lock;
108 }
109
110 /**
111 * Callback to (un-)lock a dynamic lock
112 */
113 static void lock_function(int mode, struct CRYPTO_dynlock_value *lock,
114 const char *file, int line)
115 {
116 if (mode & CRYPTO_LOCK)
117 {
118 lock->mutex->lock(lock->mutex);
119 }
120 else
121 {
122 lock->mutex->unlock(lock->mutex);
123 }
124 }
125
126 /**
127 * Callback to destroy a dynamic lock
128 */
129 static void destroy_function(struct CRYPTO_dynlock_value *lock,
130 const char *file, int line)
131 {
132 lock->mutex->destroy(lock->mutex);
133 free(lock);
134 }
135
136 /**
137 * Thread-local value used to cleanup thread-specific error buffers
138 */
139 static thread_value_t *cleanup;
140
141 /**
142 * Called when a thread is destroyed. Avoid recursion by setting the thread id
143 * explicitly.
144 */
145 static void cleanup_thread(void *arg)
146 {
147 #if OPENSSL_VERSION_NUMBER >= 0x1000000fL
148 CRYPTO_THREADID tid;
149
150 CRYPTO_THREADID_set_numeric(&tid, (u_long)(uintptr_t)arg);
151 ERR_remove_thread_state(&tid);
152 #else
153 ERR_remove_state((u_long)(uintptr_t)arg);
154 #endif
155 }
156
157 /**
158 * Thread-ID callback function
159 */
160 static u_long id_function(void)
161 {
162 u_long id;
163
164 /* ensure the thread ID is never zero, otherwise OpenSSL might try to
165 * acquire locks recursively */
166 id = 1 + (u_long)thread_current_id();
167
168 /* cleanup a thread's state later if OpenSSL interacted with it */
169 cleanup->set(cleanup, (void*)(uintptr_t)id);
170 return id;
171 }
172
173 #if OPENSSL_VERSION_NUMBER >= 0x1000000fL
174 /**
175 * Callback for thread ID
176 */
177 static void threadid_function(CRYPTO_THREADID *threadid)
178 {
179 CRYPTO_THREADID_set_numeric(threadid, id_function());
180 }
181 #endif /* OPENSSL_VERSION_NUMBER */
182
183 /**
184 * initialize OpenSSL for multi-threaded use
185 */
186 static void threading_init()
187 {
188 int i, num_locks;
189
190 cleanup = thread_value_create(cleanup_thread);
191
192 #if OPENSSL_VERSION_NUMBER >= 0x1000000fL
193 CRYPTO_THREADID_set_callback(threadid_function);
194 #else
195 CRYPTO_set_id_callback(id_function);
196 #endif
197
198 CRYPTO_set_locking_callback(locking_function);
199
200 CRYPTO_set_dynlock_create_callback(create_function);
201 CRYPTO_set_dynlock_lock_callback(lock_function);
202 CRYPTO_set_dynlock_destroy_callback(destroy_function);
203
204 num_locks = CRYPTO_num_locks();
205 mutex = malloc(sizeof(mutex_t*) * num_locks);
206 for (i = 0; i < num_locks; i++)
207 {
208 mutex[i] = mutex_create(MUTEX_TYPE_DEFAULT);
209 }
210 }
211
212 /**
213 * cleanup OpenSSL threading locks
214 */
215 static void threading_cleanup()
216 {
217 int i, num_locks;
218
219 num_locks = CRYPTO_num_locks();
220 for (i = 0; i < num_locks; i++)
221 {
222 mutex[i]->destroy(mutex[i]);
223 }
224 free(mutex);
225 mutex = NULL;
226
227 cleanup->destroy(cleanup);
228 }
229
230 /**
231 * Seed the OpenSSL RNG, if required
232 */
233 static bool seed_rng()
234 {
235 rng_t *rng = NULL;
236 char buf[32];
237
238 while (RAND_status() != 1)
239 {
240 if (!rng)
241 {
242 rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
243 if (!rng)
244 {
245 return FALSE;
246 }
247 }
248 if (!rng->get_bytes(rng, sizeof(buf), buf))
249 {
250 rng->destroy(rng);
251 return FALSE;
252 }
253 RAND_seed(buf, sizeof(buf));
254 }
255 DESTROY_IF(rng);
256 return TRUE;
257 }
258
259 METHOD(plugin_t, get_name, char*,
260 private_openssl_plugin_t *this)
261 {
262 return "openssl";
263 }
264
265 METHOD(plugin_t, get_features, int,
266 private_openssl_plugin_t *this, plugin_feature_t *features[])
267 {
268 static plugin_feature_t f[] = {
269 /* we provide OpenSSL threading callbacks */
270 PLUGIN_PROVIDE(CUSTOM, "openssl-threading"),
271 /* crypters */
272 PLUGIN_REGISTER(CRYPTER, openssl_crypter_create),
273 #ifndef OPENSSL_NO_AES
274 PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 16),
275 PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 24),
276 PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 32),
277 #endif
278 #ifndef OPENSSL_NO_CAMELLIA
279 PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 16),
280 PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 24),
281 PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 32),
282 #endif
283 #ifndef OPENSSL_NO_RC5
284 PLUGIN_PROVIDE(CRYPTER, ENCR_RC5, 0),
285 #endif
286 #ifndef OPENSSL_NO_CAST
287 PLUGIN_PROVIDE(CRYPTER, ENCR_CAST, 0),
288 #endif
289 #ifndef OPENSSL_NO_BLOWFISH
290 PLUGIN_PROVIDE(CRYPTER, ENCR_BLOWFISH, 0),
291 #endif
292 #ifndef OPENSSL_NO_IDEA
293 PLUGIN_PROVIDE(CRYPTER, ENCR_IDEA, 16),
294 #endif
295 #ifndef OPENSSL_NO_DES
296 PLUGIN_PROVIDE(CRYPTER, ENCR_3DES, 24),
297 PLUGIN_PROVIDE(CRYPTER, ENCR_DES, 8),
298 PLUGIN_PROVIDE(CRYPTER, ENCR_DES_ECB, 8),
299 #endif
300 PLUGIN_PROVIDE(CRYPTER, ENCR_NULL, 0),
301 /* hashers */
302 PLUGIN_REGISTER(HASHER, openssl_hasher_create),
303 #ifndef OPENSSL_NO_MD2
304 PLUGIN_PROVIDE(HASHER, HASH_MD2),
305 #endif
306 #ifndef OPENSSL_NO_MD4
307 PLUGIN_PROVIDE(HASHER, HASH_MD4),
308 #endif
309 #ifndef OPENSSL_NO_MD5
310 PLUGIN_PROVIDE(HASHER, HASH_MD5),
311 #endif
312 #ifndef OPENSSL_NO_SHA1
313 PLUGIN_PROVIDE(HASHER, HASH_SHA1),
314 #endif
315 #ifndef OPENSSL_NO_SHA256
316 PLUGIN_PROVIDE(HASHER, HASH_SHA224),
317 PLUGIN_PROVIDE(HASHER, HASH_SHA256),
318 #endif
319 #ifndef OPENSSL_NO_SHA512
320 PLUGIN_PROVIDE(HASHER, HASH_SHA384),
321 PLUGIN_PROVIDE(HASHER, HASH_SHA512),
322 #endif
323 #ifndef OPENSSL_NO_SHA1
324 /* keyed sha1 hasher (aka prf) */
325 PLUGIN_REGISTER(PRF, openssl_sha1_prf_create),
326 PLUGIN_PROVIDE(PRF, PRF_KEYED_SHA1),
327 #endif
328 #ifndef OPENSSL_NO_HMAC
329 PLUGIN_REGISTER(PRF, openssl_hmac_prf_create),
330 #ifndef OPENSSL_NO_MD5
331 PLUGIN_PROVIDE(PRF, PRF_HMAC_MD5),
332 #endif
333 #ifndef OPENSSL_NO_SHA1
334 PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA1),
335 #endif
336 #ifndef OPENSSL_NO_SHA256
337 PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_256),
338 #endif
339 #ifndef OPENSSL_NO_SHA512
340 PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_384),
341 PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_512),
342 #endif
343 PLUGIN_REGISTER(SIGNER, openssl_hmac_signer_create),
344 #ifndef OPENSSL_NO_MD5
345 PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_MD5_96),
346 PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_MD5_128),
347 #endif
348 #ifndef OPENSSL_NO_SHA1
349 PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_96),
350 PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_128),
351 PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_160),
352 #endif
353 #ifndef OPENSSL_NO_SHA256
354 PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_256_128),
355 PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_256_256),
356 #endif
357 #ifndef OPENSSL_NO_SHA512
358 PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_384_192),
359 PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_384_384),
360 PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_512_256),
361 PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_512_512),
362 #endif
363 #endif /* OPENSSL_NO_HMAC */
364 #if OPENSSL_VERSION_NUMBER >= 0x1000100fL
365 #ifndef OPENSSL_NO_AES
366 /* AES GCM */
367 PLUGIN_REGISTER(AEAD, openssl_gcm_create),
368 PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 16),
369 PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 24),
370 PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 32),
371 PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 16),
372 PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 24),
373 PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 32),
374 PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 16),
375 PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 24),
376 PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 32),
377 #endif /* OPENSSL_NO_AES */
378 #endif /* OPENSSL_VERSION_NUMBER */
379 #ifndef OPENSSL_NO_DH
380 /* MODP DH groups */
381 PLUGIN_REGISTER(DH, openssl_diffie_hellman_create),
382 PLUGIN_PROVIDE(DH, MODP_2048_BIT),
383 PLUGIN_PROVIDE(DH, MODP_2048_224),
384 PLUGIN_PROVIDE(DH, MODP_2048_256),
385 PLUGIN_PROVIDE(DH, MODP_1536_BIT),
386 PLUGIN_PROVIDE(DH, MODP_3072_BIT),
387 PLUGIN_PROVIDE(DH, MODP_4096_BIT),
388 PLUGIN_PROVIDE(DH, MODP_6144_BIT),
389 PLUGIN_PROVIDE(DH, MODP_8192_BIT),
390 PLUGIN_PROVIDE(DH, MODP_1024_BIT),
391 PLUGIN_PROVIDE(DH, MODP_1024_160),
392 PLUGIN_PROVIDE(DH, MODP_768_BIT),
393 PLUGIN_PROVIDE(DH, MODP_CUSTOM),
394 #endif
395 #ifndef OPENSSL_NO_RSA
396 /* RSA private/public key loading */
397 PLUGIN_REGISTER(PRIVKEY, openssl_rsa_private_key_load, TRUE),
398 PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
399 PLUGIN_REGISTER(PRIVKEY, openssl_rsa_private_key_connect, FALSE),
400 PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
401 PLUGIN_REGISTER(PRIVKEY_GEN, openssl_rsa_private_key_gen, FALSE),
402 PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_RSA),
403 PLUGIN_REGISTER(PUBKEY, openssl_rsa_public_key_load, TRUE),
404 PLUGIN_PROVIDE(PUBKEY, KEY_RSA),
405 PLUGIN_REGISTER(PUBKEY, openssl_rsa_public_key_load, TRUE),
406 PLUGIN_PROVIDE(PUBKEY, KEY_ANY),
407 /* signature/encryption schemes */
408 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_NULL),
409 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_NULL),
410 #ifndef OPENSSL_NO_SHA1
411 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA1),
412 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA1),
413 #endif
414 #ifndef OPENSSL_NO_SHA256
415 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA224),
416 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA256),
417 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA224),
418 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA256),
419 #endif
420 #ifndef OPENSSL_NO_SHA512
421 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA384),
422 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA512),
423 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA384),
424 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA512),
425 #endif
426 #ifndef OPENSSL_NO_MD5
427 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_MD5),
428 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_MD5),
429 #endif
430 PLUGIN_PROVIDE(PRIVKEY_DECRYPT, ENCRYPT_RSA_PKCS1),
431 PLUGIN_PROVIDE(PUBKEY_ENCRYPT, ENCRYPT_RSA_PKCS1),
432 #endif /* OPENSSL_NO_RSA */
433 /* certificate/CRL loading */
434 PLUGIN_REGISTER(CERT_DECODE, openssl_x509_load, TRUE),
435 PLUGIN_PROVIDE(CERT_DECODE, CERT_X509),
436 PLUGIN_SDEPEND(PUBKEY, KEY_RSA),
437 PLUGIN_SDEPEND(PUBKEY, KEY_ECDSA),
438 PLUGIN_SDEPEND(PUBKEY, KEY_DSA),
439 PLUGIN_REGISTER(CERT_DECODE, openssl_crl_load, TRUE),
440 PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_CRL),
441 #if OPENSSL_VERSION_NUMBER >= 0x0090807fL
442 #ifndef OPENSSL_NO_CMS
443 PLUGIN_REGISTER(CONTAINER_DECODE, openssl_pkcs7_load, TRUE),
444 PLUGIN_PROVIDE(CONTAINER_DECODE, CONTAINER_PKCS7),
445 #endif /* OPENSSL_NO_CMS */
446 #endif /* OPENSSL_VERSION_NUMBER */
447 PLUGIN_REGISTER(CONTAINER_DECODE, openssl_pkcs12_load, TRUE),
448 PLUGIN_PROVIDE(CONTAINER_DECODE, CONTAINER_PKCS12),
449 #ifndef OPENSSL_NO_ECDH
450 /* EC DH groups */
451 PLUGIN_REGISTER(DH, openssl_ec_diffie_hellman_create),
452 PLUGIN_PROVIDE(DH, ECP_256_BIT),
453 PLUGIN_PROVIDE(DH, ECP_384_BIT),
454 PLUGIN_PROVIDE(DH, ECP_521_BIT),
455 PLUGIN_PROVIDE(DH, ECP_224_BIT),
456 PLUGIN_PROVIDE(DH, ECP_192_BIT),
457 PLUGIN_PROVIDE(DH, ECP_224_BP),
458 PLUGIN_PROVIDE(DH, ECP_256_BP),
459 PLUGIN_PROVIDE(DH, ECP_384_BP),
460 PLUGIN_PROVIDE(DH, ECP_512_BP),
461 #endif
462 #ifndef OPENSSL_NO_ECDSA
463 /* EC private/public key loading */
464 PLUGIN_REGISTER(PRIVKEY, openssl_ec_private_key_load, TRUE),
465 PLUGIN_PROVIDE(PRIVKEY, KEY_ECDSA),
466 PLUGIN_REGISTER(PRIVKEY_GEN, openssl_ec_private_key_gen, FALSE),
467 PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ECDSA),
468 PLUGIN_REGISTER(PUBKEY, openssl_ec_public_key_load, TRUE),
469 PLUGIN_PROVIDE(PUBKEY, KEY_ECDSA),
470 /* signature encryption schemes */
471 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_NULL),
472 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_NULL),
473 #ifndef OPENSSL_NO_SHA1
474 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA1_DER),
475 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA1_DER),
476 #endif
477 #ifndef OPENSSL_NO_SHA256
478 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA256_DER),
479 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA256_DER),
480 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_256),
481 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_256),
482 #endif
483 #ifndef OPENSSL_NO_SHA512
484 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA384_DER),
485 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA512_DER),
486 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA384_DER),
487 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA512_DER),
488 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_384),
489 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_521),
490 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_384),
491 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_521),
492 #endif
493 #endif /* OPENSSL_NO_ECDSA */
494 PLUGIN_REGISTER(RNG, openssl_rng_create),
495 PLUGIN_PROVIDE(RNG, RNG_STRONG),
496 PLUGIN_PROVIDE(RNG, RNG_WEAK),
497 };
498 *features = f;
499 return countof(f);
500 }
501
502 METHOD(plugin_t, destroy, void,
503 private_openssl_plugin_t *this)
504 {
505 CONF_modules_free();
506 OBJ_cleanup();
507 EVP_cleanup();
508 #ifndef OPENSSL_NO_ENGINE
509 ENGINE_cleanup();
510 #endif /* OPENSSL_NO_ENGINE */
511 CRYPTO_cleanup_all_ex_data();
512 threading_cleanup();
513 ERR_free_strings();
514
515 free(this);
516 }
517
518 /*
519 * see header file
520 */
521 plugin_t *openssl_plugin_create()
522 {
523 private_openssl_plugin_t *this;
524 int fips_mode;
525
526 fips_mode = lib->settings->get_int(lib->settings,
527 "%s.plugins.openssl.fips_mode", FIPS_MODE, lib->ns);
528 #ifdef OPENSSL_FIPS
529 if (fips_mode)
530 {
531 if (FIPS_mode() != fips_mode && !FIPS_mode_set(fips_mode))
532 {
533 DBG1(DBG_LIB, "unable to set openssl FIPS mode(%d) from (%d)",
534 fips_mode, FIPS_mode());
535 return NULL;
536 }
537 }
538 #else
539 if (fips_mode)
540 {
541 DBG1(DBG_LIB, "openssl FIPS mode(%d) unavailable", fips_mode);
542 return NULL;
543 }
544 #endif
545
546 INIT(this,
547 .public = {
548 .plugin = {
549 .get_name = _get_name,
550 .get_features = _get_features,
551 .destroy = _destroy,
552 },
553 },
554 );
555
556 threading_init();
557
558 OPENSSL_config(NULL);
559 OpenSSL_add_all_algorithms();
560
561 #ifdef OPENSSL_FIPS
562 /* we do this here as it may have been enabled via openssl.conf */
563 fips_mode = FIPS_mode();
564 dbg(DBG_LIB, strpfx(lib->ns, "charon") ? 1 : 2,
565 "openssl FIPS mode(%d) - %sabled ", fips_mode, fips_mode ? "en" : "dis");
566 #endif /* OPENSSL_FIPS */
567
568 #ifndef OPENSSL_NO_ENGINE
569 /* activate support for hardware accelerators */
570 ENGINE_load_builtin_engines();
571 ENGINE_register_all_complete();
572 #endif /* OPENSSL_NO_ENGINE */
573
574 if (!seed_rng())
575 {
576 DBG1(DBG_CFG, "no RNG found to seed OpenSSL");
577 destroy(this);
578 return NULL;
579 }
580
581 return &this->public.plugin;
582 }