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