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