opensc-sys 0.1.1

FFI bindings to OpenSC
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
/*
 * sc-pkcs11.h: OpenSC project's PKCS#11 implementation header
 *
 * Copyright (C) 2002  Timo Teräs <timo.teras@iki.fi>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef __sc_pkcs11_h__
#define __sc_pkcs11_h__

#include "config.h"

#include "libopensc/opensc.h"
#include "libopensc/pkcs15.h"
#include "libopensc/log.h"

#define CRYPTOKI_EXPORTS
#include "pkcs11.h"
#include "pkcs11-opensc.h"
#include "pkcs11-display.h"

#ifdef __cplusplus
extern "C" {
#endif

#define SC_PKCS11_PIN_UNBLOCK_NOT_ALLOWED	0
#define SC_PKCS11_PIN_UNBLOCK_UNLOGGED_SETPIN	1
#define SC_PKCS11_PIN_UNBLOCK_SCONTEXT_SETPIN	2
#define SC_PKCS11_PIN_UNBLOCK_SO_LOGGED_INITPIN	3

#define SC_PKCS11_SLOT_FOR_PIN_USER	1
#define SC_PKCS11_SLOT_FOR_PIN_SIGN	2
#define SC_PKCS11_SLOT_CREATE_ALL	8

#define SC_PKCS11_SLOT_FOR_PINS		(SC_PKCS11_SLOT_FOR_PIN_USER | SC_PKCS11_SLOT_FOR_PIN_SIGN)

#ifdef __cplusplus
}
#endif

/* Decide whether to use pkcs11 for initialization support */
#ifdef ENABLE_OPENSSL
#define USE_PKCS15_INIT
#endif

#ifdef __cplusplus
extern "C" {
#endif

struct sc_pkcs11_session;
struct sc_pkcs11_slot;
struct sc_pkcs11_card;

struct sc_pkcs11_config {
	unsigned int plug_and_play;
	unsigned int max_virtual_slots;
	unsigned int slots_per_card;
	unsigned char lock_login;
	unsigned char atomic;
	unsigned char init_sloppy;
	unsigned int pin_unblock_style;
	unsigned int create_puk_slot;
	unsigned int create_slots_flags;
	unsigned char ignore_pin_length;
};

/*
 * PKCS#11 Object abstraction layer
 */

struct sc_pkcs11_object_ops {
	/* Generic operations */
	void (*release)(void *);

	/* Management methods */
	CK_RV (*set_attribute)(struct sc_pkcs11_session *, void *, CK_ATTRIBUTE_PTR);
	CK_RV (*get_attribute)(struct sc_pkcs11_session *, void *, CK_ATTRIBUTE_PTR);
	CK_RV (*cmp_attribute)(struct sc_pkcs11_session *, void *, CK_ATTRIBUTE_PTR);

	CK_RV (*destroy_object)(struct sc_pkcs11_session *, void *);
	CK_RV (*get_size)(struct sc_pkcs11_session *, void *);

	/* Cryptographic methods */
	CK_RV (*sign)(struct sc_pkcs11_session *, void *,
			CK_MECHANISM_PTR,
			CK_BYTE_PTR pData, CK_ULONG ulDataLen,
			CK_BYTE_PTR pSignature, CK_ULONG_PTR pulDataLen);
	CK_RV (*unwrap_key)(struct sc_pkcs11_session *, void *,
			CK_MECHANISM_PTR,
			CK_BYTE_PTR pData, CK_ULONG ulDataLen,
			void *targetKey);
	CK_RV (*decrypt)(struct sc_pkcs11_session *, void *,
			CK_MECHANISM_PTR,
			CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
			CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen);

	CK_RV (*derive)(struct sc_pkcs11_session *, void *,
			CK_MECHANISM_PTR,
			CK_BYTE_PTR pSeedData, CK_ULONG ulSeedDataLen,
			CK_BYTE_PTR pDerived, CK_ULONG_PTR pulDerivedLen);

	/* Check compatibility of PKCS#15 object usage and an asked PKCS#11 mechanism. */
	CK_RV (*can_do)(struct sc_pkcs11_session *, void *, CK_MECHANISM_TYPE, unsigned int);

	/* General validation of mechanism parameters (sign, encrypt, etc) */
	CK_RV (*init_params)(struct sc_pkcs11_session *, CK_MECHANISM_PTR);

	CK_RV (*wrap_key)(struct sc_pkcs11_session *, void *,
			CK_MECHANISM_PTR,
			void*,
			CK_BYTE_PTR pData, CK_ULONG_PTR ulDataLen);

	/* Others to be added when implemented */
};

struct sc_pkcs11_object {
	CK_OBJECT_HANDLE handle;
	int flags;
	struct sc_pkcs11_object_ops *ops;
};

#define SC_PKCS11_OBJECT_SEEN	0x0001
#define SC_PKCS11_OBJECT_HIDDEN	0x0002
#define SC_PKCS11_OBJECT_RECURS	0x8000


/*
 * PKCS#11 smart card Framework abstraction
 */

struct sc_pkcs11_framework_ops {
	/* Detect and bind card to framework */
	CK_RV (*bind)(struct sc_pkcs11_card *, struct sc_app_info *);
	/* Unbind and release allocated resources */
	CK_RV (*unbind)(struct sc_pkcs11_card *);

	/* Create tokens to virtual slots and
	 * objects in tokens; called after bind */
	CK_RV (*create_tokens)(struct sc_pkcs11_card *, struct sc_app_info *);
	CK_RV (*release_token)(struct sc_pkcs11_card *, void *);

	/* Login and logout */
	CK_RV (*login)(struct sc_pkcs11_slot *,
				CK_USER_TYPE, CK_CHAR_PTR, CK_ULONG);
	CK_RV (*logout)(struct sc_pkcs11_slot *);
	CK_RV (*change_pin)(struct sc_pkcs11_slot *,
				CK_CHAR_PTR, CK_ULONG,
				CK_CHAR_PTR, CK_ULONG);
	/*
	 * In future: functions to create new objects (i.e. certificates, private keys)
	 */
	CK_RV (*init_token)(struct sc_pkcs11_slot *, void *,
				CK_UTF8CHAR_PTR, CK_ULONG,
				CK_UTF8CHAR_PTR);
	CK_RV (*init_pin)(struct sc_pkcs11_slot *,
				CK_UTF8CHAR_PTR, CK_ULONG);
	CK_RV (*create_object)(struct sc_pkcs11_slot *,
				CK_ATTRIBUTE_PTR, CK_ULONG,
				CK_OBJECT_HANDLE_PTR);
	CK_RV (*gen_keypair)(struct sc_pkcs11_slot *,
				CK_MECHANISM_PTR,
				CK_ATTRIBUTE_PTR, CK_ULONG,
				CK_ATTRIBUTE_PTR, CK_ULONG,
				CK_OBJECT_HANDLE_PTR, CK_OBJECT_HANDLE_PTR);
	CK_RV (*get_random)(struct sc_pkcs11_slot *,
				CK_BYTE_PTR, CK_ULONG);
};

/*
 * PKCS#11 Slot (used to access card with specific framework data)
 */

#ifndef _WIN32
typedef unsigned long long sc_timestamp_t;
#else
typedef unsigned __int64   sc_timestamp_t;
#endif

#define SC_PKCS11_FRAMEWORK_DATA_MAX_NUM	4
struct sc_pkcs11_card {
	sc_reader_t *reader;
	sc_card_t *card;
	struct sc_pkcs11_framework_ops *framework;
	void *fws_data[SC_PKCS11_FRAMEWORK_DATA_MAX_NUM];

	/* List of supported mechanisms */
	struct sc_pkcs11_mechanism_type **mechanisms;
	unsigned int nmechanisms;
};

/* If the slot did already show with `C_GetSlotList`, then we need to keep this
 * slot alive. PKCS#11 2.30 allows allows adding but not removing slots until
 * the application calls `C_GetSlotList` with `NULL`. This flag tracks the
 * visibility to the application */
#define SC_PKCS11_SLOT_FLAG_SEEN 1

struct sc_pkcs11_slot {
	CK_SLOT_ID id;			/* ID of the slot */
	int login_user;			/* Currently logged in user */
	CK_SLOT_INFO slot_info;		/* Slot specific information (information about reader) */
	CK_TOKEN_INFO token_info;	/* Token specific information (information about card) */
	sc_reader_t *reader;		/* same as card->reader if there's a card present */
	struct sc_pkcs11_card *p11card;	/* The card associated with this slot */
	unsigned int events;		/* Card events SC_EVENT_CARD_{INSERTED,REMOVED} */
	void *fw_data;			/* Framework specific data */  /* TODO: get know how it used */
	list_t objects;			/* Objects in this slot */
	unsigned int nsessions;		/* Number of sessions using this slot */
	sc_timestamp_t slot_state_expires;

	int fw_data_idx;		/* Index of framework data */
	struct sc_app_info *app_info;	/* Application associated to slot */
	list_t logins;			/* tracks all calls to C_Login if atomic operations are requested */
	int flags;
};
typedef struct sc_pkcs11_slot sc_pkcs11_slot_t;


/* Forward decl */
typedef struct sc_pkcs11_operation sc_pkcs11_operation_t;

enum {
	SC_PKCS11_OPERATION_FIND = 0,
	SC_PKCS11_OPERATION_SIGN,
	SC_PKCS11_OPERATION_VERIFY,
	SC_PKCS11_OPERATION_DIGEST,
	SC_PKCS11_OPERATION_DECRYPT,
	SC_PKCS11_OPERATION_DERIVE,
	SC_PKCS11_OPERATION_WRAP,
	SC_PKCS11_OPERATION_UNWRAP,
	SC_PKCS11_OPERATION_MAX
};

/* This describes a PKCS11 mechanism */
struct sc_pkcs11_mechanism_type {
	CK_MECHANISM_TYPE mech;		/* algorithm: md5, sha1, ... */
	CK_MECHANISM_INFO mech_info;	/* mechanism info */
	CK_MECHANISM_TYPE key_type;	/* for sign/decipher ops */
	unsigned int	  obj_size;

	/* General management */
	void		  (*release)(sc_pkcs11_operation_t *);

	/* Digest/sign Operations */
	CK_RV		  (*md_init)(sc_pkcs11_operation_t *);
	CK_RV		  (*md_update)(sc_pkcs11_operation_t *,
					CK_BYTE_PTR, CK_ULONG);
	CK_RV		  (*md_final)(sc_pkcs11_operation_t *,
					CK_BYTE_PTR, CK_ULONG_PTR);

	CK_RV		  (*sign_init)(sc_pkcs11_operation_t *,
					struct sc_pkcs11_object *);
	CK_RV		  (*sign_update)(sc_pkcs11_operation_t *,
					CK_BYTE_PTR, CK_ULONG);
	CK_RV		  (*sign_final)(sc_pkcs11_operation_t *,
					CK_BYTE_PTR, CK_ULONG_PTR);
	CK_RV		  (*sign_size)(sc_pkcs11_operation_t *,
					CK_ULONG_PTR);
	CK_RV		  (*verif_init)(sc_pkcs11_operation_t *,
					struct sc_pkcs11_object *);
	CK_RV		  (*verif_update)(sc_pkcs11_operation_t *,
					CK_BYTE_PTR, CK_ULONG);
	CK_RV		  (*verif_final)(sc_pkcs11_operation_t *,
					CK_BYTE_PTR, CK_ULONG);
	CK_RV		  (*decrypt_init)(sc_pkcs11_operation_t *,
					struct sc_pkcs11_object *);
	CK_RV		  (*decrypt)(sc_pkcs11_operation_t *,
					CK_BYTE_PTR, CK_ULONG,
					CK_BYTE_PTR, CK_ULONG_PTR);
	CK_RV		  (*derive)(sc_pkcs11_operation_t *,
					struct sc_pkcs11_object *,
					CK_BYTE_PTR, CK_ULONG,
					CK_BYTE_PTR, CK_ULONG_PTR);
	CK_RV		  (*wrap)(sc_pkcs11_operation_t *,
					struct sc_pkcs11_object *,
					struct sc_pkcs11_object *,
					CK_BYTE_PTR, CK_ULONG_PTR);
	CK_RV		  (*unwrap)(sc_pkcs11_operation_t *,
					struct sc_pkcs11_object *,
					CK_BYTE_PTR, CK_ULONG,
					struct sc_pkcs11_object *);

	/* mechanism specific data */
	const void *  mech_data;
	/* free mechanism specific data */
	void		  (*free_mech_data)(const void *mech_data);
};
typedef struct sc_pkcs11_mechanism_type sc_pkcs11_mechanism_type_t;

/*
 * Generic operation
 */
struct sc_pkcs11_operation {
	sc_pkcs11_mechanism_type_t *type;
	CK_MECHANISM	  mechanism;
	union {
		CK_RSA_PKCS_PSS_PARAMS pss;
		CK_RSA_PKCS_OAEP_PARAMS oaep;
	} mechanism_params;
	struct sc_pkcs11_session *session;
	void *		  priv_data;
};

/* Find Operation */
#define SC_PKCS11_FIND_INC_HANDLES	32
struct sc_pkcs11_find_operation {
	struct sc_pkcs11_operation operation;
	int num_handles, current_handle, allocated_handles;
	CK_OBJECT_HANDLE *handles;
};

/*
 * PKCS#11 Session
 */

struct sc_pkcs11_session {
	CK_SESSION_HANDLE handle;
	/* Session to this slot */
	struct sc_pkcs11_slot *slot;
	CK_FLAGS flags;
	/* Notifications */
	CK_NOTIFY notify_callback;
	CK_VOID_PTR notify_data;
	/* Active operations - one per type */
	struct sc_pkcs11_operation *operation[SC_PKCS11_OPERATION_MAX];
};
typedef struct sc_pkcs11_session sc_pkcs11_session_t;

/* Module variables */
extern struct sc_context *context;
extern struct sc_pkcs11_config sc_pkcs11_conf;
extern list_t sessions;
extern list_t virtual_slots;
extern list_t cards;

/* Framework definitions */
extern struct sc_pkcs11_framework_ops framework_pkcs15;
extern struct sc_pkcs11_framework_ops framework_pkcs15init;

void strcpy_bp(u8 *dst, const char *src, size_t dstsize);
CK_RV sc_to_cryptoki_error(int rc, const char *ctx);
void sc_pkcs11_print_attrs(int level, const char *file, unsigned int line, const char *function,
		const char *info, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount);
#define dump_template(level, info, pTemplate, ulCount) \
		sc_pkcs11_print_attrs(level, __FILE__, __LINE__, __FUNCTION__, \
				info, pTemplate, ulCount)

/* Slot and card handling functions */
CK_RV card_removed(sc_reader_t *reader);
CK_RV card_detect_all(void);
CK_RV create_slot(sc_reader_t *reader);
CK_RV initialize_reader(sc_reader_t *reader);
CK_RV card_detect(sc_reader_t *reader);
CK_RV slot_get_slot(CK_SLOT_ID id, struct sc_pkcs11_slot **);
CK_RV slot_get_token(CK_SLOT_ID id, struct sc_pkcs11_slot **);
CK_RV slot_token_removed(CK_SLOT_ID id);
CK_RV slot_allocate(struct sc_pkcs11_slot **, struct sc_pkcs11_card *);
CK_RV slot_find_changed(CK_SLOT_ID_PTR idp, int mask);
int slot_get_logged_in_state(struct sc_pkcs11_slot *slot);

/* Login tracking functions */
CK_RV restore_login_state(struct sc_pkcs11_slot *slot);
CK_RV reset_login_state(struct sc_pkcs11_slot *slot, CK_RV rv);
CK_RV push_login_state(struct sc_pkcs11_slot *slot,
		CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG ulPinLen);
void pop_login_state(struct sc_pkcs11_slot *slot);
void pop_all_login_states(struct sc_pkcs11_slot *slot);

/* Session manipulation */
CK_RV get_session(CK_SESSION_HANDLE hSession, struct sc_pkcs11_session ** session);
CK_RV session_start_operation(struct sc_pkcs11_session *,
			int, sc_pkcs11_mechanism_type_t *,
			struct sc_pkcs11_operation **);
CK_RV session_get_operation(struct sc_pkcs11_session *, int,
			struct sc_pkcs11_operation **);
CK_RV session_stop_operation(struct sc_pkcs11_session *, int);
CK_RV sc_pkcs11_close_all_sessions(CK_SLOT_ID);

/* Generic secret key stuff */
CK_RV sc_pkcs11_create_secret_key(struct sc_pkcs11_session *,
			const u8 *, size_t,
			CK_ATTRIBUTE_PTR, CK_ULONG,
			struct sc_pkcs11_object **);
/* Generic object handling */
CK_RV sc_pkcs11_any_cmp_attribute(struct sc_pkcs11_session *,
			void *, CK_ATTRIBUTE_PTR);

/* Get attributes from template (misc.c) */
CK_RV attr_find(CK_ATTRIBUTE_PTR, CK_ULONG, CK_ULONG, void *, size_t *);
CK_RV attr_find2(CK_ATTRIBUTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG,
		CK_ULONG, void *, size_t *);
CK_RV attr_find_ptr(CK_ATTRIBUTE_PTR, CK_ULONG, CK_ULONG, void **, size_t *);
CK_RV attr_find_ptr2(CK_ATTRIBUTE_PTR pTemp1, CK_ULONG ulCount1,
		CK_ATTRIBUTE_PTR pTemp2, CK_ULONG ulCount2, CK_ULONG type, void **ptr, size_t * sizep);
CK_RV attr_find_and_allocate_ptr(CK_ATTRIBUTE_PTR, CK_ULONG, CK_ULONG, void **, size_t *);
CK_RV attr_find_var(CK_ATTRIBUTE_PTR, CK_ULONG, CK_ULONG, void *, size_t *);
CK_RV attr_extract(CK_ATTRIBUTE_PTR, void *, size_t *);

/* Generic Mechanism functions */
CK_RV sc_pkcs11_register_mechanism(struct sc_pkcs11_card *,
				sc_pkcs11_mechanism_type_t *);
CK_RV sc_pkcs11_get_mechanism_list(struct sc_pkcs11_card *,
				CK_MECHANISM_TYPE_PTR, CK_ULONG_PTR);
CK_RV sc_pkcs11_get_mechanism_info(struct sc_pkcs11_card *, CK_MECHANISM_TYPE,
				CK_MECHANISM_INFO_PTR);
CK_RV sc_pkcs11_md_init(struct sc_pkcs11_session *, CK_MECHANISM_PTR);
CK_RV sc_pkcs11_md_update(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG);
CK_RV sc_pkcs11_md_final(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG_PTR);
CK_RV sc_pkcs11_sign_init(struct sc_pkcs11_session *, CK_MECHANISM_PTR,
				struct sc_pkcs11_object *, CK_MECHANISM_TYPE);
CK_RV sc_pkcs11_sign_update(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG);
CK_RV sc_pkcs11_sign_final(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG_PTR);
CK_RV sc_pkcs11_sign_size(struct sc_pkcs11_session *, CK_ULONG_PTR);
#ifdef ENABLE_OPENSSL
CK_RV sc_pkcs11_verif_init(struct sc_pkcs11_session *, CK_MECHANISM_PTR,
				struct sc_pkcs11_object *, CK_MECHANISM_TYPE);
CK_RV sc_pkcs11_verif_update(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG);
CK_RV sc_pkcs11_verif_final(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG);
#endif
CK_RV sc_pkcs11_decr_init(struct sc_pkcs11_session *, CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_MECHANISM_TYPE);
CK_RV sc_pkcs11_decr(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR);
CK_RV sc_pkcs11_wrap(struct sc_pkcs11_session *,CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_KEY_TYPE, struct sc_pkcs11_object *, CK_BYTE_PTR, CK_ULONG_PTR);
CK_RV sc_pkcs11_unwrap(struct sc_pkcs11_session *,CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_KEY_TYPE, CK_BYTE_PTR, CK_ULONG, struct sc_pkcs11_object *);
CK_RV sc_pkcs11_deri(struct sc_pkcs11_session *, CK_MECHANISM_PTR,
				struct sc_pkcs11_object *, CK_KEY_TYPE,
				CK_SESSION_HANDLE, CK_OBJECT_HANDLE, struct sc_pkcs11_object *);
sc_pkcs11_mechanism_type_t *sc_pkcs11_find_mechanism(struct sc_pkcs11_card *,
				CK_MECHANISM_TYPE, unsigned int);
sc_pkcs11_mechanism_type_t *sc_pkcs11_new_fw_mechanism(CK_MECHANISM_TYPE,
				CK_MECHANISM_INFO_PTR, CK_KEY_TYPE,
				const void *, void (*)(const void *));
sc_pkcs11_operation_t *sc_pkcs11_new_operation(sc_pkcs11_session_t *,
				sc_pkcs11_mechanism_type_t *);
void sc_pkcs11_release_operation(sc_pkcs11_operation_t **);
CK_RV sc_pkcs11_register_generic_mechanisms(struct sc_pkcs11_card *);
#ifdef ENABLE_OPENSSL
void sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *);
#endif
CK_RV sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *,
				CK_MECHANISM_TYPE, CK_MECHANISM_TYPE,
				sc_pkcs11_mechanism_type_t *);

#ifdef ENABLE_OPENSSL
CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len,
	const unsigned char *pubkey_params, unsigned int pubkey_params_len,
	CK_MECHANISM_PTR mech, sc_pkcs11_operation_t *md,
	unsigned char *inp, unsigned int inp_len,
	unsigned char *signat, unsigned int signat_len);
#endif

/* Load configuration defaults */
void load_pkcs11_parameters(struct sc_pkcs11_config *, struct sc_context *);

/* Locking primitives at the pkcs11 level */
CK_RV sc_pkcs11_init_lock(CK_C_INITIALIZE_ARGS_PTR);
CK_RV sc_pkcs11_lock(void);
void sc_pkcs11_unlock(void);
void sc_pkcs11_free_lock(void);

#ifdef __cplusplus
}
#endif

#endif  /* __sc_pkcs11_h__ */