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