]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/libstrongswan/plugins/pkcs11/pkcs11_library.c
Moved debug.[ch] to utils folder
[thirdparty/strongswan.git] / src / libstrongswan / plugins / pkcs11 / pkcs11_library.c
CommitLineData
34454dc3 1/*
85311065
TB
2 * Copyright (C) 2011 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
34454dc3
MW
5 * Copyright (C) 2010 Martin Willi
6 * Copyright (C) 2010 revosec AG
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 */
18
19#include "pkcs11_library.h"
20
21#include <dlfcn.h>
22
23#include <library.h>
f05b4272 24#include <utils/debug.h>
50e1a710 25#include <threading/mutex.h>
12642a68 26#include <collections/linked_list.h>
34454dc3
MW
27
28typedef struct private_pkcs11_library_t private_pkcs11_library_t;
29
a6456dd6
MW
30
31ENUM_BEGIN(ck_rv_names, CKR_OK, CKR_CANT_LOCK,
32 "OK",
33 "CANCEL",
34 "HOST_MEMORY",
35 "SLOT_ID_INVALID",
36 "(0x04)",
37 "GENERAL_ERROR",
38 "FUNCTION_FAILED",
39 "ARGUMENTS_BAD",
40 "NO_EVENT",
41 "NEED_TO_CREATE_THREADS",
42 "CANT_LOCK");
43ENUM_NEXT(ck_rv_names, CKR_ATTRIBUTE_READ_ONLY, CKR_ATTRIBUTE_VALUE_INVALID,
44 CKR_CANT_LOCK,
45 "ATTRIBUTE_READ_ONLY",
46 "ATTRIBUTE_SENSITIVE",
47 "ATTRIBUTE_TYPE_INVALID",
48 "ATTRIBUTE_VALUE_INVALID");
49ENUM_NEXT(ck_rv_names, CKR_DATA_INVALID, CKR_DATA_LEN_RANGE,
50 CKR_ATTRIBUTE_VALUE_INVALID,
51 "DATA_INVALID"
52 "DATA_LEN_RANGE");
53ENUM_NEXT(ck_rv_names, CKR_DEVICE_ERROR, CKR_DEVICE_REMOVED,
54 CKR_DATA_LEN_RANGE,
55 "DEVICE_ERROR",
56 "DEVICE_MEMORY",
57 "DEVICE_REMOVED");
58ENUM_NEXT(ck_rv_names, CKR_ENCRYPTED_DATA_INVALID, CKR_ENCRYPTED_DATA_LEN_RANGE,
59 CKR_DEVICE_REMOVED,
60 "ENCRYPTED_DATA_INVALID",
61 "ENCRYPTED_DATA_LEN_RANGE");
62ENUM_NEXT(ck_rv_names, CKR_FUNCTION_CANCELED, CKR_FUNCTION_NOT_SUPPORTED,
63 CKR_ENCRYPTED_DATA_LEN_RANGE,
64 "FUNCTION_CANCELED",
65 "FUNCTION_NOT_PARALLEL",
66 "(0x52)",
67 "(0x53)",
68 "FUNCTION_NOT_SUPPORTED");
69ENUM_NEXT(ck_rv_names, CKR_KEY_HANDLE_INVALID, CKR_KEY_UNEXTRACTABLE,
70 CKR_FUNCTION_NOT_SUPPORTED,
71 "KEY_HANDLE_INVALID",
72 "(0x61)",
73 "KEY_SIZE_RANGE",
74 "KEY_TYPE_INCONSISTENT",
75 "KEY_NOT_NEEDED",
76 "KEY_CHANGED",
77 "KEY_NEEDED",
78 "KEY_INDIGESTIBLE",
79 "KEY_FUNCTION_NOT_PERMITTED",
80 "KEY_NOT_WRAPPABLE",
81 "KEY_UNEXTRACTABLE");
82ENUM_NEXT(ck_rv_names, CKR_MECHANISM_INVALID, CKR_MECHANISM_PARAM_INVALID,
83 CKR_KEY_UNEXTRACTABLE,
84 "MECHANISM_INVALID",
85 "MECHANISM_PARAM_INVALID");
86ENUM_NEXT(ck_rv_names, CKR_OBJECT_HANDLE_INVALID, CKR_OBJECT_HANDLE_INVALID,
87 CKR_MECHANISM_PARAM_INVALID,
88 "OBJECT_HANDLE_INVALID");
89ENUM_NEXT(ck_rv_names, CKR_OPERATION_ACTIVE, CKR_OPERATION_NOT_INITIALIZED,
90 CKR_OBJECT_HANDLE_INVALID,
91 "OPERATION_ACTIVE",
92 "OPERATION_NOT_INITIALIZED");
93ENUM_NEXT(ck_rv_names, CKR_PIN_INCORRECT, CKR_PIN_LOCKED,
94 CKR_OPERATION_NOT_INITIALIZED,
95 "PIN_INCORRECT",
96 "PIN_INVALID",
97 "PIN_LEN_RANGE",
98 "PIN_EXPIRED",
99 "PIN_LOCKED");
100ENUM_NEXT(ck_rv_names, CKR_SESSION_CLOSED, CKR_SESSION_READ_WRITE_SO_EXISTS,
101 CKR_PIN_LOCKED,
102 "SESSION_CLOSED",
103 "SESSION_COUNT",
104 "(0xb2)",
105 "SESSION_HANDLE_INVALID",
106 "SESSION_PARALLEL_NOT_SUPPORTED",
107 "SESSION_READ_ONLY",
108 "SESSION_EXISTS",
109 "SESSION_READ_ONLY_EXISTS",
110 "SESSION_READ_WRITE_SO_EXISTS");
111ENUM_NEXT(ck_rv_names, CKR_SIGNATURE_INVALID, CKR_SIGNATURE_LEN_RANGE,
112 CKR_SESSION_READ_WRITE_SO_EXISTS,
113 "SIGNATURE_INVALID",
114 "SIGNATURE_LEN_RANGE");
115ENUM_NEXT(ck_rv_names, CKR_TEMPLATE_INCOMPLETE, CKR_TEMPLATE_INCONSISTENT,
116 CKR_SIGNATURE_LEN_RANGE,
117 "TEMPLATE_INCOMPLETE",
118 "TEMPLATE_INCONSISTENT",
119);
120ENUM_NEXT(ck_rv_names, CKR_TOKEN_NOT_PRESENT, CKR_TOKEN_WRITE_PROTECTED,
121 CKR_TEMPLATE_INCONSISTENT,
122 "TOKEN_NOT_PRESENT",
123 "TOKEN_NOT_RECOGNIZED",
124 "TOKEN_WRITE_PROTECTED");
125ENUM_NEXT(ck_rv_names, CKR_UNWRAPPING_KEY_HANDLE_INVALID, CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT,
126 CKR_TOKEN_WRITE_PROTECTED,
127 "UNWRAPPING_KEY_HANDLE_INVALID",
128 "UNWRAPPING_KEY_SIZE_RANGE",
129 "UNWRAPPING_KEY_TYPE_INCONSISTENT");
130ENUM_NEXT(ck_rv_names, CKR_USER_ALREADY_LOGGED_IN, CKR_USER_TOO_MANY_TYPES,
131 CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT,
132 "USER_ALREADY_LOGGED_IN",
133 "USER_NOT_LOGGED_IN",
134 "USER_PIN_NOT_INITIALIZED",
135 "USER_TYPE_INVALID",
136 "USER_ANOTHER_ALREADY_LOGGED_IN",
137 "USER_TOO_MANY_TYPES");
138ENUM_NEXT(ck_rv_names, CKR_WRAPPED_KEY_INVALID, CKR_WRAPPING_KEY_TYPE_INCONSISTENT,
139 CKR_USER_TOO_MANY_TYPES,
140 "WRAPPED_KEY_INVALID",
141 "(0x111)",
142 "WRAPPED_KEY_LEN_RANGE",
143 "WRAPPING_KEY_HANDLE_INVALID",
144 "WRAPPING_KEY_SIZE_RANGE",
145 "WRAPPING_KEY_TYPE_INCONSISTENT");
146ENUM_NEXT(ck_rv_names, CKR_RANDOM_SEED_NOT_SUPPORTED, CKR_RANDOM_NO_RNG,
147 CKR_WRAPPING_KEY_TYPE_INCONSISTENT,
148 "RANDOM_SEED_NOT_SUPPORTED",
149 "RANDOM_NO_RNG");
150ENUM_NEXT(ck_rv_names, CKR_DOMAIN_PARAMS_INVALID, CKR_DOMAIN_PARAMS_INVALID,
151 CKR_RANDOM_NO_RNG,
152 "DOMAIN_PARAMS_INVALID");
153ENUM_NEXT(ck_rv_names, CKR_BUFFER_TOO_SMALL, CKR_BUFFER_TOO_SMALL,
154 CKR_DOMAIN_PARAMS_INVALID,
155 "BUFFER_TOO_SMALL");
156ENUM_NEXT(ck_rv_names, CKR_SAVED_STATE_INVALID, CKR_SAVED_STATE_INVALID,
157 CKR_BUFFER_TOO_SMALL,
158 "SAVED_STATE_INVALID");
159ENUM_NEXT(ck_rv_names, CKR_INFORMATION_SENSITIVE, CKR_INFORMATION_SENSITIVE,
160 CKR_SAVED_STATE_INVALID,
161 "INFORMATION_SENSITIVE");
162ENUM_NEXT(ck_rv_names, CKR_STATE_UNSAVEABLE, CKR_STATE_UNSAVEABLE,
163 CKR_INFORMATION_SENSITIVE,
164 "STATE_UNSAVEABLE");
165ENUM_NEXT(ck_rv_names, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_CRYPTOKI_ALREADY_INITIALIZED,
166 CKR_STATE_UNSAVEABLE,
167 "CRYPTOKI_NOT_INITIALIZED",
168 "CRYPTOKI_ALREADY_INITIALIZED");
169ENUM_NEXT(ck_rv_names, CKR_MUTEX_BAD, CKR_MUTEX_NOT_LOCKED,
170 CKR_CRYPTOKI_ALREADY_INITIALIZED,
171 "MUTEX_BAD",
172 "MUTEX_NOT_LOCKED");
173ENUM_NEXT(ck_rv_names, CKR_FUNCTION_REJECTED, CKR_FUNCTION_REJECTED,
174 CKR_MUTEX_NOT_LOCKED,
175 "FUNCTION_REJECTED");
176ENUM_END(ck_rv_names, CKR_FUNCTION_REJECTED);
177
178
75451ac8
MW
179ENUM_BEGIN(ck_mech_names, CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_DSA_SHA1,
180 "RSA_PKCS_KEY_PAIR_GEN",
181 "RSA_PKCS",
182 "RSA_9796",
183 "RSA_X_509",
184 "MD2_RSA_PKCS",
185 "MD5_RSA_PKCS",
186 "SHA1_RSA_PKCS",
187 "RIPEMD128_RSA_PKCS",
188 "RIPEMD160_RSA_PKCS",
189 "RSA_PKCS_OAEP",
190 "RSA_X9_31_KEY_PAIR_GEN",
191 "RSA_X9_31",
192 "SHA1_RSA_X9_31",
193 "RSA_PKCS_PSS",
194 "SHA1_RSA_PKCS_PSS",
195 "(0xf)",
196 "DSA_KEY_PAIR_GEN",
197 "DSA",
198 "DSA_SHA1");
199ENUM_NEXT(ck_mech_names, CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE,
200 CKM_DSA_SHA1,
201 "DH_PKCS_KEY_PAIR_GEN",
202 "DH_PKCS_DERIVE");
203ENUM_NEXT(ck_mech_names, CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_MQV_DERIVE,
204 CKM_DH_PKCS_DERIVE,
205 "X9_42_DH_KEY_PAIR_GEN",
206 "X9_42_DH_DERIVE",
207 "X9_42_DH_HYBRID_DERIVE",
208 "X9_42_MQV_DERIVE");
209ENUM_NEXT(ck_mech_names, CKM_SHA256_RSA_PKCS, CKM_SHA512_RSA_PKCS_PSS,
210 CKM_X9_42_MQV_DERIVE,
211 "SHA256_RSA_PKCS",
212 "SHA384_RSA_PKCS",
213 "SHA512_RSA_PKCS",
214 "SHA256_RSA_PKCS_PSS",
215 "SHA384_RSA_PKCS_PSS",
216 "SHA512_RSA_PKCS_PSS");
217ENUM_NEXT(ck_mech_names, CKM_RC2_KEY_GEN, CKM_RC2_CBC_PAD,
218 CKM_SHA512_RSA_PKCS_PSS,
219 "RC2_KEY_GEN",
220 "RC2_ECB",
221 "RC2_CBC",
222 "RC2_MAC",
223 "RC2_MAC_GENERAL",
224 "RC2_CBC_PAD");
225ENUM_NEXT(ck_mech_names, CKM_RC4_KEY_GEN, CKM_RC4,
226 CKM_RC2_CBC_PAD,
227 "RC4_KEY_GEN",
228 "RC4");
229ENUM_NEXT(ck_mech_names, CKM_DES_KEY_GEN, CKM_DES_CBC_PAD,
230 CKM_RC4,
231 "DES_KEY_GEN",
232 "DES_ECB",
233 "DES_CBC",
234 "DES_MAC",
235 "DES_MAC_GENERAL",
236 "DES_CBC_PAD");
237ENUM_NEXT(ck_mech_names, CKM_DES2_KEY_GEN, CKM_DES3_CBC_PAD,
238 CKM_DES_CBC_PAD,
239 "DES2_KEY_GEN",
240 "DES3_KEY_GEN",
241 "DES3_ECB",
242 "DES3_CBC",
243 "DES3_MAC",
244 "DES3_MAC_GENERAL",
245 "DES3_CBC_PAD");
246ENUM_NEXT(ck_mech_names, CKM_CDMF_KEY_GEN, CKM_CDMF_CBC_PAD,
247 CKM_DES3_CBC_PAD,
248 "CDMF_KEY_GEN",
249 "CDMF_ECB",
250 "CDMF_CBC",
251 "CDMF_MAC",
252 "CDMF_MAC_GENERAL",
253 "CDMF_CBC_PAD");
254ENUM_NEXT(ck_mech_names, CKM_MD2, CKM_MD2_HMAC_GENERAL,
255 CKM_CDMF_CBC_PAD,
256 "MD2",
257 "MD2_HMAC",
258 "MD2_HMAC_GENERAL");
259ENUM_NEXT(ck_mech_names, CKM_MD5, CKM_MD5_HMAC_GENERAL,
260 CKM_MD2_HMAC_GENERAL,
261 "MD5",
262 "MD5_HMAC",
263 "MD5_HMAC_GENERAL");
264ENUM_NEXT(ck_mech_names, CKM_SHA_1, CKM_SHA_1_HMAC_GENERAL,
265 CKM_MD5_HMAC_GENERAL,
266 "SHA_1",
267 "SHA_1_HMAC",
268 "SHA_1_HMAC_GENERAL");
269ENUM_NEXT(ck_mech_names, CKM_RIPEMD128, CKM_RIPEMD128_HMAC_GENERAL,
270 CKM_SHA_1_HMAC_GENERAL,
271 "RIPEMD128",
272 "RIPEMD128_HMAC",
273 "RIPEMD128_HMAC_GENERAL");
274ENUM_NEXT(ck_mech_names, CKM_RIPEMD160, CKM_RIPEMD160_HMAC_GENERAL,
275 CKM_RIPEMD128_HMAC_GENERAL,
276 "RIPEMD160",
277 "RIPEMD160_HMAC",
278 "RIPEMD160_HMAC_GENERAL");
279ENUM_NEXT(ck_mech_names, CKM_SHA256, CKM_SHA256_HMAC_GENERAL,
280 CKM_RIPEMD160_HMAC_GENERAL,
281 "SHA256",
282 "SHA256_HMAC",
283 "SHA256_HMAC_GENERAL");
284ENUM_NEXT(ck_mech_names, CKM_SHA384, CKM_SHA384_HMAC_GENERAL,
285 CKM_SHA256_HMAC_GENERAL,
286 "SHA384",
287 "SHA384_HMAC",
288 "SHA384_HMAC_GENERAL");
289ENUM_NEXT(ck_mech_names, CKM_SHA512, CKM_SHA512_HMAC_GENERAL,
290 CKM_SHA384_HMAC_GENERAL ,
291 "SHA512",
292 "SHA512_HMAC",
293 "SHA512_HMAC_GENERAL");
294ENUM_NEXT(ck_mech_names, CKM_CAST_KEY_GEN, CKM_CAST_CBC_PAD,
295 CKM_SHA512_HMAC_GENERAL,
296 "CAST_KEY_GEN",
297 "CAST_ECB",
298 "CAST_CBC",
299 "CAST_MAC",
300 "CAST_MAC_GENERAL",
301 "CAST_CBC_PAD");
302ENUM_NEXT(ck_mech_names, CKM_CAST3_KEY_GEN, CKM_CAST3_CBC_PAD,
303 CKM_CAST_CBC_PAD,
304 "CAST3_KEY_GEN",
305 "CAST3_ECB",
306 "CAST3_CBC",
307 "CAST3_MAC",
308 "CAST3_MAC_GENERAL",
309 "CAST3_CBC_PAD");
310ENUM_NEXT(ck_mech_names, CKM_CAST128_KEY_GEN, CKM_CAST128_CBC_PAD,
311 CKM_CAST3_CBC_PAD,
312 "CAST128_KEY_GEN",
313 "CAST128_ECB",
314 "CAST128_CBC",
315 "CAST128_MAC",
316 "CAST128_MAC_GENERAL",
317 "CAST128_CBC_PAD");
318ENUM_NEXT(ck_mech_names, CKM_RC5_KEY_GEN, CKM_RC5_CBC_PAD,
319 CKM_CAST128_CBC_PAD,
320 "RC5_KEY_GEN",
321 "RC5_ECB",
322 "RC5_CBC",
323 "RC5_MAC",
324 "RC5_MAC_GENERAL",
325 "RC5_CBC_PAD");
326ENUM_NEXT(ck_mech_names, CKM_IDEA_KEY_GEN, CKM_IDEA_CBC_PAD,
327 CKM_RC5_CBC_PAD,
328 "IDEA_KEY_GEN",
329 "IDEA_ECB",
330 "IDEA_CBC",
331 "IDEA_MAC",
332 "IDEA_MAC_GENERAL",
333 "IDEA_CBC_PAD");
334ENUM_NEXT(ck_mech_names, CKM_GENERIC_SECRET_KEY_GEN, CKM_GENERIC_SECRET_KEY_GEN,
335 CKM_IDEA_CBC_PAD,
336 "GENERIC_SECRET_KEY_GEN");
337ENUM_NEXT(ck_mech_names, CKM_CONCATENATE_BASE_AND_KEY, CKM_EXTRACT_KEY_FROM_KEY,
338 CKM_GENERIC_SECRET_KEY_GEN,
339 "CONCATENATE_BASE_AND_KEY",
340 "(0x361)",
341 "CONCATENATE_BASE_AND_DATA",
342 "CONCATENATE_DATA_AND_BASE",
343 "XOR_BASE_AND_DATA",
344 "EXTRACT_KEY_FROM_KEY");
345ENUM_NEXT(ck_mech_names, CKM_SSL3_PRE_MASTER_KEY_GEN, CKM_TLS_MASTER_KEY_DERIVE_DH,
346 CKM_EXTRACT_KEY_FROM_KEY,
347 "SSL3_PRE_MASTER_KEY_GEN",
348 "SSL3_MASTER_KEY_DERIVE",
349 "SSL3_KEY_AND_MAC_DERIVE",
350 "SSL3_MASTER_KEY_DERIVE_DH",
351 "TLS_PRE_MASTER_KEY_GEN",
352 "TLS_MASTER_KEY_DERIVE",
353 "TLS_KEY_AND_MAC_DERIVE",
354 "TLS_MASTER_KEY_DERIVE_DH");
355ENUM_NEXT(ck_mech_names, CKM_SSL3_MD5_MAC, CKM_SSL3_SHA1_MAC,
356 CKM_TLS_MASTER_KEY_DERIVE_DH,
357 "SSL3_MD5_MAC",
358 "SSL3_SHA1_MAC");
359ENUM_NEXT(ck_mech_names, CKM_MD5_KEY_DERIVATION, CKM_SHA1_KEY_DERIVATION,
360 CKM_SSL3_SHA1_MAC,
361 "MD5_KEY_DERIVATION",
362 "MD2_KEY_DERIVATION",
363 "SHA1_KEY_DERIVATION");
364ENUM_NEXT(ck_mech_names, CKM_PBE_MD2_DES_CBC, CKM_PBE_SHA1_RC2_40_CBC,
365 CKM_SHA1_KEY_DERIVATION,
366 "PBE_MD2_DES_CBC",
367 "PBE_MD5_DES_CBC",
368 "PBE_MD5_CAST_CBC",
369 "PBE_MD5_CAST3_CBC",
370 "PBE_MD5_CAST128_CBC",
371 "PBE_SHA1_CAST128_CBC",
372 "PBE_SHA1_RC4_128",
373 "PBE_SHA1_RC4_40",
374 "PBE_SHA1_DES3_EDE_CBC",
375 "PBE_SHA1_DES2_EDE_CBC",
376 "PBE_SHA1_RC2_128_CBC",
377 "PBE_SHA1_RC2_40_CBC");
378ENUM_NEXT(ck_mech_names, CKM_PKCS5_PBKD2, CKM_PKCS5_PBKD2,
379 CKM_PBE_SHA1_RC2_40_CBC,
380 "PKCS5_PBKD2");
381ENUM_NEXT(ck_mech_names, CKM_PBA_SHA1_WITH_SHA1_HMAC, CKM_PBA_SHA1_WITH_SHA1_HMAC,
382 CKM_PKCS5_PBKD2,
383 "PBA_SHA1_WITH_SHA1_HMAC");
384ENUM_NEXT(ck_mech_names, CKM_KEY_WRAP_LYNKS, CKM_KEY_WRAP_SET_OAEP,
385 CKM_PBA_SHA1_WITH_SHA1_HMAC,
386 "KEY_WRAP_LYNKS",
387 "KEY_WRAP_SET_OAEP");
388ENUM_NEXT(ck_mech_names, CKM_SKIPJACK_KEY_GEN, CKM_SKIPJACK_RELAYX,
389 CKM_KEY_WRAP_SET_OAEP,
390 "SKIPJACK_KEY_GEN",
391 "SKIPJACK_ECB64",
392 "SKIPJACK_CBC64",
393 "SKIPJACK_OFB64",
394 "SKIPJACK_CFB64",
395 "SKIPJACK_CFB32",
396 "SKIPJACK_CFB16",
397 "SKIPJACK_CFB8",
398 "SKIPJACK_WRAP",
399 "SKIPJACK_PRIVATE_WRAP",
400 "SKIPJACK_RELAYX");
401ENUM_NEXT(ck_mech_names, CKM_KEA_KEY_PAIR_GEN, CKM_KEA_KEY_DERIVE,
402 CKM_SKIPJACK_RELAYX,
403 "KEA_KEY_PAIR_GEN",
404 "KEA_KEY_DERIVE");
405ENUM_NEXT(ck_mech_names, CKM_FORTEZZA_TIMESTAMP, CKM_FORTEZZA_TIMESTAMP,
406 CKM_KEA_KEY_DERIVE,
407 "FORTEZZA_TIMESTAMP");
408ENUM_NEXT(ck_mech_names, CKM_BATON_KEY_GEN, CKM_BATON_WRAP,
409 CKM_FORTEZZA_TIMESTAMP,
410 "BATON_KEY_GEN",
411 "BATON_ECB128",
412 "BATON_ECB96",
413 "BATON_CBC128",
414 "BATON_COUNTER",
415 "BATON_SHUFFLE",
416 "BATON_WRAP");
417ENUM_NEXT(ck_mech_names, CKM_ECDSA_KEY_PAIR_GEN, CKM_ECDSA_SHA1,
418 CKM_BATON_WRAP,
419 "ECDSA_KEY_PAIR_GEN",
420 "ECDSA",
421 "ECDSA_SHA1");
422ENUM_NEXT(ck_mech_names, CKM_ECDH1_DERIVE, CKM_ECMQV_DERIVE,
423 CKM_ECDSA_SHA1,
424 "ECDH1_DERIVE",
425 "ECDH1_COFACTOR_DERIVE",
426 "ECMQV_DERIVE");
427ENUM_NEXT(ck_mech_names, CKM_JUNIPER_KEY_GEN, CKM_JUNIPER_WRAP,
428 CKM_ECMQV_DERIVE,
429 "JUNIPER_KEY_GEN",
430 "JUNIPER_ECB128",
431 "JUNIPER_CBC128",
432 "JUNIPER_COUNTER",
433 "JUNIPER_SHUFFLE",
434 "JUNIPER_WRAP");
435ENUM_NEXT(ck_mech_names, CKM_FASTHASH, CKM_FASTHASH,
436 CKM_JUNIPER_WRAP,
437 "FASTHASH");
438ENUM_NEXT(ck_mech_names, CKM_AES_KEY_GEN, CKM_AES_CBC_PAD,
439 CKM_FASTHASH,
440 "AES_KEY_GEN",
441 "AES_ECB",
442 "AES_CBC",
443 "AES_MAC",
444 "AES_MAC_GENERAL",
445 "AES_CBC_PAD");
446ENUM_NEXT(ck_mech_names, CKM_DSA_PARAMETER_GEN, CKM_X9_42_DH_PARAMETER_GEN,
447 CKM_AES_CBC_PAD,
448 "DSA_PARAMETER_GEN",
449 "DH_PKCS_PARAMETER_GEN",
450 "X9_42_DH_PARAMETER_GEN");
451ENUM_END(ck_mech_names, CKM_X9_42_DH_PARAMETER_GEN);
452
6a5020fc
TB
453
454ENUM_BEGIN(ck_attr_names, CKA_CLASS, CKA_LABEL,
455 "CLASS",
456 "TOKEN",
457 "PRIVATE",
458 "LABEL");
459ENUM_NEXT(ck_attr_names, CKA_APPLICATION, CKA_OBJECT_ID, CKA_LABEL,
460 "APPLICATION",
461 "VALUE",
462 "OBJECT_ID");
463ENUM_NEXT(ck_attr_names, CKA_CERTIFICATE_TYPE, CKA_HASH_OF_ISSUER_PUBLIC_KEY,
464 CKA_OBJECT_ID,
465 "CERTIFICATE_TYPE",
466 "ISSUER",
467 "SERIAL_NUMBER",
468 "AC_ISSUER",
469 "OWNER",
470 "ATTR_TYPES",
471 "TRUSTED",
472 "CERTIFICATE_CATEGORY",
473 "JAVA_MIDP_SECURITY_DOMAIN",
474 "URL",
475 "HASH_OF_SUBJECT_PUBLIC_KEY",
476 "HASH_OF_ISSUER_PUBLIC_KEY");
477ENUM_NEXT(ck_attr_names, CKA_CHECK_VALUE, CKA_CHECK_VALUE,
478 CKA_HASH_OF_ISSUER_PUBLIC_KEY,
479 "CHECK_VALUE");
480ENUM_NEXT(ck_attr_names, CKA_KEY_TYPE, CKA_DERIVE, CKA_CHECK_VALUE,
481 "KEY_TYPE",
482 "SUBJECT",
483 "ID",
484 "SENSITIVE",
485 "ENCRYPT",
486 "DECRYPT",
487 "WRAP",
488 "UNWRAP",
489 "SIGN",
490 "SIGN_RECOVER",
491 "VERIFY",
492 "VERIFY_RECOVER",
493 "DERIVE");
494ENUM_NEXT(ck_attr_names, CKA_START_DATE, CKA_END_DATE, CKA_DERIVE,
495 "START_DATE",
496 "END_DATE");
497ENUM_NEXT(ck_attr_names, CKA_MODULUS, CKA_COEFFICIENT, CKA_END_DATE,
498 "MODULUS",
499 "MODULUS_BITS",
500 "PUBLIC_EXPONENT",
501 "PRIVATE_EXPONENT",
502 "PRIME_1",
503 "PRIME_2",
504 "EXPONENT_1",
505 "EXPONENT_2",
506 "COEFFICIENT");
507ENUM_NEXT(ck_attr_names, CKA_PRIME, CKA_SUB_PRIME_BITS, CKA_COEFFICIENT,
508 "PRIME",
509 "SUBPRIME",
510 "BASE",
511 "PRIME_BITS",
512 "SUB_PRIME_BITS");
513ENUM_NEXT(ck_attr_names, CKA_VALUE_BITS, CKA_KEY_GEN_MECHANISM,
514 CKA_SUB_PRIME_BITS,
515 "VALUE_BITS",
516 "VALUE_LEN",
517 "EXTRACTABLE",
518 "LOCAL",
519 "NEVER_EXTRACTABLE",
520 "ALWAYS_SENSITIVE",
521 "KEY_GEN_MECHANISM");
522ENUM_NEXT(ck_attr_names, CKA_MODIFIABLE, CKA_MODIFIABLE, CKA_KEY_GEN_MECHANISM,
523 "MODIFIABLE");
524ENUM_NEXT(ck_attr_names, CKA_EC_PARAMS, CKA_EC_POINT, CKA_MODIFIABLE,
525 "EC_PARAMS",
526 "EC_POINT");
527ENUM_NEXT(ck_attr_names, CKA_SECONDARY_AUTH, CKA_ALWAYS_AUTHENTICATE,
528 CKA_EC_POINT,
529 "SECONDARY_AUTH",
530 "AUTH_PIN_FLAGS",
531 "ALWAYS_AUTHENTICATE");
532ENUM_NEXT(ck_attr_names, CKA_WRAP_WITH_TRUSTED, CKA_WRAP_WITH_TRUSTED,
533 CKA_ALWAYS_AUTHENTICATE,
534 "WRAP_WITH_TRUSTED");
535ENUM_NEXT(ck_attr_names, CKA_HW_FEATURE_TYPE, CKA_HAS_RESET,
536 CKA_WRAP_WITH_TRUSTED,
537 "HW_FEATURE_TYPE",
538 "RESET_ON_INIT",
539 "HAS_RESET");
540ENUM_NEXT(ck_attr_names, CKA_PIXEL_X, CKA_BITS_PER_PIXEL, CKA_HAS_RESET,
541 "PIXEL_X",
542 "RESOLUTION",
543 "CHAR_ROWS",
544 "CHAR_COLUMNS",
545 "COLOR",
546 "BITS_PER_PIXEL");
547ENUM_NEXT(ck_attr_names, CKA_CHAR_SETS, CKA_MIME_TYPES, CKA_BITS_PER_PIXEL,
548 "CHAR_SETS",
549 "ENCODING_METHODS",
550 "MIME_TYPES");
551ENUM_NEXT(ck_attr_names, CKA_MECHANISM_TYPE, CKA_SUPPORTED_CMS_ATTRIBUTES,
552 CKA_MIME_TYPES,
553 "MECHANISM_TYPE",
554 "REQUIRED_CMS_ATTRIBUTES",
555 "DEFAULT_CMS_ATTRIBUTES",
556 "SUPPORTED_CMS_ATTRIBUTES");
557ENUM_NEXT(ck_attr_names, CKA_WRAP_TEMPLATE, CKA_UNWRAP_TEMPLATE,
558 CKA_SUPPORTED_CMS_ATTRIBUTES,
559 "WRAP_TEMPLATE",
560 "UNWRAP_TEMPLATE");
561ENUM_NEXT(ck_attr_names, CKA_ALLOWED_MECHANISMS, CKA_ALLOWED_MECHANISMS,
562 CKA_UNWRAP_TEMPLATE,
563 "ALLOWED_MECHANISMS");
564ENUM_END(ck_attr_names, CKA_ALLOWED_MECHANISMS);
565/* the values in an enum_name_t are stored as int, thus CKA_VENDOR_DEFINED
566 * will overflow and is thus not defined here */
567
568
569
34454dc3
MW
570/**
571 * Private data of an pkcs11_library_t object.
572 */
573struct private_pkcs11_library_t {
574
575 /**
576 * Public pkcs11_library_t interface.
577 */
578 pkcs11_library_t public;
579
580 /**
581 * dlopen() handle
582 */
583 void *handle;
71151d3c
MW
584
585 /**
586 * Name as passed to the constructor
587 */
588 char *name;
59df2d2a
MW
589
590 /**
591 * Supported feature set
592 */
593 pkcs11_feature_t features;
34454dc3
MW
594};
595
71151d3c
MW
596METHOD(pkcs11_library_t, get_name, char*,
597 private_pkcs11_library_t *this)
598{
599 return this->name;
600}
601
59df2d2a
MW
602METHOD(pkcs11_library_t, get_features, pkcs11_feature_t,
603 private_pkcs11_library_t *this)
604{
605 return this->features;
606}
607
9baa41c5
MW
608/**
609 * Object enumerator
610 */
611typedef struct {
612 /* implements enumerator_t */
613 enumerator_t public;
614 /* session */
615 CK_SESSION_HANDLE session;
616 /* pkcs11 library */
617 pkcs11_library_t *lib;
f3bb1bd0 618 /* attributes to retrieve */
d007ce32
MW
619 CK_ATTRIBUTE_PTR attr;
620 /* number of attributes */
621 CK_ULONG count;
c1985251
TB
622 /* object handle in case of a single object */
623 CK_OBJECT_HANDLE object;
d007ce32
MW
624 /* currently allocated attributes, to free */
625 linked_list_t *freelist;
9baa41c5
MW
626} object_enumerator_t;
627
d007ce32
MW
628/**
629 * Free contents of attributes in a list
630 */
631static void free_attrs(object_enumerator_t *this)
632{
633 CK_ATTRIBUTE_PTR attr;
634
635 while (this->freelist->remove_last(this->freelist, (void**)&attr) == SUCCESS)
636 {
637 free(attr->pValue);
638 attr->pValue = NULL;
639 attr->ulValueLen = 0;
640 }
641}
642
643/**
644 * Get attributes for a given object during enumeration
645 */
646static bool get_attributes(object_enumerator_t *this, CK_OBJECT_HANDLE object)
647{
648 CK_RV rv;
649 int i;
650
651 free_attrs(this);
652
653 /* get length of objects first */
654 rv = this->lib->f->C_GetAttributeValue(this->session, object,
655 this->attr, this->count);
656 if (rv != CKR_OK)
657 {
658 DBG1(DBG_CFG, "C_GetAttributeValue(NULL) error: %N", ck_rv_names, rv);
659 return FALSE;
660 }
661 /* allocate required chunks */
662 for (i = 0; i < this->count; i++)
663 {
664 if (this->attr[i].pValue == NULL &&
665 this->attr[i].ulValueLen != 0 && this->attr[i].ulValueLen != -1)
666 {
667 this->attr[i].pValue = malloc(this->attr[i].ulValueLen);
668 this->freelist->insert_last(this->freelist, &this->attr[i]);
669 }
670 }
671 /* get the data */
672 rv = this->lib->f->C_GetAttributeValue(this->session, object,
673 this->attr, this->count);
674 if (rv != CKR_OK)
675 {
676 free_attrs(this);
df241121 677 DBG1(DBG_CFG, "C_GetAttributeValue() error: %N", ck_rv_names, rv);
d007ce32
MW
678 return FALSE;
679 }
680 return TRUE;
681}
682
9baa41c5
MW
683METHOD(enumerator_t, object_enumerate, bool,
684 object_enumerator_t *this, CK_OBJECT_HANDLE *out)
685{
686 CK_OBJECT_HANDLE object;
687 CK_ULONG found;
688 CK_RV rv;
689
c1985251 690 if (!this->object)
9baa41c5 691 {
c1985251
TB
692 rv = this->lib->f->C_FindObjects(this->session, &object, 1, &found);
693 if (rv != CKR_OK)
694 {
695 DBG1(DBG_CFG, "C_FindObjects() failed: %N", ck_rv_names, rv);
696 return FALSE;
697 }
698 }
699 else
700 {
701 object = this->object;
702 found = 1;
9baa41c5
MW
703 }
704 if (found)
705 {
d007ce32
MW
706 if (this->attr)
707 {
708 if (!get_attributes(this, object))
709 {
710 return FALSE;
711 }
712 }
c1985251
TB
713 if (out)
714 {
715 *out = object;
716 }
9baa41c5
MW
717 return TRUE;
718 }
719 return FALSE;
720}
721
722METHOD(enumerator_t, object_destroy, void,
723 object_enumerator_t *this)
724{
c1985251
TB
725 if (!this->object)
726 {
727 this->lib->f->C_FindObjectsFinal(this->session);
728 }
d007ce32
MW
729 free_attrs(this);
730 this->freelist->destroy(this->freelist);
9baa41c5
MW
731 free(this);
732}
733
734METHOD(pkcs11_library_t, create_object_enumerator, enumerator_t*,
735 private_pkcs11_library_t *this, CK_SESSION_HANDLE session,
d007ce32
MW
736 CK_ATTRIBUTE_PTR tmpl, CK_ULONG tcount,
737 CK_ATTRIBUTE_PTR attr, CK_ULONG acount)
9baa41c5
MW
738{
739 object_enumerator_t *enumerator;
740 CK_RV rv;
741
d007ce32 742 rv = this->public.f->C_FindObjectsInit(session, tmpl, tcount);
9baa41c5
MW
743 if (rv != CKR_OK)
744 {
745 DBG1(DBG_CFG, "C_FindObjectsInit() failed: %N", ck_rv_names, rv);
746 return enumerator_create_empty();
747 }
748
749 INIT(enumerator,
750 .public = {
751 .enumerate = (void*)_object_enumerate,
752 .destroy = _object_destroy,
753 },
754 .session = session,
755 .lib = &this->public,
d007ce32
MW
756 .attr = attr,
757 .count = acount,
758 .freelist = linked_list_create(),
9baa41c5
MW
759 );
760 return &enumerator->public;
761}
762
c1985251
TB
763METHOD(pkcs11_library_t, create_object_attr_enumerator, enumerator_t*,
764 private_pkcs11_library_t *this, CK_SESSION_HANDLE session,
765 CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR attr, CK_ULONG count)
766{
767 object_enumerator_t *enumerator;
768
769 INIT(enumerator,
770 .public = {
771 .enumerate = (void*)_object_enumerate,
772 .destroy = _object_destroy,
773 },
774 .session = session,
775 .lib = &this->public,
776 .attr = attr,
777 .count = count,
778 .object = object,
779 .freelist = linked_list_create(),
780 );
781 return &enumerator->public;
782}
783
5a27bf8a
MW
784/**
785 * Enumerator over mechanisms
786 */
787typedef struct {
788 /* implements enumerator_t */
789 enumerator_t public;
790 /* PKCS#11 library */
791 pkcs11_library_t *lib;
792 /* slot of token */
793 CK_SLOT_ID slot;
794 /* mechanism type list */
795 CK_MECHANISM_TYPE_PTR mechs;
796 /* number of mechanism types */
797 CK_ULONG count;
798 /* current mechanism */
799 CK_ULONG current;
800} mechanism_enumerator_t;
801
802METHOD(enumerator_t, enumerate_mech, bool,
803 mechanism_enumerator_t *this, CK_MECHANISM_TYPE* type,
804 CK_MECHANISM_INFO *info)
805{
806 CK_RV rv;
807
808 if (this->current >= this->count)
809 {
810 return FALSE;
811 }
812 if (info)
813 {
814 rv = this->lib->f->C_GetMechanismInfo(this->slot,
815 this->mechs[this->current], info);
816 if (rv != CKR_OK)
817 {
818 DBG1(DBG_CFG, "C_GetMechanismInfo() failed: %N", ck_rv_names, rv);
819 return FALSE;
820 }
821 }
822 *type = this->mechs[this->current++];
823 return TRUE;
824}
825
826METHOD(enumerator_t, destroy_mech, void,
827 mechanism_enumerator_t *this)
828{
829 free(this->mechs);
830 free(this);
831}
832
833METHOD(pkcs11_library_t, create_mechanism_enumerator, enumerator_t*,
834 private_pkcs11_library_t *this, CK_SLOT_ID slot)
835{
836 mechanism_enumerator_t *enumerator;
837 CK_RV rv;
838
839 INIT(enumerator,
840 .public = {
841 .enumerate = (void*)_enumerate_mech,
842 .destroy = _destroy_mech,
843 },
844 .lib = &this->public,
845 .slot = slot,
846 );
847
848 rv = enumerator->lib->f->C_GetMechanismList(slot, NULL, &enumerator->count);
849 if (rv != CKR_OK)
850 {
851 DBG1(DBG_CFG, "C_GetMechanismList() failed: %N", ck_rv_names, rv);
852 free(enumerator);
853 return enumerator_create_empty();
854 }
855 enumerator->mechs = malloc(sizeof(CK_MECHANISM_TYPE) * enumerator->count);
856 enumerator->lib->f->C_GetMechanismList(slot, enumerator->mechs,
857 &enumerator->count);
858 if (rv != CKR_OK)
859 {
860 DBG1(DBG_CFG, "C_GetMechanismList() failed: %N", ck_rv_names, rv);
861 destroy_mech(enumerator);
862 return enumerator_create_empty();
863 }
864 return &enumerator->public;
865}
866
85311065
TB
867METHOD(pkcs11_library_t, get_ck_attribute, bool,
868 private_pkcs11_library_t *this, CK_SESSION_HANDLE session,
869 CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_TYPE type, chunk_t *data)
870{
871 CK_ATTRIBUTE attr = { type, NULL, 0 };
872 CK_RV rv;
873 rv = this->public.f->C_GetAttributeValue(session, obj, &attr, 1);
874 if (rv != CKR_OK)
875 {
876 DBG1(DBG_CFG, "C_GetAttributeValue(%N) error: %N", ck_attr_names, type,
877 ck_rv_names, rv);
878 return FALSE;
879 }
880 *data = chunk_alloc(attr.ulValueLen);
881 attr.pValue = data->ptr;
882 rv = this->public.f->C_GetAttributeValue(session, obj, &attr, 1);
883 if (rv != CKR_OK)
884 {
885 DBG1(DBG_CFG, "C_GetAttributeValue(%N) error: %N", ck_attr_names, type,
886 ck_rv_names, rv);
887 chunk_free(data);
888 return FALSE;
889 }
890 return TRUE;
891}
892
34454dc3
MW
893METHOD(pkcs11_library_t, destroy, void,
894 private_pkcs11_library_t *this)
895{
896 this->public.f->C_Finalize(NULL);
66033012 897 dlclose(this->handle);
ca1c2ee2 898 free(this->name);
34454dc3
MW
899 free(this);
900}
901
902/**
b3b0e57c 903 * See header
34454dc3 904 */
b3b0e57c 905void pkcs11_library_trim(char *str, int len)
34454dc3
MW
906{
907 int i;
908
b3b0e57c
MW
909 str[len - 1] = '\0';
910 for (i = len - 2; i > 0; i--)
34454dc3
MW
911 {
912 if (str[i] == ' ')
913 {
914 str[i] = '\0';
915 continue;
916 }
917 break;
918 }
919}
920
50e1a710
MW
921/**
922 * Mutex creation callback
923 */
924static CK_RV CreateMutex(CK_VOID_PTR_PTR data)
925{
ea900422 926 *data = mutex_create(MUTEX_TYPE_RECURSIVE);
50e1a710
MW
927 return CKR_OK;
928}
929
930/**
931 * Mutex destruction callback
932 */
933static CK_RV DestroyMutex(CK_VOID_PTR data)
934{
935 mutex_t *mutex = (mutex_t*)data;
936
937 mutex->destroy(mutex);
938 return CKR_OK;
939}
940
941/**
942 * Mutex lock callback
943 */
944static CK_RV LockMutex(CK_VOID_PTR data)
945{
946 mutex_t *mutex = (mutex_t*)data;
947
948 mutex->lock(mutex);
949 return CKR_OK;
950}
951
952/**
953 * Mutex unlock callback
954 */
955static CK_RV UnlockMutex(CK_VOID_PTR data)
956{
957 mutex_t *mutex = (mutex_t*)data;
958
959 mutex->unlock(mutex);
960 return CKR_OK;
961}
962
59df2d2a
MW
963/**
964 * Check if the library has at least a given cryptoki version
965 */
966static bool has_version(CK_INFO *info, int major, int minor)
967{
968 return info->cryptokiVersion.major > major ||
969 (info->cryptokiVersion.major == major &&
970 info->cryptokiVersion.minor >= minor);
971}
972
973/**
974 * Check for optional PKCS#11 library functionality
975 */
976static void check_features(private_pkcs11_library_t *this, CK_INFO *info)
977{
978 if (has_version(info, 2, 20))
979 {
980 this->features |= PKCS11_TRUSTED_CERTS;
b78ca4b0 981 this->features |= PKCS11_ALWAYS_AUTH_KEYS;
59df2d2a
MW
982 }
983}
984
34454dc3
MW
985/**
986 * Initialize a PKCS#11 library
987 */
9cda3992
MW
988static bool initialize(private_pkcs11_library_t *this, char *name, char *file,
989 bool os_locking)
34454dc3
MW
990{
991 CK_C_GetFunctionList pC_GetFunctionList;
992 CK_INFO info;
993 CK_RV rv;
cfa18d14 994 static CK_C_INITIALIZE_ARGS args = {
50e1a710
MW
995 .CreateMutex = CreateMutex,
996 .DestroyMutex = DestroyMutex,
997 .LockMutex = LockMutex,
998 .UnlockMutex = UnlockMutex,
999 };
cfa18d14
MW
1000 static CK_C_INITIALIZE_ARGS args_os = {
1001 .flags = CKF_OS_LOCKING_OK,
1002 };
34454dc3
MW
1003
1004 pC_GetFunctionList = dlsym(this->handle, "C_GetFunctionList");
1005 if (!pC_GetFunctionList)
1006 {
1007 DBG1(DBG_CFG, "C_GetFunctionList not found for '%s': %s", name, dlerror());
1008 return FALSE;
1009 }
1010 rv = pC_GetFunctionList(&this->public.f);
1011 if (rv != CKR_OK)
1012 {
a6456dd6
MW
1013 DBG1(DBG_CFG, "C_GetFunctionList() error for '%s': %N",
1014 name, ck_rv_names, rv);
34454dc3
MW
1015 return FALSE;
1016 }
9cda3992
MW
1017 if (os_locking)
1018 {
1019 rv = CKR_CANT_LOCK;
1020 }
1021 else
1022 {
1023 rv = this->public.f->C_Initialize(&args);
1024 }
50e1a710 1025 if (rv == CKR_CANT_LOCK)
9cda3992 1026 { /* fallback to OS locking */
cfa18d14
MW
1027 os_locking = TRUE;
1028 rv = this->public.f->C_Initialize(&args_os);
50e1a710 1029 }
34454dc3
MW
1030 if (rv != CKR_OK)
1031 {
a6456dd6
MW
1032 DBG1(DBG_CFG, "C_Initialize() error for '%s': %N",
1033 name, ck_rv_names, rv);
34454dc3
MW
1034 return FALSE;
1035 }
1036 rv = this->public.f->C_GetInfo(&info);
1037 if (rv != CKR_OK)
1038 {
a6456dd6
MW
1039 DBG1(DBG_CFG, "C_GetInfo() error for '%s': %N",
1040 name, ck_rv_names, rv);
34454dc3
MW
1041 this->public.f->C_Finalize(NULL);
1042 return FALSE;
1043 }
1044
b3b0e57c
MW
1045 pkcs11_library_trim(info.manufacturerID,
1046 strnlen(info.manufacturerID, sizeof(info.manufacturerID)));
1047 pkcs11_library_trim(info.libraryDescription,
1048 strnlen(info.libraryDescription, sizeof(info.libraryDescription)));
34454dc3
MW
1049
1050 DBG1(DBG_CFG, "loaded PKCS#11 v%d.%d library '%s' (%s)",
1051 info.cryptokiVersion.major, info.cryptokiVersion.minor, name, file);
b3b0e57c
MW
1052 DBG1(DBG_CFG, " %s: %s v%d.%d",
1053 info.manufacturerID, info.libraryDescription,
34454dc3 1054 info.libraryVersion.major, info.libraryVersion.minor);
cfa18d14 1055 if (os_locking)
50e1a710
MW
1056 {
1057 DBG1(DBG_CFG, " uses OS locking functions");
1058 }
59df2d2a
MW
1059
1060 check_features(this, &info);
34454dc3
MW
1061 return TRUE;
1062}
1063
1064/**
1065 * See header
1066 */
9cda3992 1067pkcs11_library_t *pkcs11_library_create(char *name, char *file, bool os_locking)
34454dc3
MW
1068{
1069 private_pkcs11_library_t *this;
1070
1071 INIT(this,
1072 .public = {
71151d3c 1073 .get_name = _get_name,
59df2d2a 1074 .get_features = _get_features,
9baa41c5 1075 .create_object_enumerator = _create_object_enumerator,
c1985251 1076 .create_object_attr_enumerator = _create_object_attr_enumerator,
5a27bf8a 1077 .create_mechanism_enumerator = _create_mechanism_enumerator,
85311065 1078 .get_ck_attribute = _get_ck_attribute,
34454dc3
MW
1079 .destroy = _destroy,
1080 },
ca1c2ee2 1081 .name = strdup(name),
34454dc3
MW
1082 .handle = dlopen(file, RTLD_LAZY),
1083 );
1084
1085 if (!this->handle)
1086 {
1087 DBG1(DBG_CFG, "opening PKCS#11 library failed: %s", dlerror());
1088 free(this);
1089 return NULL;
1090 }
1091
9cda3992 1092 if (!initialize(this, name, file, os_locking))
34454dc3
MW
1093 {
1094 dlclose(this->handle);
1095 free(this);
1096 return NULL;
1097 }
1098
1099 return &this->public;
1100}