e5af0c29222b2bf30b524718a4762e60b4401a5b
[strongswan.git] / src / libstrongswan / plugins / pkcs11 / pkcs11_library.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_library.h"
17
18 #include <dlfcn.h>
19
20 #include <library.h>
21 #include <debug.h>
22 #include <threading/mutex.h>
23 #include <utils/linked_list.h>
24
25 typedef struct private_pkcs11_library_t private_pkcs11_library_t;
26
27
28 ENUM_BEGIN(ck_rv_names, CKR_OK, CKR_CANT_LOCK,
29 "OK",
30 "CANCEL",
31 "HOST_MEMORY",
32 "SLOT_ID_INVALID",
33 "(0x04)",
34 "GENERAL_ERROR",
35 "FUNCTION_FAILED",
36 "ARGUMENTS_BAD",
37 "NO_EVENT",
38 "NEED_TO_CREATE_THREADS",
39 "CANT_LOCK");
40 ENUM_NEXT(ck_rv_names, CKR_ATTRIBUTE_READ_ONLY, CKR_ATTRIBUTE_VALUE_INVALID,
41 CKR_CANT_LOCK,
42 "ATTRIBUTE_READ_ONLY",
43 "ATTRIBUTE_SENSITIVE",
44 "ATTRIBUTE_TYPE_INVALID",
45 "ATTRIBUTE_VALUE_INVALID");
46 ENUM_NEXT(ck_rv_names, CKR_DATA_INVALID, CKR_DATA_LEN_RANGE,
47 CKR_ATTRIBUTE_VALUE_INVALID,
48 "DATA_INVALID"
49 "DATA_LEN_RANGE");
50 ENUM_NEXT(ck_rv_names, CKR_DEVICE_ERROR, CKR_DEVICE_REMOVED,
51 CKR_DATA_LEN_RANGE,
52 "DEVICE_ERROR",
53 "DEVICE_MEMORY",
54 "DEVICE_REMOVED");
55 ENUM_NEXT(ck_rv_names, CKR_ENCRYPTED_DATA_INVALID, CKR_ENCRYPTED_DATA_LEN_RANGE,
56 CKR_DEVICE_REMOVED,
57 "ENCRYPTED_DATA_INVALID",
58 "ENCRYPTED_DATA_LEN_RANGE");
59 ENUM_NEXT(ck_rv_names, CKR_FUNCTION_CANCELED, CKR_FUNCTION_NOT_SUPPORTED,
60 CKR_ENCRYPTED_DATA_LEN_RANGE,
61 "FUNCTION_CANCELED",
62 "FUNCTION_NOT_PARALLEL",
63 "(0x52)",
64 "(0x53)",
65 "FUNCTION_NOT_SUPPORTED");
66 ENUM_NEXT(ck_rv_names, CKR_KEY_HANDLE_INVALID, CKR_KEY_UNEXTRACTABLE,
67 CKR_FUNCTION_NOT_SUPPORTED,
68 "KEY_HANDLE_INVALID",
69 "(0x61)",
70 "KEY_SIZE_RANGE",
71 "KEY_TYPE_INCONSISTENT",
72 "KEY_NOT_NEEDED",
73 "KEY_CHANGED",
74 "KEY_NEEDED",
75 "KEY_INDIGESTIBLE",
76 "KEY_FUNCTION_NOT_PERMITTED",
77 "KEY_NOT_WRAPPABLE",
78 "KEY_UNEXTRACTABLE");
79 ENUM_NEXT(ck_rv_names, CKR_MECHANISM_INVALID, CKR_MECHANISM_PARAM_INVALID,
80 CKR_KEY_UNEXTRACTABLE,
81 "MECHANISM_INVALID",
82 "MECHANISM_PARAM_INVALID");
83 ENUM_NEXT(ck_rv_names, CKR_OBJECT_HANDLE_INVALID, CKR_OBJECT_HANDLE_INVALID,
84 CKR_MECHANISM_PARAM_INVALID,
85 "OBJECT_HANDLE_INVALID");
86 ENUM_NEXT(ck_rv_names, CKR_OPERATION_ACTIVE, CKR_OPERATION_NOT_INITIALIZED,
87 CKR_OBJECT_HANDLE_INVALID,
88 "OPERATION_ACTIVE",
89 "OPERATION_NOT_INITIALIZED");
90 ENUM_NEXT(ck_rv_names, CKR_PIN_INCORRECT, CKR_PIN_LOCKED,
91 CKR_OPERATION_NOT_INITIALIZED,
92 "PIN_INCORRECT",
93 "PIN_INVALID",
94 "PIN_LEN_RANGE",
95 "PIN_EXPIRED",
96 "PIN_LOCKED");
97 ENUM_NEXT(ck_rv_names, CKR_SESSION_CLOSED, CKR_SESSION_READ_WRITE_SO_EXISTS,
98 CKR_PIN_LOCKED,
99 "SESSION_CLOSED",
100 "SESSION_COUNT",
101 "(0xb2)",
102 "SESSION_HANDLE_INVALID",
103 "SESSION_PARALLEL_NOT_SUPPORTED",
104 "SESSION_READ_ONLY",
105 "SESSION_EXISTS",
106 "SESSION_READ_ONLY_EXISTS",
107 "SESSION_READ_WRITE_SO_EXISTS");
108 ENUM_NEXT(ck_rv_names, CKR_SIGNATURE_INVALID, CKR_SIGNATURE_LEN_RANGE,
109 CKR_SESSION_READ_WRITE_SO_EXISTS,
110 "SIGNATURE_INVALID",
111 "SIGNATURE_LEN_RANGE");
112 ENUM_NEXT(ck_rv_names, CKR_TEMPLATE_INCOMPLETE, CKR_TEMPLATE_INCONSISTENT,
113 CKR_SIGNATURE_LEN_RANGE,
114 "TEMPLATE_INCOMPLETE",
115 "TEMPLATE_INCONSISTENT",
116 );
117 ENUM_NEXT(ck_rv_names, CKR_TOKEN_NOT_PRESENT, CKR_TOKEN_WRITE_PROTECTED,
118 CKR_TEMPLATE_INCONSISTENT,
119 "TOKEN_NOT_PRESENT",
120 "TOKEN_NOT_RECOGNIZED",
121 "TOKEN_WRITE_PROTECTED");
122 ENUM_NEXT(ck_rv_names, CKR_UNWRAPPING_KEY_HANDLE_INVALID, CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT,
123 CKR_TOKEN_WRITE_PROTECTED,
124 "UNWRAPPING_KEY_HANDLE_INVALID",
125 "UNWRAPPING_KEY_SIZE_RANGE",
126 "UNWRAPPING_KEY_TYPE_INCONSISTENT");
127 ENUM_NEXT(ck_rv_names, CKR_USER_ALREADY_LOGGED_IN, CKR_USER_TOO_MANY_TYPES,
128 CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT,
129 "USER_ALREADY_LOGGED_IN",
130 "USER_NOT_LOGGED_IN",
131 "USER_PIN_NOT_INITIALIZED",
132 "USER_TYPE_INVALID",
133 "USER_ANOTHER_ALREADY_LOGGED_IN",
134 "USER_TOO_MANY_TYPES");
135 ENUM_NEXT(ck_rv_names, CKR_WRAPPED_KEY_INVALID, CKR_WRAPPING_KEY_TYPE_INCONSISTENT,
136 CKR_USER_TOO_MANY_TYPES,
137 "WRAPPED_KEY_INVALID",
138 "(0x111)",
139 "WRAPPED_KEY_LEN_RANGE",
140 "WRAPPING_KEY_HANDLE_INVALID",
141 "WRAPPING_KEY_SIZE_RANGE",
142 "WRAPPING_KEY_TYPE_INCONSISTENT");
143 ENUM_NEXT(ck_rv_names, CKR_RANDOM_SEED_NOT_SUPPORTED, CKR_RANDOM_NO_RNG,
144 CKR_WRAPPING_KEY_TYPE_INCONSISTENT,
145 "RANDOM_SEED_NOT_SUPPORTED",
146 "RANDOM_NO_RNG");
147 ENUM_NEXT(ck_rv_names, CKR_DOMAIN_PARAMS_INVALID, CKR_DOMAIN_PARAMS_INVALID,
148 CKR_RANDOM_NO_RNG,
149 "DOMAIN_PARAMS_INVALID");
150 ENUM_NEXT(ck_rv_names, CKR_BUFFER_TOO_SMALL, CKR_BUFFER_TOO_SMALL,
151 CKR_DOMAIN_PARAMS_INVALID,
152 "BUFFER_TOO_SMALL");
153 ENUM_NEXT(ck_rv_names, CKR_SAVED_STATE_INVALID, CKR_SAVED_STATE_INVALID,
154 CKR_BUFFER_TOO_SMALL,
155 "SAVED_STATE_INVALID");
156 ENUM_NEXT(ck_rv_names, CKR_INFORMATION_SENSITIVE, CKR_INFORMATION_SENSITIVE,
157 CKR_SAVED_STATE_INVALID,
158 "INFORMATION_SENSITIVE");
159 ENUM_NEXT(ck_rv_names, CKR_STATE_UNSAVEABLE, CKR_STATE_UNSAVEABLE,
160 CKR_INFORMATION_SENSITIVE,
161 "STATE_UNSAVEABLE");
162 ENUM_NEXT(ck_rv_names, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_CRYPTOKI_ALREADY_INITIALIZED,
163 CKR_STATE_UNSAVEABLE,
164 "CRYPTOKI_NOT_INITIALIZED",
165 "CRYPTOKI_ALREADY_INITIALIZED");
166 ENUM_NEXT(ck_rv_names, CKR_MUTEX_BAD, CKR_MUTEX_NOT_LOCKED,
167 CKR_CRYPTOKI_ALREADY_INITIALIZED,
168 "MUTEX_BAD",
169 "MUTEX_NOT_LOCKED");
170 ENUM_NEXT(ck_rv_names, CKR_FUNCTION_REJECTED, CKR_FUNCTION_REJECTED,
171 CKR_MUTEX_NOT_LOCKED,
172 "FUNCTION_REJECTED");
173 ENUM_END(ck_rv_names, CKR_FUNCTION_REJECTED);
174
175
176 ENUM_BEGIN(ck_mech_names, CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_DSA_SHA1,
177 "RSA_PKCS_KEY_PAIR_GEN",
178 "RSA_PKCS",
179 "RSA_9796",
180 "RSA_X_509",
181 "MD2_RSA_PKCS",
182 "MD5_RSA_PKCS",
183 "SHA1_RSA_PKCS",
184 "RIPEMD128_RSA_PKCS",
185 "RIPEMD160_RSA_PKCS",
186 "RSA_PKCS_OAEP",
187 "RSA_X9_31_KEY_PAIR_GEN",
188 "RSA_X9_31",
189 "SHA1_RSA_X9_31",
190 "RSA_PKCS_PSS",
191 "SHA1_RSA_PKCS_PSS",
192 "(0xf)",
193 "DSA_KEY_PAIR_GEN",
194 "DSA",
195 "DSA_SHA1");
196 ENUM_NEXT(ck_mech_names, CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE,
197 CKM_DSA_SHA1,
198 "DH_PKCS_KEY_PAIR_GEN",
199 "DH_PKCS_DERIVE");
200 ENUM_NEXT(ck_mech_names, CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_MQV_DERIVE,
201 CKM_DH_PKCS_DERIVE,
202 "X9_42_DH_KEY_PAIR_GEN",
203 "X9_42_DH_DERIVE",
204 "X9_42_DH_HYBRID_DERIVE",
205 "X9_42_MQV_DERIVE");
206 ENUM_NEXT(ck_mech_names, CKM_SHA256_RSA_PKCS, CKM_SHA512_RSA_PKCS_PSS,
207 CKM_X9_42_MQV_DERIVE,
208 "SHA256_RSA_PKCS",
209 "SHA384_RSA_PKCS",
210 "SHA512_RSA_PKCS",
211 "SHA256_RSA_PKCS_PSS",
212 "SHA384_RSA_PKCS_PSS",
213 "SHA512_RSA_PKCS_PSS");
214 ENUM_NEXT(ck_mech_names, CKM_RC2_KEY_GEN, CKM_RC2_CBC_PAD,
215 CKM_SHA512_RSA_PKCS_PSS,
216 "RC2_KEY_GEN",
217 "RC2_ECB",
218 "RC2_CBC",
219 "RC2_MAC",
220 "RC2_MAC_GENERAL",
221 "RC2_CBC_PAD");
222 ENUM_NEXT(ck_mech_names, CKM_RC4_KEY_GEN, CKM_RC4,
223 CKM_RC2_CBC_PAD,
224 "RC4_KEY_GEN",
225 "RC4");
226 ENUM_NEXT(ck_mech_names, CKM_DES_KEY_GEN, CKM_DES_CBC_PAD,
227 CKM_RC4,
228 "DES_KEY_GEN",
229 "DES_ECB",
230 "DES_CBC",
231 "DES_MAC",
232 "DES_MAC_GENERAL",
233 "DES_CBC_PAD");
234 ENUM_NEXT(ck_mech_names, CKM_DES2_KEY_GEN, CKM_DES3_CBC_PAD,
235 CKM_DES_CBC_PAD,
236 "DES2_KEY_GEN",
237 "DES3_KEY_GEN",
238 "DES3_ECB",
239 "DES3_CBC",
240 "DES3_MAC",
241 "DES3_MAC_GENERAL",
242 "DES3_CBC_PAD");
243 ENUM_NEXT(ck_mech_names, CKM_CDMF_KEY_GEN, CKM_CDMF_CBC_PAD,
244 CKM_DES3_CBC_PAD,
245 "CDMF_KEY_GEN",
246 "CDMF_ECB",
247 "CDMF_CBC",
248 "CDMF_MAC",
249 "CDMF_MAC_GENERAL",
250 "CDMF_CBC_PAD");
251 ENUM_NEXT(ck_mech_names, CKM_MD2, CKM_MD2_HMAC_GENERAL,
252 CKM_CDMF_CBC_PAD,
253 "MD2",
254 "MD2_HMAC",
255 "MD2_HMAC_GENERAL");
256 ENUM_NEXT(ck_mech_names, CKM_MD5, CKM_MD5_HMAC_GENERAL,
257 CKM_MD2_HMAC_GENERAL,
258 "MD5",
259 "MD5_HMAC",
260 "MD5_HMAC_GENERAL");
261 ENUM_NEXT(ck_mech_names, CKM_SHA_1, CKM_SHA_1_HMAC_GENERAL,
262 CKM_MD5_HMAC_GENERAL,
263 "SHA_1",
264 "SHA_1_HMAC",
265 "SHA_1_HMAC_GENERAL");
266 ENUM_NEXT(ck_mech_names, CKM_RIPEMD128, CKM_RIPEMD128_HMAC_GENERAL,
267 CKM_SHA_1_HMAC_GENERAL,
268 "RIPEMD128",
269 "RIPEMD128_HMAC",
270 "RIPEMD128_HMAC_GENERAL");
271 ENUM_NEXT(ck_mech_names, CKM_RIPEMD160, CKM_RIPEMD160_HMAC_GENERAL,
272 CKM_RIPEMD128_HMAC_GENERAL,
273 "RIPEMD160",
274 "RIPEMD160_HMAC",
275 "RIPEMD160_HMAC_GENERAL");
276 ENUM_NEXT(ck_mech_names, CKM_SHA256, CKM_SHA256_HMAC_GENERAL,
277 CKM_RIPEMD160_HMAC_GENERAL,
278 "SHA256",
279 "SHA256_HMAC",
280 "SHA256_HMAC_GENERAL");
281 ENUM_NEXT(ck_mech_names, CKM_SHA384, CKM_SHA384_HMAC_GENERAL,
282 CKM_SHA256_HMAC_GENERAL,
283 "SHA384",
284 "SHA384_HMAC",
285 "SHA384_HMAC_GENERAL");
286 ENUM_NEXT(ck_mech_names, CKM_SHA512, CKM_SHA512_HMAC_GENERAL,
287 CKM_SHA384_HMAC_GENERAL ,
288 "SHA512",
289 "SHA512_HMAC",
290 "SHA512_HMAC_GENERAL");
291 ENUM_NEXT(ck_mech_names, CKM_CAST_KEY_GEN, CKM_CAST_CBC_PAD,
292 CKM_SHA512_HMAC_GENERAL,
293 "CAST_KEY_GEN",
294 "CAST_ECB",
295 "CAST_CBC",
296 "CAST_MAC",
297 "CAST_MAC_GENERAL",
298 "CAST_CBC_PAD");
299 ENUM_NEXT(ck_mech_names, CKM_CAST3_KEY_GEN, CKM_CAST3_CBC_PAD,
300 CKM_CAST_CBC_PAD,
301 "CAST3_KEY_GEN",
302 "CAST3_ECB",
303 "CAST3_CBC",
304 "CAST3_MAC",
305 "CAST3_MAC_GENERAL",
306 "CAST3_CBC_PAD");
307 ENUM_NEXT(ck_mech_names, CKM_CAST128_KEY_GEN, CKM_CAST128_CBC_PAD,
308 CKM_CAST3_CBC_PAD,
309 "CAST128_KEY_GEN",
310 "CAST128_ECB",
311 "CAST128_CBC",
312 "CAST128_MAC",
313 "CAST128_MAC_GENERAL",
314 "CAST128_CBC_PAD");
315 ENUM_NEXT(ck_mech_names, CKM_RC5_KEY_GEN, CKM_RC5_CBC_PAD,
316 CKM_CAST128_CBC_PAD,
317 "RC5_KEY_GEN",
318 "RC5_ECB",
319 "RC5_CBC",
320 "RC5_MAC",
321 "RC5_MAC_GENERAL",
322 "RC5_CBC_PAD");
323 ENUM_NEXT(ck_mech_names, CKM_IDEA_KEY_GEN, CKM_IDEA_CBC_PAD,
324 CKM_RC5_CBC_PAD,
325 "IDEA_KEY_GEN",
326 "IDEA_ECB",
327 "IDEA_CBC",
328 "IDEA_MAC",
329 "IDEA_MAC_GENERAL",
330 "IDEA_CBC_PAD");
331 ENUM_NEXT(ck_mech_names, CKM_GENERIC_SECRET_KEY_GEN, CKM_GENERIC_SECRET_KEY_GEN,
332 CKM_IDEA_CBC_PAD,
333 "GENERIC_SECRET_KEY_GEN");
334 ENUM_NEXT(ck_mech_names, CKM_CONCATENATE_BASE_AND_KEY, CKM_EXTRACT_KEY_FROM_KEY,
335 CKM_GENERIC_SECRET_KEY_GEN,
336 "CONCATENATE_BASE_AND_KEY",
337 "(0x361)",
338 "CONCATENATE_BASE_AND_DATA",
339 "CONCATENATE_DATA_AND_BASE",
340 "XOR_BASE_AND_DATA",
341 "EXTRACT_KEY_FROM_KEY");
342 ENUM_NEXT(ck_mech_names, CKM_SSL3_PRE_MASTER_KEY_GEN, CKM_TLS_MASTER_KEY_DERIVE_DH,
343 CKM_EXTRACT_KEY_FROM_KEY,
344 "SSL3_PRE_MASTER_KEY_GEN",
345 "SSL3_MASTER_KEY_DERIVE",
346 "SSL3_KEY_AND_MAC_DERIVE",
347 "SSL3_MASTER_KEY_DERIVE_DH",
348 "TLS_PRE_MASTER_KEY_GEN",
349 "TLS_MASTER_KEY_DERIVE",
350 "TLS_KEY_AND_MAC_DERIVE",
351 "TLS_MASTER_KEY_DERIVE_DH");
352 ENUM_NEXT(ck_mech_names, CKM_SSL3_MD5_MAC, CKM_SSL3_SHA1_MAC,
353 CKM_TLS_MASTER_KEY_DERIVE_DH,
354 "SSL3_MD5_MAC",
355 "SSL3_SHA1_MAC");
356 ENUM_NEXT(ck_mech_names, CKM_MD5_KEY_DERIVATION, CKM_SHA1_KEY_DERIVATION,
357 CKM_SSL3_SHA1_MAC,
358 "MD5_KEY_DERIVATION",
359 "MD2_KEY_DERIVATION",
360 "SHA1_KEY_DERIVATION");
361 ENUM_NEXT(ck_mech_names, CKM_PBE_MD2_DES_CBC, CKM_PBE_SHA1_RC2_40_CBC,
362 CKM_SHA1_KEY_DERIVATION,
363 "PBE_MD2_DES_CBC",
364 "PBE_MD5_DES_CBC",
365 "PBE_MD5_CAST_CBC",
366 "PBE_MD5_CAST3_CBC",
367 "PBE_MD5_CAST128_CBC",
368 "PBE_SHA1_CAST128_CBC",
369 "PBE_SHA1_RC4_128",
370 "PBE_SHA1_RC4_40",
371 "PBE_SHA1_DES3_EDE_CBC",
372 "PBE_SHA1_DES2_EDE_CBC",
373 "PBE_SHA1_RC2_128_CBC",
374 "PBE_SHA1_RC2_40_CBC");
375 ENUM_NEXT(ck_mech_names, CKM_PKCS5_PBKD2, CKM_PKCS5_PBKD2,
376 CKM_PBE_SHA1_RC2_40_CBC,
377 "PKCS5_PBKD2");
378 ENUM_NEXT(ck_mech_names, CKM_PBA_SHA1_WITH_SHA1_HMAC, CKM_PBA_SHA1_WITH_SHA1_HMAC,
379 CKM_PKCS5_PBKD2,
380 "PBA_SHA1_WITH_SHA1_HMAC");
381 ENUM_NEXT(ck_mech_names, CKM_KEY_WRAP_LYNKS, CKM_KEY_WRAP_SET_OAEP,
382 CKM_PBA_SHA1_WITH_SHA1_HMAC,
383 "KEY_WRAP_LYNKS",
384 "KEY_WRAP_SET_OAEP");
385 ENUM_NEXT(ck_mech_names, CKM_SKIPJACK_KEY_GEN, CKM_SKIPJACK_RELAYX,
386 CKM_KEY_WRAP_SET_OAEP,
387 "SKIPJACK_KEY_GEN",
388 "SKIPJACK_ECB64",
389 "SKIPJACK_CBC64",
390 "SKIPJACK_OFB64",
391 "SKIPJACK_CFB64",
392 "SKIPJACK_CFB32",
393 "SKIPJACK_CFB16",
394 "SKIPJACK_CFB8",
395 "SKIPJACK_WRAP",
396 "SKIPJACK_PRIVATE_WRAP",
397 "SKIPJACK_RELAYX");
398 ENUM_NEXT(ck_mech_names, CKM_KEA_KEY_PAIR_GEN, CKM_KEA_KEY_DERIVE,
399 CKM_SKIPJACK_RELAYX,
400 "KEA_KEY_PAIR_GEN",
401 "KEA_KEY_DERIVE");
402 ENUM_NEXT(ck_mech_names, CKM_FORTEZZA_TIMESTAMP, CKM_FORTEZZA_TIMESTAMP,
403 CKM_KEA_KEY_DERIVE,
404 "FORTEZZA_TIMESTAMP");
405 ENUM_NEXT(ck_mech_names, CKM_BATON_KEY_GEN, CKM_BATON_WRAP,
406 CKM_FORTEZZA_TIMESTAMP,
407 "BATON_KEY_GEN",
408 "BATON_ECB128",
409 "BATON_ECB96",
410 "BATON_CBC128",
411 "BATON_COUNTER",
412 "BATON_SHUFFLE",
413 "BATON_WRAP");
414 ENUM_NEXT(ck_mech_names, CKM_ECDSA_KEY_PAIR_GEN, CKM_ECDSA_SHA1,
415 CKM_BATON_WRAP,
416 "ECDSA_KEY_PAIR_GEN",
417 "ECDSA",
418 "ECDSA_SHA1");
419 ENUM_NEXT(ck_mech_names, CKM_ECDH1_DERIVE, CKM_ECMQV_DERIVE,
420 CKM_ECDSA_SHA1,
421 "ECDH1_DERIVE",
422 "ECDH1_COFACTOR_DERIVE",
423 "ECMQV_DERIVE");
424 ENUM_NEXT(ck_mech_names, CKM_JUNIPER_KEY_GEN, CKM_JUNIPER_WRAP,
425 CKM_ECMQV_DERIVE,
426 "JUNIPER_KEY_GEN",
427 "JUNIPER_ECB128",
428 "JUNIPER_CBC128",
429 "JUNIPER_COUNTER",
430 "JUNIPER_SHUFFLE",
431 "JUNIPER_WRAP");
432 ENUM_NEXT(ck_mech_names, CKM_FASTHASH, CKM_FASTHASH,
433 CKM_JUNIPER_WRAP,
434 "FASTHASH");
435 ENUM_NEXT(ck_mech_names, CKM_AES_KEY_GEN, CKM_AES_CBC_PAD,
436 CKM_FASTHASH,
437 "AES_KEY_GEN",
438 "AES_ECB",
439 "AES_CBC",
440 "AES_MAC",
441 "AES_MAC_GENERAL",
442 "AES_CBC_PAD");
443 ENUM_NEXT(ck_mech_names, CKM_DSA_PARAMETER_GEN, CKM_X9_42_DH_PARAMETER_GEN,
444 CKM_AES_CBC_PAD,
445 "DSA_PARAMETER_GEN",
446 "DH_PKCS_PARAMETER_GEN",
447 "X9_42_DH_PARAMETER_GEN");
448 ENUM_END(ck_mech_names, CKM_X9_42_DH_PARAMETER_GEN);
449
450 /**
451 * Private data of an pkcs11_library_t object.
452 */
453 struct private_pkcs11_library_t {
454
455 /**
456 * Public pkcs11_library_t interface.
457 */
458 pkcs11_library_t public;
459
460 /**
461 * dlopen() handle
462 */
463 void *handle;
464
465 /**
466 * Name as passed to the constructor
467 */
468 char *name;
469
470 /**
471 * Supported feature set
472 */
473 pkcs11_feature_t features;
474 };
475
476 METHOD(pkcs11_library_t, get_name, char*,
477 private_pkcs11_library_t *this)
478 {
479 return this->name;
480 }
481
482 METHOD(pkcs11_library_t, get_features, pkcs11_feature_t,
483 private_pkcs11_library_t *this)
484 {
485 return this->features;
486 }
487
488 /**
489 * Object enumerator
490 */
491 typedef struct {
492 /* implements enumerator_t */
493 enumerator_t public;
494 /* session */
495 CK_SESSION_HANDLE session;
496 /* pkcs11 library */
497 pkcs11_library_t *lib;
498 /* attributes to retreive */
499 CK_ATTRIBUTE_PTR attr;
500 /* number of attributes */
501 CK_ULONG count;
502 /* currently allocated attributes, to free */
503 linked_list_t *freelist;
504 } object_enumerator_t;
505
506 /**
507 * Free contents of attributes in a list
508 */
509 static void free_attrs(object_enumerator_t *this)
510 {
511 CK_ATTRIBUTE_PTR attr;
512
513 while (this->freelist->remove_last(this->freelist, (void**)&attr) == SUCCESS)
514 {
515 free(attr->pValue);
516 attr->pValue = NULL;
517 attr->ulValueLen = 0;
518 }
519 }
520
521 /**
522 * Get attributes for a given object during enumeration
523 */
524 static bool get_attributes(object_enumerator_t *this, CK_OBJECT_HANDLE object)
525 {
526 CK_RV rv;
527 int i;
528
529 free_attrs(this);
530
531 /* get length of objects first */
532 rv = this->lib->f->C_GetAttributeValue(this->session, object,
533 this->attr, this->count);
534 if (rv != CKR_OK)
535 {
536 DBG1(DBG_CFG, "C_GetAttributeValue(NULL) error: %N", ck_rv_names, rv);
537 return FALSE;
538 }
539 /* allocate required chunks */
540 for (i = 0; i < this->count; i++)
541 {
542 if (this->attr[i].pValue == NULL &&
543 this->attr[i].ulValueLen != 0 && this->attr[i].ulValueLen != -1)
544 {
545 this->attr[i].pValue = malloc(this->attr[i].ulValueLen);
546 this->freelist->insert_last(this->freelist, &this->attr[i]);
547 }
548 }
549 /* get the data */
550 rv = this->lib->f->C_GetAttributeValue(this->session, object,
551 this->attr, this->count);
552 if (rv != CKR_OK)
553 {
554 free_attrs(this);
555 DBG1(DBG_CFG, "C_GetAttributeValue(NULL) error: %N", ck_rv_names, rv);
556 return FALSE;
557 }
558 return TRUE;
559 }
560
561 METHOD(enumerator_t, object_enumerate, bool,
562 object_enumerator_t *this, CK_OBJECT_HANDLE *out)
563 {
564 CK_OBJECT_HANDLE object;
565 CK_ULONG found;
566 CK_RV rv;
567
568 rv = this->lib->f->C_FindObjects(this->session, &object, 1, &found);
569 if (rv != CKR_OK)
570 {
571 DBG1(DBG_CFG, "C_FindObjects() failed: %N", ck_rv_names, rv);
572 return FALSE;
573 }
574 if (found)
575 {
576 if (this->attr)
577 {
578 if (!get_attributes(this, object))
579 {
580 return FALSE;
581 }
582 }
583 *out = object;
584 return TRUE;
585 }
586 return FALSE;
587 }
588
589 METHOD(enumerator_t, object_destroy, void,
590 object_enumerator_t *this)
591 {
592 this->lib->f->C_FindObjectsFinal(this->session);
593 free_attrs(this);
594 this->freelist->destroy(this->freelist);
595 free(this);
596 }
597
598 METHOD(pkcs11_library_t, create_object_enumerator, enumerator_t*,
599 private_pkcs11_library_t *this, CK_SESSION_HANDLE session,
600 CK_ATTRIBUTE_PTR tmpl, CK_ULONG tcount,
601 CK_ATTRIBUTE_PTR attr, CK_ULONG acount)
602 {
603 object_enumerator_t *enumerator;
604 CK_RV rv;
605
606 rv = this->public.f->C_FindObjectsInit(session, tmpl, tcount);
607 if (rv != CKR_OK)
608 {
609 DBG1(DBG_CFG, "C_FindObjectsInit() failed: %N", ck_rv_names, rv);
610 return enumerator_create_empty();
611 }
612
613 INIT(enumerator,
614 .public = {
615 .enumerate = (void*)_object_enumerate,
616 .destroy = _object_destroy,
617 },
618 .session = session,
619 .lib = &this->public,
620 .attr = attr,
621 .count = acount,
622 .freelist = linked_list_create(),
623 );
624 return &enumerator->public;
625 }
626
627 /**
628 * Enumerator over mechanisms
629 */
630 typedef struct {
631 /* implements enumerator_t */
632 enumerator_t public;
633 /* PKCS#11 library */
634 pkcs11_library_t *lib;
635 /* slot of token */
636 CK_SLOT_ID slot;
637 /* mechanism type list */
638 CK_MECHANISM_TYPE_PTR mechs;
639 /* number of mechanism types */
640 CK_ULONG count;
641 /* current mechanism */
642 CK_ULONG current;
643 } mechanism_enumerator_t;
644
645 METHOD(enumerator_t, enumerate_mech, bool,
646 mechanism_enumerator_t *this, CK_MECHANISM_TYPE* type,
647 CK_MECHANISM_INFO *info)
648 {
649 CK_RV rv;
650
651 if (this->current >= this->count)
652 {
653 return FALSE;
654 }
655 if (info)
656 {
657 rv = this->lib->f->C_GetMechanismInfo(this->slot,
658 this->mechs[this->current], info);
659 if (rv != CKR_OK)
660 {
661 DBG1(DBG_CFG, "C_GetMechanismInfo() failed: %N", ck_rv_names, rv);
662 return FALSE;
663 }
664 }
665 *type = this->mechs[this->current++];
666 return TRUE;
667 }
668
669 METHOD(enumerator_t, destroy_mech, void,
670 mechanism_enumerator_t *this)
671 {
672 free(this->mechs);
673 free(this);
674 }
675
676 METHOD(pkcs11_library_t, create_mechanism_enumerator, enumerator_t*,
677 private_pkcs11_library_t *this, CK_SLOT_ID slot)
678 {
679 mechanism_enumerator_t *enumerator;
680 CK_RV rv;
681
682 INIT(enumerator,
683 .public = {
684 .enumerate = (void*)_enumerate_mech,
685 .destroy = _destroy_mech,
686 },
687 .lib = &this->public,
688 .slot = slot,
689 );
690
691 rv = enumerator->lib->f->C_GetMechanismList(slot, NULL, &enumerator->count);
692 if (rv != CKR_OK)
693 {
694 DBG1(DBG_CFG, "C_GetMechanismList() failed: %N", ck_rv_names, rv);
695 free(enumerator);
696 return enumerator_create_empty();
697 }
698 enumerator->mechs = malloc(sizeof(CK_MECHANISM_TYPE) * enumerator->count);
699 enumerator->lib->f->C_GetMechanismList(slot, enumerator->mechs,
700 &enumerator->count);
701 if (rv != CKR_OK)
702 {
703 DBG1(DBG_CFG, "C_GetMechanismList() failed: %N", ck_rv_names, rv);
704 destroy_mech(enumerator);
705 return enumerator_create_empty();
706 }
707 return &enumerator->public;
708 }
709
710 METHOD(pkcs11_library_t, destroy, void,
711 private_pkcs11_library_t *this)
712 {
713 this->public.f->C_Finalize(NULL);
714 dlclose(this->handle);
715 free(this);
716 }
717
718 /**
719 * See header
720 */
721 void pkcs11_library_trim(char *str, int len)
722 {
723 int i;
724
725 str[len - 1] = '\0';
726 for (i = len - 2; i > 0; i--)
727 {
728 if (str[i] == ' ')
729 {
730 str[i] = '\0';
731 continue;
732 }
733 break;
734 }
735 }
736
737 /**
738 * Mutex creation callback
739 */
740 static CK_RV CreateMutex(CK_VOID_PTR_PTR data)
741 {
742 *data = mutex_create(MUTEX_TYPE_DEFAULT);
743 return CKR_OK;
744 }
745
746 /**
747 * Mutex destruction callback
748 */
749 static CK_RV DestroyMutex(CK_VOID_PTR data)
750 {
751 mutex_t *mutex = (mutex_t*)data;
752
753 mutex->destroy(mutex);
754 return CKR_OK;
755 }
756
757 /**
758 * Mutex lock callback
759 */
760 static CK_RV LockMutex(CK_VOID_PTR data)
761 {
762 mutex_t *mutex = (mutex_t*)data;
763
764 mutex->lock(mutex);
765 return CKR_OK;
766 }
767
768 /**
769 * Mutex unlock callback
770 */
771 static CK_RV UnlockMutex(CK_VOID_PTR data)
772 {
773 mutex_t *mutex = (mutex_t*)data;
774
775 mutex->unlock(mutex);
776 return CKR_OK;
777 }
778
779 /**
780 * Check if the library has at least a given cryptoki version
781 */
782 static bool has_version(CK_INFO *info, int major, int minor)
783 {
784 return info->cryptokiVersion.major > major ||
785 (info->cryptokiVersion.major == major &&
786 info->cryptokiVersion.minor >= minor);
787 }
788
789 /**
790 * Check for optional PKCS#11 library functionality
791 */
792 static void check_features(private_pkcs11_library_t *this, CK_INFO *info)
793 {
794 if (has_version(info, 2, 20))
795 {
796 this->features |= PKCS11_TRUSTED_CERTS;
797 }
798 }
799
800 /**
801 * Initialize a PKCS#11 library
802 */
803 static bool initialize(private_pkcs11_library_t *this, char *name, char *file,
804 bool os_locking)
805 {
806 CK_C_GetFunctionList pC_GetFunctionList;
807 CK_INFO info;
808 CK_RV rv;
809 static CK_C_INITIALIZE_ARGS args = {
810 .CreateMutex = CreateMutex,
811 .DestroyMutex = DestroyMutex,
812 .LockMutex = LockMutex,
813 .UnlockMutex = UnlockMutex,
814 };
815 static CK_C_INITIALIZE_ARGS args_os = {
816 .flags = CKF_OS_LOCKING_OK,
817 };
818
819 pC_GetFunctionList = dlsym(this->handle, "C_GetFunctionList");
820 if (!pC_GetFunctionList)
821 {
822 DBG1(DBG_CFG, "C_GetFunctionList not found for '%s': %s", name, dlerror());
823 return FALSE;
824 }
825 rv = pC_GetFunctionList(&this->public.f);
826 if (rv != CKR_OK)
827 {
828 DBG1(DBG_CFG, "C_GetFunctionList() error for '%s': %N",
829 name, ck_rv_names, rv);
830 return FALSE;
831 }
832 if (os_locking)
833 {
834 rv = CKR_CANT_LOCK;
835 }
836 else
837 {
838 rv = this->public.f->C_Initialize(&args);
839 }
840 if (rv == CKR_CANT_LOCK)
841 { /* fallback to OS locking */
842 os_locking = TRUE;
843 rv = this->public.f->C_Initialize(&args_os);
844 }
845 if (rv != CKR_OK)
846 {
847 DBG1(DBG_CFG, "C_Initialize() error for '%s': %N",
848 name, ck_rv_names, rv);
849 return FALSE;
850 }
851 rv = this->public.f->C_GetInfo(&info);
852 if (rv != CKR_OK)
853 {
854 DBG1(DBG_CFG, "C_GetInfo() error for '%s': %N",
855 name, ck_rv_names, rv);
856 this->public.f->C_Finalize(NULL);
857 return FALSE;
858 }
859
860 pkcs11_library_trim(info.manufacturerID,
861 strnlen(info.manufacturerID, sizeof(info.manufacturerID)));
862 pkcs11_library_trim(info.libraryDescription,
863 strnlen(info.libraryDescription, sizeof(info.libraryDescription)));
864
865 DBG1(DBG_CFG, "loaded PKCS#11 v%d.%d library '%s' (%s)",
866 info.cryptokiVersion.major, info.cryptokiVersion.minor, name, file);
867 DBG1(DBG_CFG, " %s: %s v%d.%d",
868 info.manufacturerID, info.libraryDescription,
869 info.libraryVersion.major, info.libraryVersion.minor);
870 if (os_locking)
871 {
872 DBG1(DBG_CFG, " uses OS locking functions");
873 }
874
875 check_features(this, &info);
876 return TRUE;
877 }
878
879 /**
880 * See header
881 */
882 pkcs11_library_t *pkcs11_library_create(char *name, char *file, bool os_locking)
883 {
884 private_pkcs11_library_t *this;
885
886 INIT(this,
887 .public = {
888 .get_name = _get_name,
889 .get_features = _get_features,
890 .create_object_enumerator = _create_object_enumerator,
891 .create_mechanism_enumerator = _create_mechanism_enumerator,
892 .destroy = _destroy,
893 },
894 .name = name,
895 .handle = dlopen(file, RTLD_LAZY),
896 );
897
898 if (!this->handle)
899 {
900 DBG1(DBG_CFG, "opening PKCS#11 library failed: %s", dlerror());
901 free(this);
902 return NULL;
903 }
904
905 if (!initialize(this, name, file, os_locking))
906 {
907 dlclose(this->handle);
908 free(this);
909 return NULL;
910 }
911
912 return &this->public;
913 }