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