Statistics
| Branch: | Tag: | Revision:

root / src / libstrongswan / plugins / openssl / openssl_plugin.c @ ee3d4ef8016c151a0e19dc91bd0445f4aac1e2ef

History | View | Annotate | Download (9 KB)

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