test debug
[heimdal.git] / lib / hx509 / softp11.c
blobca94fda427266f39012f88bbaf61976b6b6b1ade
1 /*
2 * Copyright (c) 2004 - 2008 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
34 #include "hx_locl.h"
35 #include "pkcs11.h"
37 #define OBJECT_ID_MASK 0xfff
38 #define HANDLE_OBJECT_ID(h) ((h) & OBJECT_ID_MASK)
39 #define OBJECT_ID(obj) HANDLE_OBJECT_ID((obj)->object_handle)
42 struct st_attr {
43 CK_ATTRIBUTE attribute;
44 int secret;
47 struct st_object {
48 CK_OBJECT_HANDLE object_handle;
49 struct st_attr *attrs;
50 int num_attributes;
51 enum {
52 STO_T_CERTIFICATE,
53 STO_T_PRIVATE_KEY,
54 STO_T_PUBLIC_KEY
55 } type;
56 hx509_cert cert;
59 static struct soft_token {
60 CK_VOID_PTR application;
61 CK_NOTIFY notify;
62 char *config_file;
63 hx509_certs certs;
64 struct {
65 struct st_object **objs;
66 int num_objs;
67 } object;
68 struct {
69 int hardware_slot;
70 int app_error_fatal;
71 int login_done;
72 } flags;
73 int open_sessions;
74 struct session_state {
75 CK_SESSION_HANDLE session_handle;
77 struct {
78 CK_ATTRIBUTE *attributes;
79 CK_ULONG num_attributes;
80 int next_object;
81 } find;
83 int encrypt_object;
84 CK_MECHANISM_PTR encrypt_mechanism;
85 int decrypt_object;
86 CK_MECHANISM_PTR decrypt_mechanism;
87 int sign_object;
88 CK_MECHANISM_PTR sign_mechanism;
89 int verify_object;
90 CK_MECHANISM_PTR verify_mechanism;
91 int digest_object;
92 } state[10];
93 #define MAX_NUM_SESSION (sizeof(soft_token.state)/sizeof(soft_token.state[0]))
94 FILE *logfile;
95 } soft_token;
97 static hx509_context context;
99 static void
100 application_error(const char *fmt, ...)
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();
110 static void
111 st_logf(const char *fmt, ...)
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);
122 static CK_RV
123 init_context(void)
125 if (context == NULL) {
126 int ret = hx509_context_init(&context);
127 if (ret)
128 return CKR_GENERAL_ERROR;
130 return CKR_OK;
133 #define INIT_CONTEXT() { CK_RV icret = init_context(); if (icret) return icret; }
135 static void
136 snprintf_fill(char *str, size_t size, char fillchar, const char *fmt, ...)
138 int len;
139 va_list ap;
140 len = vsnprintf(str, size, fmt, ap);
141 va_end(ap);
142 if (len < 0 || len > size)
143 return;
144 while(len < size)
145 str[len++] = fillchar;
148 #ifndef TEST_APP
149 #define printf error_use_st_logf
150 #endif
152 #define VERIFY_SESSION_HANDLE(s, state) \
154 CK_RV ret; \
155 ret = verify_session_handle(s, state); \
156 if (ret != CKR_OK) { \
157 /* return CKR_OK */; \
161 static CK_RV
162 verify_session_handle(CK_SESSION_HANDLE hSession,
163 struct session_state **state)
165 int i;
167 for (i = 0; i < MAX_NUM_SESSION; i++){
168 if (soft_token.state[i].session_handle == hSession)
169 break;
171 if (i == MAX_NUM_SESSION) {
172 application_error("use of invalid handle: 0x%08lx\n",
173 (unsigned long)hSession);
174 return CKR_SESSION_HANDLE_INVALID;
176 if (state)
177 *state = &soft_token.state[i];
178 return CKR_OK;
181 static CK_RV
182 object_handle_to_object(CK_OBJECT_HANDLE handle,
183 struct st_object **object)
185 int i = HANDLE_OBJECT_ID(handle);
187 *object = NULL;
188 if (i >= soft_token.object.num_objs)
189 return CKR_ARGUMENTS_BAD;
190 if (soft_token.object.objs[i] == NULL)
191 return CKR_ARGUMENTS_BAD;
192 if (soft_token.object.objs[i]->object_handle != handle)
193 return CKR_ARGUMENTS_BAD;
194 *object = soft_token.object.objs[i];
195 return CKR_OK;
198 static int
199 attributes_match(const struct st_object *obj,
200 const CK_ATTRIBUTE *attributes,
201 CK_ULONG num_attributes)
203 CK_ULONG i;
204 int j;
205 st_logf("attributes_match: %ld\n", (unsigned long)OBJECT_ID(obj));
207 for (i = 0; i < num_attributes; i++) {
208 int match = 0;
209 for (j = 0; j < obj->num_attributes; j++) {
210 if (attributes[i].type == obj->attrs[j].attribute.type &&
211 attributes[i].ulValueLen == obj->attrs[j].attribute.ulValueLen &&
212 memcmp(attributes[i].pValue, obj->attrs[j].attribute.pValue,
213 attributes[i].ulValueLen) == 0) {
214 match = 1;
215 break;
218 if (match == 0) {
219 st_logf("type %d attribute have no match\n", attributes[i].type);
220 return 0;
223 st_logf("attribute matches\n");
224 return 1;
227 static void
228 print_attributes(const CK_ATTRIBUTE *attributes,
229 CK_ULONG num_attributes)
231 CK_ULONG i;
233 st_logf("find objects: attrs: %lu\n", (unsigned long)num_attributes);
235 for (i = 0; i < num_attributes; i++) {
236 st_logf(" type: ");
237 switch (attributes[i].type) {
238 case CKA_TOKEN: {
239 CK_BBOOL *ck_true;
240 if (attributes[i].ulValueLen != sizeof(CK_BBOOL)) {
241 application_error("token attribute wrong length\n");
242 break;
244 ck_true = attributes[i].pValue;
245 st_logf("token: %s", *ck_true ? "TRUE" : "FALSE");
246 break;
248 case CKA_CLASS: {
249 CK_OBJECT_CLASS *class;
250 if (attributes[i].ulValueLen != sizeof(CK_ULONG)) {
251 application_error("class attribute wrong length\n");
252 break;
254 class = attributes[i].pValue;
255 st_logf("class ");
256 switch (*class) {
257 case CKO_CERTIFICATE:
258 st_logf("certificate");
259 break;
260 case CKO_PUBLIC_KEY:
261 st_logf("public key");
262 break;
263 case CKO_PRIVATE_KEY:
264 st_logf("private key");
265 break;
266 case CKO_SECRET_KEY:
267 st_logf("secret key");
268 break;
269 case CKO_DOMAIN_PARAMETERS:
270 st_logf("domain parameters");
271 break;
272 default:
273 st_logf("[class %lx]", (long unsigned)*class);
274 break;
276 break;
278 case CKA_PRIVATE:
279 st_logf("private");
280 break;
281 case CKA_LABEL:
282 st_logf("label");
283 break;
284 case CKA_APPLICATION:
285 st_logf("application");
286 break;
287 case CKA_VALUE:
288 st_logf("value");
289 break;
290 case CKA_ID:
291 st_logf("id");
292 break;
293 default:
294 st_logf("[unknown 0x%08lx]", (unsigned long)attributes[i].type);
295 break;
297 st_logf("\n");
301 static struct st_object *
302 add_st_object(void)
304 struct st_object *o, **objs;
305 int i;
307 o = malloc(sizeof(*o));
308 if (o == NULL)
309 return NULL;
310 memset(o, 0, sizeof(*o));
311 o->attrs = NULL;
312 o->num_attributes = 0;
314 for (i = 0; i < soft_token.object.num_objs; i++) {
315 if (soft_token.object.objs == NULL) {
316 soft_token.object.objs[i] = o;
317 break;
320 if (i == soft_token.object.num_objs) {
321 objs = realloc(soft_token.object.objs,
322 (soft_token.object.num_objs + 1) * sizeof(soft_token.object.objs[0]));
323 if (objs == NULL) {
324 free(o);
325 return NULL;
327 soft_token.object.objs = objs;
328 soft_token.object.objs[soft_token.object.num_objs++] = o;
330 soft_token.object.objs[i]->object_handle =
331 (random() & (~OBJECT_ID_MASK)) | i;
333 return o;
336 static CK_RV
337 add_object_attribute(struct st_object *o,
338 int secret,
339 CK_ATTRIBUTE_TYPE type,
340 CK_VOID_PTR pValue,
341 CK_ULONG ulValueLen)
343 struct st_attr *a;
344 int i;
346 i = o->num_attributes;
347 a = realloc(o->attrs, (i + 1) * sizeof(o->attrs[0]));
348 if (a == NULL)
349 return CKR_DEVICE_MEMORY;
350 o->attrs = a;
351 o->attrs[i].secret = secret;
352 o->attrs[i].attribute.type = type;
353 o->attrs[i].attribute.pValue = malloc(ulValueLen);
354 if (o->attrs[i].attribute.pValue == NULL && ulValueLen != 0)
355 return CKR_DEVICE_MEMORY;
356 memcpy(o->attrs[i].attribute.pValue, pValue, ulValueLen);
357 o->attrs[i].attribute.ulValueLen = ulValueLen;
358 o->num_attributes++;
360 return CKR_OK;
363 static CK_RV
364 add_pubkey_info(hx509_context hxctx, struct st_object *o,
365 CK_KEY_TYPE key_type, hx509_cert cert)
367 BIGNUM *num;
368 CK_BYTE *modulus = NULL;
369 size_t modulus_len = 0;
370 CK_ULONG modulus_bits = 0;
371 CK_BYTE *exponent = NULL;
372 size_t exponent_len = 0;
374 if (key_type != CKK_RSA)
375 return CKR_OK;
377 num = _hx509_private_key_get_internal(context,
378 _hx509_cert_private_key(cert),
379 "rsa-modulus");
380 if (num == NULL)
381 return CKR_GENERAL_ERROR;
382 modulus_bits = BN_num_bits(num);
384 modulus_len = BN_num_bytes(num);
385 modulus = malloc(modulus_len);
386 BN_bn2bin(num, modulus);
387 BN_free(num);
389 add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len);
390 add_object_attribute(o, 0, CKA_MODULUS_BITS,
391 &modulus_bits, sizeof(modulus_bits));
393 free(modulus);
395 num = _hx509_private_key_get_internal(context,
396 _hx509_cert_private_key(cert),
397 "rsa-exponent");
398 if (num == NULL)
399 return CKR_GENERAL_ERROR;
401 exponent_len = BN_num_bytes(num);
402 exponent = malloc(exponent_len);
403 BN_bn2bin(num, exponent);
404 BN_free(num);
406 add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT,
407 exponent, exponent_len);
409 free(exponent);
411 return CKR_OK;
415 struct foo {
416 char *label;
417 char *id;
420 static int
421 add_cert(hx509_context hxctx, void *ctx, hx509_cert cert)
423 struct foo *foo = (struct foo *)ctx;
424 struct st_object *o = NULL;
425 CK_BBOOL bool_true = CK_TRUE;
426 CK_BBOOL bool_false = CK_FALSE;
427 CK_OBJECT_CLASS c;
428 CK_CERTIFICATE_TYPE cert_type = CKC_X_509;
429 CK_KEY_TYPE key_type;
430 CK_MECHANISM_TYPE mech_type;
431 CK_RV ret = CKR_GENERAL_ERROR;
432 int hret;
433 heim_octet_string cert_data, subject_data, issuer_data, serial_data;
435 st_logf("adding certificate\n");
437 serial_data.data = NULL;
438 serial_data.length = 0;
439 cert_data = subject_data = issuer_data = serial_data;
441 hret = hx509_cert_binary(hxctx, cert, &cert_data);
442 if (hret)
443 goto out;
446 hx509_name name;
448 hret = hx509_cert_get_issuer(cert, &name);
449 if (hret)
450 goto out;
451 hret = hx509_name_binary(name, &issuer_data);
452 hx509_name_free(&name);
453 if (hret)
454 goto out;
456 hret = hx509_cert_get_subject(cert, &name);
457 if (hret)
458 goto out;
459 hret = hx509_name_binary(name, &subject_data);
460 hx509_name_free(&name);
461 if (hret)
462 goto out;
466 o = add_st_object();
467 if (o == NULL) {
468 ret = CKR_DEVICE_MEMORY;
469 goto out;
471 o->type = STO_T_CERTIFICATE;
472 o->cert = hx509_cert_ref(cert);
474 key_type = CKK_RSA; /* XXX */
476 #if 0
477 switch (EVP_PKEY_type(public_key->type)) {
478 case EVP_PKEY_RSA:
479 key_type = CKK_RSA;
480 break;
481 case EVP_PKEY_DSA:
482 key_type = CKK_DSA;
483 break;
484 default:
485 /* XXX */
486 break;
488 #endif
490 c = CKO_CERTIFICATE;
491 add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c));
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));
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));
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));
506 st_logf("add cert ok: %lx\n", (unsigned long)OBJECT_ID(o));
508 o = add_st_object();
509 if (o == NULL) {
510 ret = CKR_DEVICE_MEMORY;
511 goto out;
513 o->type = STO_T_PUBLIC_KEY;
514 o->cert = hx509_cert_ref(cert);
516 c = CKO_PUBLIC_KEY;
517 add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c));
518 add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true));
519 add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false));
520 add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false));
521 add_object_attribute(o, 0, CKA_LABEL, foo->label, strlen(foo->label));
523 add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type));
524 add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id));
525 add_object_attribute(o, 0, CKA_START_DATE, "", 1); /* XXX */
526 add_object_attribute(o, 0, CKA_END_DATE, "", 1); /* XXX */
527 add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false));
528 add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false));
529 mech_type = CKM_RSA_X_509;
530 add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type));
532 add_object_attribute(o, 0, CKA_SUBJECT, subject_data.data, subject_data.length);
533 add_object_attribute(o, 0, CKA_ENCRYPT, &bool_true, sizeof(bool_true));
534 add_object_attribute(o, 0, CKA_VERIFY, &bool_true, sizeof(bool_true));
535 add_object_attribute(o, 0, CKA_VERIFY_RECOVER, &bool_false, sizeof(bool_false));
536 add_object_attribute(o, 0, CKA_WRAP, &bool_true, sizeof(bool_true));
537 add_object_attribute(o, 0, CKA_TRUSTED, &bool_true, sizeof(bool_true));
539 add_pubkey_info(hxctx, o, key_type, cert);
541 st_logf("add key ok: %lx\n", (unsigned long)OBJECT_ID(o));
543 if (hx509_cert_have_private_key(cert)) {
544 CK_FLAGS flags;
546 o = add_st_object();
547 if (o == NULL) {
548 ret = CKR_DEVICE_MEMORY;
549 goto out;
551 o->type = STO_T_PRIVATE_KEY;
552 o->cert = hx509_cert_ref(cert);
554 c = CKO_PRIVATE_KEY;
555 add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c));
556 add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true));
557 add_object_attribute(o, 0, CKA_PRIVATE, &bool_true, sizeof(bool_false));
558 add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false));
559 add_object_attribute(o, 0, CKA_LABEL, foo->label, strlen(foo->label));
561 add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type));
562 add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id));
563 add_object_attribute(o, 0, CKA_START_DATE, "", 1); /* XXX */
564 add_object_attribute(o, 0, CKA_END_DATE, "", 1); /* XXX */
565 add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false));
566 add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false));
567 mech_type = CKM_RSA_X_509;
568 add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type));
570 add_object_attribute(o, 0, CKA_SUBJECT, subject_data.data, subject_data.length);
571 add_object_attribute(o, 0, CKA_SENSITIVE, &bool_true, sizeof(bool_true));
572 add_object_attribute(o, 0, CKA_SECONDARY_AUTH, &bool_false, sizeof(bool_true));
573 flags = 0;
574 add_object_attribute(o, 0, CKA_AUTH_PIN_FLAGS, &flags, sizeof(flags));
576 add_object_attribute(o, 0, CKA_DECRYPT, &bool_true, sizeof(bool_true));
577 add_object_attribute(o, 0, CKA_SIGN, &bool_true, sizeof(bool_true));
578 add_object_attribute(o, 0, CKA_SIGN_RECOVER, &bool_false, sizeof(bool_false));
579 add_object_attribute(o, 0, CKA_UNWRAP, &bool_true, sizeof(bool_true));
580 add_object_attribute(o, 0, CKA_EXTRACTABLE, &bool_true, sizeof(bool_true));
581 add_object_attribute(o, 0, CKA_NEVER_EXTRACTABLE, &bool_false, sizeof(bool_false));
583 add_pubkey_info(hxctx, o, key_type, cert);
586 ret = CKR_OK;
587 out:
588 if (ret != CKR_OK) {
589 st_logf("something went wrong when adding cert!\n");
591 /* XXX wack o */;
593 hx509_xfree(cert_data.data);
594 hx509_xfree(serial_data.data);
595 hx509_xfree(issuer_data.data);
596 hx509_xfree(subject_data.data);
598 return 0;
602 static CK_RV
603 add_certificate(const char *cert_file,
604 const char *pin,
605 char *id,
606 char *label)
608 int ret;
609 hx509_certs certs;
611 struct foo foo;
612 foo.id = id;
613 foo.label = label;
615 ret = hx509_certs_init(context, cert_file, 0, NULL, &certs);
616 if (ret) {
617 st_logf("failed to open file %s\n", cert_file);
618 return CKR_GENERAL_ERROR;
621 ret = hx509_certs_iter(context, certs, add_cert, &foo);
622 hx509_certs_free(&certs);
623 if (ret) {
624 st_logf("failed adding certs from file %s\n", cert_file);
625 return CKR_GENERAL_ERROR;
628 return CKR_OK;
631 static void
632 find_object_final(struct session_state *state)
634 if (state->find.attributes) {
635 CK_ULONG i;
637 for (i = 0; i < state->find.num_attributes; i++) {
638 if (state->find.attributes[i].pValue)
639 free(state->find.attributes[i].pValue);
641 free(state->find.attributes);
642 state->find.attributes = NULL;
643 state->find.num_attributes = 0;
644 state->find.next_object = -1;
648 static void
649 reset_crypto_state(struct session_state *state)
651 state->encrypt_object = -1;
652 if (state->encrypt_mechanism)
653 free(state->encrypt_mechanism);
654 state->encrypt_mechanism = NULL_PTR;
655 state->decrypt_object = -1;
656 if (state->decrypt_mechanism)
657 free(state->decrypt_mechanism);
658 state->decrypt_mechanism = NULL_PTR;
659 state->sign_object = -1;
660 if (state->sign_mechanism)
661 free(state->sign_mechanism);
662 state->sign_mechanism = NULL_PTR;
663 state->verify_object = -1;
664 if (state->verify_mechanism)
665 free(state->verify_mechanism);
666 state->verify_mechanism = NULL_PTR;
667 state->digest_object = -1;
670 static void
671 close_session(struct session_state *state)
673 if (state->find.attributes) {
674 application_error("application didn't do C_FindObjectsFinal\n");
675 find_object_final(state);
678 state->session_handle = CK_INVALID_HANDLE;
679 soft_token.application = NULL_PTR;
680 soft_token.notify = NULL_PTR;
681 reset_crypto_state(state);
684 static const char *
685 has_session(void)
687 return soft_token.open_sessions > 0 ? "yes" : "no";
690 static CK_RV
691 read_conf_file(const char *fn, CK_USER_TYPE userType, const char *pin)
693 char buf[1024], *type, *s, *p;
694 int anchor;
695 FILE *f;
696 CK_RV ret = CKR_OK;
698 f = fopen(fn, "r");
699 if (f == NULL) {
700 st_logf("can't open configuration file %s\n", fn);
701 return CKR_GENERAL_ERROR;
704 while(fgets(buf, sizeof(buf), f) != NULL) {
705 buf[strcspn(buf, "\n")] = '\0';
707 anchor = 0;
709 st_logf("line: %s\n", buf);
711 p = buf;
712 while (isspace(*p))
713 p++;
714 if (*p == '#')
715 continue;
716 while (isspace(*p))
717 p++;
719 s = NULL;
720 type = strtok_r(p, "\t", &s);
721 if (type == NULL)
722 continue;
724 if (strcasecmp("certificate", type) == 0) {
725 char *cert, *id, *label;
727 id = strtok_r(NULL, "\t", &s);
728 if (id == NULL) {
729 st_logf("no id\n");
730 continue;
732 st_logf("id: %s\n", id);
733 label = strtok_r(NULL, "\t", &s);
734 if (label == NULL) {
735 st_logf("no label\n");
736 continue;
738 cert = strtok_r(NULL, "\t", &s);
739 if (cert == NULL) {
740 st_logf("no certfiicate store\n");
741 continue;
744 st_logf("adding: %s: %s in file %s\n", id, label, cert);
746 ret = add_certificate(cert, pin, id, label);
747 if (ret)
748 goto out;
749 } else {
750 st_logf("unknown type: %s\n", type);
753 out:
754 fclose(f);
756 return ret;
759 static CK_RV
760 func_not_supported(void)
762 st_logf("function not supported\n");
763 return CKR_FUNCTION_NOT_SUPPORTED;
766 CK_RV
767 C_Initialize(CK_VOID_PTR a)
769 CK_C_INITIALIZE_ARGS_PTR args = a;
770 CK_RV ret;
771 int i;
773 st_logf("Initialize\n");
775 INIT_CONTEXT();
777 OpenSSL_add_all_algorithms();
779 srandom(getpid() ^ time(NULL));
781 for (i = 0; i < MAX_NUM_SESSION; i++) {
782 soft_token.state[i].session_handle = CK_INVALID_HANDLE;
783 soft_token.state[i].find.attributes = NULL;
784 soft_token.state[i].find.num_attributes = 0;
785 soft_token.state[i].find.next_object = -1;
786 reset_crypto_state(&soft_token.state[i]);
789 soft_token.flags.hardware_slot = 1;
790 soft_token.flags.app_error_fatal = 0;
791 soft_token.flags.login_done = 0;
793 soft_token.object.objs = NULL;
794 soft_token.object.num_objs = 0;
796 soft_token.logfile = NULL;
797 #if 0
798 soft_token.logfile = stdout;
799 #endif
800 #if 0
801 soft_token.logfile = fopen("/tmp/log-pkcs11.txt", "a");
802 #endif
804 if (a != NULL_PTR) {
805 st_logf("\tCreateMutex:\t%p\n", args->CreateMutex);
806 st_logf("\tDestroyMutext\t%p\n", args->DestroyMutex);
807 st_logf("\tLockMutext\t%p\n", args->LockMutex);
808 st_logf("\tUnlockMutext\t%p\n", args->UnlockMutex);
809 st_logf("\tFlags\t%04x\n", (unsigned int)args->flags);
813 char *fn = NULL, *home = NULL;
815 if (getuid() == geteuid()) {
816 fn = getenv("SOFTPKCS11RC");
817 if (fn)
818 fn = strdup(fn);
819 home = getenv("HOME");
821 if (fn == NULL && home == NULL) {
822 struct passwd *pw = getpwuid(getuid());
823 if(pw != NULL)
824 home = pw->pw_dir;
826 if (fn == NULL) {
827 if (home)
828 asprintf(&fn, "%s/.soft-token.rc", home);
829 else
830 fn = strdup("/etc/soft-token.rc");
833 soft_token.config_file = fn;
836 ret = read_conf_file(soft_token.config_file, CKU_USER, NULL);
837 if (ret == CKR_OK)
838 soft_token.flags.login_done = 1;
840 return CKR_OK;
843 CK_RV
844 C_Finalize(CK_VOID_PTR args)
846 int i;
848 INIT_CONTEXT();
850 st_logf("Finalize\n");
852 for (i = 0; i < MAX_NUM_SESSION; i++) {
853 if (soft_token.state[i].session_handle != CK_INVALID_HANDLE) {
854 application_error("application finalized without "
855 "closing session\n");
856 close_session(&soft_token.state[i]);
860 return CKR_OK;
863 CK_RV
864 C_GetInfo(CK_INFO_PTR args)
866 INIT_CONTEXT();
868 st_logf("GetInfo\n");
870 memset(args, 17, sizeof(*args));
871 args->cryptokiVersion.major = 2;
872 args->cryptokiVersion.minor = 10;
873 snprintf_fill((char *)args->manufacturerID,
874 sizeof(args->manufacturerID),
875 ' ',
876 "Heimdal hx509 SoftToken");
877 snprintf_fill((char *)args->libraryDescription,
878 sizeof(args->libraryDescription), ' ',
879 "Heimdal hx509 SoftToken");
880 args->libraryVersion.major = 2;
881 args->libraryVersion.minor = 0;
883 return CKR_OK;
886 extern CK_FUNCTION_LIST funcs;
888 CK_RV
889 C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
891 INIT_CONTEXT();
893 *ppFunctionList = &funcs;
894 return CKR_OK;
897 CK_RV
898 C_GetSlotList(CK_BBOOL tokenPresent,
899 CK_SLOT_ID_PTR pSlotList,
900 CK_ULONG_PTR pulCount)
902 INIT_CONTEXT();
903 st_logf("GetSlotList: %s\n",
904 tokenPresent ? "tokenPresent" : "token not Present");
905 if (pSlotList)
906 pSlotList[0] = 1;
907 *pulCount = 1;
908 return CKR_OK;
911 CK_RV
912 C_GetSlotInfo(CK_SLOT_ID slotID,
913 CK_SLOT_INFO_PTR pInfo)
915 INIT_CONTEXT();
916 st_logf("GetSlotInfo: slot: %d : %s\n", (int)slotID, has_session());
918 memset(pInfo, 18, sizeof(*pInfo));
920 if (slotID != 1)
921 return CKR_ARGUMENTS_BAD;
923 snprintf_fill((char *)pInfo->slotDescription,
924 sizeof(pInfo->slotDescription),
925 ' ',
926 "Heimdal hx509 SoftToken (slot)");
927 snprintf_fill((char *)pInfo->manufacturerID,
928 sizeof(pInfo->manufacturerID),
929 ' ',
930 "Heimdal hx509 SoftToken (slot)");
931 pInfo->flags = CKF_TOKEN_PRESENT;
932 if (soft_token.flags.hardware_slot)
933 pInfo->flags |= CKF_HW_SLOT;
934 pInfo->hardwareVersion.major = 1;
935 pInfo->hardwareVersion.minor = 0;
936 pInfo->firmwareVersion.major = 1;
937 pInfo->firmwareVersion.minor = 0;
939 return CKR_OK;
942 CK_RV
943 C_GetTokenInfo(CK_SLOT_ID slotID,
944 CK_TOKEN_INFO_PTR pInfo)
946 INIT_CONTEXT();
947 st_logf("GetTokenInfo: %s\n", has_session());
949 memset(pInfo, 19, sizeof(*pInfo));
951 snprintf_fill((char *)pInfo->label,
952 sizeof(pInfo->label),
953 ' ',
954 "Heimdal hx509 SoftToken (token)");
955 snprintf_fill((char *)pInfo->manufacturerID,
956 sizeof(pInfo->manufacturerID),
957 ' ',
958 "Heimdal hx509 SoftToken (token)");
959 snprintf_fill((char *)pInfo->model,
960 sizeof(pInfo->model),
961 ' ',
962 "Heimdal hx509 SoftToken (token)");
963 snprintf_fill((char *)pInfo->serialNumber,
964 sizeof(pInfo->serialNumber),
965 ' ',
966 "4711");
967 pInfo->flags =
968 CKF_TOKEN_INITIALIZED |
969 CKF_USER_PIN_INITIALIZED;
971 if (soft_token.flags.login_done == 0)
972 pInfo->flags |= CKF_LOGIN_REQUIRED;
974 /* CFK_RNG |
975 CKF_RESTORE_KEY_NOT_NEEDED |
977 pInfo->ulMaxSessionCount = MAX_NUM_SESSION;
978 pInfo->ulSessionCount = soft_token.open_sessions;
979 pInfo->ulMaxRwSessionCount = MAX_NUM_SESSION;
980 pInfo->ulRwSessionCount = soft_token.open_sessions;
981 pInfo->ulMaxPinLen = 1024;
982 pInfo->ulMinPinLen = 0;
983 pInfo->ulTotalPublicMemory = 4711;
984 pInfo->ulFreePublicMemory = 4712;
985 pInfo->ulTotalPrivateMemory = 4713;
986 pInfo->ulFreePrivateMemory = 4714;
987 pInfo->hardwareVersion.major = 2;
988 pInfo->hardwareVersion.minor = 0;
989 pInfo->firmwareVersion.major = 2;
990 pInfo->firmwareVersion.minor = 0;
992 return CKR_OK;
995 CK_RV
996 C_GetMechanismList(CK_SLOT_ID slotID,
997 CK_MECHANISM_TYPE_PTR pMechanismList,
998 CK_ULONG_PTR pulCount)
1000 INIT_CONTEXT();
1001 st_logf("GetMechanismList\n");
1003 *pulCount = 1;
1004 if (pMechanismList == NULL_PTR)
1005 return CKR_OK;
1006 pMechanismList[1] = CKM_RSA_PKCS;
1008 return CKR_OK;
1011 CK_RV
1012 C_GetMechanismInfo(CK_SLOT_ID slotID,
1013 CK_MECHANISM_TYPE type,
1014 CK_MECHANISM_INFO_PTR pInfo)
1016 INIT_CONTEXT();
1017 st_logf("GetMechanismInfo: slot %d type: %d\n",
1018 (int)slotID, (int)type);
1019 memset(pInfo, 0, sizeof(*pInfo));
1021 return CKR_OK;
1024 CK_RV
1025 C_InitToken(CK_SLOT_ID slotID,
1026 CK_UTF8CHAR_PTR pPin,
1027 CK_ULONG ulPinLen,
1028 CK_UTF8CHAR_PTR pLabel)
1030 INIT_CONTEXT();
1031 st_logf("InitToken: slot %d\n", (int)slotID);
1032 return CKR_FUNCTION_NOT_SUPPORTED;
1035 CK_RV
1036 C_OpenSession(CK_SLOT_ID slotID,
1037 CK_FLAGS flags,
1038 CK_VOID_PTR pApplication,
1039 CK_NOTIFY Notify,
1040 CK_SESSION_HANDLE_PTR phSession)
1042 int i;
1043 INIT_CONTEXT();
1044 st_logf("OpenSession: slot: %d\n", (int)slotID);
1046 if (soft_token.open_sessions == MAX_NUM_SESSION)
1047 return CKR_SESSION_COUNT;
1049 soft_token.application = pApplication;
1050 soft_token.notify = Notify;
1052 for (i = 0; i < MAX_NUM_SESSION; i++)
1053 if (soft_token.state[i].session_handle == CK_INVALID_HANDLE)
1054 break;
1055 if (i == MAX_NUM_SESSION)
1056 abort();
1058 soft_token.open_sessions++;
1060 soft_token.state[i].session_handle =
1061 (CK_SESSION_HANDLE)(random() & 0xfffff);
1062 *phSession = soft_token.state[i].session_handle;
1064 return CKR_OK;
1067 CK_RV
1068 C_CloseSession(CK_SESSION_HANDLE hSession)
1070 struct session_state *state;
1071 INIT_CONTEXT();
1072 st_logf("CloseSession\n");
1074 if (verify_session_handle(hSession, &state) != CKR_OK)
1075 application_error("closed session not open");
1076 else
1077 close_session(state);
1079 return CKR_OK;
1082 CK_RV
1083 C_CloseAllSessions(CK_SLOT_ID slotID)
1085 int i;
1086 INIT_CONTEXT();
1088 st_logf("CloseAllSessions\n");
1090 for (i = 0; i < MAX_NUM_SESSION; i++)
1091 if (soft_token.state[i].session_handle != CK_INVALID_HANDLE)
1092 close_session(&soft_token.state[i]);
1094 return CKR_OK;
1097 CK_RV
1098 C_GetSessionInfo(CK_SESSION_HANDLE hSession,
1099 CK_SESSION_INFO_PTR pInfo)
1101 st_logf("GetSessionInfo\n");
1102 INIT_CONTEXT();
1104 VERIFY_SESSION_HANDLE(hSession, NULL);
1106 memset(pInfo, 20, sizeof(*pInfo));
1108 pInfo->slotID = 1;
1109 if (soft_token.flags.login_done)
1110 pInfo->state = CKS_RO_USER_FUNCTIONS;
1111 else
1112 pInfo->state = CKS_RO_PUBLIC_SESSION;
1113 pInfo->flags = CKF_SERIAL_SESSION;
1114 pInfo->ulDeviceError = 0;
1116 return CKR_OK;
1119 CK_RV
1120 C_Login(CK_SESSION_HANDLE hSession,
1121 CK_USER_TYPE userType,
1122 CK_UTF8CHAR_PTR pPin,
1123 CK_ULONG ulPinLen)
1125 char *pin = NULL;
1126 CK_RV ret;
1127 INIT_CONTEXT();
1129 st_logf("Login\n");
1131 VERIFY_SESSION_HANDLE(hSession, NULL);
1133 if (pPin != NULL_PTR) {
1134 asprintf(&pin, "%.*s", (int)ulPinLen, pPin);
1135 st_logf("type: %d password: %s\n", (int)userType, pin);
1139 * Login
1142 ret = read_conf_file(soft_token.config_file, userType, pin);
1143 if (ret == CKR_OK)
1144 soft_token.flags.login_done = 1;
1146 free(pin);
1148 return soft_token.flags.login_done ? CKR_OK : CKR_PIN_INCORRECT;
1151 CK_RV
1152 C_Logout(CK_SESSION_HANDLE hSession)
1154 st_logf("Logout\n");
1155 INIT_CONTEXT();
1157 VERIFY_SESSION_HANDLE(hSession, NULL);
1158 return CKR_FUNCTION_NOT_SUPPORTED;
1161 CK_RV
1162 C_GetObjectSize(CK_SESSION_HANDLE hSession,
1163 CK_OBJECT_HANDLE hObject,
1164 CK_ULONG_PTR pulSize)
1166 st_logf("GetObjectSize\n");
1167 INIT_CONTEXT();
1169 VERIFY_SESSION_HANDLE(hSession, NULL);
1170 return CKR_FUNCTION_NOT_SUPPORTED;
1173 CK_RV
1174 C_GetAttributeValue(CK_SESSION_HANDLE hSession,
1175 CK_OBJECT_HANDLE hObject,
1176 CK_ATTRIBUTE_PTR pTemplate,
1177 CK_ULONG ulCount)
1179 struct session_state *state;
1180 struct st_object *obj;
1181 CK_ULONG i;
1182 CK_RV ret;
1183 int j;
1185 INIT_CONTEXT();
1187 st_logf("GetAttributeValue: %lx\n",
1188 (unsigned long)HANDLE_OBJECT_ID(hObject));
1189 VERIFY_SESSION_HANDLE(hSession, &state);
1191 if ((ret = object_handle_to_object(hObject, &obj)) != CKR_OK) {
1192 st_logf("object not found: %lx\n",
1193 (unsigned long)HANDLE_OBJECT_ID(hObject));
1194 return ret;
1197 for (i = 0; i < ulCount; i++) {
1198 st_logf(" getting 0x%08lx\n", (unsigned long)pTemplate[i].type);
1199 for (j = 0; j < obj->num_attributes; j++) {
1200 if (obj->attrs[j].secret) {
1201 pTemplate[i].ulValueLen = (CK_ULONG)-1;
1202 break;
1204 if (pTemplate[i].type == obj->attrs[j].attribute.type) {
1205 if (pTemplate[i].pValue != NULL_PTR && obj->attrs[j].secret == 0) {
1206 if (pTemplate[i].ulValueLen >= obj->attrs[j].attribute.ulValueLen)
1207 memcpy(pTemplate[i].pValue, obj->attrs[j].attribute.pValue,
1208 obj->attrs[j].attribute.ulValueLen);
1210 pTemplate[i].ulValueLen = obj->attrs[j].attribute.ulValueLen;
1211 break;
1214 if (j == obj->num_attributes) {
1215 st_logf("key type: 0x%08lx not found\n", (unsigned long)pTemplate[i].type);
1216 pTemplate[i].ulValueLen = (CK_ULONG)-1;
1220 return CKR_OK;
1223 CK_RV
1224 C_FindObjectsInit(CK_SESSION_HANDLE hSession,
1225 CK_ATTRIBUTE_PTR pTemplate,
1226 CK_ULONG ulCount)
1228 struct session_state *state;
1230 st_logf("FindObjectsInit\n");
1232 INIT_CONTEXT();
1234 VERIFY_SESSION_HANDLE(hSession, &state);
1236 if (state->find.next_object != -1) {
1237 application_error("application didn't do C_FindObjectsFinal\n");
1238 find_object_final(state);
1240 if (ulCount) {
1241 CK_ULONG i;
1243 print_attributes(pTemplate, ulCount);
1245 state->find.attributes =
1246 calloc(1, ulCount * sizeof(state->find.attributes[0]));
1247 if (state->find.attributes == NULL)
1248 return CKR_DEVICE_MEMORY;
1249 for (i = 0; i < ulCount; i++) {
1250 state->find.attributes[i].pValue =
1251 malloc(pTemplate[i].ulValueLen);
1252 if (state->find.attributes[i].pValue == NULL) {
1253 find_object_final(state);
1254 return CKR_DEVICE_MEMORY;
1256 memcpy(state->find.attributes[i].pValue,
1257 pTemplate[i].pValue, pTemplate[i].ulValueLen);
1258 state->find.attributes[i].type = pTemplate[i].type;
1259 state->find.attributes[i].ulValueLen = pTemplate[i].ulValueLen;
1261 state->find.num_attributes = ulCount;
1262 state->find.next_object = 0;
1263 } else {
1264 st_logf("find all objects\n");
1265 state->find.attributes = NULL;
1266 state->find.num_attributes = 0;
1267 state->find.next_object = 0;
1270 return CKR_OK;
1273 CK_RV
1274 C_FindObjects(CK_SESSION_HANDLE hSession,
1275 CK_OBJECT_HANDLE_PTR phObject,
1276 CK_ULONG ulMaxObjectCount,
1277 CK_ULONG_PTR pulObjectCount)
1279 struct session_state *state;
1280 int i;
1282 INIT_CONTEXT();
1284 st_logf("FindObjects\n");
1286 VERIFY_SESSION_HANDLE(hSession, &state);
1288 if (state->find.next_object == -1) {
1289 application_error("application didn't do C_FindObjectsInit\n");
1290 return CKR_ARGUMENTS_BAD;
1292 if (ulMaxObjectCount == 0) {
1293 application_error("application asked for 0 objects\n");
1294 return CKR_ARGUMENTS_BAD;
1296 *pulObjectCount = 0;
1297 for (i = state->find.next_object; i < soft_token.object.num_objs; i++) {
1298 st_logf("FindObjects: %d\n", i);
1299 state->find.next_object = i + 1;
1300 if (attributes_match(soft_token.object.objs[i],
1301 state->find.attributes,
1302 state->find.num_attributes)) {
1303 *phObject++ = soft_token.object.objs[i]->object_handle;
1304 ulMaxObjectCount--;
1305 (*pulObjectCount)++;
1306 if (ulMaxObjectCount == 0)
1307 break;
1310 return CKR_OK;
1313 CK_RV
1314 C_FindObjectsFinal(CK_SESSION_HANDLE hSession)
1316 struct session_state *state;
1318 INIT_CONTEXT();
1320 st_logf("FindObjectsFinal\n");
1321 VERIFY_SESSION_HANDLE(hSession, &state);
1322 find_object_final(state);
1323 return CKR_OK;
1326 static CK_RV
1327 commonInit(CK_ATTRIBUTE *attr_match, int attr_match_len,
1328 const CK_MECHANISM_TYPE *mechs, int mechs_len,
1329 const CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey,
1330 struct st_object **o)
1332 CK_RV ret;
1333 int i;
1335 *o = NULL;
1336 if ((ret = object_handle_to_object(hKey, o)) != CKR_OK)
1337 return ret;
1339 ret = attributes_match(*o, attr_match, attr_match_len);
1340 if (!ret) {
1341 application_error("called commonInit on key that doesn't "
1342 "support required attr");
1343 return CKR_ARGUMENTS_BAD;
1346 for (i = 0; i < mechs_len; i++)
1347 if (mechs[i] == pMechanism->mechanism)
1348 break;
1349 if (i == mechs_len) {
1350 application_error("called mech (%08lx) not supported\n",
1351 pMechanism->mechanism);
1352 return CKR_ARGUMENTS_BAD;
1354 return CKR_OK;
1358 static CK_RV
1359 dup_mechanism(CK_MECHANISM_PTR *dup, const CK_MECHANISM_PTR pMechanism)
1361 CK_MECHANISM_PTR p;
1363 p = malloc(sizeof(*p));
1364 if (p == NULL)
1365 return CKR_DEVICE_MEMORY;
1367 if (*dup)
1368 free(*dup);
1369 *dup = p;
1370 memcpy(p, pMechanism, sizeof(*p));
1372 return CKR_OK;
1375 #if 0
1377 CK_RV
1378 C_EncryptInit(CK_SESSION_HANDLE hSession,
1379 CK_MECHANISM_PTR pMechanism,
1380 CK_OBJECT_HANDLE hKey)
1382 struct session_state *state;
1383 CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS };
1384 CK_BBOOL bool_true = CK_TRUE;
1385 CK_ATTRIBUTE attr[] = {
1386 { CKA_ENCRYPT, &bool_true, sizeof(bool_true) }
1388 struct st_object *o;
1389 CK_RV ret;
1391 INIT_CONTEXT();
1393 st_logf("EncryptInit\n");
1394 VERIFY_SESSION_HANDLE(hSession, &state);
1396 ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
1397 mechs, sizeof(mechs)/sizeof(mechs[0]),
1398 pMechanism, hKey, &o);
1399 if (ret)
1400 return ret;
1402 ret = dup_mechanism(&state->encrypt_mechanism, pMechanism);
1403 if (ret == CKR_OK)
1404 state->encrypt_object = OBJECT_ID(o);
1406 return ret;
1409 CK_RV
1410 C_Encrypt(CK_SESSION_HANDLE hSession,
1411 CK_BYTE_PTR pData,
1412 CK_ULONG ulDataLen,
1413 CK_BYTE_PTR pEncryptedData,
1414 CK_ULONG_PTR pulEncryptedDataLen)
1416 CK_RV ret = CKR_FUNCTION_NOT_SUPPORTED;
1417 #if 0
1418 struct session_state *state;
1419 struct st_object *o;
1420 void *buffer = NULL;
1421 RSA *rsa;
1422 int padding, len, buffer_len, padding_len;
1424 INIT_CONTEXT();
1426 st_logf("Encrypt\n");
1428 VERIFY_SESSION_HANDLE(hSession, &state);
1430 if (state->encrypt_object == -1)
1431 return CKR_ARGUMENTS_BAD;
1433 o = soft_token.object.objs[state->encrypt_object];
1435 if (o->u.public_key == NULL) {
1436 st_logf("public key NULL\n");
1437 return CKR_ARGUMENTS_BAD;
1440 rsa = o->u.public_key->pkey.rsa;
1442 if (rsa == NULL)
1443 return CKR_ARGUMENTS_BAD;
1445 RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */
1447 buffer_len = RSA_size(rsa);
1449 buffer = malloc(buffer_len);
1450 if (buffer == NULL) {
1451 ret = CKR_DEVICE_MEMORY;
1452 goto out;
1455 ret = CKR_OK;
1456 switch(state->encrypt_mechanism->mechanism) {
1457 case CKM_RSA_PKCS:
1458 padding = RSA_PKCS1_PADDING;
1459 padding_len = RSA_PKCS1_PADDING_SIZE;
1460 break;
1461 default:
1462 ret = CKR_FUNCTION_NOT_SUPPORTED;
1463 goto out;
1466 if (buffer_len + padding_len < ulDataLen) {
1467 ret = CKR_ARGUMENTS_BAD;
1468 goto out;
1471 if (pulEncryptedDataLen == NULL) {
1472 st_logf("pulEncryptedDataLen NULL\n");
1473 ret = CKR_ARGUMENTS_BAD;
1474 goto out;
1477 if (pData == NULL_PTR) {
1478 st_logf("data NULL\n");
1479 ret = CKR_ARGUMENTS_BAD;
1480 goto out;
1483 len = RSA_public_encrypt(ulDataLen, pData, buffer, rsa, padding);
1484 if (len <= 0) {
1485 ret = CKR_DEVICE_ERROR;
1486 goto out;
1488 if (len > buffer_len)
1489 abort();
1491 if (pEncryptedData != NULL_PTR)
1492 memcpy(pEncryptedData, buffer, len);
1493 *pulEncryptedDataLen = len;
1495 out:
1496 if (buffer) {
1497 memset(buffer, 0, buffer_len);
1498 free(buffer);
1500 #endif
1501 return ret;
1504 CK_RV
1505 C_EncryptUpdate(CK_SESSION_HANDLE hSession,
1506 CK_BYTE_PTR pPart,
1507 CK_ULONG ulPartLen,
1508 CK_BYTE_PTR pEncryptedPart,
1509 CK_ULONG_PTR pulEncryptedPartLen)
1511 INIT_CONTEXT();
1512 st_logf("EncryptUpdate\n");
1513 VERIFY_SESSION_HANDLE(hSession, NULL);
1514 return CKR_FUNCTION_NOT_SUPPORTED;
1518 CK_RV
1519 C_EncryptFinal(CK_SESSION_HANDLE hSession,
1520 CK_BYTE_PTR pLastEncryptedPart,
1521 CK_ULONG_PTR pulLastEncryptedPartLen)
1523 INIT_CONTEXT();
1524 st_logf("EncryptFinal\n");
1525 VERIFY_SESSION_HANDLE(hSession, NULL);
1526 return CKR_FUNCTION_NOT_SUPPORTED;
1530 /* C_DecryptInit initializes a decryption operation. */
1531 CK_RV
1532 C_DecryptInit(CK_SESSION_HANDLE hSession,
1533 CK_MECHANISM_PTR pMechanism,
1534 CK_OBJECT_HANDLE hKey)
1536 struct session_state *state;
1537 CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS };
1538 CK_BBOOL bool_true = CK_TRUE;
1539 CK_ATTRIBUTE attr[] = {
1540 { CKA_DECRYPT, &bool_true, sizeof(bool_true) }
1542 struct st_object *o;
1543 CK_RV ret;
1545 INIT_CONTEXT();
1546 st_logf("DecryptInit\n");
1547 VERIFY_SESSION_HANDLE(hSession, &state);
1549 ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
1550 mechs, sizeof(mechs)/sizeof(mechs[0]),
1551 pMechanism, hKey, &o);
1552 if (ret)
1553 return ret;
1555 ret = dup_mechanism(&state->decrypt_mechanism, pMechanism);
1556 if (ret == CKR_OK)
1557 state->decrypt_object = OBJECT_ID(o);
1559 return CKR_OK;
1563 CK_RV
1564 C_Decrypt(CK_SESSION_HANDLE hSession,
1565 CK_BYTE_PTR pEncryptedData,
1566 CK_ULONG ulEncryptedDataLen,
1567 CK_BYTE_PTR pData,
1568 CK_ULONG_PTR pulDataLen)
1570 CK_RV ret = CKR_FUNCTION_NOT_SUPPORTED;
1571 #if 0
1572 struct session_state *state;
1573 struct st_object *o;
1574 void *buffer = NULL;
1575 RSA *rsa;
1576 int padding, len, buffer_len, padding_len;
1578 INIT_CONTEXT();
1579 st_logf("Decrypt\n");
1581 VERIFY_SESSION_HANDLE(hSession, &state);
1583 if (state->decrypt_object == -1)
1584 return CKR_ARGUMENTS_BAD;
1586 o = soft_token.object.objs[state->decrypt_object];
1588 if (o->u.private_key.key == NULL) {
1589 st_logf("private key NULL\n");
1590 return CKR_ARGUMENTS_BAD;
1593 rsa = o->u.private_key.key->pkey.rsa;
1595 if (rsa == NULL)
1596 return CKR_ARGUMENTS_BAD;
1598 RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */
1600 buffer_len = RSA_size(rsa);
1602 buffer = malloc(buffer_len);
1603 if (buffer == NULL) {
1604 ret = CKR_DEVICE_MEMORY;
1605 goto out;
1608 ret = CKR_OK;
1609 switch(state->decrypt_mechanism->mechanism) {
1610 case CKM_RSA_PKCS:
1611 padding = RSA_PKCS1_PADDING;
1612 padding_len = RSA_PKCS1_PADDING_SIZE;
1613 break;
1614 default:
1615 ret = CKR_FUNCTION_NOT_SUPPORTED;
1616 goto out;
1619 if (buffer_len + padding_len < ulEncryptedDataLen) {
1620 ret = CKR_ARGUMENTS_BAD;
1621 goto out;
1624 if (pulDataLen == NULL) {
1625 st_logf("pulDataLen NULL\n");
1626 ret = CKR_ARGUMENTS_BAD;
1627 goto out;
1630 if (pEncryptedData == NULL_PTR) {
1631 st_logf("data NULL\n");
1632 ret = CKR_ARGUMENTS_BAD;
1633 goto out;
1636 len = RSA_private_decrypt(ulEncryptedDataLen, pEncryptedData, buffer,
1637 rsa, padding);
1638 if (len <= 0) {
1639 ret = CKR_DEVICE_ERROR;
1640 goto out;
1642 if (len > buffer_len)
1643 abort();
1645 if (pData != NULL_PTR)
1646 memcpy(pData, buffer, len);
1647 *pulDataLen = len;
1649 out:
1650 if (buffer) {
1651 memset(buffer, 0, buffer_len);
1652 free(buffer);
1654 #endif
1655 return ret;
1659 CK_RV
1660 C_DecryptUpdate(CK_SESSION_HANDLE hSession,
1661 CK_BYTE_PTR pEncryptedPart,
1662 CK_ULONG ulEncryptedPartLen,
1663 CK_BYTE_PTR pPart,
1664 CK_ULONG_PTR pulPartLen)
1667 st_logf("DecryptUpdate\n");
1668 INIT_CONTEXT();
1669 VERIFY_SESSION_HANDLE(hSession, NULL);
1670 return CKR_FUNCTION_NOT_SUPPORTED;
1674 CK_RV
1675 C_DecryptFinal(CK_SESSION_HANDLE hSession,
1676 CK_BYTE_PTR pLastPart,
1677 CK_ULONG_PTR pulLastPartLen)
1679 st_logf("DecryptFinal\n");
1680 INIT_CONTEXT();
1681 VERIFY_SESSION_HANDLE(hSession, NULL);
1682 return CKR_FUNCTION_NOT_SUPPORTED;
1684 #endif
1686 CK_RV
1687 C_DigestInit(CK_SESSION_HANDLE hSession,
1688 CK_MECHANISM_PTR pMechanism)
1690 st_logf("DigestInit\n");
1691 INIT_CONTEXT();
1692 VERIFY_SESSION_HANDLE(hSession, NULL);
1693 return CKR_FUNCTION_NOT_SUPPORTED;
1696 CK_RV
1697 C_SignInit(CK_SESSION_HANDLE hSession,
1698 CK_MECHANISM_PTR pMechanism,
1699 CK_OBJECT_HANDLE hKey)
1701 struct session_state *state;
1702 CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS };
1703 CK_BBOOL bool_true = CK_TRUE;
1704 CK_ATTRIBUTE attr[] = {
1705 { CKA_SIGN, &bool_true, sizeof(bool_true) }
1707 struct st_object *o;
1708 CK_RV ret;
1710 INIT_CONTEXT();
1711 st_logf("SignInit\n");
1712 VERIFY_SESSION_HANDLE(hSession, &state);
1714 ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
1715 mechs, sizeof(mechs)/sizeof(mechs[0]),
1716 pMechanism, hKey, &o);
1717 if (ret)
1718 return ret;
1720 ret = dup_mechanism(&state->sign_mechanism, pMechanism);
1721 if (ret == CKR_OK)
1722 state->sign_object = OBJECT_ID(o);
1724 return CKR_OK;
1727 CK_RV
1728 C_Sign(CK_SESSION_HANDLE hSession,
1729 CK_BYTE_PTR pData,
1730 CK_ULONG ulDataLen,
1731 CK_BYTE_PTR pSignature,
1732 CK_ULONG_PTR pulSignatureLen)
1734 struct session_state *state;
1735 struct st_object *o;
1736 CK_RV ret;
1737 uint hret;
1738 const AlgorithmIdentifier *alg;
1739 heim_octet_string sig, data;
1741 INIT_CONTEXT();
1742 st_logf("Sign\n");
1743 VERIFY_SESSION_HANDLE(hSession, &state);
1745 sig.data = NULL;
1746 sig.length = 0;
1748 if (state->sign_object == -1)
1749 return CKR_ARGUMENTS_BAD;
1751 if (pulSignatureLen == NULL) {
1752 st_logf("signature len NULL\n");
1753 ret = CKR_ARGUMENTS_BAD;
1754 goto out;
1757 if (pData == NULL_PTR) {
1758 st_logf("data NULL\n");
1759 ret = CKR_ARGUMENTS_BAD;
1760 goto out;
1763 o = soft_token.object.objs[state->sign_object];
1765 if (hx509_cert_have_private_key(o->cert) == 0) {
1766 st_logf("private key NULL\n");
1767 return CKR_ARGUMENTS_BAD;
1770 switch(state->sign_mechanism->mechanism) {
1771 case CKM_RSA_PKCS:
1772 alg = hx509_signature_rsa_pkcs1_x509();
1773 break;
1774 default:
1775 ret = CKR_FUNCTION_NOT_SUPPORTED;
1776 goto out;
1779 data.data = pData;
1780 data.length = ulDataLen;
1782 hret = _hx509_create_signature(context,
1783 _hx509_cert_private_key(o->cert),
1784 alg,
1785 &data,
1786 NULL,
1787 &sig);
1788 if (hret) {
1789 ret = CKR_DEVICE_ERROR;
1790 goto out;
1792 *pulSignatureLen = sig.length;
1794 if (pSignature != NULL_PTR)
1795 memcpy(pSignature, sig.data, sig.length);
1797 ret = CKR_OK;
1798 out:
1799 if (sig.data) {
1800 memset(sig.data, 0, sig.length);
1801 der_free_octet_string(&sig);
1803 return ret;
1806 CK_RV
1807 C_SignUpdate(CK_SESSION_HANDLE hSession,
1808 CK_BYTE_PTR pPart,
1809 CK_ULONG ulPartLen)
1811 INIT_CONTEXT();
1812 st_logf("SignUpdate\n");
1813 VERIFY_SESSION_HANDLE(hSession, NULL);
1814 return CKR_FUNCTION_NOT_SUPPORTED;
1818 CK_RV
1819 C_SignFinal(CK_SESSION_HANDLE hSession,
1820 CK_BYTE_PTR pSignature,
1821 CK_ULONG_PTR pulSignatureLen)
1823 INIT_CONTEXT();
1824 st_logf("SignUpdate\n");
1825 VERIFY_SESSION_HANDLE(hSession, NULL);
1826 return CKR_FUNCTION_NOT_SUPPORTED;
1829 CK_RV
1830 C_VerifyInit(CK_SESSION_HANDLE hSession,
1831 CK_MECHANISM_PTR pMechanism,
1832 CK_OBJECT_HANDLE hKey)
1834 struct session_state *state;
1835 CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS };
1836 CK_BBOOL bool_true = CK_TRUE;
1837 CK_ATTRIBUTE attr[] = {
1838 { CKA_VERIFY, &bool_true, sizeof(bool_true) }
1840 struct st_object *o;
1841 CK_RV ret;
1843 INIT_CONTEXT();
1844 st_logf("VerifyInit\n");
1845 VERIFY_SESSION_HANDLE(hSession, &state);
1847 ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
1848 mechs, sizeof(mechs)/sizeof(mechs[0]),
1849 pMechanism, hKey, &o);
1850 if (ret)
1851 return ret;
1853 ret = dup_mechanism(&state->verify_mechanism, pMechanism);
1854 if (ret == CKR_OK)
1855 state->verify_object = OBJECT_ID(o);
1857 return ret;
1860 CK_RV
1861 C_Verify(CK_SESSION_HANDLE hSession,
1862 CK_BYTE_PTR pData,
1863 CK_ULONG ulDataLen,
1864 CK_BYTE_PTR pSignature,
1865 CK_ULONG ulSignatureLen)
1867 struct session_state *state;
1868 struct st_object *o;
1869 const AlgorithmIdentifier *alg;
1870 CK_RV ret;
1871 int hret;
1872 heim_octet_string data, sig;
1874 INIT_CONTEXT();
1875 st_logf("Verify\n");
1876 VERIFY_SESSION_HANDLE(hSession, &state);
1878 if (state->verify_object == -1)
1879 return CKR_ARGUMENTS_BAD;
1881 o = soft_token.object.objs[state->verify_object];
1883 switch(state->verify_mechanism->mechanism) {
1884 case CKM_RSA_PKCS:
1885 alg = hx509_signature_rsa_pkcs1_x509();
1886 break;
1887 default:
1888 ret = CKR_FUNCTION_NOT_SUPPORTED;
1889 goto out;
1892 sig.data = pData;
1893 sig.length = ulDataLen;
1894 data.data = pSignature;
1895 data.length = ulSignatureLen;
1897 hret = _hx509_verify_signature(context,
1898 _hx509_get_cert(o->cert),
1899 alg,
1900 &data,
1901 &sig);
1902 if (hret) {
1903 ret = CKR_GENERAL_ERROR;
1904 goto out;
1906 ret = CKR_OK;
1908 out:
1909 return ret;
1913 CK_RV
1914 C_VerifyUpdate(CK_SESSION_HANDLE hSession,
1915 CK_BYTE_PTR pPart,
1916 CK_ULONG ulPartLen)
1918 INIT_CONTEXT();
1919 st_logf("VerifyUpdate\n");
1920 VERIFY_SESSION_HANDLE(hSession, NULL);
1921 return CKR_FUNCTION_NOT_SUPPORTED;
1924 CK_RV
1925 C_VerifyFinal(CK_SESSION_HANDLE hSession,
1926 CK_BYTE_PTR pSignature,
1927 CK_ULONG ulSignatureLen)
1929 INIT_CONTEXT();
1930 st_logf("VerifyFinal\n");
1931 VERIFY_SESSION_HANDLE(hSession, NULL);
1932 return CKR_FUNCTION_NOT_SUPPORTED;
1935 CK_RV
1936 C_GenerateRandom(CK_SESSION_HANDLE hSession,
1937 CK_BYTE_PTR RandomData,
1938 CK_ULONG ulRandomLen)
1940 INIT_CONTEXT();
1941 st_logf("GenerateRandom\n");
1942 VERIFY_SESSION_HANDLE(hSession, NULL);
1943 return CKR_FUNCTION_NOT_SUPPORTED;
1947 CK_FUNCTION_LIST funcs = {
1948 { 2, 11 },
1949 C_Initialize,
1950 C_Finalize,
1951 C_GetInfo,
1952 C_GetFunctionList,
1953 C_GetSlotList,
1954 C_GetSlotInfo,
1955 C_GetTokenInfo,
1956 C_GetMechanismList,
1957 C_GetMechanismInfo,
1958 C_InitToken,
1959 (void *)func_not_supported, /* C_InitPIN */
1960 (void *)func_not_supported, /* C_SetPIN */
1961 C_OpenSession,
1962 C_CloseSession,
1963 C_CloseAllSessions,
1964 C_GetSessionInfo,
1965 (void *)func_not_supported, /* C_GetOperationState */
1966 (void *)func_not_supported, /* C_SetOperationState */
1967 C_Login,
1968 C_Logout,
1969 (void *)func_not_supported, /* C_CreateObject */
1970 (void *)func_not_supported, /* C_CopyObject */
1971 (void *)func_not_supported, /* C_DestroyObject */
1972 (void *)func_not_supported, /* C_GetObjectSize */
1973 C_GetAttributeValue,
1974 (void *)func_not_supported, /* C_SetAttributeValue */
1975 C_FindObjectsInit,
1976 C_FindObjects,
1977 C_FindObjectsFinal,
1978 (void *)func_not_supported, /* C_EncryptInit, */
1979 (void *)func_not_supported, /* C_Encrypt, */
1980 (void *)func_not_supported, /* C_EncryptUpdate, */
1981 (void *)func_not_supported, /* C_EncryptFinal, */
1982 (void *)func_not_supported, /* C_DecryptInit, */
1983 (void *)func_not_supported, /* C_Decrypt, */
1984 (void *)func_not_supported, /* C_DecryptUpdate, */
1985 (void *)func_not_supported, /* C_DecryptFinal, */
1986 C_DigestInit,
1987 (void *)func_not_supported, /* C_Digest */
1988 (void *)func_not_supported, /* C_DigestUpdate */
1989 (void *)func_not_supported, /* C_DigestKey */
1990 (void *)func_not_supported, /* C_DigestFinal */
1991 C_SignInit,
1992 C_Sign,
1993 C_SignUpdate,
1994 C_SignFinal,
1995 (void *)func_not_supported, /* C_SignRecoverInit */
1996 (void *)func_not_supported, /* C_SignRecover */
1997 C_VerifyInit,
1998 C_Verify,
1999 C_VerifyUpdate,
2000 C_VerifyFinal,
2001 (void *)func_not_supported, /* C_VerifyRecoverInit */
2002 (void *)func_not_supported, /* C_VerifyRecover */
2003 (void *)func_not_supported, /* C_DigestEncryptUpdate */
2004 (void *)func_not_supported, /* C_DecryptDigestUpdate */
2005 (void *)func_not_supported, /* C_SignEncryptUpdate */
2006 (void *)func_not_supported, /* C_DecryptVerifyUpdate */
2007 (void *)func_not_supported, /* C_GenerateKey */
2008 (void *)func_not_supported, /* C_GenerateKeyPair */
2009 (void *)func_not_supported, /* C_WrapKey */
2010 (void *)func_not_supported, /* C_UnwrapKey */
2011 (void *)func_not_supported, /* C_DeriveKey */
2012 (void *)func_not_supported, /* C_SeedRandom */
2013 C_GenerateRandom,
2014 (void *)func_not_supported, /* C_GetFunctionStatus */
2015 (void *)func_not_supported, /* C_CancelFunction */
2016 (void *)func_not_supported /* C_WaitForSlotEvent */