Implemented X.509 certificate reading using OpenSSL
[strongswan.git] / src / libstrongswan / plugins / openssl / openssl_plugin.c
1 /*
2 * Copyright (C) 2008 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 <openssl/conf.h>
18 #include <openssl/evp.h>
19 #include <openssl/engine.h>
20 #include <openssl/crypto.h>
21
22 #include "openssl_plugin.h"
23
24 #include <library.h>
25 #include <threading/thread.h>
26 #include <threading/mutex.h>
27 #include "openssl_util.h"
28 #include "openssl_crypter.h"
29 #include "openssl_hasher.h"
30 #include "openssl_sha1_prf.h"
31 #include "openssl_diffie_hellman.h"
32 #include "openssl_ec_diffie_hellman.h"
33 #include "openssl_rsa_private_key.h"
34 #include "openssl_rsa_public_key.h"
35 #include "openssl_ec_private_key.h"
36 #include "openssl_ec_public_key.h"
37 #include "openssl_x509.h"
38
39 typedef struct private_openssl_plugin_t private_openssl_plugin_t;
40
41 /**
42 * private data of openssl_plugin
43 */
44 struct private_openssl_plugin_t {
45
46 /**
47 * public functions
48 */
49 openssl_plugin_t public;
50 };
51
52 /**
53 * Array of static mutexs, with CRYPTO_num_locks() mutex
54 */
55 static mutex_t **mutex = NULL;
56
57 /**
58 * Locking callback for static locks
59 */
60 static void locking_function(int mode, int type, const char *file, int line)
61 {
62 if (mutex)
63 {
64 if (mode & CRYPTO_LOCK)
65 {
66 mutex[type]->lock(mutex[type]);
67 }
68 else
69 {
70 mutex[type]->unlock(mutex[type]);
71 }
72 }
73 }
74
75 /**
76 * Implementation of dynlock
77 */
78 struct CRYPTO_dynlock_value {
79 mutex_t *mutex;
80 };
81
82 /**
83 * Callback to create a dynamic lock
84 */
85 static struct CRYPTO_dynlock_value *create_function(const char *file, int line)
86 {
87 struct CRYPTO_dynlock_value *lock;
88
89 lock = malloc_thing(struct CRYPTO_dynlock_value);
90 lock->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
91 return lock;
92 }
93
94 /**
95 * Callback to (un-)lock a dynamic lock
96 */
97 static void lock_function(int mode, struct CRYPTO_dynlock_value *lock,
98 const char *file, int line)
99 {
100 if (mode & CRYPTO_LOCK)
101 {
102 lock->mutex->lock(lock->mutex);
103 }
104 else
105 {
106 lock->mutex->unlock(lock->mutex);
107 }
108 }
109
110 /**
111 * Callback to destroy a dynamic lock
112 */
113 static void destroy_function(struct CRYPTO_dynlock_value *lock,
114 const char *file, int line)
115 {
116 lock->mutex->destroy(lock->mutex);
117 free(lock);
118 }
119
120 /**
121 * Thread-ID callback function
122 */
123 static unsigned long id_function(void)
124 {
125 return (unsigned long)thread_current_id();
126 }
127
128 /**
129 * initialize OpenSSL for multi-threaded use
130 */
131 static void threading_init()
132 {
133 int i, num_locks;
134
135 CRYPTO_set_id_callback(id_function);
136 CRYPTO_set_locking_callback(locking_function);
137
138 CRYPTO_set_dynlock_create_callback(create_function);
139 CRYPTO_set_dynlock_lock_callback(lock_function);
140 CRYPTO_set_dynlock_destroy_callback(destroy_function);
141
142 num_locks = CRYPTO_num_locks();
143 mutex = malloc(sizeof(mutex_t*) * num_locks);
144 for (i = 0; i < num_locks; i++)
145 {
146 mutex[i] = mutex_create(MUTEX_TYPE_DEFAULT);
147 }
148 }
149
150 /**
151 * cleanup OpenSSL threading locks
152 */
153 static void threading_cleanup()
154 {
155 int i, num_locks;
156
157 num_locks = CRYPTO_num_locks();
158 for (i = 0; i < num_locks; i++)
159 {
160 mutex[i]->destroy(mutex[i]);
161 }
162 free(mutex);
163 mutex = NULL;
164 }
165
166 /**
167 * Implementation of openssl_plugin_t.destroy
168 */
169 static void destroy(private_openssl_plugin_t *this)
170 {
171 lib->crypto->remove_crypter(lib->crypto,
172 (crypter_constructor_t)openssl_crypter_create);
173 lib->crypto->remove_hasher(lib->crypto,
174 (hasher_constructor_t)openssl_hasher_create);
175 lib->crypto->remove_prf(lib->crypto,
176 (prf_constructor_t)openssl_sha1_prf_create);
177 lib->crypto->remove_dh(lib->crypto,
178 (dh_constructor_t)openssl_diffie_hellman_create);
179 lib->crypto->remove_dh(lib->crypto,
180 (dh_constructor_t)openssl_ec_diffie_hellman_create);
181 lib->creds->remove_builder(lib->creds,
182 (builder_function_t)openssl_rsa_private_key_load);
183 lib->creds->remove_builder(lib->creds,
184 (builder_function_t)openssl_rsa_private_key_gen);
185 lib->creds->remove_builder(lib->creds,
186 (builder_function_t)openssl_rsa_private_key_connect);
187 lib->creds->remove_builder(lib->creds,
188 (builder_function_t)openssl_rsa_public_key_load);
189 lib->creds->remove_builder(lib->creds,
190 (builder_function_t)openssl_ec_private_key_load);
191 lib->creds->remove_builder(lib->creds,
192 (builder_function_t)openssl_ec_private_key_gen);
193 lib->creds->remove_builder(lib->creds,
194 (builder_function_t)openssl_ec_public_key_load);
195 lib->creds->remove_builder(lib->creds,
196 (builder_function_t)openssl_x509_load);
197
198 ENGINE_cleanup();
199 EVP_cleanup();
200 CONF_modules_free();
201
202 threading_cleanup();
203
204 free(this);
205 }
206
207 /*
208 * see header file
209 */
210 plugin_t *openssl_plugin_create()
211 {
212 private_openssl_plugin_t *this = malloc_thing(private_openssl_plugin_t);
213
214 this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
215
216 threading_init();
217
218 OPENSSL_config(NULL);
219 OpenSSL_add_all_algorithms();
220
221 /* activate support for hardware accelerators */
222 ENGINE_load_builtin_engines();
223 ENGINE_register_all_complete();
224
225 /* crypter */
226 lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC,
227 (crypter_constructor_t)openssl_crypter_create);
228 lib->crypto->add_crypter(lib->crypto, ENCR_CAMELLIA_CBC,
229 (crypter_constructor_t)openssl_crypter_create);
230 lib->crypto->add_crypter(lib->crypto, ENCR_3DES,
231 (crypter_constructor_t)openssl_crypter_create);
232 lib->crypto->add_crypter(lib->crypto, ENCR_RC5,
233 (crypter_constructor_t)openssl_crypter_create);
234 lib->crypto->add_crypter(lib->crypto, ENCR_IDEA,
235 (crypter_constructor_t)openssl_crypter_create);
236 lib->crypto->add_crypter(lib->crypto, ENCR_CAST,
237 (crypter_constructor_t)openssl_crypter_create);
238 lib->crypto->add_crypter(lib->crypto, ENCR_BLOWFISH,
239 (crypter_constructor_t)openssl_crypter_create);
240 lib->crypto->add_crypter(lib->crypto, ENCR_DES,
241 (crypter_constructor_t)openssl_crypter_create);
242 lib->crypto->add_crypter(lib->crypto, ENCR_DES_ECB,
243 (crypter_constructor_t)openssl_crypter_create);
244 lib->crypto->add_crypter(lib->crypto, ENCR_NULL,
245 (crypter_constructor_t)openssl_crypter_create);
246
247 /* hasher */
248 lib->crypto->add_hasher(lib->crypto, HASH_SHA1,
249 (hasher_constructor_t)openssl_hasher_create);
250 lib->crypto->add_hasher(lib->crypto, HASH_MD2,
251 (hasher_constructor_t)openssl_hasher_create);
252 lib->crypto->add_hasher(lib->crypto, HASH_MD4,
253 (hasher_constructor_t)openssl_hasher_create);
254 lib->crypto->add_hasher(lib->crypto, HASH_MD5,
255 (hasher_constructor_t)openssl_hasher_create);
256 lib->crypto->add_hasher(lib->crypto, HASH_SHA224,
257 (hasher_constructor_t)openssl_hasher_create);
258 lib->crypto->add_hasher(lib->crypto, HASH_SHA256,
259 (hasher_constructor_t)openssl_hasher_create);
260 lib->crypto->add_hasher(lib->crypto, HASH_SHA384,
261 (hasher_constructor_t)openssl_hasher_create);
262 lib->crypto->add_hasher(lib->crypto, HASH_SHA512,
263 (hasher_constructor_t)openssl_hasher_create);
264
265 /* prf */
266 lib->crypto->add_prf(lib->crypto, PRF_KEYED_SHA1,
267 (prf_constructor_t)openssl_sha1_prf_create);
268
269 /* (ec) diffie hellman */
270 lib->crypto->add_dh(lib->crypto, MODP_2048_BIT,
271 (dh_constructor_t)openssl_diffie_hellman_create);
272 lib->crypto->add_dh(lib->crypto, MODP_2048_224,
273 (dh_constructor_t)openssl_diffie_hellman_create);
274 lib->crypto->add_dh(lib->crypto, MODP_2048_256,
275 (dh_constructor_t)openssl_diffie_hellman_create);
276 lib->crypto->add_dh(lib->crypto, MODP_1536_BIT,
277 (dh_constructor_t)openssl_diffie_hellman_create);
278 lib->crypto->add_dh(lib->crypto, ECP_256_BIT,
279 (dh_constructor_t)openssl_ec_diffie_hellman_create);
280 lib->crypto->add_dh(lib->crypto, ECP_384_BIT,
281 (dh_constructor_t)openssl_ec_diffie_hellman_create);
282 lib->crypto->add_dh(lib->crypto, ECP_521_BIT,
283 (dh_constructor_t)openssl_ec_diffie_hellman_create);
284 lib->crypto->add_dh(lib->crypto, ECP_224_BIT,
285 (dh_constructor_t)openssl_ec_diffie_hellman_create);
286 lib->crypto->add_dh(lib->crypto, ECP_192_BIT,
287 (dh_constructor_t)openssl_ec_diffie_hellman_create);
288 lib->crypto->add_dh(lib->crypto, MODP_3072_BIT,
289 (dh_constructor_t)openssl_diffie_hellman_create);
290 lib->crypto->add_dh(lib->crypto, MODP_4096_BIT,
291 (dh_constructor_t)openssl_diffie_hellman_create);
292 lib->crypto->add_dh(lib->crypto, MODP_6144_BIT,
293 (dh_constructor_t)openssl_diffie_hellman_create);
294 lib->crypto->add_dh(lib->crypto, MODP_8192_BIT,
295 (dh_constructor_t)openssl_diffie_hellman_create);
296 lib->crypto->add_dh(lib->crypto, MODP_1024_BIT,
297 (dh_constructor_t)openssl_diffie_hellman_create);
298 lib->crypto->add_dh(lib->crypto, MODP_1024_160,
299 (dh_constructor_t)openssl_diffie_hellman_create);
300 lib->crypto->add_dh(lib->crypto, MODP_768_BIT,
301 (dh_constructor_t)openssl_diffie_hellman_create);
302
303 /* rsa */
304 lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
305 (builder_function_t)openssl_rsa_private_key_load);
306 lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
307 (builder_function_t)openssl_rsa_private_key_gen);
308 lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
309 (builder_function_t)openssl_rsa_private_key_connect);
310 lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
311 (builder_function_t)openssl_rsa_public_key_load);
312 lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
313 (builder_function_t)openssl_rsa_public_key_load);
314
315 /* ec */
316 lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
317 (builder_function_t)openssl_ec_private_key_load);
318 lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
319 (builder_function_t)openssl_ec_private_key_gen);
320 lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA,
321 (builder_function_t)openssl_ec_public_key_load);
322
323 /* X509 certificates */
324 lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509,
325 (builder_function_t)openssl_x509_load);
326
327 return &this->public.plugin;
328 }
329