Implemented hasher_t using PKCS#11
[strongswan.git] / src / libstrongswan / plugins / pkcs11 / pkcs11_plugin.c
1 /*
2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "pkcs11_plugin.h"
17
18 #include <library.h>
19 #include <debug.h>
20 #include <utils/linked_list.h>
21 #include <threading/mutex.h>
22
23 #include "pkcs11_manager.h"
24 #include "pkcs11_creds.h"
25 #include "pkcs11_private_key.h"
26 #include "pkcs11_hasher.h"
27
28 typedef struct private_pkcs11_plugin_t private_pkcs11_plugin_t;
29
30 /**
31 * private data of pkcs11_plugin
32 */
33 struct private_pkcs11_plugin_t {
34
35 /**
36 * public functions
37 */
38 pkcs11_plugin_t public;
39
40 /**
41 * PKCS#11 library/slot manager
42 */
43 pkcs11_manager_t *manager;
44
45 /**
46 * List of credential sets, pkcs11_creds_t
47 */
48 linked_list_t *creds;
49
50 /**
51 * mutex to lock list
52 */
53 mutex_t *mutex;
54 };
55
56 /**
57 * Token event callback function
58 */
59 static void token_event_cb(private_pkcs11_plugin_t *this, pkcs11_library_t *p11,
60 CK_SLOT_ID slot, bool add)
61 {
62 enumerator_t *enumerator;
63 pkcs11_creds_t *creds, *found = NULL;;
64
65 if (add)
66 {
67 creds = pkcs11_creds_create(p11, slot);
68 if (creds)
69 {
70 this->mutex->lock(this->mutex);
71 this->creds->insert_last(this->creds, creds);
72 this->mutex->unlock(this->mutex);
73 lib->credmgr->add_set(lib->credmgr, &creds->set);
74 }
75 }
76 else
77 {
78 this->mutex->lock(this->mutex);
79 enumerator = this->creds->create_enumerator(this->creds);
80 while (enumerator->enumerate(enumerator, &creds))
81 {
82 if (creds->get_library(creds) == p11 &&
83 creds->get_slot(creds) == slot)
84 {
85 found = creds;
86 this->creds->remove_at(this->creds, enumerator);
87 break;
88 }
89 }
90 enumerator->destroy(enumerator);
91 this->mutex->unlock(this->mutex);
92
93 if (found)
94 {
95 lib->credmgr->remove_set(lib->credmgr, &found->set);
96 found->destroy(found);
97 /* flush the cache after a token is gone */
98 lib->credmgr->flush_cache(lib->credmgr, CERT_X509);
99 }
100 }
101 }
102
103 METHOD(plugin_t, destroy, void,
104 private_pkcs11_plugin_t *this)
105 {
106 pkcs11_creds_t *creds;
107
108 lib->creds->remove_builder(lib->creds,
109 (builder_function_t)pkcs11_private_key_connect);
110 while (this->creds->remove_last(this->creds, (void**)&creds) == SUCCESS)
111 {
112 lib->credmgr->remove_set(lib->credmgr, &creds->set);
113 creds->destroy(creds);
114 }
115 lib->crypto->remove_hasher(lib->crypto,
116 (hasher_constructor_t)pkcs11_hasher_create);
117 this->creds->destroy(this->creds);
118 this->manager->destroy(this->manager);
119 this->mutex->destroy(this->mutex);
120 free(this);
121 }
122
123 /*
124 * see header file
125 */
126 plugin_t *pkcs11_plugin_create()
127 {
128 private_pkcs11_plugin_t *this;
129
130 INIT(this,
131 .public.plugin.destroy = _destroy,
132 .creds = linked_list_create(),
133 .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
134 );
135
136 if (lib->settings->get_bool(lib->settings,
137 "libstrongswan.plugins.pkcs11.use_hasher", FALSE))
138 {
139 lib->crypto->add_hasher(lib->crypto, HASH_MD2,
140 (hasher_constructor_t)pkcs11_hasher_create);
141 lib->crypto->add_hasher(lib->crypto, HASH_MD5,
142 (hasher_constructor_t)pkcs11_hasher_create);
143 lib->crypto->add_hasher(lib->crypto, HASH_SHA1,
144 (hasher_constructor_t)pkcs11_hasher_create);
145 lib->crypto->add_hasher(lib->crypto, HASH_SHA256,
146 (hasher_constructor_t)pkcs11_hasher_create);
147 lib->crypto->add_hasher(lib->crypto, HASH_SHA384,
148 (hasher_constructor_t)pkcs11_hasher_create);
149 lib->crypto->add_hasher(lib->crypto, HASH_SHA512,
150 (hasher_constructor_t)pkcs11_hasher_create);
151 }
152
153 this->manager = pkcs11_manager_create((void*)token_event_cb, this);
154
155 lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
156 (builder_function_t)pkcs11_private_key_connect);
157
158 return &this->public.plugin;
159 }