xref: /freebsd/crypto/heimdal/lib/hx509/softp11.c (revision ed549cb0)
1c19800e8SDoug Rabson /*
2ae771770SStanislav Sedov  * Copyright (c) 2004 - 2008 Kungliga Tekniska Högskolan
3c19800e8SDoug Rabson  * (Royal Institute of Technology, Stockholm, Sweden).
4c19800e8SDoug Rabson  * All rights reserved.
5c19800e8SDoug Rabson  *
6c19800e8SDoug Rabson  * Redistribution and use in source and binary forms, with or without
7c19800e8SDoug Rabson  * modification, are permitted provided that the following conditions
8c19800e8SDoug Rabson  * are met:
9c19800e8SDoug Rabson  *
10c19800e8SDoug Rabson  * 1. Redistributions of source code must retain the above copyright
11c19800e8SDoug Rabson  *    notice, this list of conditions and the following disclaimer.
12c19800e8SDoug Rabson  *
13c19800e8SDoug Rabson  * 2. Redistributions in binary form must reproduce the above copyright
14c19800e8SDoug Rabson  *    notice, this list of conditions and the following disclaimer in the
15c19800e8SDoug Rabson  *    documentation and/or other materials provided with the distribution.
16c19800e8SDoug Rabson  *
17c19800e8SDoug Rabson  * 3. Neither the name of the Institute nor the names of its contributors
18c19800e8SDoug Rabson  *    may be used to endorse or promote products derived from this software
19c19800e8SDoug Rabson  *    without specific prior written permission.
20c19800e8SDoug Rabson  *
21c19800e8SDoug Rabson  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22c19800e8SDoug Rabson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23c19800e8SDoug Rabson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24c19800e8SDoug Rabson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25c19800e8SDoug Rabson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26c19800e8SDoug Rabson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27c19800e8SDoug Rabson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28c19800e8SDoug Rabson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29c19800e8SDoug Rabson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30c19800e8SDoug Rabson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31c19800e8SDoug Rabson  * SUCH DAMAGE.
32c19800e8SDoug Rabson  */
33c19800e8SDoug Rabson 
34ae771770SStanislav Sedov #define CRYPTOKI_EXPORTS 1
35ae771770SStanislav Sedov 
36c19800e8SDoug Rabson #include "hx_locl.h"
37c19800e8SDoug Rabson #include "pkcs11.h"
38c19800e8SDoug Rabson 
39c19800e8SDoug Rabson #define OBJECT_ID_MASK		0xfff
40c19800e8SDoug Rabson #define HANDLE_OBJECT_ID(h)	((h) & OBJECT_ID_MASK)
41c19800e8SDoug Rabson #define OBJECT_ID(obj)		HANDLE_OBJECT_ID((obj)->object_handle)
42c19800e8SDoug Rabson 
43ae771770SStanislav Sedov #ifndef HAVE_RANDOM
44ae771770SStanislav Sedov #define random() rand()
45ae771770SStanislav Sedov #define srandom(s) srand(s)
46ae771770SStanislav Sedov #endif
47ae771770SStanislav Sedov 
48ae771770SStanislav Sedov #ifdef _WIN32
49ae771770SStanislav Sedov #include <shlobj.h>
50ae771770SStanislav Sedov #endif
51c19800e8SDoug Rabson 
52c19800e8SDoug Rabson struct st_attr {
53c19800e8SDoug Rabson     CK_ATTRIBUTE attribute;
54c19800e8SDoug Rabson     int secret;
55c19800e8SDoug Rabson };
56c19800e8SDoug Rabson 
57c19800e8SDoug Rabson struct st_object {
58c19800e8SDoug Rabson     CK_OBJECT_HANDLE object_handle;
59c19800e8SDoug Rabson     struct st_attr *attrs;
60c19800e8SDoug Rabson     int num_attributes;
61c19800e8SDoug Rabson     hx509_cert cert;
62c19800e8SDoug Rabson };
63c19800e8SDoug Rabson 
64c19800e8SDoug Rabson static struct soft_token {
65c19800e8SDoug Rabson     CK_VOID_PTR application;
66c19800e8SDoug Rabson     CK_NOTIFY notify;
67c19800e8SDoug Rabson     char *config_file;
68c19800e8SDoug Rabson     hx509_certs certs;
69c19800e8SDoug Rabson     struct {
70c19800e8SDoug Rabson 	struct st_object **objs;
71c19800e8SDoug Rabson 	int num_objs;
72c19800e8SDoug Rabson     } object;
73c19800e8SDoug Rabson     struct {
74c19800e8SDoug Rabson 	int hardware_slot;
75c19800e8SDoug Rabson 	int app_error_fatal;
76c19800e8SDoug Rabson 	int login_done;
77c19800e8SDoug Rabson     } flags;
78c19800e8SDoug Rabson     int open_sessions;
79c19800e8SDoug Rabson     struct session_state {
80c19800e8SDoug Rabson 	CK_SESSION_HANDLE session_handle;
81c19800e8SDoug Rabson 
82c19800e8SDoug Rabson 	struct {
83c19800e8SDoug Rabson 	    CK_ATTRIBUTE *attributes;
84c19800e8SDoug Rabson 	    CK_ULONG num_attributes;
85c19800e8SDoug Rabson 	    int next_object;
86c19800e8SDoug Rabson 	} find;
87c19800e8SDoug Rabson 
88c19800e8SDoug Rabson 	int sign_object;
89c19800e8SDoug Rabson 	CK_MECHANISM_PTR sign_mechanism;
90c19800e8SDoug Rabson 	int verify_object;
91c19800e8SDoug Rabson 	CK_MECHANISM_PTR verify_mechanism;
92c19800e8SDoug Rabson     } state[10];
93c19800e8SDoug Rabson #define MAX_NUM_SESSION (sizeof(soft_token.state)/sizeof(soft_token.state[0]))
94c19800e8SDoug Rabson     FILE *logfile;
95c19800e8SDoug Rabson } soft_token;
96c19800e8SDoug Rabson 
97c19800e8SDoug Rabson static hx509_context context;
98c19800e8SDoug Rabson 
99c19800e8SDoug Rabson static void
application_error(const char * fmt,...)100c19800e8SDoug Rabson application_error(const char *fmt, ...)
101c19800e8SDoug Rabson {
102c19800e8SDoug Rabson     va_list ap;
103c19800e8SDoug Rabson     va_start(ap, fmt);
104c19800e8SDoug Rabson     vprintf(fmt, ap);
105c19800e8SDoug Rabson     va_end(ap);
106c19800e8SDoug Rabson     if (soft_token.flags.app_error_fatal)
107c19800e8SDoug Rabson 	abort();
108c19800e8SDoug Rabson }
109c19800e8SDoug Rabson 
110c19800e8SDoug Rabson static void
st_logf(const char * fmt,...)111c19800e8SDoug Rabson st_logf(const char *fmt, ...)
112c19800e8SDoug Rabson {
113c19800e8SDoug Rabson     va_list ap;
114c19800e8SDoug Rabson     if (soft_token.logfile == NULL)
115c19800e8SDoug Rabson 	return;
116c19800e8SDoug Rabson     va_start(ap, fmt);
117c19800e8SDoug Rabson     vfprintf(soft_token.logfile, fmt, ap);
118c19800e8SDoug Rabson     va_end(ap);
119c19800e8SDoug Rabson     fflush(soft_token.logfile);
120c19800e8SDoug Rabson }
121c19800e8SDoug Rabson 
122c19800e8SDoug Rabson static CK_RV
init_context(void)123c19800e8SDoug Rabson init_context(void)
124c19800e8SDoug Rabson {
125c19800e8SDoug Rabson     if (context == NULL) {
126c19800e8SDoug Rabson 	int ret = hx509_context_init(&context);
127c19800e8SDoug Rabson 	if (ret)
128c19800e8SDoug Rabson 	    return CKR_GENERAL_ERROR;
129c19800e8SDoug Rabson     }
130c19800e8SDoug Rabson     return CKR_OK;
131c19800e8SDoug Rabson }
132c19800e8SDoug Rabson 
133c19800e8SDoug Rabson #define INIT_CONTEXT() { CK_RV icret = init_context(); if (icret) return icret; }
134c19800e8SDoug Rabson 
135c19800e8SDoug Rabson static void
snprintf_fill(char * str,size_t size,char fillchar,const char * fmt,...)136c19800e8SDoug Rabson snprintf_fill(char *str, size_t size, char fillchar, const char *fmt, ...)
137c19800e8SDoug Rabson {
138c19800e8SDoug Rabson     int len;
139c19800e8SDoug Rabson     va_list ap;
140ae771770SStanislav Sedov     va_start(ap, fmt);
141c19800e8SDoug Rabson     len = vsnprintf(str, size, fmt, ap);
142c19800e8SDoug Rabson     va_end(ap);
143ae771770SStanislav Sedov     if (len < 0 || (size_t)len > size)
144c19800e8SDoug Rabson 	return;
145ae771770SStanislav Sedov     while ((size_t)len < size)
146c19800e8SDoug Rabson 	str[len++] = fillchar;
147c19800e8SDoug Rabson }
148c19800e8SDoug Rabson 
149c19800e8SDoug Rabson #ifndef TEST_APP
150c19800e8SDoug Rabson #define printf error_use_st_logf
151c19800e8SDoug Rabson #endif
152c19800e8SDoug Rabson 
153c19800e8SDoug Rabson #define VERIFY_SESSION_HANDLE(s, state)			\
154c19800e8SDoug Rabson {							\
155ae771770SStanislav Sedov     CK_RV xret;						\
156ae771770SStanislav Sedov     xret = verify_session_handle(s, state);		\
157ae771770SStanislav Sedov     if (xret != CKR_OK) {				\
158c19800e8SDoug Rabson 	/* return CKR_OK */;				\
159c19800e8SDoug Rabson     }							\
160c19800e8SDoug Rabson }
161c19800e8SDoug Rabson 
162c19800e8SDoug Rabson static CK_RV
verify_session_handle(CK_SESSION_HANDLE hSession,struct session_state ** state)163c19800e8SDoug Rabson verify_session_handle(CK_SESSION_HANDLE hSession,
164c19800e8SDoug Rabson 		      struct session_state **state)
165c19800e8SDoug Rabson {
166ae771770SStanislav Sedov     size_t i;
167c19800e8SDoug Rabson 
168c19800e8SDoug Rabson     for (i = 0; i < MAX_NUM_SESSION; i++){
169c19800e8SDoug Rabson 	if (soft_token.state[i].session_handle == hSession)
170c19800e8SDoug Rabson 	    break;
171c19800e8SDoug Rabson     }
172c19800e8SDoug Rabson     if (i == MAX_NUM_SESSION) {
173c19800e8SDoug Rabson 	application_error("use of invalid handle: 0x%08lx\n",
174c19800e8SDoug Rabson 			  (unsigned long)hSession);
175c19800e8SDoug Rabson 	return CKR_SESSION_HANDLE_INVALID;
176c19800e8SDoug Rabson     }
177c19800e8SDoug Rabson     if (state)
178c19800e8SDoug Rabson 	*state = &soft_token.state[i];
179c19800e8SDoug Rabson     return CKR_OK;
180c19800e8SDoug Rabson }
181c19800e8SDoug Rabson 
182c19800e8SDoug Rabson static CK_RV
object_handle_to_object(CK_OBJECT_HANDLE handle,struct st_object ** object)183c19800e8SDoug Rabson object_handle_to_object(CK_OBJECT_HANDLE handle,
184c19800e8SDoug Rabson 			struct st_object **object)
185c19800e8SDoug Rabson {
186c19800e8SDoug Rabson     int i = HANDLE_OBJECT_ID(handle);
187c19800e8SDoug Rabson 
188c19800e8SDoug Rabson     *object = NULL;
189c19800e8SDoug Rabson     if (i >= soft_token.object.num_objs)
190c19800e8SDoug Rabson 	return CKR_ARGUMENTS_BAD;
191c19800e8SDoug Rabson     if (soft_token.object.objs[i] == NULL)
192c19800e8SDoug Rabson 	return CKR_ARGUMENTS_BAD;
193c19800e8SDoug Rabson     if (soft_token.object.objs[i]->object_handle != handle)
194c19800e8SDoug Rabson 	return CKR_ARGUMENTS_BAD;
195c19800e8SDoug Rabson     *object = soft_token.object.objs[i];
196c19800e8SDoug Rabson     return CKR_OK;
197c19800e8SDoug Rabson }
198c19800e8SDoug Rabson 
199c19800e8SDoug Rabson static int
attributes_match(const struct st_object * obj,const CK_ATTRIBUTE * attributes,CK_ULONG num_attributes)200c19800e8SDoug Rabson attributes_match(const struct st_object *obj,
201c19800e8SDoug Rabson 		 const CK_ATTRIBUTE *attributes,
202c19800e8SDoug Rabson 		 CK_ULONG num_attributes)
203c19800e8SDoug Rabson {
204c19800e8SDoug Rabson     CK_ULONG i;
205c19800e8SDoug Rabson     int j;
206c19800e8SDoug Rabson 
207c19800e8SDoug Rabson     st_logf("attributes_match: %ld\n", (unsigned long)OBJECT_ID(obj));
208c19800e8SDoug Rabson 
209c19800e8SDoug Rabson     for (i = 0; i < num_attributes; i++) {
210c19800e8SDoug Rabson 	int match = 0;
211c19800e8SDoug Rabson 	for (j = 0; j < obj->num_attributes; j++) {
212c19800e8SDoug Rabson 	    if (attributes[i].type == obj->attrs[j].attribute.type &&
213c19800e8SDoug Rabson 		attributes[i].ulValueLen == obj->attrs[j].attribute.ulValueLen &&
214c19800e8SDoug Rabson 		memcmp(attributes[i].pValue, obj->attrs[j].attribute.pValue,
215c19800e8SDoug Rabson 		       attributes[i].ulValueLen) == 0) {
216c19800e8SDoug Rabson 		match = 1;
217c19800e8SDoug Rabson 		break;
218c19800e8SDoug Rabson 	    }
219c19800e8SDoug Rabson 	}
220c19800e8SDoug Rabson 	if (match == 0) {
221c19800e8SDoug Rabson 	    st_logf("type %d attribute have no match\n", attributes[i].type);
222c19800e8SDoug Rabson 	    return 0;
223c19800e8SDoug Rabson 	}
224c19800e8SDoug Rabson     }
225c19800e8SDoug Rabson     st_logf("attribute matches\n");
226c19800e8SDoug Rabson     return 1;
227c19800e8SDoug Rabson }
228c19800e8SDoug Rabson 
229c19800e8SDoug Rabson static void
print_attributes(const CK_ATTRIBUTE * attributes,CK_ULONG num_attributes)230c19800e8SDoug Rabson print_attributes(const CK_ATTRIBUTE *attributes,
231c19800e8SDoug Rabson 		 CK_ULONG num_attributes)
232c19800e8SDoug Rabson {
233c19800e8SDoug Rabson     CK_ULONG i;
234c19800e8SDoug Rabson 
235c19800e8SDoug Rabson     st_logf("find objects: attrs: %lu\n", (unsigned long)num_attributes);
236c19800e8SDoug Rabson 
237c19800e8SDoug Rabson     for (i = 0; i < num_attributes; i++) {
238c19800e8SDoug Rabson 	st_logf("  type: ");
239c19800e8SDoug Rabson 	switch (attributes[i].type) {
240c19800e8SDoug Rabson 	case CKA_TOKEN: {
241c19800e8SDoug Rabson 	    CK_BBOOL *ck_true;
242c19800e8SDoug Rabson 	    if (attributes[i].ulValueLen != sizeof(CK_BBOOL)) {
243c19800e8SDoug Rabson 		application_error("token attribute wrong length\n");
244c19800e8SDoug Rabson 		break;
245c19800e8SDoug Rabson 	    }
246c19800e8SDoug Rabson 	    ck_true = attributes[i].pValue;
247c19800e8SDoug Rabson 	    st_logf("token: %s", *ck_true ? "TRUE" : "FALSE");
248c19800e8SDoug Rabson 	    break;
249c19800e8SDoug Rabson 	}
250c19800e8SDoug Rabson 	case CKA_CLASS: {
251c19800e8SDoug Rabson 	    CK_OBJECT_CLASS *class;
252c19800e8SDoug Rabson 	    if (attributes[i].ulValueLen != sizeof(CK_ULONG)) {
253c19800e8SDoug Rabson 		application_error("class attribute wrong length\n");
254c19800e8SDoug Rabson 		break;
255c19800e8SDoug Rabson 	    }
256c19800e8SDoug Rabson 	    class = attributes[i].pValue;
257c19800e8SDoug Rabson 	    st_logf("class ");
258c19800e8SDoug Rabson 	    switch (*class) {
259c19800e8SDoug Rabson 	    case CKO_CERTIFICATE:
260c19800e8SDoug Rabson 		st_logf("certificate");
261c19800e8SDoug Rabson 		break;
262c19800e8SDoug Rabson 	    case CKO_PUBLIC_KEY:
263c19800e8SDoug Rabson 		st_logf("public key");
264c19800e8SDoug Rabson 		break;
265c19800e8SDoug Rabson 	    case CKO_PRIVATE_KEY:
266c19800e8SDoug Rabson 		st_logf("private key");
267c19800e8SDoug Rabson 		break;
268c19800e8SDoug Rabson 	    case CKO_SECRET_KEY:
269c19800e8SDoug Rabson 		st_logf("secret key");
270c19800e8SDoug Rabson 		break;
271c19800e8SDoug Rabson 	    case CKO_DOMAIN_PARAMETERS:
272c19800e8SDoug Rabson 		st_logf("domain parameters");
273c19800e8SDoug Rabson 		break;
274c19800e8SDoug Rabson 	    default:
275c19800e8SDoug Rabson 		st_logf("[class %lx]", (long unsigned)*class);
276c19800e8SDoug Rabson 		break;
277c19800e8SDoug Rabson 	    }
278c19800e8SDoug Rabson 	    break;
279c19800e8SDoug Rabson 	}
280c19800e8SDoug Rabson 	case CKA_PRIVATE:
281c19800e8SDoug Rabson 	    st_logf("private");
282c19800e8SDoug Rabson 	    break;
283c19800e8SDoug Rabson 	case CKA_LABEL:
284c19800e8SDoug Rabson 	    st_logf("label");
285c19800e8SDoug Rabson 	    break;
286c19800e8SDoug Rabson 	case CKA_APPLICATION:
287c19800e8SDoug Rabson 	    st_logf("application");
288c19800e8SDoug Rabson 	    break;
289c19800e8SDoug Rabson 	case CKA_VALUE:
290c19800e8SDoug Rabson 	    st_logf("value");
291c19800e8SDoug Rabson 	    break;
292c19800e8SDoug Rabson 	case CKA_ID:
293c19800e8SDoug Rabson 	    st_logf("id");
294c19800e8SDoug Rabson 	    break;
295c19800e8SDoug Rabson 	default:
296c19800e8SDoug Rabson 	    st_logf("[unknown 0x%08lx]", (unsigned long)attributes[i].type);
297c19800e8SDoug Rabson 	    break;
298c19800e8SDoug Rabson 	}
299c19800e8SDoug Rabson 	st_logf("\n");
300c19800e8SDoug Rabson     }
301c19800e8SDoug Rabson }
302c19800e8SDoug Rabson 
303c19800e8SDoug Rabson static struct st_object *
add_st_object(void)304c19800e8SDoug Rabson add_st_object(void)
305c19800e8SDoug Rabson {
306c19800e8SDoug Rabson     struct st_object *o, **objs;
307c19800e8SDoug Rabson     int i;
308c19800e8SDoug Rabson 
309ae771770SStanislav Sedov     o = calloc(1, sizeof(*o));
310c19800e8SDoug Rabson     if (o == NULL)
311c19800e8SDoug Rabson 	return NULL;
312c19800e8SDoug Rabson 
313c19800e8SDoug Rabson     for (i = 0; i < soft_token.object.num_objs; i++) {
314c19800e8SDoug Rabson 	if (soft_token.object.objs == NULL) {
315c19800e8SDoug Rabson 	    soft_token.object.objs[i] = o;
316c19800e8SDoug Rabson 	    break;
317c19800e8SDoug Rabson 	}
318c19800e8SDoug Rabson     }
319c19800e8SDoug Rabson     if (i == soft_token.object.num_objs) {
320c19800e8SDoug Rabson 	objs = realloc(soft_token.object.objs,
321c19800e8SDoug Rabson 		       (soft_token.object.num_objs + 1) * sizeof(soft_token.object.objs[0]));
322c19800e8SDoug Rabson 	if (objs == NULL) {
323c19800e8SDoug Rabson 	    free(o);
324c19800e8SDoug Rabson 	    return NULL;
325c19800e8SDoug Rabson 	}
326c19800e8SDoug Rabson 	soft_token.object.objs = objs;
327c19800e8SDoug Rabson 	soft_token.object.objs[soft_token.object.num_objs++] = o;
328c19800e8SDoug Rabson     }
329c19800e8SDoug Rabson     soft_token.object.objs[i]->object_handle =
330c19800e8SDoug Rabson 	(random() & (~OBJECT_ID_MASK)) | i;
331c19800e8SDoug Rabson 
332c19800e8SDoug Rabson     return o;
333c19800e8SDoug Rabson }
334c19800e8SDoug Rabson 
335c19800e8SDoug Rabson static CK_RV
add_object_attribute(struct st_object * o,int secret,CK_ATTRIBUTE_TYPE type,CK_VOID_PTR pValue,CK_ULONG ulValueLen)336c19800e8SDoug Rabson add_object_attribute(struct st_object *o,
337c19800e8SDoug Rabson 		     int secret,
338c19800e8SDoug Rabson 		     CK_ATTRIBUTE_TYPE type,
339c19800e8SDoug Rabson 		     CK_VOID_PTR pValue,
340c19800e8SDoug Rabson 		     CK_ULONG ulValueLen)
341c19800e8SDoug Rabson {
342c19800e8SDoug Rabson     struct st_attr *a;
343c19800e8SDoug Rabson     int i;
344c19800e8SDoug Rabson 
345ed549cb0SCy Schubert     if (pValue == NULL && ulValueLen)
346ed549cb0SCy Schubert         return CKR_ARGUMENTS_BAD;
347ed549cb0SCy Schubert 
348c19800e8SDoug Rabson     i = o->num_attributes;
349c19800e8SDoug Rabson     a = realloc(o->attrs, (i + 1) * sizeof(o->attrs[0]));
350c19800e8SDoug Rabson     if (a == NULL)
351c19800e8SDoug Rabson 	return CKR_DEVICE_MEMORY;
352c19800e8SDoug Rabson     o->attrs = a;
353c19800e8SDoug Rabson     o->attrs[i].secret = secret;
354c19800e8SDoug Rabson     o->attrs[i].attribute.type = type;
355c19800e8SDoug Rabson     o->attrs[i].attribute.pValue = malloc(ulValueLen);
356c19800e8SDoug Rabson     if (o->attrs[i].attribute.pValue == NULL && ulValueLen != 0)
357c19800e8SDoug Rabson 	return CKR_DEVICE_MEMORY;
358ed549cb0SCy Schubert     if (ulValueLen)
359c19800e8SDoug Rabson         memcpy(o->attrs[i].attribute.pValue, pValue, ulValueLen);
360c19800e8SDoug Rabson     o->attrs[i].attribute.ulValueLen = ulValueLen;
361c19800e8SDoug Rabson     o->num_attributes++;
362c19800e8SDoug Rabson 
363c19800e8SDoug Rabson     return CKR_OK;
364c19800e8SDoug Rabson }
365c19800e8SDoug Rabson 
366c19800e8SDoug Rabson static CK_RV
add_pubkey_info(hx509_context hxctx,struct st_object * o,CK_KEY_TYPE key_type,hx509_cert cert)367c19800e8SDoug Rabson add_pubkey_info(hx509_context hxctx, struct st_object *o,
368c19800e8SDoug Rabson 		CK_KEY_TYPE key_type, hx509_cert cert)
369c19800e8SDoug Rabson {
370c19800e8SDoug Rabson     BIGNUM *num;
371c19800e8SDoug Rabson     CK_BYTE *modulus = NULL;
372c19800e8SDoug Rabson     size_t modulus_len = 0;
373c19800e8SDoug Rabson     CK_ULONG modulus_bits = 0;
374c19800e8SDoug Rabson     CK_BYTE *exponent = NULL;
375c19800e8SDoug Rabson     size_t exponent_len = 0;
376c19800e8SDoug Rabson 
377c19800e8SDoug Rabson     if (key_type != CKK_RSA)
378c19800e8SDoug Rabson 	return CKR_OK;
379c19800e8SDoug Rabson     if (_hx509_cert_private_key(cert) == NULL)
380c19800e8SDoug Rabson 	return CKR_OK;
381c19800e8SDoug Rabson 
382c19800e8SDoug Rabson     num = _hx509_private_key_get_internal(context,
383c19800e8SDoug Rabson 					  _hx509_cert_private_key(cert),
384c19800e8SDoug Rabson 					  "rsa-modulus");
385c19800e8SDoug Rabson     if (num == NULL)
386c19800e8SDoug Rabson 	return CKR_GENERAL_ERROR;
387c19800e8SDoug Rabson     modulus_bits = BN_num_bits(num);
388c19800e8SDoug Rabson 
389c19800e8SDoug Rabson     modulus_len = BN_num_bytes(num);
390c19800e8SDoug Rabson     modulus = malloc(modulus_len);
391c19800e8SDoug Rabson     BN_bn2bin(num, modulus);
392c19800e8SDoug Rabson     BN_free(num);
393c19800e8SDoug Rabson 
394c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len);
395c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_MODULUS_BITS,
396c19800e8SDoug Rabson 			 &modulus_bits, sizeof(modulus_bits));
397c19800e8SDoug Rabson 
398c19800e8SDoug Rabson     free(modulus);
399c19800e8SDoug Rabson 
400c19800e8SDoug Rabson     num = _hx509_private_key_get_internal(context,
401c19800e8SDoug Rabson 					  _hx509_cert_private_key(cert),
402c19800e8SDoug Rabson 					  "rsa-exponent");
403c19800e8SDoug Rabson     if (num == NULL)
404c19800e8SDoug Rabson 	return CKR_GENERAL_ERROR;
405c19800e8SDoug Rabson 
406c19800e8SDoug Rabson     exponent_len = BN_num_bytes(num);
407c19800e8SDoug Rabson     exponent = malloc(exponent_len);
408c19800e8SDoug Rabson     BN_bn2bin(num, exponent);
409c19800e8SDoug Rabson     BN_free(num);
410c19800e8SDoug Rabson 
411c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT,
412c19800e8SDoug Rabson 			 exponent, exponent_len);
413c19800e8SDoug Rabson 
414c19800e8SDoug Rabson     free(exponent);
415c19800e8SDoug Rabson 
416c19800e8SDoug Rabson     return CKR_OK;
417c19800e8SDoug Rabson }
418c19800e8SDoug Rabson 
419c19800e8SDoug Rabson 
420c19800e8SDoug Rabson struct foo {
421c19800e8SDoug Rabson     char *label;
422c19800e8SDoug Rabson     char *id;
423c19800e8SDoug Rabson };
424c19800e8SDoug Rabson 
425c19800e8SDoug Rabson static int
add_cert(hx509_context hxctx,void * ctx,hx509_cert cert)426c19800e8SDoug Rabson add_cert(hx509_context hxctx, void *ctx, hx509_cert cert)
427c19800e8SDoug Rabson {
428ae771770SStanislav Sedov     static char empty[] = "";
429c19800e8SDoug Rabson     struct foo *foo = (struct foo *)ctx;
430c19800e8SDoug Rabson     struct st_object *o = NULL;
431c19800e8SDoug Rabson     CK_OBJECT_CLASS type;
432c19800e8SDoug Rabson     CK_BBOOL bool_true = CK_TRUE;
433c19800e8SDoug Rabson     CK_BBOOL bool_false = CK_FALSE;
434c19800e8SDoug Rabson     CK_CERTIFICATE_TYPE cert_type = CKC_X_509;
435c19800e8SDoug Rabson     CK_KEY_TYPE key_type;
436c19800e8SDoug Rabson     CK_MECHANISM_TYPE mech_type;
437c19800e8SDoug Rabson     CK_RV ret = CKR_GENERAL_ERROR;
438c19800e8SDoug Rabson     int hret;
439c19800e8SDoug Rabson     heim_octet_string cert_data, subject_data, issuer_data, serial_data;
440c19800e8SDoug Rabson 
441c19800e8SDoug Rabson     st_logf("adding certificate\n");
442c19800e8SDoug Rabson 
443c19800e8SDoug Rabson     serial_data.data = NULL;
444c19800e8SDoug Rabson     serial_data.length = 0;
445c19800e8SDoug Rabson     cert_data = subject_data = issuer_data = serial_data;
446c19800e8SDoug Rabson 
447c19800e8SDoug Rabson     hret = hx509_cert_binary(hxctx, cert, &cert_data);
448c19800e8SDoug Rabson     if (hret)
449c19800e8SDoug Rabson 	goto out;
450c19800e8SDoug Rabson 
451c19800e8SDoug Rabson     {
452c19800e8SDoug Rabson 	    hx509_name name;
453c19800e8SDoug Rabson 
454c19800e8SDoug Rabson 	    hret = hx509_cert_get_issuer(cert, &name);
455c19800e8SDoug Rabson 	    if (hret)
456c19800e8SDoug Rabson 		goto out;
457c19800e8SDoug Rabson 	    hret = hx509_name_binary(name, &issuer_data);
458c19800e8SDoug Rabson 	    hx509_name_free(&name);
459c19800e8SDoug Rabson 	    if (hret)
460c19800e8SDoug Rabson 		goto out;
461c19800e8SDoug Rabson 
462c19800e8SDoug Rabson 	    hret = hx509_cert_get_subject(cert, &name);
463c19800e8SDoug Rabson 	    if (hret)
464c19800e8SDoug Rabson 		goto out;
465c19800e8SDoug Rabson 	    hret = hx509_name_binary(name, &subject_data);
466c19800e8SDoug Rabson 	    hx509_name_free(&name);
467c19800e8SDoug Rabson 	    if (hret)
468c19800e8SDoug Rabson 		goto out;
469c19800e8SDoug Rabson     }
470c19800e8SDoug Rabson 
471c19800e8SDoug Rabson     {
472c19800e8SDoug Rabson 	AlgorithmIdentifier alg;
473c19800e8SDoug Rabson 
474c19800e8SDoug Rabson 	hret = hx509_cert_get_SPKI_AlgorithmIdentifier(context, cert, &alg);
475c19800e8SDoug Rabson 	if (hret) {
476c19800e8SDoug Rabson 	    ret = CKR_DEVICE_MEMORY;
477c19800e8SDoug Rabson 	    goto out;
478c19800e8SDoug Rabson 	}
479c19800e8SDoug Rabson 
480c19800e8SDoug Rabson 	key_type = CKK_RSA; /* XXX */
481c19800e8SDoug Rabson 
482c19800e8SDoug Rabson 	free_AlgorithmIdentifier(&alg);
483c19800e8SDoug Rabson     }
484c19800e8SDoug Rabson 
485c19800e8SDoug Rabson 
486c19800e8SDoug Rabson     type = CKO_CERTIFICATE;
487c19800e8SDoug Rabson     o = add_st_object();
488c19800e8SDoug Rabson     if (o == NULL) {
489c19800e8SDoug Rabson 	ret = CKR_DEVICE_MEMORY;
490c19800e8SDoug Rabson 	goto out;
491c19800e8SDoug Rabson     }
492c19800e8SDoug Rabson 
493c19800e8SDoug Rabson     o->cert = hx509_cert_ref(cert);
494c19800e8SDoug Rabson 
495c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_CLASS, &type, sizeof(type));
496c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true));
497c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false));
498c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false));
499c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_LABEL, foo->label, strlen(foo->label));
500c19800e8SDoug Rabson 
501c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type));
502c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id));
503c19800e8SDoug Rabson 
504c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_SUBJECT, subject_data.data, subject_data.length);
505c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_ISSUER, issuer_data.data, issuer_data.length);
506c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_SERIAL_NUMBER, serial_data.data, serial_data.length);
507c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_VALUE, cert_data.data, cert_data.length);
508c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_TRUSTED, &bool_false, sizeof(bool_false));
509c19800e8SDoug Rabson 
510c19800e8SDoug Rabson     st_logf("add cert ok: %lx\n", (unsigned long)OBJECT_ID(o));
511c19800e8SDoug Rabson 
512c19800e8SDoug Rabson     type = CKO_PUBLIC_KEY;
513c19800e8SDoug Rabson     o = add_st_object();
514c19800e8SDoug Rabson     if (o == NULL) {
515c19800e8SDoug Rabson 	ret = CKR_DEVICE_MEMORY;
516c19800e8SDoug Rabson 	goto out;
517c19800e8SDoug Rabson     }
518c19800e8SDoug Rabson     o->cert = hx509_cert_ref(cert);
519c19800e8SDoug Rabson 
520c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_CLASS, &type, sizeof(type));
521c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true));
522c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false));
523c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false));
524c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_LABEL, foo->label, strlen(foo->label));
525c19800e8SDoug Rabson 
526c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type));
527c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id));
528ae771770SStanislav Sedov     add_object_attribute(o, 0, CKA_START_DATE, empty, 1); /* XXX */
529ae771770SStanislav Sedov     add_object_attribute(o, 0, CKA_END_DATE, empty, 1); /* XXX */
530c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false));
531c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false));
532c19800e8SDoug Rabson     mech_type = CKM_RSA_X_509;
533c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type));
534c19800e8SDoug Rabson 
535c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_SUBJECT, subject_data.data, subject_data.length);
536c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_ENCRYPT, &bool_true, sizeof(bool_true));
537c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_VERIFY, &bool_true, sizeof(bool_true));
538c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_VERIFY_RECOVER, &bool_false, sizeof(bool_false));
539c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_WRAP, &bool_true, sizeof(bool_true));
540c19800e8SDoug Rabson     add_object_attribute(o, 0, CKA_TRUSTED, &bool_true, sizeof(bool_true));
541c19800e8SDoug Rabson 
542c19800e8SDoug Rabson     add_pubkey_info(hxctx, o, key_type, cert);
543c19800e8SDoug Rabson 
544c19800e8SDoug Rabson     st_logf("add key ok: %lx\n", (unsigned long)OBJECT_ID(o));
545c19800e8SDoug Rabson 
546c19800e8SDoug Rabson     if (hx509_cert_have_private_key(cert)) {
547c19800e8SDoug Rabson 	CK_FLAGS flags;
548c19800e8SDoug Rabson 
549c19800e8SDoug Rabson 	type = CKO_PRIVATE_KEY;
550c19800e8SDoug Rabson 	o = add_st_object();
551c19800e8SDoug Rabson 	if (o == NULL) {
552c19800e8SDoug Rabson 	    ret = CKR_DEVICE_MEMORY;
553c19800e8SDoug Rabson 	    goto out;
554c19800e8SDoug Rabson 	}
555c19800e8SDoug Rabson 	o->cert = hx509_cert_ref(cert);
556c19800e8SDoug Rabson 
557c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_CLASS, &type, sizeof(type));
558c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true));
559c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_PRIVATE, &bool_true, sizeof(bool_false));
560c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false));
561c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_LABEL, foo->label, strlen(foo->label));
562c19800e8SDoug Rabson 
563c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type));
564c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id));
565ae771770SStanislav Sedov 	add_object_attribute(o, 0, CKA_START_DATE, empty, 1); /* XXX */
566ae771770SStanislav Sedov 	add_object_attribute(o, 0, CKA_END_DATE, empty, 1); /* XXX */
567c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false));
568c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false));
569c19800e8SDoug Rabson 	mech_type = CKM_RSA_X_509;
570c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type));
571c19800e8SDoug Rabson 
572c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_SUBJECT, subject_data.data, subject_data.length);
573c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_SENSITIVE, &bool_true, sizeof(bool_true));
574c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_SECONDARY_AUTH, &bool_false, sizeof(bool_true));
575c19800e8SDoug Rabson 	flags = 0;
576c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_AUTH_PIN_FLAGS, &flags, sizeof(flags));
577c19800e8SDoug Rabson 
578c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_DECRYPT, &bool_true, sizeof(bool_true));
579c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_SIGN, &bool_true, sizeof(bool_true));
580c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_SIGN_RECOVER, &bool_false, sizeof(bool_false));
581c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_UNWRAP, &bool_true, sizeof(bool_true));
582c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_EXTRACTABLE, &bool_true, sizeof(bool_true));
583c19800e8SDoug Rabson 	add_object_attribute(o, 0, CKA_NEVER_EXTRACTABLE, &bool_false, sizeof(bool_false));
584c19800e8SDoug Rabson 
585c19800e8SDoug Rabson 	add_pubkey_info(hxctx, o, key_type, cert);
586c19800e8SDoug Rabson     }
587c19800e8SDoug Rabson 
588c19800e8SDoug Rabson     ret = CKR_OK;
589c19800e8SDoug Rabson  out:
590c19800e8SDoug Rabson     if (ret != CKR_OK) {
591c19800e8SDoug Rabson 	st_logf("something went wrong when adding cert!\n");
592c19800e8SDoug Rabson 
593c19800e8SDoug Rabson 	/* XXX wack o */;
594c19800e8SDoug Rabson     }
595c19800e8SDoug Rabson     hx509_xfree(cert_data.data);
596c19800e8SDoug Rabson     hx509_xfree(serial_data.data);
597c19800e8SDoug Rabson     hx509_xfree(issuer_data.data);
598c19800e8SDoug Rabson     hx509_xfree(subject_data.data);
599c19800e8SDoug Rabson 
600c19800e8SDoug Rabson     return 0;
601c19800e8SDoug Rabson }
602c19800e8SDoug Rabson 
603c19800e8SDoug Rabson static CK_RV
add_certificate(const char * cert_file,const char * pin,char * id,char * label)604c19800e8SDoug Rabson add_certificate(const char *cert_file,
605c19800e8SDoug Rabson 		const char *pin,
606c19800e8SDoug Rabson 		char *id,
607c19800e8SDoug Rabson 		char *label)
608c19800e8SDoug Rabson {
609c19800e8SDoug Rabson     hx509_certs certs;
610c19800e8SDoug Rabson     hx509_lock lock = NULL;
611c19800e8SDoug Rabson     int ret, flags = 0;
612c19800e8SDoug Rabson 
613c19800e8SDoug Rabson     struct foo foo;
614c19800e8SDoug Rabson     foo.id = id;
615c19800e8SDoug Rabson     foo.label = label;
616c19800e8SDoug Rabson 
617c19800e8SDoug Rabson     if (pin == NULL)
618c19800e8SDoug Rabson 	flags |= HX509_CERTS_UNPROTECT_ALL;
619c19800e8SDoug Rabson 
620c19800e8SDoug Rabson     if (pin) {
621c19800e8SDoug Rabson 	char *str;
622c19800e8SDoug Rabson 	asprintf(&str, "PASS:%s", pin);
623c19800e8SDoug Rabson 
624c19800e8SDoug Rabson 	hx509_lock_init(context, &lock);
625c19800e8SDoug Rabson 	hx509_lock_command_string(lock, str);
626c19800e8SDoug Rabson 
627c19800e8SDoug Rabson 	memset(str, 0, strlen(str));
628c19800e8SDoug Rabson 	free(str);
629c19800e8SDoug Rabson     }
630c19800e8SDoug Rabson 
631c19800e8SDoug Rabson     ret = hx509_certs_init(context, cert_file, flags, lock, &certs);
632c19800e8SDoug Rabson     if (ret) {
633c19800e8SDoug Rabson 	st_logf("failed to open file %s\n", cert_file);
634c19800e8SDoug Rabson 	return CKR_GENERAL_ERROR;
635c19800e8SDoug Rabson     }
636c19800e8SDoug Rabson 
637ae771770SStanislav Sedov     ret = hx509_certs_iter_f(context, certs, add_cert, &foo);
638c19800e8SDoug Rabson     hx509_certs_free(&certs);
639c19800e8SDoug Rabson     if (ret) {
640c19800e8SDoug Rabson 	st_logf("failed adding certs from file %s\n", cert_file);
641c19800e8SDoug Rabson 	return CKR_GENERAL_ERROR;
642c19800e8SDoug Rabson     }
643c19800e8SDoug Rabson 
644c19800e8SDoug Rabson     return CKR_OK;
645c19800e8SDoug Rabson }
646c19800e8SDoug Rabson 
647c19800e8SDoug Rabson static void
find_object_final(struct session_state * state)648c19800e8SDoug Rabson find_object_final(struct session_state *state)
649c19800e8SDoug Rabson {
650c19800e8SDoug Rabson     if (state->find.attributes) {
651c19800e8SDoug Rabson 	CK_ULONG i;
652c19800e8SDoug Rabson 
653c19800e8SDoug Rabson 	for (i = 0; i < state->find.num_attributes; i++) {
654c19800e8SDoug Rabson 	    if (state->find.attributes[i].pValue)
655c19800e8SDoug Rabson 		free(state->find.attributes[i].pValue);
656c19800e8SDoug Rabson 	}
657c19800e8SDoug Rabson 	free(state->find.attributes);
658c19800e8SDoug Rabson 	state->find.attributes = NULL;
659c19800e8SDoug Rabson 	state->find.num_attributes = 0;
660c19800e8SDoug Rabson 	state->find.next_object = -1;
661c19800e8SDoug Rabson     }
662c19800e8SDoug Rabson }
663c19800e8SDoug Rabson 
664c19800e8SDoug Rabson static void
reset_crypto_state(struct session_state * state)665c19800e8SDoug Rabson reset_crypto_state(struct session_state *state)
666c19800e8SDoug Rabson {
667c19800e8SDoug Rabson     state->sign_object = -1;
668c19800e8SDoug Rabson     if (state->sign_mechanism)
669c19800e8SDoug Rabson 	free(state->sign_mechanism);
670c19800e8SDoug Rabson     state->sign_mechanism = NULL_PTR;
671c19800e8SDoug Rabson     state->verify_object = -1;
672c19800e8SDoug Rabson     if (state->verify_mechanism)
673c19800e8SDoug Rabson 	free(state->verify_mechanism);
674c19800e8SDoug Rabson     state->verify_mechanism = NULL_PTR;
675c19800e8SDoug Rabson }
676c19800e8SDoug Rabson 
677c19800e8SDoug Rabson static void
close_session(struct session_state * state)678c19800e8SDoug Rabson close_session(struct session_state *state)
679c19800e8SDoug Rabson {
680c19800e8SDoug Rabson     if (state->find.attributes) {
681c19800e8SDoug Rabson 	application_error("application didn't do C_FindObjectsFinal\n");
682c19800e8SDoug Rabson 	find_object_final(state);
683c19800e8SDoug Rabson     }
684c19800e8SDoug Rabson 
685c19800e8SDoug Rabson     state->session_handle = CK_INVALID_HANDLE;
686c19800e8SDoug Rabson     soft_token.application = NULL_PTR;
687c19800e8SDoug Rabson     soft_token.notify = NULL_PTR;
688c19800e8SDoug Rabson     reset_crypto_state(state);
689c19800e8SDoug Rabson }
690c19800e8SDoug Rabson 
691c19800e8SDoug Rabson static const char *
has_session(void)692c19800e8SDoug Rabson has_session(void)
693c19800e8SDoug Rabson {
694c19800e8SDoug Rabson     return soft_token.open_sessions > 0 ? "yes" : "no";
695c19800e8SDoug Rabson }
696c19800e8SDoug Rabson 
697c19800e8SDoug Rabson static CK_RV
read_conf_file(const char * fn,CK_USER_TYPE userType,const char * pin)698c19800e8SDoug Rabson read_conf_file(const char *fn, CK_USER_TYPE userType, const char *pin)
699c19800e8SDoug Rabson {
700c19800e8SDoug Rabson     char buf[1024], *type, *s, *p;
701c19800e8SDoug Rabson     FILE *f;
702c19800e8SDoug Rabson     CK_RV ret = CKR_OK;
703c19800e8SDoug Rabson     CK_RV failed = CKR_OK;
704c19800e8SDoug Rabson 
705ae771770SStanislav Sedov     if (fn == NULL) {
706ae771770SStanislav Sedov         st_logf("Can't open configuration file.  No file specified\n");
707ae771770SStanislav Sedov         return CKR_GENERAL_ERROR;
708ae771770SStanislav Sedov     }
709ae771770SStanislav Sedov 
710c19800e8SDoug Rabson     f = fopen(fn, "r");
711c19800e8SDoug Rabson     if (f == NULL) {
712c19800e8SDoug Rabson 	st_logf("can't open configuration file %s\n", fn);
713c19800e8SDoug Rabson 	return CKR_GENERAL_ERROR;
714c19800e8SDoug Rabson     }
715ae771770SStanislav Sedov     rk_cloexec_file(f);
716c19800e8SDoug Rabson 
717c19800e8SDoug Rabson     while(fgets(buf, sizeof(buf), f) != NULL) {
718c19800e8SDoug Rabson 	buf[strcspn(buf, "\n")] = '\0';
719c19800e8SDoug Rabson 
720c19800e8SDoug Rabson 	st_logf("line: %s\n", buf);
721c19800e8SDoug Rabson 
722c19800e8SDoug Rabson 	p = buf;
723ae771770SStanislav Sedov 	while (isspace((unsigned char)*p))
724c19800e8SDoug Rabson 	    p++;
725c19800e8SDoug Rabson 	if (*p == '#')
726c19800e8SDoug Rabson 	    continue;
727ae771770SStanislav Sedov 	while (isspace((unsigned char)*p))
728c19800e8SDoug Rabson 	    p++;
729c19800e8SDoug Rabson 
730c19800e8SDoug Rabson 	s = NULL;
731c19800e8SDoug Rabson 	type = strtok_r(p, "\t", &s);
732c19800e8SDoug Rabson 	if (type == NULL)
733c19800e8SDoug Rabson 	    continue;
734c19800e8SDoug Rabson 
735c19800e8SDoug Rabson 	if (strcasecmp("certificate", type) == 0) {
736c19800e8SDoug Rabson 	    char *cert, *id, *label;
737c19800e8SDoug Rabson 
738c19800e8SDoug Rabson 	    id = strtok_r(NULL, "\t", &s);
739c19800e8SDoug Rabson 	    if (id == NULL) {
740c19800e8SDoug Rabson 		st_logf("no id\n");
741c19800e8SDoug Rabson 		continue;
742c19800e8SDoug Rabson 	    }
743c19800e8SDoug Rabson 	    st_logf("id: %s\n", id);
744c19800e8SDoug Rabson 	    label = strtok_r(NULL, "\t", &s);
745c19800e8SDoug Rabson 	    if (label == NULL) {
746c19800e8SDoug Rabson 		st_logf("no label\n");
747c19800e8SDoug Rabson 		continue;
748c19800e8SDoug Rabson 	    }
749c19800e8SDoug Rabson 	    cert = strtok_r(NULL, "\t", &s);
750c19800e8SDoug Rabson 	    if (cert == NULL) {
751c19800e8SDoug Rabson 		st_logf("no certfiicate store\n");
752c19800e8SDoug Rabson 		continue;
753c19800e8SDoug Rabson 	    }
754c19800e8SDoug Rabson 
755c19800e8SDoug Rabson 	    st_logf("adding: %s: %s in file %s\n", id, label, cert);
756c19800e8SDoug Rabson 
757c19800e8SDoug Rabson 	    ret = add_certificate(cert, pin, id, label);
758c19800e8SDoug Rabson 	    if (ret)
759c19800e8SDoug Rabson 		failed = ret;
760c19800e8SDoug Rabson 	} else if (strcasecmp("debug", type) == 0) {
761c19800e8SDoug Rabson 	    char *name;
762c19800e8SDoug Rabson 
763c19800e8SDoug Rabson 	    name = strtok_r(NULL, "\t", &s);
764c19800e8SDoug Rabson 	    if (name == NULL) {
765c19800e8SDoug Rabson 		st_logf("no filename\n");
766c19800e8SDoug Rabson 		continue;
767c19800e8SDoug Rabson 	    }
768c19800e8SDoug Rabson 
769c19800e8SDoug Rabson 	    if (soft_token.logfile)
770c19800e8SDoug Rabson 		fclose(soft_token.logfile);
771c19800e8SDoug Rabson 
772c19800e8SDoug Rabson 	    if (strcasecmp(name, "stdout") == 0)
773c19800e8SDoug Rabson 		soft_token.logfile = stdout;
774ae771770SStanislav Sedov 	    else {
775c19800e8SDoug Rabson 		soft_token.logfile = fopen(name, "a");
776ae771770SStanislav Sedov 		if (soft_token.logfile)
777ae771770SStanislav Sedov 		    rk_cloexec_file(soft_token.logfile);
778ae771770SStanislav Sedov 	    }
779c19800e8SDoug Rabson 	    if (soft_token.logfile == NULL)
780c19800e8SDoug Rabson 		st_logf("failed to open file: %s\n", name);
781c19800e8SDoug Rabson 
782c19800e8SDoug Rabson 	} else if (strcasecmp("app-fatal", type) == 0) {
783c19800e8SDoug Rabson 	    char *name;
784c19800e8SDoug Rabson 
785c19800e8SDoug Rabson 	    name = strtok_r(NULL, "\t", &s);
786c19800e8SDoug Rabson 	    if (name == NULL) {
787c19800e8SDoug Rabson 		st_logf("argument to app-fatal\n");
788c19800e8SDoug Rabson 		continue;
789c19800e8SDoug Rabson 	    }
790c19800e8SDoug Rabson 
791c19800e8SDoug Rabson 	    if (strcmp(name, "true") == 0 || strcmp(name, "on") == 0)
792c19800e8SDoug Rabson 		soft_token.flags.app_error_fatal = 1;
793c19800e8SDoug Rabson 	    else if (strcmp(name, "false") == 0 || strcmp(name, "off") == 0)
794c19800e8SDoug Rabson 		soft_token.flags.app_error_fatal = 0;
795c19800e8SDoug Rabson 	    else
796c19800e8SDoug Rabson 		st_logf("unknown app-fatal: %s\n", name);
797c19800e8SDoug Rabson 
798c19800e8SDoug Rabson 	} else {
799c19800e8SDoug Rabson 	    st_logf("unknown type: %s\n", type);
800c19800e8SDoug Rabson 	}
801c19800e8SDoug Rabson     }
802c19800e8SDoug Rabson 
803c19800e8SDoug Rabson     fclose(f);
804c19800e8SDoug Rabson 
805c19800e8SDoug Rabson     return failed;
806c19800e8SDoug Rabson }
807c19800e8SDoug Rabson 
808c19800e8SDoug Rabson static CK_RV
func_not_supported(void)809c19800e8SDoug Rabson func_not_supported(void)
810c19800e8SDoug Rabson {
811c19800e8SDoug Rabson     st_logf("function not supported\n");
812c19800e8SDoug Rabson     return CKR_FUNCTION_NOT_SUPPORTED;
813c19800e8SDoug Rabson }
814c19800e8SDoug Rabson 
815ae771770SStanislav Sedov static char *
get_config_file_for_user(void)816ae771770SStanislav Sedov get_config_file_for_user(void)
817ae771770SStanislav Sedov {
818ae771770SStanislav Sedov     char *fn = NULL;
819ae771770SStanislav Sedov 
820ae771770SStanislav Sedov #ifndef _WIN32
821ae771770SStanislav Sedov     char *home = NULL;
822ae771770SStanislav Sedov 
823ae771770SStanislav Sedov     if (!issuid()) {
824ae771770SStanislav Sedov         fn = getenv("SOFTPKCS11RC");
825ae771770SStanislav Sedov         if (fn)
826ae771770SStanislav Sedov             fn = strdup(fn);
827ae771770SStanislav Sedov         home = getenv("HOME");
828ae771770SStanislav Sedov     }
829ae771770SStanislav Sedov     if (fn == NULL && home == NULL) {
830ae771770SStanislav Sedov         struct passwd *pw = getpwuid(getuid());
831ae771770SStanislav Sedov         if(pw != NULL)
832ae771770SStanislav Sedov             home = pw->pw_dir;
833ae771770SStanislav Sedov     }
834ae771770SStanislav Sedov     if (fn == NULL) {
835ae771770SStanislav Sedov         if (home)
836ae771770SStanislav Sedov             asprintf(&fn, "%s/.soft-token.rc", home);
837ae771770SStanislav Sedov         else
838ae771770SStanislav Sedov             fn = strdup("/etc/soft-token.rc");
839ae771770SStanislav Sedov     }
840ae771770SStanislav Sedov #else  /* Windows */
841ae771770SStanislav Sedov 
842ae771770SStanislav Sedov     char appdatafolder[MAX_PATH];
843ae771770SStanislav Sedov 
844ae771770SStanislav Sedov     fn = getenv("SOFTPKCS11RC");
845ae771770SStanislav Sedov 
846ae771770SStanislav Sedov     /* Retrieve the roaming AppData folder for the current user.  The
847ae771770SStanislav Sedov        current user is the user account represented by the current
848ae771770SStanislav Sedov        thread token. */
849ae771770SStanislav Sedov 
850ae771770SStanislav Sedov     if (fn == NULL &&
851ae771770SStanislav Sedov         SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, appdatafolder))) {
852ae771770SStanislav Sedov 
853ae771770SStanislav Sedov         asprintf(&fn, "%s\\.soft-token.rc", appdatafolder);
854ae771770SStanislav Sedov     }
855ae771770SStanislav Sedov 
856ae771770SStanislav Sedov #endif  /* _WIN32 */
857ae771770SStanislav Sedov 
858ae771770SStanislav Sedov     return fn;
859ae771770SStanislav Sedov }
860ae771770SStanislav Sedov 
861ae771770SStanislav Sedov 
862ae771770SStanislav Sedov CK_RV CK_SPEC
C_Initialize(CK_VOID_PTR a)863c19800e8SDoug Rabson C_Initialize(CK_VOID_PTR a)
864c19800e8SDoug Rabson {
865c19800e8SDoug Rabson     CK_C_INITIALIZE_ARGS_PTR args = a;
866c19800e8SDoug Rabson     CK_RV ret;
867ae771770SStanislav Sedov     size_t i;
868c19800e8SDoug Rabson 
869c19800e8SDoug Rabson     st_logf("Initialize\n");
870c19800e8SDoug Rabson 
871c19800e8SDoug Rabson     INIT_CONTEXT();
872c19800e8SDoug Rabson 
873c19800e8SDoug Rabson     OpenSSL_add_all_algorithms();
874c19800e8SDoug Rabson 
875ae771770SStanislav Sedov     srandom(getpid() ^ (int) time(NULL));
876c19800e8SDoug Rabson 
877c19800e8SDoug Rabson     for (i = 0; i < MAX_NUM_SESSION; i++) {
878c19800e8SDoug Rabson 	soft_token.state[i].session_handle = CK_INVALID_HANDLE;
879c19800e8SDoug Rabson 	soft_token.state[i].find.attributes = NULL;
880c19800e8SDoug Rabson 	soft_token.state[i].find.num_attributes = 0;
881c19800e8SDoug Rabson 	soft_token.state[i].find.next_object = -1;
882c19800e8SDoug Rabson 	reset_crypto_state(&soft_token.state[i]);
883c19800e8SDoug Rabson     }
884c19800e8SDoug Rabson 
885c19800e8SDoug Rabson     soft_token.flags.hardware_slot = 1;
886c19800e8SDoug Rabson     soft_token.flags.app_error_fatal = 0;
887c19800e8SDoug Rabson     soft_token.flags.login_done = 0;
888c19800e8SDoug Rabson 
889c19800e8SDoug Rabson     soft_token.object.objs = NULL;
890c19800e8SDoug Rabson     soft_token.object.num_objs = 0;
891c19800e8SDoug Rabson 
892c19800e8SDoug Rabson     soft_token.logfile = NULL;
893c19800e8SDoug Rabson #if 0
894c19800e8SDoug Rabson     soft_token.logfile = stdout;
895c19800e8SDoug Rabson #endif
896c19800e8SDoug Rabson #if 0
897c19800e8SDoug Rabson     soft_token.logfile = fopen("/tmp/log-pkcs11.txt", "a");
898c19800e8SDoug Rabson #endif
899c19800e8SDoug Rabson 
900c19800e8SDoug Rabson     if (a != NULL_PTR) {
901c19800e8SDoug Rabson 	st_logf("\tCreateMutex:\t%p\n", args->CreateMutex);
902c19800e8SDoug Rabson 	st_logf("\tDestroyMutext\t%p\n", args->DestroyMutex);
903c19800e8SDoug Rabson 	st_logf("\tLockMutext\t%p\n", args->LockMutex);
904c19800e8SDoug Rabson 	st_logf("\tUnlockMutext\t%p\n", args->UnlockMutex);
905c19800e8SDoug Rabson 	st_logf("\tFlags\t%04x\n", (unsigned int)args->flags);
906c19800e8SDoug Rabson     }
907c19800e8SDoug Rabson 
908ae771770SStanislav Sedov     soft_token.config_file = get_config_file_for_user();
909c19800e8SDoug Rabson 
910c19800e8SDoug Rabson     /*
911c19800e8SDoug Rabson      * This operations doesn't return CKR_OK if any of the
912c19800e8SDoug Rabson      * certificates failes to be unparsed (ie password protected).
913c19800e8SDoug Rabson      */
914c19800e8SDoug Rabson     ret = read_conf_file(soft_token.config_file, CKU_USER, NULL);
915c19800e8SDoug Rabson     if (ret == CKR_OK)
916c19800e8SDoug Rabson 	soft_token.flags.login_done = 1;
917c19800e8SDoug Rabson 
918c19800e8SDoug Rabson     return CKR_OK;
919c19800e8SDoug Rabson }
920c19800e8SDoug Rabson 
921c19800e8SDoug Rabson CK_RV
C_Finalize(CK_VOID_PTR args)922c19800e8SDoug Rabson C_Finalize(CK_VOID_PTR args)
923c19800e8SDoug Rabson {
924ae771770SStanislav Sedov     size_t i;
925c19800e8SDoug Rabson 
926c19800e8SDoug Rabson     INIT_CONTEXT();
927c19800e8SDoug Rabson 
928c19800e8SDoug Rabson     st_logf("Finalize\n");
929c19800e8SDoug Rabson 
930c19800e8SDoug Rabson     for (i = 0; i < MAX_NUM_SESSION; i++) {
931c19800e8SDoug Rabson 	if (soft_token.state[i].session_handle != CK_INVALID_HANDLE) {
932c19800e8SDoug Rabson 	    application_error("application finalized without "
933c19800e8SDoug Rabson 			      "closing session\n");
934c19800e8SDoug Rabson 	    close_session(&soft_token.state[i]);
935c19800e8SDoug Rabson 	}
936c19800e8SDoug Rabson     }
937c19800e8SDoug Rabson 
938c19800e8SDoug Rabson     return CKR_OK;
939c19800e8SDoug Rabson }
940c19800e8SDoug Rabson 
941c19800e8SDoug Rabson CK_RV
C_GetInfo(CK_INFO_PTR args)942c19800e8SDoug Rabson C_GetInfo(CK_INFO_PTR args)
943c19800e8SDoug Rabson {
944c19800e8SDoug Rabson     INIT_CONTEXT();
945c19800e8SDoug Rabson 
946c19800e8SDoug Rabson     st_logf("GetInfo\n");
947c19800e8SDoug Rabson 
948c19800e8SDoug Rabson     memset(args, 17, sizeof(*args));
949c19800e8SDoug Rabson     args->cryptokiVersion.major = 2;
950c19800e8SDoug Rabson     args->cryptokiVersion.minor = 10;
951c19800e8SDoug Rabson     snprintf_fill((char *)args->manufacturerID,
952c19800e8SDoug Rabson 		  sizeof(args->manufacturerID),
953c19800e8SDoug Rabson 		  ' ',
954c19800e8SDoug Rabson 		  "Heimdal hx509 SoftToken");
955c19800e8SDoug Rabson     snprintf_fill((char *)args->libraryDescription,
956c19800e8SDoug Rabson 		  sizeof(args->libraryDescription), ' ',
957c19800e8SDoug Rabson 		  "Heimdal hx509 SoftToken");
958c19800e8SDoug Rabson     args->libraryVersion.major = 2;
959c19800e8SDoug Rabson     args->libraryVersion.minor = 0;
960c19800e8SDoug Rabson 
961c19800e8SDoug Rabson     return CKR_OK;
962c19800e8SDoug Rabson }
963c19800e8SDoug Rabson 
964c19800e8SDoug Rabson extern CK_FUNCTION_LIST funcs;
965c19800e8SDoug Rabson 
966c19800e8SDoug Rabson CK_RV
C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)967c19800e8SDoug Rabson C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
968c19800e8SDoug Rabson {
969c19800e8SDoug Rabson     INIT_CONTEXT();
970c19800e8SDoug Rabson 
971c19800e8SDoug Rabson     *ppFunctionList = &funcs;
972c19800e8SDoug Rabson     return CKR_OK;
973c19800e8SDoug Rabson }
974c19800e8SDoug Rabson 
975c19800e8SDoug Rabson CK_RV
C_GetSlotList(CK_BBOOL tokenPresent,CK_SLOT_ID_PTR pSlotList,CK_ULONG_PTR pulCount)976c19800e8SDoug Rabson C_GetSlotList(CK_BBOOL tokenPresent,
977c19800e8SDoug Rabson 	      CK_SLOT_ID_PTR pSlotList,
978c19800e8SDoug Rabson 	      CK_ULONG_PTR   pulCount)
979c19800e8SDoug Rabson {
980c19800e8SDoug Rabson     INIT_CONTEXT();
981c19800e8SDoug Rabson     st_logf("GetSlotList: %s\n",
982c19800e8SDoug Rabson 	    tokenPresent ? "tokenPresent" : "token not Present");
983c19800e8SDoug Rabson     if (pSlotList)
984c19800e8SDoug Rabson 	pSlotList[0] = 1;
985c19800e8SDoug Rabson     *pulCount = 1;
986c19800e8SDoug Rabson     return CKR_OK;
987c19800e8SDoug Rabson }
988c19800e8SDoug Rabson 
989c19800e8SDoug Rabson CK_RV
C_GetSlotInfo(CK_SLOT_ID slotID,CK_SLOT_INFO_PTR pInfo)990c19800e8SDoug Rabson C_GetSlotInfo(CK_SLOT_ID slotID,
991c19800e8SDoug Rabson 	      CK_SLOT_INFO_PTR pInfo)
992c19800e8SDoug Rabson {
993c19800e8SDoug Rabson     INIT_CONTEXT();
994c19800e8SDoug Rabson     st_logf("GetSlotInfo: slot: %d : %s\n", (int)slotID, has_session());
995c19800e8SDoug Rabson 
996c19800e8SDoug Rabson     memset(pInfo, 18, sizeof(*pInfo));
997c19800e8SDoug Rabson 
998c19800e8SDoug Rabson     if (slotID != 1)
999c19800e8SDoug Rabson 	return CKR_ARGUMENTS_BAD;
1000c19800e8SDoug Rabson 
1001c19800e8SDoug Rabson     snprintf_fill((char *)pInfo->slotDescription,
1002c19800e8SDoug Rabson 		  sizeof(pInfo->slotDescription),
1003c19800e8SDoug Rabson 		  ' ',
1004c19800e8SDoug Rabson 		  "Heimdal hx509 SoftToken (slot)");
1005c19800e8SDoug Rabson     snprintf_fill((char *)pInfo->manufacturerID,
1006c19800e8SDoug Rabson 		  sizeof(pInfo->manufacturerID),
1007c19800e8SDoug Rabson 		  ' ',
1008c19800e8SDoug Rabson 		  "Heimdal hx509 SoftToken (slot)");
1009c19800e8SDoug Rabson     pInfo->flags = CKF_TOKEN_PRESENT;
1010c19800e8SDoug Rabson     if (soft_token.flags.hardware_slot)
1011c19800e8SDoug Rabson 	pInfo->flags |= CKF_HW_SLOT;
1012c19800e8SDoug Rabson     pInfo->hardwareVersion.major = 1;
1013c19800e8SDoug Rabson     pInfo->hardwareVersion.minor = 0;
1014c19800e8SDoug Rabson     pInfo->firmwareVersion.major = 1;
1015c19800e8SDoug Rabson     pInfo->firmwareVersion.minor = 0;
1016c19800e8SDoug Rabson 
1017c19800e8SDoug Rabson     return CKR_OK;
1018c19800e8SDoug Rabson }
1019c19800e8SDoug Rabson 
1020c19800e8SDoug Rabson CK_RV
C_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)1021c19800e8SDoug Rabson C_GetTokenInfo(CK_SLOT_ID slotID,
1022c19800e8SDoug Rabson 	       CK_TOKEN_INFO_PTR pInfo)
1023c19800e8SDoug Rabson {
1024c19800e8SDoug Rabson     INIT_CONTEXT();
1025c19800e8SDoug Rabson     st_logf("GetTokenInfo: %s\n", has_session());
1026c19800e8SDoug Rabson 
1027c19800e8SDoug Rabson     memset(pInfo, 19, sizeof(*pInfo));
1028c19800e8SDoug Rabson 
1029c19800e8SDoug Rabson     snprintf_fill((char *)pInfo->label,
1030c19800e8SDoug Rabson 		  sizeof(pInfo->label),
1031c19800e8SDoug Rabson 		  ' ',
1032c19800e8SDoug Rabson 		  "Heimdal hx509 SoftToken (token)");
1033c19800e8SDoug Rabson     snprintf_fill((char *)pInfo->manufacturerID,
1034c19800e8SDoug Rabson 		  sizeof(pInfo->manufacturerID),
1035c19800e8SDoug Rabson 		  ' ',
1036c19800e8SDoug Rabson 		  "Heimdal hx509 SoftToken (token)");
1037c19800e8SDoug Rabson     snprintf_fill((char *)pInfo->model,
1038c19800e8SDoug Rabson 		  sizeof(pInfo->model),
1039c19800e8SDoug Rabson 		  ' ',
1040c19800e8SDoug Rabson 		  "Heimdal hx509 SoftToken (token)");
1041c19800e8SDoug Rabson     snprintf_fill((char *)pInfo->serialNumber,
1042c19800e8SDoug Rabson 		  sizeof(pInfo->serialNumber),
1043c19800e8SDoug Rabson 		  ' ',
1044c19800e8SDoug Rabson 		  "4711");
1045c19800e8SDoug Rabson     pInfo->flags =
1046c19800e8SDoug Rabson 	CKF_TOKEN_INITIALIZED |
1047c19800e8SDoug Rabson 	CKF_USER_PIN_INITIALIZED;
1048c19800e8SDoug Rabson 
1049c19800e8SDoug Rabson     if (soft_token.flags.login_done == 0)
1050c19800e8SDoug Rabson 	pInfo->flags |= CKF_LOGIN_REQUIRED;
1051c19800e8SDoug Rabson 
1052c19800e8SDoug Rabson     /* CFK_RNG |
1053c19800e8SDoug Rabson        CKF_RESTORE_KEY_NOT_NEEDED |
1054c19800e8SDoug Rabson     */
1055c19800e8SDoug Rabson     pInfo->ulMaxSessionCount = MAX_NUM_SESSION;
1056c19800e8SDoug Rabson     pInfo->ulSessionCount = soft_token.open_sessions;
1057c19800e8SDoug Rabson     pInfo->ulMaxRwSessionCount = MAX_NUM_SESSION;
1058c19800e8SDoug Rabson     pInfo->ulRwSessionCount = soft_token.open_sessions;
1059c19800e8SDoug Rabson     pInfo->ulMaxPinLen = 1024;
1060c19800e8SDoug Rabson     pInfo->ulMinPinLen = 0;
1061c19800e8SDoug Rabson     pInfo->ulTotalPublicMemory = 4711;
1062c19800e8SDoug Rabson     pInfo->ulFreePublicMemory = 4712;
1063c19800e8SDoug Rabson     pInfo->ulTotalPrivateMemory = 4713;
1064c19800e8SDoug Rabson     pInfo->ulFreePrivateMemory = 4714;
1065c19800e8SDoug Rabson     pInfo->hardwareVersion.major = 2;
1066c19800e8SDoug Rabson     pInfo->hardwareVersion.minor = 0;
1067c19800e8SDoug Rabson     pInfo->firmwareVersion.major = 2;
1068c19800e8SDoug Rabson     pInfo->firmwareVersion.minor = 0;
1069c19800e8SDoug Rabson 
1070c19800e8SDoug Rabson     return CKR_OK;
1071c19800e8SDoug Rabson }
1072c19800e8SDoug Rabson 
1073c19800e8SDoug Rabson CK_RV
C_GetMechanismList(CK_SLOT_ID slotID,CK_MECHANISM_TYPE_PTR pMechanismList,CK_ULONG_PTR pulCount)1074c19800e8SDoug Rabson C_GetMechanismList(CK_SLOT_ID slotID,
1075c19800e8SDoug Rabson 		   CK_MECHANISM_TYPE_PTR pMechanismList,
1076c19800e8SDoug Rabson 		   CK_ULONG_PTR pulCount)
1077c19800e8SDoug Rabson {
1078c19800e8SDoug Rabson     INIT_CONTEXT();
1079c19800e8SDoug Rabson     st_logf("GetMechanismList\n");
1080c19800e8SDoug Rabson 
1081c19800e8SDoug Rabson     *pulCount = 1;
1082c19800e8SDoug Rabson     if (pMechanismList == NULL_PTR)
1083c19800e8SDoug Rabson 	return CKR_OK;
1084c19800e8SDoug Rabson     pMechanismList[1] = CKM_RSA_PKCS;
1085c19800e8SDoug Rabson 
1086c19800e8SDoug Rabson     return CKR_OK;
1087c19800e8SDoug Rabson }
1088c19800e8SDoug Rabson 
1089c19800e8SDoug Rabson CK_RV
C_GetMechanismInfo(CK_SLOT_ID slotID,CK_MECHANISM_TYPE type,CK_MECHANISM_INFO_PTR pInfo)1090c19800e8SDoug Rabson C_GetMechanismInfo(CK_SLOT_ID slotID,
1091c19800e8SDoug Rabson 		   CK_MECHANISM_TYPE type,
1092c19800e8SDoug Rabson 		   CK_MECHANISM_INFO_PTR pInfo)
1093c19800e8SDoug Rabson {
1094c19800e8SDoug Rabson     INIT_CONTEXT();
1095c19800e8SDoug Rabson     st_logf("GetMechanismInfo: slot %d type: %d\n",
1096c19800e8SDoug Rabson 	    (int)slotID, (int)type);
1097c19800e8SDoug Rabson     memset(pInfo, 0, sizeof(*pInfo));
1098c19800e8SDoug Rabson 
1099c19800e8SDoug Rabson     return CKR_OK;
1100c19800e8SDoug Rabson }
1101c19800e8SDoug Rabson 
1102c19800e8SDoug Rabson CK_RV
C_InitToken(CK_SLOT_ID slotID,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen,CK_UTF8CHAR_PTR pLabel)1103c19800e8SDoug Rabson C_InitToken(CK_SLOT_ID slotID,
1104c19800e8SDoug Rabson 	    CK_UTF8CHAR_PTR pPin,
1105c19800e8SDoug Rabson 	    CK_ULONG ulPinLen,
1106c19800e8SDoug Rabson 	    CK_UTF8CHAR_PTR pLabel)
1107c19800e8SDoug Rabson {
1108c19800e8SDoug Rabson     INIT_CONTEXT();
1109c19800e8SDoug Rabson     st_logf("InitToken: slot %d\n", (int)slotID);
1110c19800e8SDoug Rabson     return CKR_FUNCTION_NOT_SUPPORTED;
1111c19800e8SDoug Rabson }
1112c19800e8SDoug Rabson 
1113c19800e8SDoug Rabson CK_RV
C_OpenSession(CK_SLOT_ID slotID,CK_FLAGS flags,CK_VOID_PTR pApplication,CK_NOTIFY Notify,CK_SESSION_HANDLE_PTR phSession)1114c19800e8SDoug Rabson C_OpenSession(CK_SLOT_ID slotID,
1115c19800e8SDoug Rabson 	      CK_FLAGS flags,
1116c19800e8SDoug Rabson 	      CK_VOID_PTR pApplication,
1117c19800e8SDoug Rabson 	      CK_NOTIFY Notify,
1118c19800e8SDoug Rabson 	      CK_SESSION_HANDLE_PTR phSession)
1119c19800e8SDoug Rabson {
1120ae771770SStanislav Sedov     size_t i;
1121c19800e8SDoug Rabson     INIT_CONTEXT();
1122c19800e8SDoug Rabson     st_logf("OpenSession: slot: %d\n", (int)slotID);
1123c19800e8SDoug Rabson 
1124c19800e8SDoug Rabson     if (soft_token.open_sessions == MAX_NUM_SESSION)
1125c19800e8SDoug Rabson 	return CKR_SESSION_COUNT;
1126c19800e8SDoug Rabson 
1127c19800e8SDoug Rabson     soft_token.application = pApplication;
1128c19800e8SDoug Rabson     soft_token.notify = Notify;
1129c19800e8SDoug Rabson 
1130c19800e8SDoug Rabson     for (i = 0; i < MAX_NUM_SESSION; i++)
1131c19800e8SDoug Rabson 	if (soft_token.state[i].session_handle == CK_INVALID_HANDLE)
1132c19800e8SDoug Rabson 	    break;
1133c19800e8SDoug Rabson     if (i == MAX_NUM_SESSION)
1134c19800e8SDoug Rabson 	abort();
1135c19800e8SDoug Rabson 
1136c19800e8SDoug Rabson     soft_token.open_sessions++;
1137c19800e8SDoug Rabson 
1138c19800e8SDoug Rabson     soft_token.state[i].session_handle =
1139c19800e8SDoug Rabson 	(CK_SESSION_HANDLE)(random() & 0xfffff);
1140c19800e8SDoug Rabson     *phSession = soft_token.state[i].session_handle;
1141c19800e8SDoug Rabson 
1142c19800e8SDoug Rabson     return CKR_OK;
1143c19800e8SDoug Rabson }
1144c19800e8SDoug Rabson 
1145c19800e8SDoug Rabson CK_RV
C_CloseSession(CK_SESSION_HANDLE hSession)1146c19800e8SDoug Rabson C_CloseSession(CK_SESSION_HANDLE hSession)
1147c19800e8SDoug Rabson {
1148c19800e8SDoug Rabson     struct session_state *state;
1149c19800e8SDoug Rabson     INIT_CONTEXT();
1150c19800e8SDoug Rabson     st_logf("CloseSession\n");
1151c19800e8SDoug Rabson 
1152c19800e8SDoug Rabson     if (verify_session_handle(hSession, &state) != CKR_OK)
1153c19800e8SDoug Rabson 	application_error("closed session not open");
1154c19800e8SDoug Rabson     else
1155c19800e8SDoug Rabson 	close_session(state);
1156c19800e8SDoug Rabson 
1157c19800e8SDoug Rabson     return CKR_OK;
1158c19800e8SDoug Rabson }
1159c19800e8SDoug Rabson 
1160c19800e8SDoug Rabson CK_RV
C_CloseAllSessions(CK_SLOT_ID slotID)1161c19800e8SDoug Rabson C_CloseAllSessions(CK_SLOT_ID slotID)
1162c19800e8SDoug Rabson {
1163ae771770SStanislav Sedov     size_t i;
1164c19800e8SDoug Rabson     INIT_CONTEXT();
1165c19800e8SDoug Rabson 
1166c19800e8SDoug Rabson     st_logf("CloseAllSessions\n");
1167c19800e8SDoug Rabson 
1168c19800e8SDoug Rabson     for (i = 0; i < MAX_NUM_SESSION; i++)
1169c19800e8SDoug Rabson 	if (soft_token.state[i].session_handle != CK_INVALID_HANDLE)
1170c19800e8SDoug Rabson 	    close_session(&soft_token.state[i]);
1171c19800e8SDoug Rabson 
1172c19800e8SDoug Rabson     return CKR_OK;
1173c19800e8SDoug Rabson }
1174c19800e8SDoug Rabson 
1175c19800e8SDoug Rabson CK_RV
C_GetSessionInfo(CK_SESSION_HANDLE hSession,CK_SESSION_INFO_PTR pInfo)1176c19800e8SDoug Rabson C_GetSessionInfo(CK_SESSION_HANDLE hSession,
1177c19800e8SDoug Rabson 		 CK_SESSION_INFO_PTR pInfo)
1178c19800e8SDoug Rabson {
1179c19800e8SDoug Rabson     st_logf("GetSessionInfo\n");
1180c19800e8SDoug Rabson     INIT_CONTEXT();
1181c19800e8SDoug Rabson 
1182c19800e8SDoug Rabson     VERIFY_SESSION_HANDLE(hSession, NULL);
1183c19800e8SDoug Rabson 
1184c19800e8SDoug Rabson     memset(pInfo, 20, sizeof(*pInfo));
1185c19800e8SDoug Rabson 
1186c19800e8SDoug Rabson     pInfo->slotID = 1;
1187c19800e8SDoug Rabson     if (soft_token.flags.login_done)
1188c19800e8SDoug Rabson 	pInfo->state = CKS_RO_USER_FUNCTIONS;
1189c19800e8SDoug Rabson     else
1190c19800e8SDoug Rabson 	pInfo->state = CKS_RO_PUBLIC_SESSION;
1191c19800e8SDoug Rabson     pInfo->flags = CKF_SERIAL_SESSION;
1192c19800e8SDoug Rabson     pInfo->ulDeviceError = 0;
1193c19800e8SDoug Rabson 
1194c19800e8SDoug Rabson     return CKR_OK;
1195c19800e8SDoug Rabson }
1196c19800e8SDoug Rabson 
1197c19800e8SDoug Rabson CK_RV
C_Login(CK_SESSION_HANDLE hSession,CK_USER_TYPE userType,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen)1198c19800e8SDoug Rabson C_Login(CK_SESSION_HANDLE hSession,
1199c19800e8SDoug Rabson 	CK_USER_TYPE userType,
1200c19800e8SDoug Rabson 	CK_UTF8CHAR_PTR pPin,
1201c19800e8SDoug Rabson 	CK_ULONG ulPinLen)
1202c19800e8SDoug Rabson {
1203c19800e8SDoug Rabson     char *pin = NULL;
1204c19800e8SDoug Rabson     CK_RV ret;
1205c19800e8SDoug Rabson     INIT_CONTEXT();
1206c19800e8SDoug Rabson 
1207c19800e8SDoug Rabson     st_logf("Login\n");
1208c19800e8SDoug Rabson 
1209c19800e8SDoug Rabson     VERIFY_SESSION_HANDLE(hSession, NULL);
1210c19800e8SDoug Rabson 
1211c19800e8SDoug Rabson     if (pPin != NULL_PTR) {
1212c19800e8SDoug Rabson 	asprintf(&pin, "%.*s", (int)ulPinLen, pPin);
1213c19800e8SDoug Rabson 	st_logf("type: %d password: %s\n", (int)userType, pin);
1214c19800e8SDoug Rabson     }
1215c19800e8SDoug Rabson 
1216c19800e8SDoug Rabson     /*
1217c19800e8SDoug Rabson      * Login
1218c19800e8SDoug Rabson      */
1219c19800e8SDoug Rabson 
1220c19800e8SDoug Rabson     ret = read_conf_file(soft_token.config_file, userType, pin);
1221c19800e8SDoug Rabson     if (ret == CKR_OK)
1222c19800e8SDoug Rabson 	soft_token.flags.login_done = 1;
1223c19800e8SDoug Rabson 
1224c19800e8SDoug Rabson     free(pin);
1225c19800e8SDoug Rabson 
1226c19800e8SDoug Rabson     return soft_token.flags.login_done ? CKR_OK : CKR_PIN_INCORRECT;
1227c19800e8SDoug Rabson }
1228c19800e8SDoug Rabson 
1229c19800e8SDoug Rabson CK_RV
C_Logout(CK_SESSION_HANDLE hSession)1230c19800e8SDoug Rabson C_Logout(CK_SESSION_HANDLE hSession)
1231c19800e8SDoug Rabson {
1232c19800e8SDoug Rabson     st_logf("Logout\n");
1233c19800e8SDoug Rabson     INIT_CONTEXT();
1234c19800e8SDoug Rabson 
1235c19800e8SDoug Rabson     VERIFY_SESSION_HANDLE(hSession, NULL);
1236c19800e8SDoug Rabson     return CKR_FUNCTION_NOT_SUPPORTED;
1237c19800e8SDoug Rabson }
1238c19800e8SDoug Rabson 
1239c19800e8SDoug Rabson CK_RV
C_GetObjectSize(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ULONG_PTR pulSize)1240c19800e8SDoug Rabson C_GetObjectSize(CK_SESSION_HANDLE hSession,
1241c19800e8SDoug Rabson 		CK_OBJECT_HANDLE hObject,
1242c19800e8SDoug Rabson 		CK_ULONG_PTR pulSize)
1243c19800e8SDoug Rabson {
1244c19800e8SDoug Rabson     st_logf("GetObjectSize\n");
1245c19800e8SDoug Rabson     INIT_CONTEXT();
1246c19800e8SDoug Rabson 
1247c19800e8SDoug Rabson     VERIFY_SESSION_HANDLE(hSession, NULL);
1248c19800e8SDoug Rabson     return CKR_FUNCTION_NOT_SUPPORTED;
1249c19800e8SDoug Rabson }
1250c19800e8SDoug Rabson 
1251c19800e8SDoug Rabson CK_RV
C_GetAttributeValue(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)1252c19800e8SDoug Rabson C_GetAttributeValue(CK_SESSION_HANDLE hSession,
1253c19800e8SDoug Rabson 		    CK_OBJECT_HANDLE hObject,
1254c19800e8SDoug Rabson 		    CK_ATTRIBUTE_PTR pTemplate,
1255c19800e8SDoug Rabson 		    CK_ULONG ulCount)
1256c19800e8SDoug Rabson {
1257c19800e8SDoug Rabson     struct session_state *state;
1258c19800e8SDoug Rabson     struct st_object *obj;
1259c19800e8SDoug Rabson     CK_ULONG i;
1260c19800e8SDoug Rabson     CK_RV ret;
1261c19800e8SDoug Rabson     int j;
1262c19800e8SDoug Rabson 
1263c19800e8SDoug Rabson     INIT_CONTEXT();
1264c19800e8SDoug Rabson 
1265c19800e8SDoug Rabson     st_logf("GetAttributeValue: %lx\n",
1266c19800e8SDoug Rabson 	    (unsigned long)HANDLE_OBJECT_ID(hObject));
1267c19800e8SDoug Rabson     VERIFY_SESSION_HANDLE(hSession, &state);
1268c19800e8SDoug Rabson 
1269c19800e8SDoug Rabson     if ((ret = object_handle_to_object(hObject, &obj)) != CKR_OK) {
1270c19800e8SDoug Rabson 	st_logf("object not found: %lx\n",
1271c19800e8SDoug Rabson 		(unsigned long)HANDLE_OBJECT_ID(hObject));
1272c19800e8SDoug Rabson 	return ret;
1273c19800e8SDoug Rabson     }
1274c19800e8SDoug Rabson 
1275c19800e8SDoug Rabson     for (i = 0; i < ulCount; i++) {
1276c19800e8SDoug Rabson 	st_logf("	getting 0x%08lx\n", (unsigned long)pTemplate[i].type);
1277c19800e8SDoug Rabson 	for (j = 0; j < obj->num_attributes; j++) {
1278c19800e8SDoug Rabson 	    if (obj->attrs[j].secret) {
1279c19800e8SDoug Rabson 		pTemplate[i].ulValueLen = (CK_ULONG)-1;
1280c19800e8SDoug Rabson 		break;
1281c19800e8SDoug Rabson 	    }
1282c19800e8SDoug Rabson 	    if (pTemplate[i].type == obj->attrs[j].attribute.type) {
1283c19800e8SDoug Rabson 		if (pTemplate[i].pValue != NULL_PTR && obj->attrs[j].secret == 0) {
1284c19800e8SDoug Rabson 		    if (pTemplate[i].ulValueLen >= obj->attrs[j].attribute.ulValueLen)
1285c19800e8SDoug Rabson 			memcpy(pTemplate[i].pValue, obj->attrs[j].attribute.pValue,
1286c19800e8SDoug Rabson 			       obj->attrs[j].attribute.ulValueLen);
1287c19800e8SDoug Rabson 		}
1288c19800e8SDoug Rabson 		pTemplate[i].ulValueLen = obj->attrs[j].attribute.ulValueLen;
1289c19800e8SDoug Rabson 		break;
1290c19800e8SDoug Rabson 	    }
1291c19800e8SDoug Rabson 	}
1292c19800e8SDoug Rabson 	if (j == obj->num_attributes) {
1293c19800e8SDoug Rabson 	    st_logf("key type: 0x%08lx not found\n", (unsigned long)pTemplate[i].type);
1294c19800e8SDoug Rabson 	    pTemplate[i].ulValueLen = (CK_ULONG)-1;
1295c19800e8SDoug Rabson 	}
1296c19800e8SDoug Rabson 
1297c19800e8SDoug Rabson     }
1298c19800e8SDoug Rabson     return CKR_OK;
1299c19800e8SDoug Rabson }
1300c19800e8SDoug Rabson 
1301c19800e8SDoug Rabson CK_RV
C_FindObjectsInit(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)1302c19800e8SDoug Rabson C_FindObjectsInit(CK_SESSION_HANDLE hSession,
1303c19800e8SDoug Rabson 		  CK_ATTRIBUTE_PTR pTemplate,
1304c19800e8SDoug Rabson 		  CK_ULONG ulCount)
1305c19800e8SDoug Rabson {
1306c19800e8SDoug Rabson     struct session_state *state;
1307c19800e8SDoug Rabson 
1308c19800e8SDoug Rabson     st_logf("FindObjectsInit\n");
1309c19800e8SDoug Rabson 
1310c19800e8SDoug Rabson     INIT_CONTEXT();
1311c19800e8SDoug Rabson 
1312c19800e8SDoug Rabson     VERIFY_SESSION_HANDLE(hSession, &state);
1313c19800e8SDoug Rabson 
1314c19800e8SDoug Rabson     if (state->find.next_object != -1) {
1315c19800e8SDoug Rabson 	application_error("application didn't do C_FindObjectsFinal\n");
1316c19800e8SDoug Rabson 	find_object_final(state);
1317c19800e8SDoug Rabson     }
1318c19800e8SDoug Rabson     if (ulCount) {
1319c19800e8SDoug Rabson 	CK_ULONG i;
1320c19800e8SDoug Rabson 
1321c19800e8SDoug Rabson 	print_attributes(pTemplate, ulCount);
1322c19800e8SDoug Rabson 
1323c19800e8SDoug Rabson 	state->find.attributes =
1324c19800e8SDoug Rabson 	    calloc(1, ulCount * sizeof(state->find.attributes[0]));
1325c19800e8SDoug Rabson 	if (state->find.attributes == NULL)
1326c19800e8SDoug Rabson 	    return CKR_DEVICE_MEMORY;
1327c19800e8SDoug Rabson 	for (i = 0; i < ulCount; i++) {
1328c19800e8SDoug Rabson 	    state->find.attributes[i].pValue =
1329c19800e8SDoug Rabson 		malloc(pTemplate[i].ulValueLen);
1330c19800e8SDoug Rabson 	    if (state->find.attributes[i].pValue == NULL) {
1331c19800e8SDoug Rabson 		find_object_final(state);
1332c19800e8SDoug Rabson 		return CKR_DEVICE_MEMORY;
1333c19800e8SDoug Rabson 	    }
1334c19800e8SDoug Rabson 	    memcpy(state->find.attributes[i].pValue,
1335c19800e8SDoug Rabson 		   pTemplate[i].pValue, pTemplate[i].ulValueLen);
1336c19800e8SDoug Rabson 	    state->find.attributes[i].type = pTemplate[i].type;
1337c19800e8SDoug Rabson 	    state->find.attributes[i].ulValueLen = pTemplate[i].ulValueLen;
1338c19800e8SDoug Rabson 	}
1339c19800e8SDoug Rabson 	state->find.num_attributes = ulCount;
1340c19800e8SDoug Rabson 	state->find.next_object = 0;
1341c19800e8SDoug Rabson     } else {
1342c19800e8SDoug Rabson 	st_logf("find all objects\n");
1343c19800e8SDoug Rabson 	state->find.attributes = NULL;
1344c19800e8SDoug Rabson 	state->find.num_attributes = 0;
1345c19800e8SDoug Rabson 	state->find.next_object = 0;
1346c19800e8SDoug Rabson     }
1347c19800e8SDoug Rabson 
1348c19800e8SDoug Rabson     return CKR_OK;
1349c19800e8SDoug Rabson }
1350c19800e8SDoug Rabson 
1351c19800e8SDoug Rabson CK_RV
C_FindObjects(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE_PTR phObject,CK_ULONG ulMaxObjectCount,CK_ULONG_PTR pulObjectCount)1352c19800e8SDoug Rabson C_FindObjects(CK_SESSION_HANDLE hSession,
1353c19800e8SDoug Rabson 	      CK_OBJECT_HANDLE_PTR phObject,
1354c19800e8SDoug Rabson 	      CK_ULONG ulMaxObjectCount,
1355c19800e8SDoug Rabson 	      CK_ULONG_PTR pulObjectCount)
1356c19800e8SDoug Rabson {
1357c19800e8SDoug Rabson     struct session_state *state;
1358c19800e8SDoug Rabson     int i;
1359c19800e8SDoug Rabson 
1360c19800e8SDoug Rabson     INIT_CONTEXT();
1361c19800e8SDoug Rabson 
1362c19800e8SDoug Rabson     st_logf("FindObjects\n");
1363c19800e8SDoug Rabson 
1364c19800e8SDoug Rabson     VERIFY_SESSION_HANDLE(hSession, &state);
1365c19800e8SDoug Rabson 
1366c19800e8SDoug Rabson     if (state->find.next_object == -1) {
1367c19800e8SDoug Rabson 	application_error("application didn't do C_FindObjectsInit\n");
1368c19800e8SDoug Rabson 	return CKR_ARGUMENTS_BAD;
1369c19800e8SDoug Rabson     }
1370c19800e8SDoug Rabson     if (ulMaxObjectCount == 0) {
1371c19800e8SDoug Rabson 	application_error("application asked for 0 objects\n");
1372c19800e8SDoug Rabson 	return CKR_ARGUMENTS_BAD;
1373c19800e8SDoug Rabson     }
1374c19800e8SDoug Rabson     *pulObjectCount = 0;
1375c19800e8SDoug Rabson     for (i = state->find.next_object; i < soft_token.object.num_objs; i++) {
1376c19800e8SDoug Rabson 	st_logf("FindObjects: %d\n", i);
1377c19800e8SDoug Rabson 	state->find.next_object = i + 1;
1378c19800e8SDoug Rabson 	if (attributes_match(soft_token.object.objs[i],
1379c19800e8SDoug Rabson 			     state->find.attributes,
1380c19800e8SDoug Rabson 			     state->find.num_attributes)) {
1381c19800e8SDoug Rabson 	    *phObject++ = soft_token.object.objs[i]->object_handle;
1382c19800e8SDoug Rabson 	    ulMaxObjectCount--;
1383c19800e8SDoug Rabson 	    (*pulObjectCount)++;
1384c19800e8SDoug Rabson 	    if (ulMaxObjectCount == 0)
1385c19800e8SDoug Rabson 		break;
1386c19800e8SDoug Rabson 	}
1387c19800e8SDoug Rabson     }
1388c19800e8SDoug Rabson     return CKR_OK;
1389c19800e8SDoug Rabson }
1390c19800e8SDoug Rabson 
1391c19800e8SDoug Rabson CK_RV
C_FindObjectsFinal(CK_SESSION_HANDLE hSession)1392c19800e8SDoug Rabson C_FindObjectsFinal(CK_SESSION_HANDLE hSession)
1393c19800e8SDoug Rabson {
1394c19800e8SDoug Rabson     struct session_state *state;
1395c19800e8SDoug Rabson 
1396c19800e8SDoug Rabson     INIT_CONTEXT();
1397c19800e8SDoug Rabson 
1398c19800e8SDoug Rabson     st_logf("FindObjectsFinal\n");
1399c19800e8SDoug Rabson     VERIFY_SESSION_HANDLE(hSession, &state);
1400c19800e8SDoug Rabson     find_object_final(state);
1401c19800e8SDoug Rabson     return CKR_OK;
1402c19800e8SDoug Rabson }
1403c19800e8SDoug Rabson 
1404c19800e8SDoug Rabson static CK_RV
commonInit(CK_ATTRIBUTE * attr_match,int attr_match_len,const CK_MECHANISM_TYPE * mechs,int mechs_len,const CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey,struct st_object ** o)1405c19800e8SDoug Rabson commonInit(CK_ATTRIBUTE *attr_match, int attr_match_len,
1406c19800e8SDoug Rabson 	   const CK_MECHANISM_TYPE *mechs, int mechs_len,
1407c19800e8SDoug Rabson 	   const CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey,
1408c19800e8SDoug Rabson 	   struct st_object **o)
1409c19800e8SDoug Rabson {
1410c19800e8SDoug Rabson     CK_RV ret;
1411c19800e8SDoug Rabson     int i;
1412c19800e8SDoug Rabson 
1413c19800e8SDoug Rabson     *o = NULL;
1414c19800e8SDoug Rabson     if ((ret = object_handle_to_object(hKey, o)) != CKR_OK)
1415c19800e8SDoug Rabson 	return ret;
1416c19800e8SDoug Rabson 
1417c19800e8SDoug Rabson     ret = attributes_match(*o, attr_match, attr_match_len);
1418c19800e8SDoug Rabson     if (!ret) {
1419c19800e8SDoug Rabson 	application_error("called commonInit on key that doesn't "
1420c19800e8SDoug Rabson 			  "support required attr");
1421c19800e8SDoug Rabson 	return CKR_ARGUMENTS_BAD;
1422c19800e8SDoug Rabson     }
1423c19800e8SDoug Rabson 
1424c19800e8SDoug Rabson     for (i = 0; i < mechs_len; i++)
1425c19800e8SDoug Rabson 	if (mechs[i] == pMechanism->mechanism)
1426c19800e8SDoug Rabson 	    break;
1427c19800e8SDoug Rabson     if (i == mechs_len) {
1428c19800e8SDoug Rabson 	application_error("called mech (%08lx) not supported\n",
1429c19800e8SDoug Rabson 			  pMechanism->mechanism);
1430c19800e8SDoug Rabson 	return CKR_ARGUMENTS_BAD;
1431c19800e8SDoug Rabson     }
1432c19800e8SDoug Rabson     return CKR_OK;
1433c19800e8SDoug Rabson }
1434c19800e8SDoug Rabson 
1435c19800e8SDoug Rabson 
1436c19800e8SDoug Rabson static CK_RV
dup_mechanism(CK_MECHANISM_PTR * dp,const CK_MECHANISM_PTR pMechanism)1437ae771770SStanislav Sedov dup_mechanism(CK_MECHANISM_PTR *dp, const CK_MECHANISM_PTR pMechanism)
1438c19800e8SDoug Rabson {
1439c19800e8SDoug Rabson     CK_MECHANISM_PTR p;
1440c19800e8SDoug Rabson 
1441c19800e8SDoug Rabson     p = malloc(sizeof(*p));
1442c19800e8SDoug Rabson     if (p == NULL)
1443c19800e8SDoug Rabson 	return CKR_DEVICE_MEMORY;
1444c19800e8SDoug Rabson 
1445ae771770SStanislav Sedov     if (*dp)
1446ae771770SStanislav Sedov 	free(*dp);
1447ae771770SStanislav Sedov     *dp = p;
1448c19800e8SDoug Rabson     memcpy(p, pMechanism, sizeof(*p));
1449c19800e8SDoug Rabson 
1450c19800e8SDoug Rabson     return CKR_OK;
1451c19800e8SDoug Rabson }
1452c19800e8SDoug Rabson 
1453c19800e8SDoug Rabson CK_RV
C_DigestInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism)1454c19800e8SDoug Rabson C_DigestInit(CK_SESSION_HANDLE hSession,
1455c19800e8SDoug Rabson 	     CK_MECHANISM_PTR pMechanism)
1456c19800e8SDoug Rabson {
1457c19800e8SDoug Rabson     st_logf("DigestInit\n");
1458c19800e8SDoug Rabson     INIT_CONTEXT();
1459c19800e8SDoug Rabson     VERIFY_SESSION_HANDLE(hSession, NULL);
1460c19800e8SDoug Rabson     return CKR_FUNCTION_NOT_SUPPORTED;
1461c19800e8SDoug Rabson }
1462c19800e8SDoug Rabson 
1463c19800e8SDoug Rabson CK_RV
C_SignInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)1464c19800e8SDoug Rabson C_SignInit(CK_SESSION_HANDLE hSession,
1465c19800e8SDoug Rabson 	   CK_MECHANISM_PTR pMechanism,
1466c19800e8SDoug Rabson 	   CK_OBJECT_HANDLE hKey)
1467c19800e8SDoug Rabson {
1468c19800e8SDoug Rabson     struct session_state *state;
1469c19800e8SDoug Rabson     CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS };
1470c19800e8SDoug Rabson     CK_BBOOL bool_true = CK_TRUE;
1471c19800e8SDoug Rabson     CK_ATTRIBUTE attr[] = {
1472c19800e8SDoug Rabson 	{ CKA_SIGN, &bool_true, sizeof(bool_true) }
1473c19800e8SDoug Rabson     };
1474c19800e8SDoug Rabson     struct st_object *o;
1475c19800e8SDoug Rabson     CK_RV ret;
1476c19800e8SDoug Rabson 
1477c19800e8SDoug Rabson     INIT_CONTEXT();
1478c19800e8SDoug Rabson     st_logf("SignInit\n");
1479c19800e8SDoug Rabson     VERIFY_SESSION_HANDLE(hSession, &state);
1480c19800e8SDoug Rabson 
1481c19800e8SDoug Rabson     ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
1482c19800e8SDoug Rabson 		     mechs, sizeof(mechs)/sizeof(mechs[0]),
1483c19800e8SDoug Rabson 		     pMechanism, hKey, &o);
1484c19800e8SDoug Rabson     if (ret)
1485c19800e8SDoug Rabson 	return ret;
1486c19800e8SDoug Rabson 
1487c19800e8SDoug Rabson     ret = dup_mechanism(&state->sign_mechanism, pMechanism);
1488c19800e8SDoug Rabson     if (ret == CKR_OK)
1489c19800e8SDoug Rabson 	state->sign_object = OBJECT_ID(o);
1490c19800e8SDoug Rabson 
1491c19800e8SDoug Rabson     return CKR_OK;
1492c19800e8SDoug Rabson }
1493c19800e8SDoug Rabson 
1494c19800e8SDoug Rabson CK_RV
C_Sign(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)1495c19800e8SDoug Rabson C_Sign(CK_SESSION_HANDLE hSession,
1496c19800e8SDoug Rabson        CK_BYTE_PTR pData,
1497c19800e8SDoug Rabson        CK_ULONG ulDataLen,
1498c19800e8SDoug Rabson        CK_BYTE_PTR pSignature,
1499c19800e8SDoug Rabson        CK_ULONG_PTR pulSignatureLen)
1500c19800e8SDoug Rabson {
1501c19800e8SDoug Rabson     struct session_state *state;
1502c19800e8SDoug Rabson     struct st_object *o;
1503c19800e8SDoug Rabson     CK_RV ret;
1504ae771770SStanislav Sedov     int hret;
1505c19800e8SDoug Rabson     const AlgorithmIdentifier *alg;
1506c19800e8SDoug Rabson     heim_octet_string sig, data;
1507c19800e8SDoug Rabson 
1508c19800e8SDoug Rabson     INIT_CONTEXT();
1509c19800e8SDoug Rabson     st_logf("Sign\n");
1510c19800e8SDoug Rabson     VERIFY_SESSION_HANDLE(hSession, &state);
1511c19800e8SDoug Rabson 
1512c19800e8SDoug Rabson     sig.data = NULL;
1513c19800e8SDoug Rabson     sig.length = 0;
1514c19800e8SDoug Rabson 
1515c19800e8SDoug Rabson     if (state->sign_object == -1)
1516c19800e8SDoug Rabson 	return CKR_ARGUMENTS_BAD;
1517c19800e8SDoug Rabson 
1518c19800e8SDoug Rabson     if (pulSignatureLen == NULL) {
1519c19800e8SDoug Rabson 	st_logf("signature len NULL\n");
1520c19800e8SDoug Rabson 	ret = CKR_ARGUMENTS_BAD;
1521c19800e8SDoug Rabson 	goto out;
1522c19800e8SDoug Rabson     }
1523c19800e8SDoug Rabson 
1524c19800e8SDoug Rabson     if (pData == NULL_PTR) {
1525c19800e8SDoug Rabson 	st_logf("data NULL\n");
1526c19800e8SDoug Rabson 	ret = CKR_ARGUMENTS_BAD;
1527c19800e8SDoug Rabson 	goto out;
1528c19800e8SDoug Rabson     }
1529c19800e8SDoug Rabson 
1530c19800e8SDoug Rabson     o = soft_token.object.objs[state->sign_object];
1531c19800e8SDoug Rabson 
1532c19800e8SDoug Rabson     if (hx509_cert_have_private_key(o->cert) == 0) {
1533c19800e8SDoug Rabson 	st_logf("private key NULL\n");
1534c19800e8SDoug Rabson 	return CKR_ARGUMENTS_BAD;
1535c19800e8SDoug Rabson     }
1536c19800e8SDoug Rabson 
1537c19800e8SDoug Rabson     switch(state->sign_mechanism->mechanism) {
1538c19800e8SDoug Rabson     case CKM_RSA_PKCS:
1539c19800e8SDoug Rabson 	alg = hx509_signature_rsa_pkcs1_x509();
1540c19800e8SDoug Rabson 	break;
1541c19800e8SDoug Rabson     default:
1542c19800e8SDoug Rabson 	ret = CKR_FUNCTION_NOT_SUPPORTED;
1543c19800e8SDoug Rabson 	goto out;
1544c19800e8SDoug Rabson     }
1545c19800e8SDoug Rabson 
1546c19800e8SDoug Rabson     data.data = pData;
1547c19800e8SDoug Rabson     data.length = ulDataLen;
1548c19800e8SDoug Rabson 
1549c19800e8SDoug Rabson     hret = _hx509_create_signature(context,
1550c19800e8SDoug Rabson 				   _hx509_cert_private_key(o->cert),
1551c19800e8SDoug Rabson 				   alg,
1552c19800e8SDoug Rabson 				   &data,
1553c19800e8SDoug Rabson 				   NULL,
1554c19800e8SDoug Rabson 				   &sig);
1555c19800e8SDoug Rabson     if (hret) {
1556c19800e8SDoug Rabson 	ret = CKR_DEVICE_ERROR;
1557c19800e8SDoug Rabson 	goto out;
1558c19800e8SDoug Rabson     }
1559c19800e8SDoug Rabson     *pulSignatureLen = sig.length;
1560c19800e8SDoug Rabson 
1561c19800e8SDoug Rabson     if (pSignature != NULL_PTR)
1562c19800e8SDoug Rabson 	memcpy(pSignature, sig.data, sig.length);
1563c19800e8SDoug Rabson 
1564c19800e8SDoug Rabson     ret = CKR_OK;
1565c19800e8SDoug Rabson  out:
1566c19800e8SDoug Rabson     if (sig.data) {
1567c19800e8SDoug Rabson 	memset(sig.data, 0, sig.length);
1568c19800e8SDoug Rabson 	der_free_octet_string(&sig);
1569c19800e8SDoug Rabson     }
1570c19800e8SDoug Rabson     return ret;
1571c19800e8SDoug Rabson }
1572c19800e8SDoug Rabson 
1573c19800e8SDoug Rabson CK_RV
C_SignUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)1574c19800e8SDoug Rabson C_SignUpdate(CK_SESSION_HANDLE hSession,
1575c19800e8SDoug Rabson 	     CK_BYTE_PTR pPart,
1576c19800e8SDoug Rabson 	     CK_ULONG ulPartLen)
1577c19800e8SDoug Rabson {
1578c19800e8SDoug Rabson     INIT_CONTEXT();
1579c19800e8SDoug Rabson     st_logf("SignUpdate\n");
1580c19800e8SDoug Rabson     VERIFY_SESSION_HANDLE(hSession, NULL);
1581c19800e8SDoug Rabson     return CKR_FUNCTION_NOT_SUPPORTED;
1582c19800e8SDoug Rabson }
1583c19800e8SDoug Rabson 
1584c19800e8SDoug Rabson 
1585c19800e8SDoug Rabson CK_RV
C_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)1586c19800e8SDoug Rabson C_SignFinal(CK_SESSION_HANDLE hSession,
1587c19800e8SDoug Rabson 	    CK_BYTE_PTR pSignature,
1588c19800e8SDoug Rabson 	    CK_ULONG_PTR pulSignatureLen)
1589c19800e8SDoug Rabson {
1590c19800e8SDoug Rabson     INIT_CONTEXT();
1591c19800e8SDoug Rabson     st_logf("SignUpdate\n");
1592c19800e8SDoug Rabson     VERIFY_SESSION_HANDLE(hSession, NULL);
1593c19800e8SDoug Rabson     return CKR_FUNCTION_NOT_SUPPORTED;
1594c19800e8SDoug Rabson }
1595c19800e8SDoug Rabson 
1596c19800e8SDoug Rabson CK_RV
C_VerifyInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)1597c19800e8SDoug Rabson C_VerifyInit(CK_SESSION_HANDLE hSession,
1598c19800e8SDoug Rabson 	     CK_MECHANISM_PTR pMechanism,
1599c19800e8SDoug Rabson 	     CK_OBJECT_HANDLE hKey)
1600c19800e8SDoug Rabson {
1601c19800e8SDoug Rabson     struct session_state *state;
1602c19800e8SDoug Rabson     CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS };
1603c19800e8SDoug Rabson     CK_BBOOL bool_true = CK_TRUE;
1604c19800e8SDoug Rabson     CK_ATTRIBUTE attr[] = {
1605c19800e8SDoug Rabson 	{ CKA_VERIFY, &bool_true, sizeof(bool_true) }
1606c19800e8SDoug Rabson     };
1607c19800e8SDoug Rabson     struct st_object *o;
1608c19800e8SDoug Rabson     CK_RV ret;
1609c19800e8SDoug Rabson 
1610c19800e8SDoug Rabson     INIT_CONTEXT();
1611c19800e8SDoug Rabson     st_logf("VerifyInit\n");
1612c19800e8SDoug Rabson     VERIFY_SESSION_HANDLE(hSession, &state);
1613c19800e8SDoug Rabson 
1614c19800e8SDoug Rabson     ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
1615c19800e8SDoug Rabson 		     mechs, sizeof(mechs)/sizeof(mechs[0]),
1616c19800e8SDoug Rabson 		     pMechanism, hKey, &o);
1617c19800e8SDoug Rabson     if (ret)
1618c19800e8SDoug Rabson 	return ret;
1619c19800e8SDoug Rabson 
1620c19800e8SDoug Rabson     ret = dup_mechanism(&state->verify_mechanism, pMechanism);
1621c19800e8SDoug Rabson     if (ret == CKR_OK)
1622c19800e8SDoug Rabson 	state->verify_object = OBJECT_ID(o);
1623c19800e8SDoug Rabson 
1624c19800e8SDoug Rabson     return ret;
1625c19800e8SDoug Rabson }
1626c19800e8SDoug Rabson 
1627c19800e8SDoug Rabson CK_RV
C_Verify(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)1628c19800e8SDoug Rabson C_Verify(CK_SESSION_HANDLE hSession,
1629c19800e8SDoug Rabson 	 CK_BYTE_PTR pData,
1630c19800e8SDoug Rabson 	 CK_ULONG ulDataLen,
1631c19800e8SDoug Rabson 	 CK_BYTE_PTR pSignature,
1632c19800e8SDoug Rabson 	 CK_ULONG ulSignatureLen)
1633c19800e8SDoug Rabson {
1634c19800e8SDoug Rabson     struct session_state *state;
1635c19800e8SDoug Rabson     struct st_object *o;
1636c19800e8SDoug Rabson     const AlgorithmIdentifier *alg;
1637c19800e8SDoug Rabson     CK_RV ret;
1638c19800e8SDoug Rabson     int hret;
1639c19800e8SDoug Rabson     heim_octet_string data, sig;
1640c19800e8SDoug Rabson 
1641c19800e8SDoug Rabson     INIT_CONTEXT();
1642c19800e8SDoug Rabson     st_logf("Verify\n");
1643c19800e8SDoug Rabson     VERIFY_SESSION_HANDLE(hSession, &state);
1644c19800e8SDoug Rabson 
1645c19800e8SDoug Rabson     if (state->verify_object == -1)
1646c19800e8SDoug Rabson 	return CKR_ARGUMENTS_BAD;
1647c19800e8SDoug Rabson 
1648c19800e8SDoug Rabson     o = soft_token.object.objs[state->verify_object];
1649c19800e8SDoug Rabson 
1650c19800e8SDoug Rabson     switch(state->verify_mechanism->mechanism) {
1651c19800e8SDoug Rabson     case CKM_RSA_PKCS:
1652c19800e8SDoug Rabson 	alg = hx509_signature_rsa_pkcs1_x509();
1653c19800e8SDoug Rabson 	break;
1654c19800e8SDoug Rabson     default:
1655c19800e8SDoug Rabson 	ret = CKR_FUNCTION_NOT_SUPPORTED;
1656c19800e8SDoug Rabson 	goto out;
1657c19800e8SDoug Rabson     }
1658c19800e8SDoug Rabson 
1659c19800e8SDoug Rabson     sig.data = pData;
1660c19800e8SDoug Rabson     sig.length = ulDataLen;
1661c19800e8SDoug Rabson     data.data = pSignature;
1662c19800e8SDoug Rabson     data.length = ulSignatureLen;
1663c19800e8SDoug Rabson 
1664c19800e8SDoug Rabson     hret = _hx509_verify_signature(context,
1665ae771770SStanislav Sedov 				   o->cert,
1666c19800e8SDoug Rabson 				   alg,
1667c19800e8SDoug Rabson 				   &data,
1668c19800e8SDoug Rabson 				   &sig);
1669c19800e8SDoug Rabson     if (hret) {
1670c19800e8SDoug Rabson 	ret = CKR_GENERAL_ERROR;
1671c19800e8SDoug Rabson 	goto out;
1672c19800e8SDoug Rabson     }
1673c19800e8SDoug Rabson     ret = CKR_OK;
1674c19800e8SDoug Rabson 
1675c19800e8SDoug Rabson  out:
1676c19800e8SDoug Rabson     return ret;
1677c19800e8SDoug Rabson }
1678c19800e8SDoug Rabson 
1679c19800e8SDoug Rabson 
1680c19800e8SDoug Rabson CK_RV
C_VerifyUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)1681c19800e8SDoug Rabson C_VerifyUpdate(CK_SESSION_HANDLE hSession,
1682c19800e8SDoug Rabson 	       CK_BYTE_PTR pPart,
1683c19800e8SDoug Rabson 	       CK_ULONG ulPartLen)
1684c19800e8SDoug Rabson {
1685c19800e8SDoug Rabson     INIT_CONTEXT();
1686c19800e8SDoug Rabson     st_logf("VerifyUpdate\n");
1687c19800e8SDoug Rabson     VERIFY_SESSION_HANDLE(hSession, NULL);
1688c19800e8SDoug Rabson     return CKR_FUNCTION_NOT_SUPPORTED;
1689c19800e8SDoug Rabson }
1690c19800e8SDoug Rabson 
1691c19800e8SDoug Rabson CK_RV
C_VerifyFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)1692c19800e8SDoug Rabson C_VerifyFinal(CK_SESSION_HANDLE hSession,
1693c19800e8SDoug Rabson 	      CK_BYTE_PTR pSignature,
1694c19800e8SDoug Rabson 	      CK_ULONG ulSignatureLen)
1695c19800e8SDoug Rabson {
1696c19800e8SDoug Rabson     INIT_CONTEXT();
1697c19800e8SDoug Rabson     st_logf("VerifyFinal\n");
1698c19800e8SDoug Rabson     VERIFY_SESSION_HANDLE(hSession, NULL);
1699c19800e8SDoug Rabson     return CKR_FUNCTION_NOT_SUPPORTED;
1700c19800e8SDoug Rabson }
1701c19800e8SDoug Rabson 
1702c19800e8SDoug Rabson CK_RV
C_GenerateRandom(CK_SESSION_HANDLE hSession,CK_BYTE_PTR RandomData,CK_ULONG ulRandomLen)1703c19800e8SDoug Rabson C_GenerateRandom(CK_SESSION_HANDLE hSession,
1704c19800e8SDoug Rabson 		 CK_BYTE_PTR RandomData,
1705c19800e8SDoug Rabson 		 CK_ULONG ulRandomLen)
1706c19800e8SDoug Rabson {
1707c19800e8SDoug Rabson     INIT_CONTEXT();
1708c19800e8SDoug Rabson     st_logf("GenerateRandom\n");
1709c19800e8SDoug Rabson     VERIFY_SESSION_HANDLE(hSession, NULL);
1710c19800e8SDoug Rabson     return CKR_FUNCTION_NOT_SUPPORTED;
1711c19800e8SDoug Rabson }
1712c19800e8SDoug Rabson 
1713c19800e8SDoug Rabson 
1714c19800e8SDoug Rabson CK_FUNCTION_LIST funcs = {
1715c19800e8SDoug Rabson     { 2, 11 },
1716c19800e8SDoug Rabson     C_Initialize,
1717c19800e8SDoug Rabson     C_Finalize,
1718c19800e8SDoug Rabson     C_GetInfo,
1719c19800e8SDoug Rabson     C_GetFunctionList,
1720c19800e8SDoug Rabson     C_GetSlotList,
1721c19800e8SDoug Rabson     C_GetSlotInfo,
1722c19800e8SDoug Rabson     C_GetTokenInfo,
1723c19800e8SDoug Rabson     C_GetMechanismList,
1724c19800e8SDoug Rabson     C_GetMechanismInfo,
1725c19800e8SDoug Rabson     C_InitToken,
1726c19800e8SDoug Rabson     (void *)func_not_supported, /* C_InitPIN */
1727c19800e8SDoug Rabson     (void *)func_not_supported, /* C_SetPIN */
1728c19800e8SDoug Rabson     C_OpenSession,
1729c19800e8SDoug Rabson     C_CloseSession,
1730c19800e8SDoug Rabson     C_CloseAllSessions,
1731c19800e8SDoug Rabson     C_GetSessionInfo,
1732c19800e8SDoug Rabson     (void *)func_not_supported, /* C_GetOperationState */
1733c19800e8SDoug Rabson     (void *)func_not_supported, /* C_SetOperationState */
1734c19800e8SDoug Rabson     C_Login,
1735c19800e8SDoug Rabson     C_Logout,
1736c19800e8SDoug Rabson     (void *)func_not_supported, /* C_CreateObject */
1737c19800e8SDoug Rabson     (void *)func_not_supported, /* C_CopyObject */
1738c19800e8SDoug Rabson     (void *)func_not_supported, /* C_DestroyObject */
1739c19800e8SDoug Rabson     (void *)func_not_supported, /* C_GetObjectSize */
1740c19800e8SDoug Rabson     C_GetAttributeValue,
1741c19800e8SDoug Rabson     (void *)func_not_supported, /* C_SetAttributeValue */
1742c19800e8SDoug Rabson     C_FindObjectsInit,
1743c19800e8SDoug Rabson     C_FindObjects,
1744c19800e8SDoug Rabson     C_FindObjectsFinal,
1745c19800e8SDoug Rabson     (void *)func_not_supported, /* C_EncryptInit, */
1746c19800e8SDoug Rabson     (void *)func_not_supported, /* C_Encrypt, */
1747c19800e8SDoug Rabson     (void *)func_not_supported, /* C_EncryptUpdate, */
1748c19800e8SDoug Rabson     (void *)func_not_supported, /* C_EncryptFinal, */
1749c19800e8SDoug Rabson     (void *)func_not_supported, /* C_DecryptInit, */
1750c19800e8SDoug Rabson     (void *)func_not_supported, /* C_Decrypt, */
1751c19800e8SDoug Rabson     (void *)func_not_supported, /* C_DecryptUpdate, */
1752c19800e8SDoug Rabson     (void *)func_not_supported, /* C_DecryptFinal, */
1753c19800e8SDoug Rabson     C_DigestInit,
1754c19800e8SDoug Rabson     (void *)func_not_supported, /* C_Digest */
1755c19800e8SDoug Rabson     (void *)func_not_supported, /* C_DigestUpdate */
1756c19800e8SDoug Rabson     (void *)func_not_supported, /* C_DigestKey */
1757c19800e8SDoug Rabson     (void *)func_not_supported, /* C_DigestFinal */
1758c19800e8SDoug Rabson     C_SignInit,
1759c19800e8SDoug Rabson     C_Sign,
1760c19800e8SDoug Rabson     C_SignUpdate,
1761c19800e8SDoug Rabson     C_SignFinal,
1762c19800e8SDoug Rabson     (void *)func_not_supported, /* C_SignRecoverInit */
1763c19800e8SDoug Rabson     (void *)func_not_supported, /* C_SignRecover */
1764c19800e8SDoug Rabson     C_VerifyInit,
1765c19800e8SDoug Rabson     C_Verify,
1766c19800e8SDoug Rabson     C_VerifyUpdate,
1767c19800e8SDoug Rabson     C_VerifyFinal,
1768c19800e8SDoug Rabson     (void *)func_not_supported, /* C_VerifyRecoverInit */
1769c19800e8SDoug Rabson     (void *)func_not_supported, /* C_VerifyRecover */
1770c19800e8SDoug Rabson     (void *)func_not_supported, /* C_DigestEncryptUpdate */
1771c19800e8SDoug Rabson     (void *)func_not_supported, /* C_DecryptDigestUpdate */
1772c19800e8SDoug Rabson     (void *)func_not_supported, /* C_SignEncryptUpdate */
1773c19800e8SDoug Rabson     (void *)func_not_supported, /* C_DecryptVerifyUpdate */
1774c19800e8SDoug Rabson     (void *)func_not_supported, /* C_GenerateKey */
1775c19800e8SDoug Rabson     (void *)func_not_supported, /* C_GenerateKeyPair */
1776c19800e8SDoug Rabson     (void *)func_not_supported, /* C_WrapKey */
1777c19800e8SDoug Rabson     (void *)func_not_supported, /* C_UnwrapKey */
1778c19800e8SDoug Rabson     (void *)func_not_supported, /* C_DeriveKey */
1779c19800e8SDoug Rabson     (void *)func_not_supported, /* C_SeedRandom */
1780c19800e8SDoug Rabson     C_GenerateRandom,
1781c19800e8SDoug Rabson     (void *)func_not_supported, /* C_GetFunctionStatus */
1782c19800e8SDoug Rabson     (void *)func_not_supported, /* C_CancelFunction */
1783c19800e8SDoug Rabson     (void *)func_not_supported  /* C_WaitForSlotEvent */
1784c19800e8SDoug Rabson };
1785