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