summaryrefslogtreecommitdiff
path: root/ckcapi.h
blob: 4e69c0dfd1c83e40e7f6e189671cb2382efb5383 (plain)
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
#ifndef CKCAPI_H
#define CKCAPI_H

#ifndef ASSERT
#include "assert.h"
#define ASSERT assert
#endif

#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x400
#include <windows.h>

#define CRYPTOKI_EXPORTS
#include "pkcs11/cryptoki.h"

#include "ckcapi-util.h"

struct _CkCapiObject;
struct _CkCapiSession;

typedef struct _CkCapiObject CkCapiObject;
typedef struct _CkCapiSession CkCapiSession;

/* Represents 'any' class in searches */
#define CKO_ANY CK_INVALID_HANDLE

/* ------------------------------------------------------------------
 * cryptoki-capi.c
 */

#define DBG(args) \
	ckcapi_debug args

void ckcapi_debug(const char* msg, ...);
void ckcapi_lock_global(void);
void ckcapi_unlock_global(void);
CK_RV	ckcapi_winerr_to_ckr		(DWORD werr);

CK_RV ckcapi_return_data(CK_VOID_PTR dst, CK_ULONG_PTR dlen, 
						 CK_VOID_PTR src, DWORD slen);

/* object data ------------------- */

typedef CK_RV (*CkCapiGetAttribute)(void* obj, CK_ATTRIBUTE_TYPE type, 
								    CK_VOID_PTR data, CK_ULONG_PTR len);

typedef void (*CkCapiRelease)(void* value);

typedef struct _CkCapiObjectDataVtable
{
	CkCapiGetAttribute get_bool;
	CkCapiGetAttribute get_ulong;
	CkCapiGetAttribute get_bytes;
	CkCapiGetAttribute get_date;
	CkCapiRelease release;
}
CkCapiObjectDataVtable;

typedef struct _CkCapiObjectData
{
	CK_OBJECT_HANDLE object;
	void* data;
	const CkCapiObjectDataVtable* data_funcs;
}
CkCapiObjectData;


/* ------------------------------------------------------------------ 
 * cryptoki-capi-session.c
 */

/* For operation_type in CkCapiSession */
enum
{
	OPERATION_NONE = 0,
	OPERATION_FIND = 1,
};

typedef void (*CkCapiSessionCancel) (struct _CkCapiSession* sess);

typedef struct _CkCapiSession 
{
	CK_ULONG id;                    /* Unique ID for this session */
	int in_call;					/* Whether this session is use in PKCS#11 function */

	int operation_type;				/* Whether an operation is happening or not */
	void* operation_data;			/* Data for this operation */
	CkCapiSessionCancel operation_cancel;	/* Callback to cancel operation when necessary */

	CkCapiHash* object_data;

	CK_NOTIFY notify_callback;      /* Application specified callback */
	CK_VOID_PTR user_data;          /* Argument for above */

	int refs;                       /* Reference count */
	HANDLE mutex;					/* Mutex for protecting this structure */
} 
CkCapiSession;

#define DBGS(sess, msg) \
	ckcapi_debug("S%d: %s", (sess) ? (sess)->id : 0, (msg))

CkCapiSession* ckcapi_session_create(void);
void ckcapi_session_destroy(CkCapiSession* sess);
CK_RV ckcapi_session_register(CkCapiSession* sess);
CK_RV ckcapi_session_get_lock_ref(CK_ULONG id, int remove, CkCapiSession **sess);
void ckcapi_session_unref_unlock(CkCapiSession* sess);
void ckcapi_session_close_all();

CK_RV		ckcapi_session_find_init			(CkCapiSession* sess, CK_ATTRIBUTE_PTR templ, CK_ULONG count);
CK_RV		ckcapi_session_find				(CkCapiSession* sess, CK_OBJECT_HANDLE_PTR objects, 
											 CK_ULONG max_object_count, CK_ULONG_PTR object_count);
CK_RV		ckcapi_session_find_final		(CkCapiSession* sess);

CK_RV		ckcapi_session_get_object_data	(CkCapiSession* sess, CkCapiObject* obj, 
											 CkCapiObjectData** objdata);

CK_RV		ckcapi_session_get_object_data_for		(CkCapiSession* sess, CK_OBJECT_HANDLE hand, 
													 CkCapiObjectData** objdata);

CK_RV		ckcapi_session_set_object_data	(CkCapiSession* sess, CkCapiObject* obj, 
											 const CkCapiObjectData* objdata);

void		ckcapi_session_clear_object_data	(CkCapiSession* sess, CkCapiObject* obj);

typedef void (*CkCapiEnumObjectData)(CkCapiSession* sess, CkCapiObject* obj, CkCapiObjectData* data, void* arg);

void		ckcapi_session_enum_object_data	(CkCapiSession* sess, CkCapiEnumObjectData enum_func, void* arg);


/* ------------------------------------------------------------------ 
 * ckcapi-object.c
 */

/* Used internally to guarantee uniqueness between object types */
enum
{
	OBJECT_CERT =	 1,
	OBJECT_BUILTIN = 2,
	OBJECT_TRUST =	 3
};


typedef CK_RV (*CkCapiPurge)(struct _CkCapiObject* obj);
typedef CK_RV (*CkCapiLoadData)(CkCapiSession* sess, struct _CkCapiObject* obj, 
								CkCapiObjectData* objdata);

typedef struct _CkCapiObjectVtable
{
	CkCapiLoadData load_data;
	CkCapiRelease release;
}
CkCapiObjectVtable;

/* 
 * Each object has a unique key which guarantees that we're 
 * not loading the same objects over and over again. 
 * Usually these are contiguous members of a struct. These 
 * macros help calculate the address and length of such a 
 * unique key 
 */

/* The unique key starts at the address of the starting struct member */
#define UNIQUE_KEY_AT(obj, mem)	\
	(void*)(&((obj->mem)))

/* Calculates key length between first and last struct members */
#define UNIQUE_KEY_LEN(obj, first, last) \
	UNIQUE_KEY_VAR_LEN(obj, first, last, sizeof(obj->last))

/* Calcs key len between first and a certain num of bytes past last struct member */
#define UNIQUE_KEY_VAR_LEN(obj, first, last, len) \
	((((char*)&((obj->last))) - ((char*)&((obj->first)))) + (len))

struct _CkCapiObject
{
	CK_OBJECT_HANDLE id;
	const CkCapiObjectVtable* obj_funcs;
	void* unique_key;
	size_t unique_len;
};

#define DBGO(obj, msg) \
	ckcapi_debug("O%d: %s", (obj) ? (obj)->id : 0, (msg))
#define DBGOD(objdata, msg) \
	ckcapi_debug("O%d: %s", (objdata) ? (objdata)->obj : 0, (msg))

CK_OBJECT_HANDLE	ckcapi_object_get_max_handle	(void);

CkCapiObject*		ckcapi_object_lookup			(CkCapiSession* sess, CK_OBJECT_HANDLE obj);

CK_RV				ckcapi_object_register			(CkCapiSession* sess, CkCapiObject* obj);

void				ckcapi_object_clear_all			(void);


CK_BBOOL			ckcapi_object_data_match		(CkCapiObjectData* objdata, 
													 CK_ATTRIBUTE_PTR matches, CK_ULONG count);

CK_BBOOL			ckcapi_object_data_match_attr	(CkCapiObjectData* objdata, 
													 CK_ATTRIBUTE_PTR match);

CK_RV				ckcapi_object_data_get_attrs	(CkCapiObjectData* objdata, CK_ATTRIBUTE_PTR attrs, 
													 CK_ULONG count);

/* -------------------------------------------------------------------
 * ckcapi-cert.c
 */

CK_RV				ckcapi_cert_find				(CkCapiSession* sess, CK_OBJECT_CLASS cls, 
													 CK_ATTRIBUTE_PTR match,  CK_ULONG count, 
													 CkCapiArray* arr);

CK_RV				ckcapi_cert_find_specific		(CkCapiSession* sess, CK_OBJECT_CLASS cls, 
													 CK_ATTRIBUTE_PTR issuer, CK_ATTRIBUTE_PTR serial, 
													 CK_OBJECT_HANDLE_PTR obj);

/* Called by trust stuff */
CK_RV				ckcapi_cert_get_bytes_attribute	(void* cert, CK_ATTRIBUTE_TYPE type, 
													 CK_VOID_PTR data, CK_ULONG_PTR len);

/* -------------------------------------------------------------------
 * ckcapi-builtin.c
 */

CK_RV				ckcapi_builtin_find				(CkCapiSession* sess, CK_OBJECT_CLASS cls, 
													 CK_ATTRIBUTE_PTR match, CK_ULONG count, 
													 CkCapiArray* arr);

/* -------------------------------------------------------------------
 * ckcapi-trust.c
 */

CK_RV				ckcapi_trust_find				(CkCapiSession* sess, CK_OBJECT_CLASS cls, 
													 CK_ATTRIBUTE_PTR match, CK_ULONG count, 
													 CkCapiArray* arr);

CK_RV				ckcapi_trust_find_specific		(CkCapiSession* sess, CK_OBJECT_CLASS cls, 
													 CK_ATTRIBUTE_PTR issuer, CK_ATTRIBUTE_PTR serial, 
													 CK_OBJECT_HANDLE_PTR obj);


#endif /* CRYPTOKI_CAPI_H */