1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3 * Copyright (c) 2004-2006, Stockholms universitet
4 * (Stockholm University, Stockholm Sweden)
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * 3. Neither the name of the university nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 #include "k5-platform.h"
36
37 #include <openssl/err.h>
38 #include <openssl/evp.h>
39 #include <openssl/pem.h>
40 #include <openssl/rand.h>
41 #include <openssl/x509.h>
42
43 #include <ctype.h>
44 #include <pwd.h>
45
46 #include <pkcs11.h>
47
48 #if OPENSSL_VERSION_NUMBER < 0x10100000L
49 #define EVP_PKEY_get0_RSA(key) ((key)->pkey.rsa)
50 #define RSA_PKCS1_OpenSSL RSA_PKCS1_SSLeay
51 #define RSA_get0_key compat_rsa_get0_key
52 static void
compat_rsa_get0_key(const RSA * rsa,const BIGNUM ** n,const BIGNUM ** e,const BIGNUM ** d)53 compat_rsa_get0_key(const RSA *rsa, const BIGNUM **n, const BIGNUM **e,
54 const BIGNUM **d)
55 {
56 if (n != NULL)
57 *n = rsa->n;
58 if (e != NULL)
59 *e = rsa->e;
60 if (d != NULL)
61 *d = rsa->d;
62 }
63 #endif
64
65 #define OPENSSL_ASN1_MALLOC_ENCODE(T, B, BL, S, R) \
66 { \
67 unsigned char *p; \
68 (BL) = i2d_##T((S), NULL); \
69 if ((BL) <= 0) { \
70 (R) = EINVAL; \
71 } else { \
72 (B) = malloc((BL)); \
73 if ((B) == NULL) { \
74 (R) = ENOMEM; \
75 } else { \
76 p = (B); \
77 (R) = 0; \
78 (BL) = i2d_##T((S), &p); \
79 if ((BL) <= 0) { \
80 free((B)); \
81 (B) = NULL; \
82 (R) = EINVAL; \
83 } \
84 } \
85 } \
86 }
87
88 /* RCSID("$Id: main.c,v 1.24 2006/01/11 12:42:53 lha Exp $"); */
89
90 #define OBJECT_ID_MASK 0xfff
91 #define HANDLE_OBJECT_ID(h) ((h) & OBJECT_ID_MASK)
92 #define OBJECT_ID(obj) HANDLE_OBJECT_ID((obj)->object_handle)
93
94 struct st_attr {
95 CK_ATTRIBUTE attribute;
96 int secret;
97 };
98
99 struct st_object {
100 CK_OBJECT_HANDLE object_handle;
101 struct st_attr *attrs;
102 int num_attributes;
103 enum {
104 STO_T_CERTIFICATE,
105 STO_T_PRIVATE_KEY,
106 STO_T_PUBLIC_KEY
107 } type;
108 union {
109 X509 *cert;
110 EVP_PKEY *public_key;
111 struct {
112 char *file;
113 EVP_PKEY *key;
114 X509 *cert;
115 } private_key;
116 } u;
117 };
118
119 static struct soft_token {
120 CK_VOID_PTR application;
121 CK_NOTIFY notify;
122 struct {
123 struct st_object **objs;
124 int num_objs;
125 } object;
126 struct {
127 int hardware_slot;
128 int app_error_fatal;
129 int login_done;
130 } flags;
131 int open_sessions;
132 struct session_state {
133 CK_SESSION_HANDLE session_handle;
134
135 struct {
136 CK_ATTRIBUTE *attributes;
137 CK_ULONG num_attributes;
138 int next_object;
139 } find;
140
141 int encrypt_object;
142 CK_MECHANISM_PTR encrypt_mechanism;
143 int decrypt_object;
144 CK_MECHANISM_PTR decrypt_mechanism;
145 int sign_object;
146 CK_MECHANISM_PTR sign_mechanism;
147 int verify_object;
148 CK_MECHANISM_PTR verify_mechanism;
149 int digest_object;
150 } state[10];
151 #define MAX_NUM_SESSION (sizeof(soft_token.state)/sizeof(soft_token.state[0]))
152 FILE *logfile;
153 CK_SESSION_HANDLE next_session_handle;
154 } soft_token;
155
156 static void
application_error(const char * fmt,...)157 application_error(const char *fmt, ...)
158 {
159 va_list ap;
160 va_start(ap, fmt);
161 vprintf(fmt, ap);
162 va_end(ap);
163 if (soft_token.flags.app_error_fatal)
164 abort();
165 }
166
167 static void
st_logf(const char * fmt,...)168 st_logf(const char *fmt, ...)
169 {
170 va_list ap;
171 if (soft_token.logfile == NULL)
172 return;
173 va_start(ap, fmt);
174 vfprintf(soft_token.logfile, fmt, ap);
175 va_end(ap);
176 fflush(soft_token.logfile);
177 }
178
179 static void
snprintf_fill(char * str,int size,char fillchar,const char * fmt,...)180 snprintf_fill(char *str, int size, char fillchar, const char *fmt, ...)
181 {
182 int len;
183 va_list ap;
184 va_start(ap, fmt);
185 len = vsnprintf(str, size, fmt, ap);
186 va_end(ap);
187 if (len < 0 || len > size)
188 return;
189 while(len < size)
190 str[len++] = fillchar;
191 }
192
193 #ifndef TEST_APP
194 #define printf error_use_st_logf
195 #endif
196
197 #define VERIFY_SESSION_HANDLE(s, state) \
198 { \
199 CK_RV vshret; \
200 vshret = verify_session_handle(s, state); \
201 if (vshret != CKR_OK) { \
202 /* return CKR_OK */; \
203 } \
204 }
205
206 static CK_RV
verify_session_handle(CK_SESSION_HANDLE hSession,struct session_state ** state)207 verify_session_handle(CK_SESSION_HANDLE hSession,
208 struct session_state **state)
209 {
210 size_t i;
211
212 for (i = 0; i < MAX_NUM_SESSION; i++){
213 if (soft_token.state[i].session_handle == hSession)
214 break;
215 }
216 if (i == MAX_NUM_SESSION) {
217 application_error("use of invalid handle: 0x%08lx\n",
218 (unsigned long)hSession);
219 return CKR_SESSION_HANDLE_INVALID;
220 }
221 if (state)
222 *state = &soft_token.state[i];
223 return CKR_OK;
224 }
225
226 static CK_RV
object_handle_to_object(CK_OBJECT_HANDLE handle,struct st_object ** object)227 object_handle_to_object(CK_OBJECT_HANDLE handle,
228 struct st_object **object)
229 {
230 int i = HANDLE_OBJECT_ID(handle);
231
232 *object = NULL;
233 if (i >= soft_token.object.num_objs)
234 return CKR_ARGUMENTS_BAD;
235 if (soft_token.object.objs[i] == NULL)
236 return CKR_ARGUMENTS_BAD;
237 if (soft_token.object.objs[i]->object_handle != handle)
238 return CKR_ARGUMENTS_BAD;
239 *object = soft_token.object.objs[i];
240 return CKR_OK;
241 }
242
243 static int
attributes_match(const struct st_object * obj,const CK_ATTRIBUTE * attributes,CK_ULONG num_attributes)244 attributes_match(const struct st_object *obj,
245 const CK_ATTRIBUTE *attributes,
246 CK_ULONG num_attributes)
247 {
248 CK_ULONG i;
249 int j;
250 st_logf("attributes_match: %ld\n", (unsigned long)OBJECT_ID(obj));
251
252 for (i = 0; i < num_attributes; i++) {
253 int match = 0;
254 for (j = 0; j < obj->num_attributes; j++) {
255 if (attributes[i].type == obj->attrs[j].attribute.type &&
256 attributes[i].ulValueLen == obj->attrs[j].attribute.ulValueLen &&
257 memcmp(attributes[i].pValue, obj->attrs[j].attribute.pValue,
258 attributes[i].ulValueLen) == 0) {
259 match = 1;
260 break;
261 }
262 }
263 if (match == 0) {
264 st_logf("type %lu attribute have no match\n", attributes[i].type);
265 return 0;
266 }
267 }
268 st_logf("attribute matches\n");
269 return 1;
270 }
271
272 static void
print_attributes(const CK_ATTRIBUTE * attributes,CK_ULONG num_attributes)273 print_attributes(const CK_ATTRIBUTE *attributes,
274 CK_ULONG num_attributes)
275 {
276 CK_ULONG i;
277
278 st_logf("find objects: attrs: %lu\n", (unsigned long)num_attributes);
279
280 for (i = 0; i < num_attributes; i++) {
281 st_logf(" type: ");
282 switch (attributes[i].type) {
283 case CKA_TOKEN: {
284 CK_BBOOL *ck_true;
285 if (attributes[i].ulValueLen != sizeof(CK_BBOOL)) {
286 application_error("token attribute wrong length\n");
287 break;
288 }
289 ck_true = attributes[i].pValue;
290 st_logf("token: %s", *ck_true ? "TRUE" : "FALSE");
291 break;
292 }
293 case CKA_CLASS: {
294 CK_OBJECT_CLASS *class;
295 if (attributes[i].ulValueLen != sizeof(CK_ULONG)) {
296 application_error("class attribute wrong length\n");
297 break;
298 }
299 class = attributes[i].pValue;
300 st_logf("class ");
301 switch (*class) {
302 case CKO_CERTIFICATE:
303 st_logf("certificate");
304 break;
305 case CKO_PUBLIC_KEY:
306 st_logf("public key");
307 break;
308 case CKO_PRIVATE_KEY:
309 st_logf("private key");
310 break;
311 case CKO_SECRET_KEY:
312 st_logf("secret key");
313 break;
314 case CKO_DOMAIN_PARAMETERS:
315 st_logf("domain parameters");
316 break;
317 default:
318 st_logf("[class %lx]", (long unsigned)*class);
319 break;
320 }
321 break;
322 }
323 case CKA_PRIVATE:
324 st_logf("private");
325 break;
326 case CKA_LABEL:
327 st_logf("label");
328 break;
329 case CKA_APPLICATION:
330 st_logf("application");
331 break;
332 case CKA_VALUE:
333 st_logf("value");
334 break;
335 case CKA_ID:
336 st_logf("id");
337 break;
338 default:
339 st_logf("[unknown 0x%08lx]", (unsigned long)attributes[i].type);
340 break;
341 }
342 st_logf("\n");
343 }
344 }
345
346 static void
free_st_object(struct st_object * o)347 free_st_object(struct st_object *o)
348 {
349 int i;
350
351 for (i = 0; i < o->num_attributes; i++)
352 free(o->attrs[i].attribute.pValue);
353 free(o->attrs);
354 if (o->type == STO_T_CERTIFICATE) {
355 X509_free(o->u.cert);
356 } else if (o->type == STO_T_PRIVATE_KEY) {
357 free(o->u.private_key.file);
358 EVP_PKEY_free(o->u.private_key.key);
359 X509_free(o->u.private_key.cert);
360 } else if (o->type == STO_T_PUBLIC_KEY) {
361 EVP_PKEY_free(o->u.public_key);
362 }
363 free(o);
364 }
365
366 static struct st_object *
add_st_object(void)367 add_st_object(void)
368 {
369 struct st_object *o, **objs;
370
371 objs = realloc(soft_token.object.objs,
372 (soft_token.object.num_objs + 1) *
373 sizeof(soft_token.object.objs[0]));
374 if (objs == NULL)
375 return NULL;
376 soft_token.object.objs = objs;
377
378 o = calloc(1, sizeof(*o));
379 if (o == NULL)
380 return NULL;
381 o->attrs = NULL;
382 o->num_attributes = 0;
383 o->object_handle = soft_token.object.num_objs;
384
385 soft_token.object.objs[soft_token.object.num_objs++] = o;
386 return o;
387 }
388
389 static CK_RV
add_object_attribute(struct st_object * o,int secret,CK_ATTRIBUTE_TYPE type,CK_VOID_PTR pValue,CK_ULONG ulValueLen)390 add_object_attribute(struct st_object *o,
391 int secret,
392 CK_ATTRIBUTE_TYPE type,
393 CK_VOID_PTR pValue,
394 CK_ULONG ulValueLen)
395 {
396 struct st_attr *a;
397 int i;
398
399 i = o->num_attributes;
400 a = realloc(o->attrs, (i + 1) * sizeof(o->attrs[0]));
401 if (a == NULL)
402 return CKR_DEVICE_MEMORY;
403 o->attrs = a;
404 o->attrs[i].secret = secret;
405 o->attrs[i].attribute.type = type;
406 o->attrs[i].attribute.pValue = malloc(ulValueLen);
407 if (o->attrs[i].attribute.pValue == NULL && ulValueLen != 0)
408 return CKR_DEVICE_MEMORY;
409 memcpy(o->attrs[i].attribute.pValue, pValue, ulValueLen);
410 o->attrs[i].attribute.ulValueLen = ulValueLen;
411 o->num_attributes++;
412
413 return CKR_OK;
414 }
415
416 #ifdef HAVE_EVP_PKEY_GET_BN_PARAM
417
418 /* Declare owner pointers since EVP_PKEY_get_bn_param() gives us copies. */
419 #define DECLARE_BIGNUM(name) BIGNUM *name = NULL
420 #define RELEASE_BIGNUM(bn) BN_clear_free(bn)
421 static CK_RV
get_bignums(EVP_PKEY * key,BIGNUM ** n,BIGNUM ** e)422 get_bignums(EVP_PKEY *key, BIGNUM **n, BIGNUM **e)
423 {
424 if (EVP_PKEY_get_bn_param(key, "n", n) == 0 ||
425 EVP_PKEY_get_bn_param(key, "e", e) == 0)
426 return CKR_DEVICE_ERROR;
427
428 return CKR_OK;
429 }
430
431 #else
432
433 /* Declare const pointers since the old API gives us aliases. */
434 #define DECLARE_BIGNUM(name) const BIGNUM *name
435 #define RELEASE_BIGNUM(bn)
436 static CK_RV
get_bignums(EVP_PKEY * key,const BIGNUM ** n,const BIGNUM ** e)437 get_bignums(EVP_PKEY *key, const BIGNUM **n, const BIGNUM **e)
438 {
439 const RSA *rsa;
440
441 rsa = EVP_PKEY_get0_RSA(key);
442 RSA_get0_key(rsa, n, e, NULL);
443
444 return CKR_OK;
445 }
446
447 #endif
448
449 static CK_RV
add_pubkey_info(struct st_object * o,CK_KEY_TYPE key_type,EVP_PKEY * key)450 add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key)
451 {
452 CK_BYTE *modulus = NULL, *exponent = 0;
453 size_t modulus_len = 0, exponent_len = 0;
454 CK_ULONG modulus_bits = 0;
455 CK_RV ret;
456 DECLARE_BIGNUM(n);
457 DECLARE_BIGNUM(e);
458
459 if (key_type != CKK_RSA)
460 abort();
461
462 ret = get_bignums(key, &n, &e);
463 if (ret != CKR_OK)
464 goto done;
465
466 modulus_bits = BN_num_bits(n);
467 modulus_len = BN_num_bytes(n);
468 exponent_len = BN_num_bytes(e);
469
470 modulus = malloc(modulus_len);
471 exponent = malloc(exponent_len);
472 if (modulus == NULL || exponent == NULL) {
473 ret = CKR_DEVICE_MEMORY;
474 goto done;
475 }
476
477 BN_bn2bin(n, modulus);
478 BN_bn2bin(e, exponent);
479
480 add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len);
481 add_object_attribute(o, 0, CKA_MODULUS_BITS, &modulus_bits,
482 sizeof(modulus_bits));
483 add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT, exponent, exponent_len);
484
485 ret = CKR_OK;
486 done:
487 free(modulus);
488 free(exponent);
489 RELEASE_BIGNUM(n);
490 RELEASE_BIGNUM(e);
491 return ret;
492 }
493
494 static int
pem_callback(char * buf,int num,int w,void * key)495 pem_callback(char *buf, int num, int w, void *key)
496 {
497 return -1;
498 }
499
500
501 static CK_RV
add_certificate(char * label,const char * cert_file,const char * private_key_file,char * id,int anchor)502 add_certificate(char *label,
503 const char *cert_file,
504 const char *private_key_file,
505 char *id,
506 int anchor)
507 {
508 struct st_object *o = NULL;
509 CK_BBOOL bool_true = CK_TRUE;
510 CK_BBOOL bool_false = CK_FALSE;
511 CK_OBJECT_CLASS c;
512 CK_CERTIFICATE_TYPE cert_type = CKC_X_509;
513 CK_KEY_TYPE key_type;
514 CK_MECHANISM_TYPE mech_type;
515 void *cert_data = NULL;
516 size_t cert_length;
517 void *subject_data = NULL;
518 size_t subject_length;
519 void *issuer_data = NULL;
520 size_t issuer_length;
521 void *serial_data = NULL;
522 size_t serial_length;
523 CK_RV ret = CKR_GENERAL_ERROR;
524 X509 *cert;
525 EVP_PKEY *public_key;
526
527 size_t id_len = strlen(id);
528
529 {
530 FILE *f;
531
532 f = fopen(cert_file, "r");
533 if (f == NULL) {
534 st_logf("failed to open file %s\n", cert_file);
535 return CKR_GENERAL_ERROR;
536 }
537
538 cert = PEM_read_X509(f, NULL, NULL, NULL);
539 fclose(f);
540 if (cert == NULL) {
541 st_logf("failed reading PEM cert\n");
542 return CKR_GENERAL_ERROR;
543 }
544
545 OPENSSL_ASN1_MALLOC_ENCODE(X509, cert_data, cert_length, cert, ret);
546 if (ret)
547 goto out;
548
549 OPENSSL_ASN1_MALLOC_ENCODE(X509_NAME, issuer_data, issuer_length,
550 X509_get_issuer_name(cert), ret);
551 if (ret)
552 goto out;
553
554 OPENSSL_ASN1_MALLOC_ENCODE(X509_NAME, subject_data, subject_length,
555 X509_get_subject_name(cert), ret);
556 if (ret)
557 goto out;
558
559 OPENSSL_ASN1_MALLOC_ENCODE(ASN1_INTEGER, serial_data, serial_length,
560 X509_get_serialNumber(cert), ret);
561 if (ret)
562 goto out;
563
564 }
565
566 st_logf("done parsing, adding to internal structure\n");
567
568 o = add_st_object();
569 if (o == NULL) {
570 ret = CKR_DEVICE_MEMORY;
571 goto out;
572 }
573 o->type = STO_T_CERTIFICATE;
574 o->u.cert = X509_dup(cert);
575 if (o->u.cert == NULL) {
576 ret = CKR_DEVICE_MEMORY;
577 goto out;
578 }
579 public_key = X509_get_pubkey(o->u.cert);
580
581 switch (EVP_PKEY_base_id(public_key)) {
582 case EVP_PKEY_RSA:
583 key_type = CKK_RSA;
584 break;
585 case EVP_PKEY_DSA:
586 key_type = CKK_DSA;
587 break;
588 default:
589 st_logf("invalid key_type\n");
590 ret = CKR_GENERAL_ERROR;
591 goto out;
592 }
593
594 c = CKO_CERTIFICATE;
595 add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c));
596 add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true));
597 add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false));
598 add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false));
599 add_object_attribute(o, 0, CKA_LABEL, label, strlen(label));
600
601 add_object_attribute(o, 0, CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type));
602 add_object_attribute(o, 0, CKA_ID, id, id_len);
603
604 add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length);
605 add_object_attribute(o, 0, CKA_ISSUER, issuer_data, issuer_length);
606 add_object_attribute(o, 0, CKA_SERIAL_NUMBER, serial_data, serial_length);
607 add_object_attribute(o, 0, CKA_VALUE, cert_data, cert_length);
608 if (anchor)
609 add_object_attribute(o, 0, CKA_TRUSTED, &bool_true, sizeof(bool_true));
610 else
611 add_object_attribute(o, 0, CKA_TRUSTED, &bool_false, sizeof(bool_false));
612
613 st_logf("add cert ok: %lx\n", (unsigned long)OBJECT_ID(o));
614
615 o = add_st_object();
616 if (o == NULL) {
617 ret = CKR_DEVICE_MEMORY;
618 goto out;
619 }
620 o->type = STO_T_PUBLIC_KEY;
621 o->u.public_key = public_key;
622
623 c = CKO_PUBLIC_KEY;
624 add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c));
625 add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true));
626 add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false));
627 add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false));
628 add_object_attribute(o, 0, CKA_LABEL, label, strlen(label));
629
630 add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type));
631 add_object_attribute(o, 0, CKA_ID, id, id_len);
632 add_object_attribute(o, 0, CKA_START_DATE, "", 1); /* XXX */
633 add_object_attribute(o, 0, CKA_END_DATE, "", 1); /* XXX */
634 add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false));
635 add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false));
636 mech_type = CKM_RSA_X_509;
637 add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type));
638
639 add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length);
640 add_object_attribute(o, 0, CKA_ENCRYPT, &bool_true, sizeof(bool_true));
641 add_object_attribute(o, 0, CKA_VERIFY, &bool_true, sizeof(bool_true));
642 add_object_attribute(o, 0, CKA_VERIFY_RECOVER, &bool_false, sizeof(bool_false));
643 add_object_attribute(o, 0, CKA_WRAP, &bool_true, sizeof(bool_true));
644 add_object_attribute(o, 0, CKA_TRUSTED, &bool_true, sizeof(bool_true));
645
646 add_pubkey_info(o, key_type, public_key);
647
648 st_logf("add key ok: %lx\n", (unsigned long)OBJECT_ID(o));
649
650 if (private_key_file) {
651 CK_FLAGS flags;
652 FILE *f;
653
654 o = add_st_object();
655 if (o == NULL) {
656 ret = CKR_DEVICE_MEMORY;
657 goto out;
658 }
659 o->type = STO_T_PRIVATE_KEY;
660 o->u.private_key.file = strdup(private_key_file);
661 o->u.private_key.key = NULL;
662
663 o->u.private_key.cert = X509_dup(cert);
664 if (o->u.private_key.cert == NULL) {
665 ret = CKR_DEVICE_MEMORY;
666 goto out;
667 }
668
669 c = CKO_PRIVATE_KEY;
670 add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c));
671 add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true));
672 add_object_attribute(o, 0, CKA_PRIVATE, &bool_true, sizeof(bool_false));
673 add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false));
674 add_object_attribute(o, 0, CKA_LABEL, label, strlen(label));
675
676 add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type));
677 add_object_attribute(o, 0, CKA_ID, id, id_len);
678 add_object_attribute(o, 0, CKA_START_DATE, "", 1); /* XXX */
679 add_object_attribute(o, 0, CKA_END_DATE, "", 1); /* XXX */
680 add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false));
681 add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false));
682 mech_type = CKM_RSA_X_509;
683 add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type));
684
685 add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length);
686 add_object_attribute(o, 0, CKA_SENSITIVE, &bool_true, sizeof(bool_true));
687 add_object_attribute(o, 0, CKA_SECONDARY_AUTH, &bool_false, sizeof(bool_true));
688 flags = 0;
689 add_object_attribute(o, 0, CKA_AUTH_PIN_FLAGS, &flags, sizeof(flags));
690
691 add_object_attribute(o, 0, CKA_DECRYPT, &bool_true, sizeof(bool_true));
692 add_object_attribute(o, 0, CKA_SIGN, &bool_true, sizeof(bool_true));
693 add_object_attribute(o, 0, CKA_SIGN_RECOVER, &bool_false, sizeof(bool_false));
694 add_object_attribute(o, 0, CKA_UNWRAP, &bool_true, sizeof(bool_true));
695 add_object_attribute(o, 0, CKA_EXTRACTABLE, &bool_true, sizeof(bool_true));
696 add_object_attribute(o, 0, CKA_NEVER_EXTRACTABLE, &bool_false, sizeof(bool_false));
697
698 add_pubkey_info(o, key_type, public_key);
699
700 f = fopen(private_key_file, "r");
701 if (f == NULL) {
702 st_logf("failed to open private key\n");
703 return CKR_GENERAL_ERROR;
704 }
705
706 o->u.private_key.key = PEM_read_PrivateKey(f, NULL, pem_callback, NULL);
707 fclose(f);
708 if (o->u.private_key.key == NULL) {
709 st_logf("failed to read private key a startup\n");
710 /* don't bother with this failure for now,
711 fix it at C_Login time */;
712 } else {
713 /* XXX verify keytype */
714
715 if (X509_check_private_key(cert, o->u.private_key.key) != 1) {
716 EVP_PKEY_free(o->u.private_key.key);
717 o->u.private_key.key = NULL;
718 st_logf("private key doesn't verify\n");
719 } else {
720 st_logf("private key usable\n");
721 soft_token.flags.login_done = 1;
722 }
723 }
724 }
725
726 ret = CKR_OK;
727 out:
728 if (ret != CKR_OK) {
729 st_logf("something went wrong when adding cert!\n");
730
731 /* XXX wack o */;
732 }
733 free(cert_data);
734 free(serial_data);
735 free(issuer_data);
736 free(subject_data);
737 X509_free(cert);
738
739 return ret;
740 }
741
742 static void
find_object_final(struct session_state * state)743 find_object_final(struct session_state *state)
744 {
745 if (state->find.attributes) {
746 CK_ULONG i;
747
748 for (i = 0; i < state->find.num_attributes; i++) {
749 if (state->find.attributes[i].pValue)
750 free(state->find.attributes[i].pValue);
751 }
752 free(state->find.attributes);
753 state->find.attributes = NULL;
754 state->find.num_attributes = 0;
755 state->find.next_object = -1;
756 }
757 }
758
759 static void
reset_crypto_state(struct session_state * state)760 reset_crypto_state(struct session_state *state)
761 {
762 state->encrypt_object = -1;
763 if (state->encrypt_mechanism)
764 free(state->encrypt_mechanism);
765 state->encrypt_mechanism = NULL_PTR;
766 state->decrypt_object = -1;
767 if (state->decrypt_mechanism)
768 free(state->decrypt_mechanism);
769 state->decrypt_mechanism = NULL_PTR;
770 state->sign_object = -1;
771 if (state->sign_mechanism)
772 free(state->sign_mechanism);
773 state->sign_mechanism = NULL_PTR;
774 state->verify_object = -1;
775 if (state->verify_mechanism)
776 free(state->verify_mechanism);
777 state->verify_mechanism = NULL_PTR;
778 state->digest_object = -1;
779 }
780
781 static void
close_session(struct session_state * state)782 close_session(struct session_state *state)
783 {
784 if (state->find.attributes) {
785 application_error("application didn't do C_FindObjectsFinal\n");
786 find_object_final(state);
787 }
788
789 state->session_handle = CK_INVALID_HANDLE;
790 soft_token.application = NULL_PTR;
791 soft_token.notify = NULL_PTR;
792 reset_crypto_state(state);
793 }
794
795 static const char *
has_session(void)796 has_session(void)
797 {
798 return soft_token.open_sessions > 0 ? "yes" : "no";
799 }
800
801 static void
read_conf_file(const char * fn)802 read_conf_file(const char *fn)
803 {
804 char buf[1024], *cert, *key, *id, *label, *s, *p;
805 int anchor;
806 FILE *f;
807
808 f = fopen(fn, "r");
809 if (f == NULL) {
810 st_logf("can't open configuration file %s\n", fn);
811 return;
812 }
813
814 while(fgets(buf, sizeof(buf), f) != NULL) {
815 buf[strcspn(buf, "\n")] = '\0';
816
817 anchor = 0;
818
819 st_logf("line: %s\n", buf);
820
821 p = buf;
822 while (isspace(*p))
823 p++;
824 if (*p == '#')
825 continue;
826 while (isspace(*p))
827 p++;
828
829 s = NULL;
830 id = strtok_r(p, "\t", &s);
831 if (id == NULL)
832 continue;
833 label = strtok_r(NULL, "\t", &s);
834 if (label == NULL)
835 continue;
836 cert = strtok_r(NULL, "\t", &s);
837 if (cert == NULL)
838 continue;
839 key = strtok_r(NULL, "\t", &s);
840
841 /* XXX */
842 if (strcmp(id, "anchor") == 0) {
843 id = "\x00\x00";
844 anchor = 1;
845 }
846
847 st_logf("adding: %s\n", label);
848
849 add_certificate(label, cert, key, id, anchor);
850 }
851
852 fclose(f);
853 }
854
855 static CK_RV
func_not_supported(void)856 func_not_supported(void)
857 {
858 st_logf("function not supported\n");
859 return CKR_FUNCTION_NOT_SUPPORTED;
860 }
861
862 static char *
get_rcfilename()863 get_rcfilename()
864 {
865 struct passwd *pw;
866 const char *home = NULL;
867 char *fn;
868
869 if (getuid() == geteuid()) {
870 fn = getenv("SOFTPKCS11RC");
871 if (fn != NULL)
872 return strdup(fn);
873
874 home = getenv("HOME");
875 }
876
877 if (home == NULL) {
878 pw = getpwuid(getuid());
879 if (pw != NULL)
880 home = pw->pw_dir;
881 }
882
883 if (home == NULL)
884 return strdup("/etc/soft-token.rc");
885
886 if (asprintf(&fn, "%s/.soft-token.rc", home) < 0)
887 return NULL;
888 return fn;
889 }
890
891 CK_RV
C_Initialize(CK_VOID_PTR a)892 C_Initialize(CK_VOID_PTR a)
893 {
894 CK_C_INITIALIZE_ARGS_PTR args = a;
895 size_t i;
896 char *fn;
897
898 st_logf("Initialize\n");
899
900 OpenSSL_add_all_algorithms();
901 ERR_load_crypto_strings();
902
903 for (i = 0; i < MAX_NUM_SESSION; i++) {
904 soft_token.state[i].session_handle = CK_INVALID_HANDLE;
905 soft_token.state[i].find.attributes = NULL;
906 soft_token.state[i].find.num_attributes = 0;
907 soft_token.state[i].find.next_object = -1;
908 reset_crypto_state(&soft_token.state[i]);
909 }
910
911 soft_token.flags.hardware_slot = 1;
912 soft_token.flags.app_error_fatal = 0;
913 soft_token.flags.login_done = 0;
914
915 soft_token.object.objs = NULL;
916 soft_token.object.num_objs = 0;
917
918 soft_token.logfile = NULL;
919 #if 0
920 soft_token.logfile = stdout;
921 #endif
922 #if 0
923 soft_token.logfile = fopen("/tmp/log-pkcs11.txt", "a");
924 #endif
925
926 if (a != NULL_PTR) {
927 st_logf("\tCreateMutex:\t%p\n", args->CreateMutex);
928 st_logf("\tDestroyMutext\t%p\n", args->DestroyMutex);
929 st_logf("\tLockMutext\t%p\n", args->LockMutex);
930 st_logf("\tUnlockMutext\t%p\n", args->UnlockMutex);
931 st_logf("\tFlags\t%04x\n", (unsigned int)args->flags);
932 }
933
934 soft_token.next_session_handle = 1;
935
936 fn = get_rcfilename();
937 if (fn == NULL)
938 return CKR_DEVICE_MEMORY;
939 read_conf_file(fn);
940 free(fn);
941 return CKR_OK;
942 }
943
944 CK_RV
C_Finalize(CK_VOID_PTR args)945 C_Finalize(CK_VOID_PTR args)
946 {
947 size_t i;
948 int j;
949
950 st_logf("Finalize\n");
951
952 for (i = 0; i < MAX_NUM_SESSION; i++) {
953 if (soft_token.state[i].session_handle != CK_INVALID_HANDLE) {
954 application_error("application finalized without "
955 "closing session\n");
956 close_session(&soft_token.state[i]);
957 }
958 }
959
960 for (j = 0; j < soft_token.object.num_objs; j++)
961 free_st_object(soft_token.object.objs[j]);
962 free(soft_token.object.objs);
963 soft_token.object.objs = NULL;
964 soft_token.object.num_objs = 0;
965
966 return CKR_OK;
967 }
968
969 CK_RV
C_GetInfo(CK_INFO_PTR args)970 C_GetInfo(CK_INFO_PTR args)
971 {
972 st_logf("GetInfo\n");
973
974 memset(args, 17, sizeof(*args));
975 args->cryptokiVersion.major = 2;
976 args->cryptokiVersion.minor = 10;
977 snprintf_fill((char *)args->manufacturerID,
978 sizeof(args->manufacturerID),
979 ' ',
980 "SoftToken");
981 snprintf_fill((char *)args->libraryDescription,
982 sizeof(args->libraryDescription), ' ',
983 "SoftToken");
984 args->libraryVersion.major = 1;
985 args->libraryVersion.minor = 8;
986
987 return CKR_OK;
988 }
989
990 extern CK_FUNCTION_LIST funcs;
991
992 CK_RV
C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)993 C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
994 {
995 *ppFunctionList = &funcs;
996 return CKR_OK;
997 }
998
999 CK_RV
C_GetSlotList(CK_BBOOL tokenPresent,CK_SLOT_ID_PTR pSlotList,CK_ULONG_PTR pulCount)1000 C_GetSlotList(CK_BBOOL tokenPresent,
1001 CK_SLOT_ID_PTR pSlotList,
1002 CK_ULONG_PTR pulCount)
1003 {
1004 st_logf("GetSlotList: %s\n",
1005 tokenPresent ? "tokenPresent" : "token not Present");
1006 if (pSlotList)
1007 pSlotList[0] = 1;
1008 *pulCount = 1;
1009 return CKR_OK;
1010 }
1011
1012 CK_RV
C_GetSlotInfo(CK_SLOT_ID slotID,CK_SLOT_INFO_PTR pInfo)1013 C_GetSlotInfo(CK_SLOT_ID slotID,
1014 CK_SLOT_INFO_PTR pInfo)
1015 {
1016 st_logf("GetSlotInfo: slot: %d : %s\n", (int)slotID, has_session());
1017
1018 memset(pInfo, 18, sizeof(*pInfo));
1019
1020 if (slotID != 1)
1021 return CKR_ARGUMENTS_BAD;
1022
1023 snprintf_fill((char *)pInfo->slotDescription,
1024 sizeof(pInfo->slotDescription),
1025 ' ',
1026 "SoftToken (slot)");
1027 snprintf_fill((char *)pInfo->manufacturerID,
1028 sizeof(pInfo->manufacturerID),
1029 ' ',
1030 "SoftToken (slot)");
1031 pInfo->flags = CKF_TOKEN_PRESENT;
1032 if (soft_token.flags.hardware_slot)
1033 pInfo->flags |= CKF_HW_SLOT;
1034 pInfo->hardwareVersion.major = 1;
1035 pInfo->hardwareVersion.minor = 0;
1036 pInfo->firmwareVersion.major = 1;
1037 pInfo->firmwareVersion.minor = 0;
1038
1039 return CKR_OK;
1040 }
1041
1042 CK_RV
C_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)1043 C_GetTokenInfo(CK_SLOT_ID slotID,
1044 CK_TOKEN_INFO_PTR pInfo)
1045 {
1046 st_logf("GetTokenInfo: %s\n", has_session());
1047
1048 memset(pInfo, 19, sizeof(*pInfo));
1049
1050 snprintf_fill((char *)pInfo->label,
1051 sizeof(pInfo->label),
1052 ' ',
1053 "SoftToken (token)");
1054 snprintf_fill((char *)pInfo->manufacturerID,
1055 sizeof(pInfo->manufacturerID),
1056 ' ',
1057 "SoftToken (token)");
1058 snprintf_fill((char *)pInfo->model,
1059 sizeof(pInfo->model),
1060 ' ',
1061 "SoftToken (token)");
1062 snprintf_fill((char *)pInfo->serialNumber,
1063 sizeof(pInfo->serialNumber),
1064 ' ',
1065 "4711");
1066 pInfo->flags =
1067 CKF_TOKEN_INITIALIZED |
1068 CKF_USER_PIN_INITIALIZED;
1069
1070 if (soft_token.flags.login_done == 0)
1071 pInfo->flags |= CKF_LOGIN_REQUIRED;
1072
1073 /* CFK_RNG |
1074 CKF_RESTORE_KEY_NOT_NEEDED |
1075 */
1076 pInfo->ulMaxSessionCount = MAX_NUM_SESSION;
1077 pInfo->ulSessionCount = soft_token.open_sessions;
1078 pInfo->ulMaxRwSessionCount = MAX_NUM_SESSION;
1079 pInfo->ulRwSessionCount = soft_token.open_sessions;
1080 pInfo->ulMaxPinLen = 1024;
1081 pInfo->ulMinPinLen = 0;
1082 pInfo->ulTotalPublicMemory = 4711;
1083 pInfo->ulFreePublicMemory = 4712;
1084 pInfo->ulTotalPrivateMemory = 4713;
1085 pInfo->ulFreePrivateMemory = 4714;
1086 pInfo->hardwareVersion.major = 2;
1087 pInfo->hardwareVersion.minor = 0;
1088 pInfo->firmwareVersion.major = 2;
1089 pInfo->firmwareVersion.minor = 0;
1090
1091 return CKR_OK;
1092 }
1093
1094 CK_RV
C_GetMechanismList(CK_SLOT_ID slotID,CK_MECHANISM_TYPE_PTR pMechanismList,CK_ULONG_PTR pulCount)1095 C_GetMechanismList(CK_SLOT_ID slotID,
1096 CK_MECHANISM_TYPE_PTR pMechanismList,
1097 CK_ULONG_PTR pulCount)
1098 {
1099 st_logf("GetMechanismList\n");
1100
1101 *pulCount = 2;
1102 if (pMechanismList == NULL_PTR)
1103 return CKR_OK;
1104 pMechanismList[0] = CKM_RSA_X_509;
1105 pMechanismList[1] = CKM_RSA_PKCS;
1106
1107 return CKR_OK;
1108 }
1109
1110 CK_RV
C_GetMechanismInfo(CK_SLOT_ID slotID,CK_MECHANISM_TYPE type,CK_MECHANISM_INFO_PTR pInfo)1111 C_GetMechanismInfo(CK_SLOT_ID slotID,
1112 CK_MECHANISM_TYPE type,
1113 CK_MECHANISM_INFO_PTR pInfo)
1114 {
1115 st_logf("GetMechanismInfo: slot %d type: %d\n",
1116 (int)slotID, (int)type);
1117 return CKR_FUNCTION_NOT_SUPPORTED;
1118 }
1119
1120 CK_RV
C_InitToken(CK_SLOT_ID slotID,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen,CK_UTF8CHAR_PTR pLabel)1121 C_InitToken(CK_SLOT_ID slotID,
1122 CK_UTF8CHAR_PTR pPin,
1123 CK_ULONG ulPinLen,
1124 CK_UTF8CHAR_PTR pLabel)
1125 {
1126 st_logf("InitToken: slot %d\n", (int)slotID);
1127 return CKR_FUNCTION_NOT_SUPPORTED;
1128 }
1129
1130 CK_RV
C_OpenSession(CK_SLOT_ID slotID,CK_FLAGS flags,CK_VOID_PTR pApplication,CK_NOTIFY Notify,CK_SESSION_HANDLE_PTR phSession)1131 C_OpenSession(CK_SLOT_ID slotID,
1132 CK_FLAGS flags,
1133 CK_VOID_PTR pApplication,
1134 CK_NOTIFY Notify,
1135 CK_SESSION_HANDLE_PTR phSession)
1136 {
1137 size_t i;
1138
1139 st_logf("OpenSession: slot: %d\n", (int)slotID);
1140
1141 if (soft_token.open_sessions == MAX_NUM_SESSION)
1142 return CKR_SESSION_COUNT;
1143
1144 soft_token.application = pApplication;
1145 soft_token.notify = Notify;
1146
1147 for (i = 0; i < MAX_NUM_SESSION; i++)
1148 if (soft_token.state[i].session_handle == CK_INVALID_HANDLE)
1149 break;
1150 if (i == MAX_NUM_SESSION)
1151 abort();
1152
1153 soft_token.open_sessions++;
1154
1155 soft_token.state[i].session_handle = soft_token.next_session_handle++;
1156 *phSession = soft_token.state[i].session_handle;
1157
1158 return CKR_OK;
1159 }
1160
1161 CK_RV
C_CloseSession(CK_SESSION_HANDLE hSession)1162 C_CloseSession(CK_SESSION_HANDLE hSession)
1163 {
1164 struct session_state *state;
1165 st_logf("CloseSession\n");
1166
1167 if (verify_session_handle(hSession, &state) != CKR_OK)
1168 application_error("closed session not open");
1169 else
1170 close_session(state);
1171
1172 return CKR_OK;
1173 }
1174
1175 CK_RV
C_CloseAllSessions(CK_SLOT_ID slotID)1176 C_CloseAllSessions(CK_SLOT_ID slotID)
1177 {
1178 size_t i;
1179
1180 st_logf("CloseAllSessions\n");
1181
1182 for (i = 0; i < MAX_NUM_SESSION; i++)
1183 if (soft_token.state[i].session_handle != CK_INVALID_HANDLE)
1184 close_session(&soft_token.state[i]);
1185
1186 return CKR_OK;
1187 }
1188
1189 CK_RV
C_GetSessionInfo(CK_SESSION_HANDLE hSession,CK_SESSION_INFO_PTR pInfo)1190 C_GetSessionInfo(CK_SESSION_HANDLE hSession,
1191 CK_SESSION_INFO_PTR pInfo)
1192 {
1193 st_logf("GetSessionInfo\n");
1194
1195 VERIFY_SESSION_HANDLE(hSession, NULL);
1196
1197 memset(pInfo, 20, sizeof(*pInfo));
1198
1199 pInfo->slotID = 1;
1200 if (soft_token.flags.login_done)
1201 pInfo->state = CKS_RO_USER_FUNCTIONS;
1202 else
1203 pInfo->state = CKS_RO_PUBLIC_SESSION;
1204 pInfo->flags = CKF_SERIAL_SESSION;
1205 pInfo->ulDeviceError = 0;
1206
1207 return CKR_OK;
1208 }
1209
1210 CK_RV
C_Login(CK_SESSION_HANDLE hSession,CK_USER_TYPE userType,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen)1211 C_Login(CK_SESSION_HANDLE hSession,
1212 CK_USER_TYPE userType,
1213 CK_UTF8CHAR_PTR pPin,
1214 CK_ULONG ulPinLen)
1215 {
1216 char *pin = NULL;
1217 int i;
1218
1219 st_logf("Login\n");
1220
1221 VERIFY_SESSION_HANDLE(hSession, NULL);
1222
1223 if (pPin != NULL_PTR) {
1224 if (asprintf(&pin, "%.*s", (int)ulPinLen, pPin) < 0)
1225 return CKR_DEVICE_MEMORY;
1226 st_logf("type: %d password: %s\n", (int)userType, pin);
1227 }
1228
1229 for (i = 0; i < soft_token.object.num_objs; i++) {
1230 struct st_object *o = soft_token.object.objs[i];
1231 FILE *f;
1232
1233 if (o->type != STO_T_PRIVATE_KEY)
1234 continue;
1235
1236 if (o->u.private_key.key)
1237 continue;
1238
1239 f = fopen(o->u.private_key.file, "r");
1240 if (f == NULL) {
1241 st_logf("can't open private file: %s\n", o->u.private_key.file);
1242 continue;
1243 }
1244
1245 o->u.private_key.key = PEM_read_PrivateKey(f, NULL, NULL, pin);
1246 fclose(f);
1247 if (o->u.private_key.key == NULL) {
1248 st_logf("failed to read key: %s error: %s\n",
1249 o->u.private_key.file,
1250 ERR_error_string(ERR_get_error(), NULL));
1251 /* just ignore failure */;
1252 continue;
1253 }
1254
1255 /* XXX check keytype */
1256
1257 if (X509_check_private_key(o->u.private_key.cert, o->u.private_key.key) != 1) {
1258 EVP_PKEY_free(o->u.private_key.key);
1259 o->u.private_key.key = NULL;
1260 st_logf("private key %s doesn't verify\n", o->u.private_key.file);
1261 continue;
1262 }
1263
1264 soft_token.flags.login_done = 1;
1265 }
1266 free(pin);
1267
1268 return soft_token.flags.login_done ? CKR_OK : CKR_PIN_INCORRECT;
1269 }
1270
1271 CK_RV
C_Logout(CK_SESSION_HANDLE hSession)1272 C_Logout(CK_SESSION_HANDLE hSession)
1273 {
1274 st_logf("Logout\n");
1275 VERIFY_SESSION_HANDLE(hSession, NULL);
1276 return CKR_FUNCTION_NOT_SUPPORTED;
1277 }
1278
1279 CK_RV
C_GetObjectSize(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ULONG_PTR pulSize)1280 C_GetObjectSize(CK_SESSION_HANDLE hSession,
1281 CK_OBJECT_HANDLE hObject,
1282 CK_ULONG_PTR pulSize)
1283 {
1284 st_logf("GetObjectSize\n");
1285 VERIFY_SESSION_HANDLE(hSession, NULL);
1286 return CKR_FUNCTION_NOT_SUPPORTED;
1287 }
1288
1289 CK_RV
C_GetAttributeValue(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)1290 C_GetAttributeValue(CK_SESSION_HANDLE hSession,
1291 CK_OBJECT_HANDLE hObject,
1292 CK_ATTRIBUTE_PTR pTemplate,
1293 CK_ULONG ulCount)
1294 {
1295 struct session_state *state;
1296 struct st_object *obj;
1297 CK_ULONG i;
1298 CK_RV ret;
1299 int j;
1300
1301 st_logf("GetAttributeValue: %lx\n",
1302 (unsigned long)HANDLE_OBJECT_ID(hObject));
1303 VERIFY_SESSION_HANDLE(hSession, &state);
1304
1305 if ((ret = object_handle_to_object(hObject, &obj)) != CKR_OK) {
1306 st_logf("object not found: %lx\n",
1307 (unsigned long)HANDLE_OBJECT_ID(hObject));
1308 return ret;
1309 }
1310
1311 for (i = 0; i < ulCount; i++) {
1312 st_logf(" getting 0x%08lx\n", (unsigned long)pTemplate[i].type);
1313 for (j = 0; j < obj->num_attributes; j++) {
1314 if (obj->attrs[j].secret) {
1315 pTemplate[i].ulValueLen = (CK_ULONG)-1;
1316 break;
1317 }
1318 if (pTemplate[i].type == obj->attrs[j].attribute.type) {
1319 if (pTemplate[i].pValue != NULL_PTR && obj->attrs[j].secret == 0) {
1320 if (pTemplate[i].ulValueLen >= obj->attrs[j].attribute.ulValueLen)
1321 memcpy(pTemplate[i].pValue, obj->attrs[j].attribute.pValue,
1322 obj->attrs[j].attribute.ulValueLen);
1323 }
1324 pTemplate[i].ulValueLen = obj->attrs[j].attribute.ulValueLen;
1325 break;
1326 }
1327 }
1328 if (j == obj->num_attributes) {
1329 st_logf("key type: 0x%08lx not found\n", (unsigned long)pTemplate[i].type);
1330 pTemplate[i].ulValueLen = (CK_ULONG)-1;
1331 }
1332
1333 }
1334 return CKR_OK;
1335 }
1336
1337 CK_RV
C_FindObjectsInit(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)1338 C_FindObjectsInit(CK_SESSION_HANDLE hSession,
1339 CK_ATTRIBUTE_PTR pTemplate,
1340 CK_ULONG ulCount)
1341 {
1342 struct session_state *state;
1343
1344 st_logf("FindObjectsInit\n");
1345
1346 VERIFY_SESSION_HANDLE(hSession, &state);
1347
1348 if (state->find.next_object != -1) {
1349 application_error("application didn't do C_FindObjectsFinal\n");
1350 find_object_final(state);
1351 }
1352 if (ulCount) {
1353 CK_ULONG i;
1354
1355 print_attributes(pTemplate, ulCount);
1356
1357 state->find.attributes =
1358 calloc(1, ulCount * sizeof(state->find.attributes[0]));
1359 if (state->find.attributes == NULL)
1360 return CKR_DEVICE_MEMORY;
1361 for (i = 0; i < ulCount; i++) {
1362 state->find.attributes[i].pValue =
1363 malloc(pTemplate[i].ulValueLen);
1364 if (state->find.attributes[i].pValue == NULL) {
1365 find_object_final(state);
1366 return CKR_DEVICE_MEMORY;
1367 }
1368 memcpy(state->find.attributes[i].pValue,
1369 pTemplate[i].pValue, pTemplate[i].ulValueLen);
1370 state->find.attributes[i].type = pTemplate[i].type;
1371 state->find.attributes[i].ulValueLen = pTemplate[i].ulValueLen;
1372 }
1373 state->find.num_attributes = ulCount;
1374 state->find.next_object = 0;
1375 } else {
1376 st_logf("find all objects\n");
1377 state->find.attributes = NULL;
1378 state->find.num_attributes = 0;
1379 state->find.next_object = 0;
1380 }
1381
1382 return CKR_OK;
1383 }
1384
1385 CK_RV
C_FindObjects(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE_PTR phObject,CK_ULONG ulMaxObjectCount,CK_ULONG_PTR pulObjectCount)1386 C_FindObjects(CK_SESSION_HANDLE hSession,
1387 CK_OBJECT_HANDLE_PTR phObject,
1388 CK_ULONG ulMaxObjectCount,
1389 CK_ULONG_PTR pulObjectCount)
1390 {
1391 struct session_state *state;
1392 int i;
1393
1394 st_logf("FindObjects\n");
1395
1396 VERIFY_SESSION_HANDLE(hSession, &state);
1397
1398 if (state->find.next_object == -1) {
1399 application_error("application didn't do C_FindObjectsInit\n");
1400 return CKR_ARGUMENTS_BAD;
1401 }
1402 if (ulMaxObjectCount == 0) {
1403 application_error("application asked for 0 objects\n");
1404 return CKR_ARGUMENTS_BAD;
1405 }
1406 *pulObjectCount = 0;
1407 for (i = state->find.next_object; i < soft_token.object.num_objs; i++) {
1408 st_logf("FindObjects: %d\n", i);
1409 state->find.next_object = i + 1;
1410 if (attributes_match(soft_token.object.objs[i],
1411 state->find.attributes,
1412 state->find.num_attributes)) {
1413 *phObject++ = soft_token.object.objs[i]->object_handle;
1414 ulMaxObjectCount--;
1415 (*pulObjectCount)++;
1416 if (ulMaxObjectCount == 0)
1417 break;
1418 }
1419 }
1420 return CKR_OK;
1421 }
1422
1423 CK_RV
C_FindObjectsFinal(CK_SESSION_HANDLE hSession)1424 C_FindObjectsFinal(CK_SESSION_HANDLE hSession)
1425 {
1426 struct session_state *state;
1427
1428 st_logf("FindObjectsFinal\n");
1429 VERIFY_SESSION_HANDLE(hSession, &state);
1430 find_object_final(state);
1431 return CKR_OK;
1432 }
1433
1434 static CK_RV
commonInit(CK_ATTRIBUTE * attr_match,int attr_match_len,const CK_MECHANISM_TYPE * mechs,int mechs_len,const CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey,struct st_object ** o)1435 commonInit(CK_ATTRIBUTE *attr_match, int attr_match_len,
1436 const CK_MECHANISM_TYPE *mechs, int mechs_len,
1437 const CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey,
1438 struct st_object **o)
1439 {
1440 CK_RV ret;
1441 int i;
1442
1443 *o = NULL;
1444 if ((ret = object_handle_to_object(hKey, o)) != CKR_OK)
1445 return ret;
1446
1447 ret = attributes_match(*o, attr_match, attr_match_len);
1448 if (!ret) {
1449 application_error("called commonInit on key that doesn't "
1450 "support required attr");
1451 return CKR_ARGUMENTS_BAD;
1452 }
1453
1454 for (i = 0; i < mechs_len; i++)
1455 if (mechs[i] == pMechanism->mechanism)
1456 break;
1457 if (i == mechs_len) {
1458 application_error("called mech (%08lx) not supported\n",
1459 pMechanism->mechanism);
1460 return CKR_ARGUMENTS_BAD;
1461 }
1462 return CKR_OK;
1463 }
1464
1465
1466 static CK_RV
dup_mechanism(CK_MECHANISM_PTR * dup,const CK_MECHANISM_PTR pMechanism)1467 dup_mechanism(CK_MECHANISM_PTR *dup, const CK_MECHANISM_PTR pMechanism)
1468 {
1469 CK_MECHANISM_PTR p;
1470
1471 p = malloc(sizeof(*p));
1472 if (p == NULL)
1473 return CKR_DEVICE_MEMORY;
1474
1475 if (*dup)
1476 free(*dup);
1477 *dup = p;
1478 memcpy(p, pMechanism, sizeof(*p));
1479
1480 return CKR_OK;
1481 }
1482
1483
1484 CK_RV
C_EncryptInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)1485 C_EncryptInit(CK_SESSION_HANDLE hSession,
1486 CK_MECHANISM_PTR pMechanism,
1487 CK_OBJECT_HANDLE hKey)
1488 {
1489 struct session_state *state;
1490 CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 };
1491 CK_BBOOL bool_true = CK_TRUE;
1492 CK_ATTRIBUTE attr[] = {
1493 { CKA_ENCRYPT, &bool_true, sizeof(bool_true) }
1494 };
1495 struct st_object *o;
1496 CK_RV ret;
1497
1498 st_logf("EncryptInit\n");
1499 VERIFY_SESSION_HANDLE(hSession, &state);
1500
1501 ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
1502 mechs, sizeof(mechs)/sizeof(mechs[0]),
1503 pMechanism, hKey, &o);
1504 if (ret)
1505 return ret;
1506
1507 ret = dup_mechanism(&state->encrypt_mechanism, pMechanism);
1508 if (ret == CKR_OK)
1509 state->encrypt_object = OBJECT_ID(o);
1510
1511 return ret;
1512 }
1513
1514 CK_RV
C_Encrypt(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen)1515 C_Encrypt(CK_SESSION_HANDLE hSession,
1516 CK_BYTE_PTR pData,
1517 CK_ULONG ulDataLen,
1518 CK_BYTE_PTR pEncryptedData,
1519 CK_ULONG_PTR pulEncryptedDataLen)
1520 {
1521 struct session_state *state;
1522 struct st_object *o;
1523 void *buffer = NULL;
1524 CK_RV ret;
1525 size_t buffer_len = 0;
1526 int padding;
1527 EVP_PKEY_CTX *ctx = NULL;
1528
1529 st_logf("Encrypt\n");
1530
1531 VERIFY_SESSION_HANDLE(hSession, &state);
1532
1533 if (state->encrypt_object == -1)
1534 return CKR_ARGUMENTS_BAD;
1535
1536 o = soft_token.object.objs[state->encrypt_object];
1537
1538 if (o->u.public_key == NULL) {
1539 st_logf("public key NULL\n");
1540 return CKR_ARGUMENTS_BAD;
1541 }
1542
1543 if (pulEncryptedDataLen == NULL) {
1544 st_logf("pulEncryptedDataLen NULL\n");
1545 ret = CKR_ARGUMENTS_BAD;
1546 goto out;
1547 }
1548
1549 if (pData == NULL) {
1550 st_logf("data NULL\n");
1551 ret = CKR_ARGUMENTS_BAD;
1552 goto out;
1553 }
1554
1555 switch(state->encrypt_mechanism->mechanism) {
1556 case CKM_RSA_PKCS:
1557 padding = RSA_PKCS1_PADDING;
1558 break;
1559 case CKM_RSA_X_509:
1560 padding = RSA_NO_PADDING;
1561 break;
1562 default:
1563 ret = CKR_FUNCTION_NOT_SUPPORTED;
1564 goto out;
1565 }
1566
1567 ctx = EVP_PKEY_CTX_new(o->u.public_key, NULL);
1568 if (ctx == NULL || EVP_PKEY_encrypt_init(ctx) <= 0 ||
1569 EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
1570 EVP_PKEY_encrypt(ctx, NULL, &buffer_len, pData, ulDataLen) <= 0) {
1571 ret = CKR_DEVICE_ERROR;
1572 goto out;
1573 }
1574
1575 buffer = OPENSSL_malloc(buffer_len);
1576 if (buffer == NULL) {
1577 ret = CKR_DEVICE_MEMORY;
1578 goto out;
1579 }
1580
1581 if (EVP_PKEY_encrypt(ctx, buffer, &buffer_len, pData, ulDataLen) <= 0) {
1582 ret = CKR_DEVICE_ERROR;
1583 goto out;
1584 }
1585 st_logf("Encrypt done\n");
1586
1587 if (pEncryptedData != NULL)
1588 memcpy(pEncryptedData, buffer, buffer_len);
1589 *pulEncryptedDataLen = buffer_len;
1590
1591 ret = CKR_OK;
1592 out:
1593 OPENSSL_cleanse(buffer, buffer_len);
1594 OPENSSL_free(buffer);
1595 EVP_PKEY_CTX_free(ctx);
1596 return ret;
1597 }
1598
1599 CK_RV
C_EncryptUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen,CK_BYTE_PTR pEncryptedPart,CK_ULONG_PTR pulEncryptedPartLen)1600 C_EncryptUpdate(CK_SESSION_HANDLE hSession,
1601 CK_BYTE_PTR pPart,
1602 CK_ULONG ulPartLen,
1603 CK_BYTE_PTR pEncryptedPart,
1604 CK_ULONG_PTR pulEncryptedPartLen)
1605 {
1606 st_logf("EncryptUpdate\n");
1607 VERIFY_SESSION_HANDLE(hSession, NULL);
1608 return CKR_FUNCTION_NOT_SUPPORTED;
1609 }
1610
1611
1612 CK_RV
C_EncryptFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pLastEncryptedPart,CK_ULONG_PTR pulLastEncryptedPartLen)1613 C_EncryptFinal(CK_SESSION_HANDLE hSession,
1614 CK_BYTE_PTR pLastEncryptedPart,
1615 CK_ULONG_PTR pulLastEncryptedPartLen)
1616 {
1617 st_logf("EncryptFinal\n");
1618 VERIFY_SESSION_HANDLE(hSession, NULL);
1619 return CKR_FUNCTION_NOT_SUPPORTED;
1620 }
1621
1622
1623 /* C_DecryptInit initializes a decryption operation. */
1624 CK_RV
C_DecryptInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)1625 C_DecryptInit(CK_SESSION_HANDLE hSession,
1626 CK_MECHANISM_PTR pMechanism,
1627 CK_OBJECT_HANDLE hKey)
1628 {
1629 struct session_state *state;
1630 CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 };
1631 CK_BBOOL bool_true = CK_TRUE;
1632 CK_ATTRIBUTE attr[] = {
1633 { CKA_DECRYPT, &bool_true, sizeof(bool_true) }
1634 };
1635 struct st_object *o;
1636 CK_RV ret;
1637
1638 st_logf("DecryptInit\n");
1639 VERIFY_SESSION_HANDLE(hSession, &state);
1640
1641 ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
1642 mechs, sizeof(mechs)/sizeof(mechs[0]),
1643 pMechanism, hKey, &o);
1644 if (ret)
1645 return ret;
1646
1647 ret = dup_mechanism(&state->decrypt_mechanism, pMechanism);
1648 if (ret == CKR_OK)
1649 state->decrypt_object = OBJECT_ID(o);
1650
1651 return CKR_OK;
1652 }
1653
1654
1655 CK_RV
C_Decrypt(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen)1656 C_Decrypt(CK_SESSION_HANDLE hSession,
1657 CK_BYTE_PTR pEncryptedData,
1658 CK_ULONG ulEncryptedDataLen,
1659 CK_BYTE_PTR pData,
1660 CK_ULONG_PTR pulDataLen)
1661 {
1662 struct session_state *state;
1663 struct st_object *o;
1664 void *buffer = NULL;
1665 CK_RV ret;
1666 size_t buffer_len = 0;
1667 int padding;
1668 EVP_PKEY_CTX *ctx = NULL;
1669
1670 st_logf("Decrypt\n");
1671
1672 VERIFY_SESSION_HANDLE(hSession, &state);
1673
1674 if (state->decrypt_object == -1)
1675 return CKR_ARGUMENTS_BAD;
1676
1677 o = soft_token.object.objs[state->decrypt_object];
1678
1679 if (o->u.private_key.key == NULL) {
1680 st_logf("private key NULL\n");
1681 return CKR_ARGUMENTS_BAD;
1682 }
1683
1684 if (pulDataLen == NULL) {
1685 st_logf("pulDataLen NULL\n");
1686 ret = CKR_ARGUMENTS_BAD;
1687 goto out;
1688 }
1689
1690 if (pEncryptedData == NULL_PTR) {
1691 st_logf("data NULL\n");
1692 ret = CKR_ARGUMENTS_BAD;
1693 goto out;
1694 }
1695
1696 switch(state->decrypt_mechanism->mechanism) {
1697 case CKM_RSA_PKCS:
1698 padding = RSA_PKCS1_PADDING;
1699 break;
1700 case CKM_RSA_X_509:
1701 padding = RSA_NO_PADDING;
1702 break;
1703 default:
1704 ret = CKR_FUNCTION_NOT_SUPPORTED;
1705 goto out;
1706 }
1707
1708 ctx = EVP_PKEY_CTX_new(o->u.private_key.key, NULL);
1709 if (ctx == NULL || EVP_PKEY_decrypt_init(ctx) <= 0 ||
1710 EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
1711 EVP_PKEY_decrypt(ctx, NULL, &buffer_len, pEncryptedData,
1712 ulEncryptedDataLen) <= 0) {
1713 ret = CKR_DEVICE_ERROR;
1714 goto out;
1715 }
1716
1717 buffer = OPENSSL_malloc(buffer_len);
1718 if (buffer == NULL) {
1719 ret = CKR_DEVICE_MEMORY;
1720 goto out;
1721 }
1722
1723 if (EVP_PKEY_decrypt(ctx, buffer, &buffer_len, pEncryptedData,
1724 ulEncryptedDataLen) <= 0) {
1725 ret = CKR_DEVICE_ERROR;
1726 goto out;
1727 }
1728 st_logf("Decrypt done\n");
1729
1730 if (pData != NULL_PTR)
1731 memcpy(pData, buffer, buffer_len);
1732 *pulDataLen = buffer_len;
1733
1734 ret = CKR_OK;
1735 out:
1736 OPENSSL_cleanse(buffer, buffer_len);
1737 OPENSSL_free(buffer);
1738 EVP_PKEY_CTX_free(ctx);
1739 return ret;
1740 }
1741
1742
1743 CK_RV
C_DecryptUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pEncryptedPart,CK_ULONG ulEncryptedPartLen,CK_BYTE_PTR pPart,CK_ULONG_PTR pulPartLen)1744 C_DecryptUpdate(CK_SESSION_HANDLE hSession,
1745 CK_BYTE_PTR pEncryptedPart,
1746 CK_ULONG ulEncryptedPartLen,
1747 CK_BYTE_PTR pPart,
1748 CK_ULONG_PTR pulPartLen)
1749
1750 {
1751 st_logf("DecryptUpdate\n");
1752 VERIFY_SESSION_HANDLE(hSession, NULL);
1753 return CKR_FUNCTION_NOT_SUPPORTED;
1754 }
1755
1756
1757 CK_RV
C_DecryptFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pLastPart,CK_ULONG_PTR pulLastPartLen)1758 C_DecryptFinal(CK_SESSION_HANDLE hSession,
1759 CK_BYTE_PTR pLastPart,
1760 CK_ULONG_PTR pulLastPartLen)
1761 {
1762 st_logf("DecryptFinal\n");
1763 VERIFY_SESSION_HANDLE(hSession, NULL);
1764 return CKR_FUNCTION_NOT_SUPPORTED;
1765 }
1766
1767 CK_RV
C_DigestInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism)1768 C_DigestInit(CK_SESSION_HANDLE hSession,
1769 CK_MECHANISM_PTR pMechanism)
1770 {
1771 st_logf("DigestInit\n");
1772 VERIFY_SESSION_HANDLE(hSession, NULL);
1773 return CKR_FUNCTION_NOT_SUPPORTED;
1774 }
1775
1776 CK_RV
C_SignInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)1777 C_SignInit(CK_SESSION_HANDLE hSession,
1778 CK_MECHANISM_PTR pMechanism,
1779 CK_OBJECT_HANDLE hKey)
1780 {
1781 struct session_state *state;
1782 CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 };
1783 CK_BBOOL bool_true = CK_TRUE;
1784 CK_ATTRIBUTE attr[] = {
1785 { CKA_SIGN, &bool_true, sizeof(bool_true) }
1786 };
1787 struct st_object *o;
1788 CK_RV ret;
1789
1790 st_logf("SignInit\n");
1791 VERIFY_SESSION_HANDLE(hSession, &state);
1792
1793 ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
1794 mechs, sizeof(mechs)/sizeof(mechs[0]),
1795 pMechanism, hKey, &o);
1796 if (ret)
1797 return ret;
1798
1799 ret = dup_mechanism(&state->sign_mechanism, pMechanism);
1800 if (ret == CKR_OK)
1801 state->sign_object = OBJECT_ID(o);
1802
1803 return CKR_OK;
1804 }
1805
1806 CK_RV
C_Sign(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)1807 C_Sign(CK_SESSION_HANDLE hSession,
1808 CK_BYTE_PTR pData,
1809 CK_ULONG ulDataLen,
1810 CK_BYTE_PTR pSignature,
1811 CK_ULONG_PTR pulSignatureLen)
1812 {
1813 struct session_state *state;
1814 struct st_object *o;
1815 void *buffer = NULL;
1816 CK_RV ret;
1817 int padding;
1818 size_t buffer_len = 0;
1819 EVP_PKEY_CTX *ctx = NULL;
1820
1821 st_logf("Sign\n");
1822 VERIFY_SESSION_HANDLE(hSession, &state);
1823
1824 if (state->sign_object == -1)
1825 return CKR_ARGUMENTS_BAD;
1826
1827 o = soft_token.object.objs[state->sign_object];
1828
1829 if (o->u.private_key.key == NULL) {
1830 st_logf("private key NULL\n");
1831 return CKR_ARGUMENTS_BAD;
1832 }
1833
1834 if (pulSignatureLen == NULL) {
1835 st_logf("signature len NULL\n");
1836 ret = CKR_ARGUMENTS_BAD;
1837 goto out;
1838 }
1839
1840 if (pData == NULL_PTR) {
1841 st_logf("data NULL\n");
1842 ret = CKR_ARGUMENTS_BAD;
1843 goto out;
1844 }
1845
1846 switch(state->sign_mechanism->mechanism) {
1847 case CKM_RSA_PKCS:
1848 padding = RSA_PKCS1_PADDING;
1849 break;
1850 case CKM_RSA_X_509:
1851 padding = RSA_NO_PADDING;
1852 break;
1853 default:
1854 ret = CKR_FUNCTION_NOT_SUPPORTED;
1855 goto out;
1856 }
1857
1858 ctx = EVP_PKEY_CTX_new(o->u.private_key.key, NULL);
1859 if (ctx == NULL || EVP_PKEY_sign_init(ctx) <= 0 ||
1860 EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
1861 EVP_PKEY_sign(ctx, NULL, &buffer_len, pData, ulDataLen) <= 0) {
1862 ret = CKR_DEVICE_ERROR;
1863 goto out;
1864 }
1865
1866 buffer = OPENSSL_malloc(buffer_len);
1867 if (buffer == NULL) {
1868 ret = CKR_DEVICE_MEMORY;
1869 goto out;
1870 }
1871
1872 if (EVP_PKEY_sign(ctx, buffer, &buffer_len, pData, ulDataLen) <= 0) {
1873 ret = CKR_DEVICE_ERROR;
1874 goto out;
1875 }
1876 st_logf("Sign done\n");
1877
1878 if (pSignature != NULL)
1879 memcpy(pSignature, buffer, buffer_len);
1880 *pulSignatureLen = buffer_len;
1881
1882 ret = CKR_OK;
1883 out:
1884 OPENSSL_cleanse(buffer, buffer_len);
1885 OPENSSL_free(buffer);
1886 EVP_PKEY_CTX_free(ctx);
1887 return ret;
1888 }
1889
1890 CK_RV
C_SignUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)1891 C_SignUpdate(CK_SESSION_HANDLE hSession,
1892 CK_BYTE_PTR pPart,
1893 CK_ULONG ulPartLen)
1894 {
1895 st_logf("SignUpdate\n");
1896 VERIFY_SESSION_HANDLE(hSession, NULL);
1897 return CKR_FUNCTION_NOT_SUPPORTED;
1898 }
1899
1900
1901 CK_RV
C_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)1902 C_SignFinal(CK_SESSION_HANDLE hSession,
1903 CK_BYTE_PTR pSignature,
1904 CK_ULONG_PTR pulSignatureLen)
1905 {
1906 st_logf("SignUpdate\n");
1907 VERIFY_SESSION_HANDLE(hSession, NULL);
1908 return CKR_FUNCTION_NOT_SUPPORTED;
1909 }
1910
1911 CK_RV
C_VerifyInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)1912 C_VerifyInit(CK_SESSION_HANDLE hSession,
1913 CK_MECHANISM_PTR pMechanism,
1914 CK_OBJECT_HANDLE hKey)
1915 {
1916 struct session_state *state;
1917 CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 };
1918 CK_BBOOL bool_true = CK_TRUE;
1919 CK_ATTRIBUTE attr[] = {
1920 { CKA_VERIFY, &bool_true, sizeof(bool_true) }
1921 };
1922 struct st_object *o;
1923 CK_RV ret;
1924
1925 st_logf("VerifyInit\n");
1926 VERIFY_SESSION_HANDLE(hSession, &state);
1927
1928 ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
1929 mechs, sizeof(mechs)/sizeof(mechs[0]),
1930 pMechanism, hKey, &o);
1931 if (ret)
1932 return ret;
1933
1934 ret = dup_mechanism(&state->verify_mechanism, pMechanism);
1935 if (ret == CKR_OK)
1936 state->verify_object = OBJECT_ID(o);
1937
1938 return ret;
1939 }
1940
1941 CK_RV
C_Verify(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)1942 C_Verify(CK_SESSION_HANDLE hSession,
1943 CK_BYTE_PTR pData,
1944 CK_ULONG ulDataLen,
1945 CK_BYTE_PTR pSignature,
1946 CK_ULONG ulSignatureLen)
1947 {
1948 struct session_state *state;
1949 struct st_object *o;
1950 CK_RV ret;
1951 int padding;
1952 EVP_PKEY_CTX *ctx = NULL;
1953
1954 st_logf("Verify\n");
1955 VERIFY_SESSION_HANDLE(hSession, &state);
1956
1957 if (state->verify_object == -1)
1958 return CKR_ARGUMENTS_BAD;
1959
1960 o = soft_token.object.objs[state->verify_object];
1961
1962 if (o->u.public_key == NULL) {
1963 st_logf("public key NULL\n");
1964 return CKR_ARGUMENTS_BAD;
1965 }
1966
1967 if (pSignature == NULL) {
1968 st_logf("signature NULL\n");
1969 ret = CKR_ARGUMENTS_BAD;
1970 goto out;
1971 }
1972
1973 if (pData == NULL_PTR) {
1974 st_logf("data NULL\n");
1975 ret = CKR_ARGUMENTS_BAD;
1976 goto out;
1977 }
1978
1979 switch(state->verify_mechanism->mechanism) {
1980 case CKM_RSA_PKCS:
1981 padding = RSA_PKCS1_PADDING;
1982 break;
1983 case CKM_RSA_X_509:
1984 padding = RSA_NO_PADDING;
1985 break;
1986 default:
1987 ret = CKR_FUNCTION_NOT_SUPPORTED;
1988 goto out;
1989 }
1990
1991 ctx = EVP_PKEY_CTX_new(o->u.public_key, NULL);
1992 if (ctx == NULL || EVP_PKEY_verify_init(ctx) <= 0 ||
1993 EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
1994 EVP_PKEY_verify(ctx, pSignature, ulSignatureLen, pData,
1995 ulDataLen) <= 0) {
1996 ret = CKR_DEVICE_ERROR;
1997 goto out;
1998 }
1999 st_logf("Verify done\n");
2000
2001 ret = CKR_OK;
2002 out:
2003 EVP_PKEY_CTX_free(ctx);
2004 return ret;
2005 }
2006
2007 CK_RV
C_VerifyUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)2008 C_VerifyUpdate(CK_SESSION_HANDLE hSession,
2009 CK_BYTE_PTR pPart,
2010 CK_ULONG ulPartLen)
2011 {
2012 st_logf("VerifyUpdate\n");
2013 VERIFY_SESSION_HANDLE(hSession, NULL);
2014 return CKR_FUNCTION_NOT_SUPPORTED;
2015 }
2016
2017 CK_RV
C_VerifyFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)2018 C_VerifyFinal(CK_SESSION_HANDLE hSession,
2019 CK_BYTE_PTR pSignature,
2020 CK_ULONG ulSignatureLen)
2021 {
2022 st_logf("VerifyFinal\n");
2023 VERIFY_SESSION_HANDLE(hSession, NULL);
2024 return CKR_FUNCTION_NOT_SUPPORTED;
2025 }
2026
2027 CK_RV
C_GenerateRandom(CK_SESSION_HANDLE hSession,CK_BYTE_PTR RandomData,CK_ULONG ulRandomLen)2028 C_GenerateRandom(CK_SESSION_HANDLE hSession,
2029 CK_BYTE_PTR RandomData,
2030 CK_ULONG ulRandomLen)
2031 {
2032 st_logf("GenerateRandom\n");
2033 VERIFY_SESSION_HANDLE(hSession, NULL);
2034 return CKR_FUNCTION_NOT_SUPPORTED;
2035 }
2036
2037 CK_FUNCTION_LIST funcs = {
2038 { 2, 11 },
2039 C_Initialize,
2040 C_Finalize,
2041 C_GetInfo,
2042 C_GetFunctionList,
2043 C_GetSlotList,
2044 C_GetSlotInfo,
2045 C_GetTokenInfo,
2046 C_GetMechanismList,
2047 C_GetMechanismInfo,
2048 C_InitToken,
2049 (void *)func_not_supported, /* C_InitPIN */
2050 (void *)func_not_supported, /* C_SetPIN */
2051 C_OpenSession,
2052 C_CloseSession,
2053 C_CloseAllSessions,
2054 C_GetSessionInfo,
2055 (void *)func_not_supported, /* C_GetOperationState */
2056 (void *)func_not_supported, /* C_SetOperationState */
2057 C_Login,
2058 C_Logout,
2059 (void *)func_not_supported, /* C_CreateObject */
2060 (void *)func_not_supported, /* C_CopyObject */
2061 (void *)func_not_supported, /* C_DestroyObject */
2062 (void *)func_not_supported, /* C_GetObjectSize */
2063 C_GetAttributeValue,
2064 (void *)func_not_supported, /* C_SetAttributeValue */
2065 C_FindObjectsInit,
2066 C_FindObjects,
2067 C_FindObjectsFinal,
2068 C_EncryptInit,
2069 C_Encrypt,
2070 C_EncryptUpdate,
2071 C_EncryptFinal,
2072 C_DecryptInit,
2073 C_Decrypt,
2074 C_DecryptUpdate,
2075 C_DecryptFinal,
2076 C_DigestInit,
2077 (void *)func_not_supported, /* C_Digest */
2078 (void *)func_not_supported, /* C_DigestUpdate */
2079 (void *)func_not_supported, /* C_DigestKey */
2080 (void *)func_not_supported, /* C_DigestFinal */
2081 C_SignInit,
2082 C_Sign,
2083 C_SignUpdate,
2084 C_SignFinal,
2085 (void *)func_not_supported, /* C_SignRecoverInit */
2086 (void *)func_not_supported, /* C_SignRecover */
2087 C_VerifyInit,
2088 C_Verify,
2089 C_VerifyUpdate,
2090 C_VerifyFinal,
2091 (void *)func_not_supported, /* C_VerifyRecoverInit */
2092 (void *)func_not_supported, /* C_VerifyRecover */
2093 (void *)func_not_supported, /* C_DigestEncryptUpdate */
2094 (void *)func_not_supported, /* C_DecryptDigestUpdate */
2095 (void *)func_not_supported, /* C_SignEncryptUpdate */
2096 (void *)func_not_supported, /* C_DecryptVerifyUpdate */
2097 (void *)func_not_supported, /* C_GenerateKey */
2098 (void *)func_not_supported, /* C_GenerateKeyPair */
2099 (void *)func_not_supported, /* C_WrapKey */
2100 (void *)func_not_supported, /* C_UnwrapKey */
2101 (void *)func_not_supported, /* C_DeriveKey */
2102 (void *)func_not_supported, /* C_SeedRandom */
2103 C_GenerateRandom,
2104 (void *)func_not_supported, /* C_GetFunctionStatus */
2105 (void *)func_not_supported, /* C_CancelFunction */
2106 (void *)func_not_supported /* C_WaitForSlotEvent */
2107 };
2108