ef20fa793b178413206224aa8f8708309ccd5651
[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 ENUM_BEGIN(ck_attr_names, CKA_CLASS, CKA_LABEL,
452 "CLASS",
453 "TOKEN",
454 "PRIVATE",
455 "LABEL");
456 ENUM_NEXT(ck_attr_names, CKA_APPLICATION, CKA_OBJECT_ID, CKA_LABEL,
457 "APPLICATION",
458 "VALUE",
459 "OBJECT_ID");
460 ENUM_NEXT(ck_attr_names, CKA_CERTIFICATE_TYPE, CKA_HASH_OF_ISSUER_PUBLIC_KEY,
461 CKA_OBJECT_ID,
462 "CERTIFICATE_TYPE",
463 "ISSUER",
464 "SERIAL_NUMBER",
465 "AC_ISSUER",
466 "OWNER",
467 "ATTR_TYPES",
468 "TRUSTED",
469 "CERTIFICATE_CATEGORY",
470 "JAVA_MIDP_SECURITY_DOMAIN",
471 "URL",
472 "HASH_OF_SUBJECT_PUBLIC_KEY",
473 "HASH_OF_ISSUER_PUBLIC_KEY");
474 ENUM_NEXT(ck_attr_names, CKA_CHECK_VALUE, CKA_CHECK_VALUE,
475 CKA_HASH_OF_ISSUER_PUBLIC_KEY,
476 "CHECK_VALUE");
477 ENUM_NEXT(ck_attr_names, CKA_KEY_TYPE, CKA_DERIVE, CKA_CHECK_VALUE,
478 "KEY_TYPE",
479 "SUBJECT",
480 "ID",
481 "SENSITIVE",
482 "ENCRYPT",
483 "DECRYPT",
484 "WRAP",
485 "UNWRAP",
486 "SIGN",
487 "SIGN_RECOVER",
488 "VERIFY",
489 "VERIFY_RECOVER",
490 "DERIVE");
491 ENUM_NEXT(ck_attr_names, CKA_START_DATE, CKA_END_DATE, CKA_DERIVE,
492 "START_DATE",
493 "END_DATE");
494 ENUM_NEXT(ck_attr_names, CKA_MODULUS, CKA_COEFFICIENT, CKA_END_DATE,
495 "MODULUS",
496 "MODULUS_BITS",
497 "PUBLIC_EXPONENT",
498 "PRIVATE_EXPONENT",
499 "PRIME_1",
500 "PRIME_2",
501 "EXPONENT_1",
502 "EXPONENT_2",
503 "COEFFICIENT");
504 ENUM_NEXT(ck_attr_names, CKA_PRIME, CKA_SUB_PRIME_BITS, CKA_COEFFICIENT,
505 "PRIME",
506 "SUBPRIME",
507 "BASE",
508 "PRIME_BITS",
509 "SUB_PRIME_BITS");
510 ENUM_NEXT(ck_attr_names, CKA_VALUE_BITS, CKA_KEY_GEN_MECHANISM,
511 CKA_SUB_PRIME_BITS,
512 "VALUE_BITS",
513 "VALUE_LEN",
514 "EXTRACTABLE",
515 "LOCAL",
516 "NEVER_EXTRACTABLE",
517 "ALWAYS_SENSITIVE",
518 "KEY_GEN_MECHANISM");
519 ENUM_NEXT(ck_attr_names, CKA_MODIFIABLE, CKA_MODIFIABLE, CKA_KEY_GEN_MECHANISM,
520 "MODIFIABLE");
521 ENUM_NEXT(ck_attr_names, CKA_EC_PARAMS, CKA_EC_POINT, CKA_MODIFIABLE,
522 "EC_PARAMS",
523 "EC_POINT");
524 ENUM_NEXT(ck_attr_names, CKA_SECONDARY_AUTH, CKA_ALWAYS_AUTHENTICATE,
525 CKA_EC_POINT,
526 "SECONDARY_AUTH",
527 "AUTH_PIN_FLAGS",
528 "ALWAYS_AUTHENTICATE");
529 ENUM_NEXT(ck_attr_names, CKA_WRAP_WITH_TRUSTED, CKA_WRAP_WITH_TRUSTED,
530 CKA_ALWAYS_AUTHENTICATE,
531 "WRAP_WITH_TRUSTED");
532 ENUM_NEXT(ck_attr_names, CKA_HW_FEATURE_TYPE, CKA_HAS_RESET,
533 CKA_WRAP_WITH_TRUSTED,
534 "HW_FEATURE_TYPE",
535 "RESET_ON_INIT",
536 "HAS_RESET");
537 ENUM_NEXT(ck_attr_names, CKA_PIXEL_X, CKA_BITS_PER_PIXEL, CKA_HAS_RESET,
538 "PIXEL_X",
539 "RESOLUTION",
540 "CHAR_ROWS",
541 "CHAR_COLUMNS",
542 "COLOR",
543 "BITS_PER_PIXEL");
544 ENUM_NEXT(ck_attr_names, CKA_CHAR_SETS, CKA_MIME_TYPES, CKA_BITS_PER_PIXEL,
545 "CHAR_SETS",
546 "ENCODING_METHODS",
547 "MIME_TYPES");
548 ENUM_NEXT(ck_attr_names, CKA_MECHANISM_TYPE, CKA_SUPPORTED_CMS_ATTRIBUTES,
549 CKA_MIME_TYPES,
550 "MECHANISM_TYPE",
551 "REQUIRED_CMS_ATTRIBUTES",
552 "DEFAULT_CMS_ATTRIBUTES",
553 "SUPPORTED_CMS_ATTRIBUTES");
554 ENUM_NEXT(ck_attr_names, CKA_WRAP_TEMPLATE, CKA_UNWRAP_TEMPLATE,
555 CKA_SUPPORTED_CMS_ATTRIBUTES,
556 "WRAP_TEMPLATE",
557 "UNWRAP_TEMPLATE");
558 ENUM_NEXT(ck_attr_names, CKA_ALLOWED_MECHANISMS, CKA_ALLOWED_MECHANISMS,
559 CKA_UNWRAP_TEMPLATE,
560 "ALLOWED_MECHANISMS");
561 ENUM_END(ck_attr_names, CKA_ALLOWED_MECHANISMS);
562 /* the values in an enum_name_t are stored as int, thus CKA_VENDOR_DEFINED
563 * will overflow and is thus not defined here */
564
565
566
567 /**
568 * Private data of an pkcs11_library_t object.
569 */
570 struct private_pkcs11_library_t {
571
572 /**
573 * Public pkcs11_library_t interface.
574 */
575 pkcs11_library_t public;
576
577 /**
578 * dlopen() handle
579 */
580 void *handle;
581
582 /**
583 * Name as passed to the constructor
584 */
585 char *name;
586
587 /**
588 * Supported feature set
589 */
590 pkcs11_feature_t features;
591 };
592
593 METHOD(pkcs11_library_t, get_name, char*,
594 private_pkcs11_library_t *this)
595 {
596 return this->name;
597 }
598
599 METHOD(pkcs11_library_t, get_features, pkcs11_feature_t,
600 private_pkcs11_library_t *this)
601 {
602 return this->features;
603 }
604
605 /**
606 * Object enumerator
607 */
608 typedef struct {
609 /* implements enumerator_t */
610 enumerator_t public;
611 /* session */
612 CK_SESSION_HANDLE session;
613 /* pkcs11 library */
614 pkcs11_library_t *lib;
615 /* attributes to retrieve */
616 CK_ATTRIBUTE_PTR attr;
617 /* number of attributes */
618 CK_ULONG count;
619 /* currently allocated attributes, to free */
620 linked_list_t *freelist;
621 } object_enumerator_t;
622
623 /**
624 * Free contents of attributes in a list
625 */
626 static void free_attrs(object_enumerator_t *this)
627 {
628 CK_ATTRIBUTE_PTR attr;
629
630 while (this->freelist->remove_last(this->freelist, (void**)&attr) == SUCCESS)
631 {
632 free(attr->pValue);
633 attr->pValue = NULL;
634 attr->ulValueLen = 0;
635 }
636 }
637
638 /**
639 * Get attributes for a given object during enumeration
640 */
641 static bool get_attributes(object_enumerator_t *this, CK_OBJECT_HANDLE object)
642 {
643 CK_RV rv;
644 int i;
645
646 free_attrs(this);
647
648 /* get length of objects first */
649 rv = this->lib->f->C_GetAttributeValue(this->session, object,
650 this->attr, this->count);
651 if (rv != CKR_OK)
652 {
653 DBG1(DBG_CFG, "C_GetAttributeValue(NULL) error: %N", ck_rv_names, rv);
654 return FALSE;
655 }
656 /* allocate required chunks */
657 for (i = 0; i < this->count; i++)
658 {
659 if (this->attr[i].pValue == NULL &&
660 this->attr[i].ulValueLen != 0 && this->attr[i].ulValueLen != -1)
661 {
662 this->attr[i].pValue = malloc(this->attr[i].ulValueLen);
663 this->freelist->insert_last(this->freelist, &this->attr[i]);
664 }
665 }
666 /* get the data */
667 rv = this->lib->f->C_GetAttributeValue(this->session, object,
668 this->attr, this->count);
669 if (rv != CKR_OK)
670 {
671 free_attrs(this);
672 DBG1(DBG_CFG, "C_GetAttributeValue() error: %N", ck_rv_names, rv);
673 return FALSE;
674 }
675 return TRUE;
676 }
677
678 METHOD(enumerator_t, object_enumerate, bool,
679 object_enumerator_t *this, CK_OBJECT_HANDLE *out)
680 {
681 CK_OBJECT_HANDLE object;
682 CK_ULONG found;
683 CK_RV rv;
684
685 rv = this->lib->f->C_FindObjects(this->session, &object, 1, &found);
686 if (rv != CKR_OK)
687 {
688 DBG1(DBG_CFG, "C_FindObjects() failed: %N", ck_rv_names, rv);
689 return FALSE;
690 }
691 if (found)
692 {
693 if (this->attr)
694 {
695 if (!get_attributes(this, object))
696 {
697 return FALSE;
698 }
699 }
700 *out = object;
701 return TRUE;
702 }
703 return FALSE;
704 }
705
706 METHOD(enumerator_t, object_destroy, void,
707 object_enumerator_t *this)
708 {
709 this->lib->f->C_FindObjectsFinal(this->session);
710 free_attrs(this);
711 this->freelist->destroy(this->freelist);
712 free(this);
713 }
714
715 METHOD(pkcs11_library_t, create_object_enumerator, enumerator_t*,
716 private_pkcs11_library_t *this, CK_SESSION_HANDLE session,
717 CK_ATTRIBUTE_PTR tmpl, CK_ULONG tcount,
718 CK_ATTRIBUTE_PTR attr, CK_ULONG acount)
719 {
720 object_enumerator_t *enumerator;
721 CK_RV rv;
722
723 rv = this->public.f->C_FindObjectsInit(session, tmpl, tcount);
724 if (rv != CKR_OK)
725 {
726 DBG1(DBG_CFG, "C_FindObjectsInit() failed: %N", ck_rv_names, rv);
727 return enumerator_create_empty();
728 }
729
730 INIT(enumerator,
731 .public = {
732 .enumerate = (void*)_object_enumerate,
733 .destroy = _object_destroy,
734 },
735 .session = session,
736 .lib = &this->public,
737 .attr = attr,
738 .count = acount,
739 .freelist = linked_list_create(),
740 );
741 return &enumerator->public;
742 }
743
744 /**
745 * Enumerator over mechanisms
746 */
747 typedef struct {
748 /* implements enumerator_t */
749 enumerator_t public;
750 /* PKCS#11 library */
751 pkcs11_library_t *lib;
752 /* slot of token */
753 CK_SLOT_ID slot;
754 /* mechanism type list */
755 CK_MECHANISM_TYPE_PTR mechs;
756 /* number of mechanism types */
757 CK_ULONG count;
758 /* current mechanism */
759 CK_ULONG current;
760 } mechanism_enumerator_t;
761
762 METHOD(enumerator_t, enumerate_mech, bool,
763 mechanism_enumerator_t *this, CK_MECHANISM_TYPE* type,
764 CK_MECHANISM_INFO *info)
765 {
766 CK_RV rv;
767
768 if (this->current >= this->count)
769 {
770 return FALSE;
771 }
772 if (info)
773 {
774 rv = this->lib->f->C_GetMechanismInfo(this->slot,
775 this->mechs[this->current], info);
776 if (rv != CKR_OK)
777 {
778 DBG1(DBG_CFG, "C_GetMechanismInfo() failed: %N", ck_rv_names, rv);
779 return FALSE;
780 }
781 }
782 *type = this->mechs[this->current++];
783 return TRUE;
784 }
785
786 METHOD(enumerator_t, destroy_mech, void,
787 mechanism_enumerator_t *this)
788 {
789 free(this->mechs);
790 free(this);
791 }
792
793 METHOD(pkcs11_library_t, create_mechanism_enumerator, enumerator_t*,
794 private_pkcs11_library_t *this, CK_SLOT_ID slot)
795 {
796 mechanism_enumerator_t *enumerator;
797 CK_RV rv;
798
799 INIT(enumerator,
800 .public = {
801 .enumerate = (void*)_enumerate_mech,
802 .destroy = _destroy_mech,
803 },
804 .lib = &this->public,
805 .slot = slot,
806 );
807
808 rv = enumerator->lib->f->C_GetMechanismList(slot, NULL, &enumerator->count);
809 if (rv != CKR_OK)
810 {
811 DBG1(DBG_CFG, "C_GetMechanismList() failed: %N", ck_rv_names, rv);
812 free(enumerator);
813 return enumerator_create_empty();
814 }
815 enumerator->mechs = malloc(sizeof(CK_MECHANISM_TYPE) * enumerator->count);
816 enumerator->lib->f->C_GetMechanismList(slot, enumerator->mechs,
817 &enumerator->count);
818 if (rv != CKR_OK)
819 {
820 DBG1(DBG_CFG, "C_GetMechanismList() failed: %N", ck_rv_names, rv);
821 destroy_mech(enumerator);
822 return enumerator_create_empty();
823 }
824 return &enumerator->public;
825 }
826
827 METHOD(pkcs11_library_t, destroy, void,
828 private_pkcs11_library_t *this)
829 {
830 this->public.f->C_Finalize(NULL);
831 dlclose(this->handle);
832 free(this);
833 }
834
835 /**
836 * See header
837 */
838 void pkcs11_library_trim(char *str, int len)
839 {
840 int i;
841
842 str[len - 1] = '\0';
843 for (i = len - 2; i > 0; i--)
844 {
845 if (str[i] == ' ')
846 {
847 str[i] = '\0';
848 continue;
849 }
850 break;
851 }
852 }
853
854 /**
855 * Mutex creation callback
856 */
857 static CK_RV CreateMutex(CK_VOID_PTR_PTR data)
858 {
859 *data = mutex_create(MUTEX_TYPE_RECURSIVE);
860 return CKR_OK;
861 }
862
863 /**
864 * Mutex destruction callback
865 */
866 static CK_RV DestroyMutex(CK_VOID_PTR data)
867 {
868 mutex_t *mutex = (mutex_t*)data;
869
870 mutex->destroy(mutex);
871 return CKR_OK;
872 }
873
874 /**
875 * Mutex lock callback
876 */
877 static CK_RV LockMutex(CK_VOID_PTR data)
878 {
879 mutex_t *mutex = (mutex_t*)data;
880
881 mutex->lock(mutex);
882 return CKR_OK;
883 }
884
885 /**
886 * Mutex unlock callback
887 */
888 static CK_RV UnlockMutex(CK_VOID_PTR data)
889 {
890 mutex_t *mutex = (mutex_t*)data;
891
892 mutex->unlock(mutex);
893 return CKR_OK;
894 }
895
896 /**
897 * Check if the library has at least a given cryptoki version
898 */
899 static bool has_version(CK_INFO *info, int major, int minor)
900 {
901 return info->cryptokiVersion.major > major ||
902 (info->cryptokiVersion.major == major &&
903 info->cryptokiVersion.minor >= minor);
904 }
905
906 /**
907 * Check for optional PKCS#11 library functionality
908 */
909 static void check_features(private_pkcs11_library_t *this, CK_INFO *info)
910 {
911 if (has_version(info, 2, 20))
912 {
913 this->features |= PKCS11_TRUSTED_CERTS;
914 this->features |= PKCS11_ALWAYS_AUTH_KEYS;
915 }
916 }
917
918 /**
919 * Initialize a PKCS#11 library
920 */
921 static bool initialize(private_pkcs11_library_t *this, char *name, char *file,
922 bool os_locking)
923 {
924 CK_C_GetFunctionList pC_GetFunctionList;
925 CK_INFO info;
926 CK_RV rv;
927 static CK_C_INITIALIZE_ARGS args = {
928 .CreateMutex = CreateMutex,
929 .DestroyMutex = DestroyMutex,
930 .LockMutex = LockMutex,
931 .UnlockMutex = UnlockMutex,
932 };
933 static CK_C_INITIALIZE_ARGS args_os = {
934 .flags = CKF_OS_LOCKING_OK,
935 };
936
937 pC_GetFunctionList = dlsym(this->handle, "C_GetFunctionList");
938 if (!pC_GetFunctionList)
939 {
940 DBG1(DBG_CFG, "C_GetFunctionList not found for '%s': %s", name, dlerror());
941 return FALSE;
942 }
943 rv = pC_GetFunctionList(&this->public.f);
944 if (rv != CKR_OK)
945 {
946 DBG1(DBG_CFG, "C_GetFunctionList() error for '%s': %N",
947 name, ck_rv_names, rv);
948 return FALSE;
949 }
950 if (os_locking)
951 {
952 rv = CKR_CANT_LOCK;
953 }
954 else
955 {
956 rv = this->public.f->C_Initialize(&args);
957 }
958 if (rv == CKR_CANT_LOCK)
959 { /* fallback to OS locking */
960 os_locking = TRUE;
961 rv = this->public.f->C_Initialize(&args_os);
962 }
963 if (rv != CKR_OK)
964 {
965 DBG1(DBG_CFG, "C_Initialize() error for '%s': %N",
966 name, ck_rv_names, rv);
967 return FALSE;
968 }
969 rv = this->public.f->C_GetInfo(&info);
970 if (rv != CKR_OK)
971 {
972 DBG1(DBG_CFG, "C_GetInfo() error for '%s': %N",
973 name, ck_rv_names, rv);
974 this->public.f->C_Finalize(NULL);
975 return FALSE;
976 }
977
978 pkcs11_library_trim(info.manufacturerID,
979 strnlen(info.manufacturerID, sizeof(info.manufacturerID)));
980 pkcs11_library_trim(info.libraryDescription,
981 strnlen(info.libraryDescription, sizeof(info.libraryDescription)));
982
983 DBG1(DBG_CFG, "loaded PKCS#11 v%d.%d library '%s' (%s)",
984 info.cryptokiVersion.major, info.cryptokiVersion.minor, name, file);
985 DBG1(DBG_CFG, " %s: %s v%d.%d",
986 info.manufacturerID, info.libraryDescription,
987 info.libraryVersion.major, info.libraryVersion.minor);
988 if (os_locking)
989 {
990 DBG1(DBG_CFG, " uses OS locking functions");
991 }
992
993 check_features(this, &info);
994 return TRUE;
995 }
996
997 /**
998 * See header
999 */
1000 pkcs11_library_t *pkcs11_library_create(char *name, char *file, bool os_locking)
1001 {
1002 private_pkcs11_library_t *this;
1003
1004 INIT(this,
1005 .public = {
1006 .get_name = _get_name,
1007 .get_features = _get_features,
1008 .create_object_enumerator = _create_object_enumerator,
1009 .create_mechanism_enumerator = _create_mechanism_enumerator,
1010 .destroy = _destroy,
1011 },
1012 .name = name,
1013 .handle = dlopen(file, RTLD_LAZY),
1014 );
1015
1016 if (!this->handle)
1017 {
1018 DBG1(DBG_CFG, "opening PKCS#11 library failed: %s", dlerror());
1019 free(this);
1020 return NULL;
1021 }
1022
1023 if (!initialize(this, name, file, os_locking))
1024 {
1025 dlclose(this->handle);
1026 free(this);
1027 return NULL;
1028 }
1029
1030 return &this->public;
1031 }