1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
3 * Copyright (c) 2004-2006, Stockholms universitet
4 * (Stockholm University, Stockholm Sweden)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
35 #include "k5-platform.h"
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>
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
53 compat_rsa_get0_key(const RSA *rsa, const BIGNUM **n, const BIGNUM **e,
65 #define OPENSSL_ASN1_MALLOC_ENCODE(T, B, BL, S, R) \
68 (BL) = i2d_##T((S), NULL); \
78 (BL) = i2d_##T((S), &p); \
88 /* RCSID("$Id: main.c,v 1.24 2006/01/11 12:42:53 lha Exp $"); */
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)
95 CK_ATTRIBUTE attribute;
100 CK_OBJECT_HANDLE object_handle;
101 struct st_attr *attrs;
110 EVP_PKEY *public_key;
119 static struct soft_token {
120 CK_VOID_PTR application;
123 struct st_object **objs;
132 struct session_state {
133 CK_SESSION_HANDLE session_handle;
136 CK_ATTRIBUTE *attributes;
137 CK_ULONG num_attributes;
142 CK_MECHANISM_PTR encrypt_mechanism;
144 CK_MECHANISM_PTR decrypt_mechanism;
146 CK_MECHANISM_PTR sign_mechanism;
148 CK_MECHANISM_PTR verify_mechanism;
151 #define MAX_NUM_SESSION (sizeof(soft_token.state)/sizeof(soft_token.state[0]))
153 CK_SESSION_HANDLE next_session_handle;
157 application_error(const char *fmt, ...)
163 if (soft_token.flags.app_error_fatal)
168 st_logf(const char *fmt, ...)
171 if (soft_token.logfile == NULL)
174 vfprintf(soft_token.logfile, fmt, ap);
176 fflush(soft_token.logfile);
180 snprintf_fill(char *str, int size, char fillchar, const char *fmt, ...)
185 len = vsnprintf(str, size, fmt, ap);
187 if (len < 0 || len > size)
190 str[len++] = fillchar;
194 #define printf error_use_st_logf
197 #define VERIFY_SESSION_HANDLE(s, state) \
200 vshret = verify_session_handle(s, state); \
201 if (vshret != CKR_OK) { \
202 /* return CKR_OK */; \
207 verify_session_handle(CK_SESSION_HANDLE hSession,
208 struct session_state **state)
212 for (i = 0; i < MAX_NUM_SESSION; i++){
213 if (soft_token.state[i].session_handle == hSession)
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;
222 *state = &soft_token.state[i];
227 object_handle_to_object(CK_OBJECT_HANDLE handle,
228 struct st_object **object)
230 int i = HANDLE_OBJECT_ID(handle);
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];
244 attributes_match(const struct st_object *obj,
245 const CK_ATTRIBUTE *attributes,
246 CK_ULONG num_attributes)
250 st_logf("attributes_match: %ld\n", (unsigned long)OBJECT_ID(obj));
252 for (i = 0; i < num_attributes; i++) {
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) {
264 st_logf("type %lu attribute have no match\n", attributes[i].type);
268 st_logf("attribute matches\n");
273 print_attributes(const CK_ATTRIBUTE *attributes,
274 CK_ULONG num_attributes)
278 st_logf("find objects: attrs: %lu\n", (unsigned long)num_attributes);
280 for (i = 0; i < num_attributes; i++) {
282 switch (attributes[i].type) {
285 if (attributes[i].ulValueLen != sizeof(CK_BBOOL)) {
286 application_error("token attribute wrong length\n");
289 ck_true = attributes[i].pValue;
290 st_logf("token: %s", *ck_true ? "TRUE" : "FALSE");
294 CK_OBJECT_CLASS *class;
295 if (attributes[i].ulValueLen != sizeof(CK_ULONG)) {
296 application_error("class attribute wrong length\n");
299 class = attributes[i].pValue;
302 case CKO_CERTIFICATE:
303 st_logf("certificate");
306 st_logf("public key");
308 case CKO_PRIVATE_KEY:
309 st_logf("private key");
312 st_logf("secret key");
314 case CKO_DOMAIN_PARAMETERS:
315 st_logf("domain parameters");
318 st_logf("[class %lx]", (long unsigned)*class);
329 case CKA_APPLICATION:
330 st_logf("application");
339 st_logf("[unknown 0x%08lx]", (unsigned long)attributes[i].type);
347 free_st_object(struct st_object *o)
351 for (i = 0; i < o->num_attributes; i++)
352 free(o->attrs[i].attribute.pValue);
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);
366 static struct st_object *
369 struct st_object *o, **objs;
371 objs = realloc(soft_token.object.objs,
372 (soft_token.object.num_objs + 1) *
373 sizeof(soft_token.object.objs[0]));
376 soft_token.object.objs = objs;
378 o = calloc(1, sizeof(*o));
382 o->num_attributes = 0;
383 o->object_handle = soft_token.object.num_objs;
385 soft_token.object.objs[soft_token.object.num_objs++] = o;
390 add_object_attribute(struct st_object *o,
392 CK_ATTRIBUTE_TYPE type,
399 i = o->num_attributes;
400 a = realloc(o->attrs, (i + 1) * sizeof(o->attrs[0]));
402 return CKR_DEVICE_MEMORY;
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;
416 #ifdef HAVE_EVP_PKEY_GET_BN_PARAM
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)
422 get_bignums(EVP_PKEY *key, BIGNUM **n, BIGNUM **e)
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;
433 /* Declare const pointers since the old API gives us aliases. */
434 #define DECLARE_BIGNUM(name) const BIGNUM *name
435 #define RELEASE_BIGNUM(bn)
437 get_bignums(EVP_PKEY *key, const BIGNUM **n, const BIGNUM **e)
441 rsa = EVP_PKEY_get0_RSA(key);
442 RSA_get0_key(rsa, n, e, NULL);
450 add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key)
452 CK_BYTE *modulus = NULL, *exponent = 0;
453 size_t modulus_len = 0, exponent_len = 0;
454 CK_ULONG modulus_bits = 0;
459 if (key_type != CKK_RSA)
462 ret = get_bignums(key, &n, &e);
466 modulus_bits = BN_num_bits(n);
467 modulus_len = BN_num_bytes(n);
468 exponent_len = BN_num_bytes(e);
470 modulus = malloc(modulus_len);
471 exponent = malloc(exponent_len);
472 if (modulus == NULL || exponent == NULL) {
473 ret = CKR_DEVICE_MEMORY;
477 BN_bn2bin(n, modulus);
478 BN_bn2bin(e, exponent);
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);
495 pem_callback(char *buf, int num, int w, void *key)
502 add_certificate(char *label,
503 const char *cert_file,
504 const char *private_key_file,
508 struct st_object *o = NULL;
509 CK_BBOOL bool_true = CK_TRUE;
510 CK_BBOOL bool_false = CK_FALSE;
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;
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;
525 EVP_PKEY *public_key;
527 size_t id_len = strlen(id);
532 f = fopen(cert_file, "r");
534 st_logf("failed to open file %s\n", cert_file);
535 return CKR_GENERAL_ERROR;
538 cert = PEM_read_X509(f, NULL, NULL, NULL);
541 st_logf("failed reading PEM cert\n");
542 return CKR_GENERAL_ERROR;
545 OPENSSL_ASN1_MALLOC_ENCODE(X509, cert_data, cert_length, cert, ret);
549 OPENSSL_ASN1_MALLOC_ENCODE(X509_NAME, issuer_data, issuer_length,
550 X509_get_issuer_name(cert), ret);
554 OPENSSL_ASN1_MALLOC_ENCODE(X509_NAME, subject_data, subject_length,
555 X509_get_subject_name(cert), ret);
559 OPENSSL_ASN1_MALLOC_ENCODE(ASN1_INTEGER, serial_data, serial_length,
560 X509_get_serialNumber(cert), ret);
566 st_logf("done parsing, adding to internal structure\n");
570 ret = CKR_DEVICE_MEMORY;
573 o->type = STO_T_CERTIFICATE;
574 o->u.cert = X509_dup(cert);
575 if (o->u.cert == NULL) {
576 ret = CKR_DEVICE_MEMORY;
579 public_key = X509_get_pubkey(o->u.cert);
581 switch (EVP_PKEY_base_id(public_key)) {
589 st_logf("invalid key_type\n");
590 ret = CKR_GENERAL_ERROR;
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));
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);
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);
609 add_object_attribute(o, 0, CKA_TRUSTED, &bool_true, sizeof(bool_true));
611 add_object_attribute(o, 0, CKA_TRUSTED, &bool_false, sizeof(bool_false));
613 st_logf("add cert ok: %lx\n", (unsigned long)OBJECT_ID(o));
617 ret = CKR_DEVICE_MEMORY;
620 o->type = STO_T_PUBLIC_KEY;
621 o->u.public_key = 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));
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));
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));
646 add_pubkey_info(o, key_type, public_key);
648 st_logf("add key ok: %lx\n", (unsigned long)OBJECT_ID(o));
650 if (private_key_file) {
656 ret = CKR_DEVICE_MEMORY;
659 o->type = STO_T_PRIVATE_KEY;
660 o->u.private_key.file = strdup(private_key_file);
661 o->u.private_key.key = NULL;
663 o->u.private_key.cert = X509_dup(cert);
664 if (o->u.private_key.cert == NULL) {
665 ret = CKR_DEVICE_MEMORY;
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));
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));
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));
689 add_object_attribute(o, 0, CKA_AUTH_PIN_FLAGS, &flags, sizeof(flags));
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));
698 add_pubkey_info(o, key_type, public_key);
700 f = fopen(private_key_file, "r");
702 st_logf("failed to open private key\n");
703 return CKR_GENERAL_ERROR;
706 o->u.private_key.key = PEM_read_PrivateKey(f, NULL, pem_callback, NULL);
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 */;
713 /* XXX verify keytype */
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");
720 st_logf("private key usable\n");
721 soft_token.flags.login_done = 1;
729 st_logf("something went wrong when adding cert!\n");
743 find_object_final(struct session_state *state)
745 if (state->find.attributes) {
748 for (i = 0; i < state->find.num_attributes; i++) {
749 if (state->find.attributes[i].pValue)
750 free(state->find.attributes[i].pValue);
752 free(state->find.attributes);
753 state->find.attributes = NULL;
754 state->find.num_attributes = 0;
755 state->find.next_object = -1;
760 reset_crypto_state(struct session_state *state)
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;
782 close_session(struct session_state *state)
784 if (state->find.attributes) {
785 application_error("application didn't do C_FindObjectsFinal\n");
786 find_object_final(state);
789 state->session_handle = CK_INVALID_HANDLE;
790 soft_token.application = NULL_PTR;
791 soft_token.notify = NULL_PTR;
792 reset_crypto_state(state);
798 return soft_token.open_sessions > 0 ? "yes" : "no";
802 read_conf_file(const char *fn)
804 char buf[1024], *cert, *key, *id, *label, *s, *p;
810 st_logf("can't open configuration file %s\n", fn);
814 while(fgets(buf, sizeof(buf), f) != NULL) {
815 buf[strcspn(buf, "\n")] = '\0';
819 st_logf("line: %s\n", buf);
830 id = strtok_r(p, "\t", &s);
833 label = strtok_r(NULL, "\t", &s);
836 cert = strtok_r(NULL, "\t", &s);
839 key = strtok_r(NULL, "\t", &s);
842 if (strcmp(id, "anchor") == 0) {
847 st_logf("adding: %s\n", label);
849 add_certificate(label, cert, key, id, anchor);
856 func_not_supported(void)
858 st_logf("function not supported\n");
859 return CKR_FUNCTION_NOT_SUPPORTED;
866 const char *home = NULL;
869 if (getuid() == geteuid()) {
870 fn = getenv("SOFTPKCS11RC");
874 home = getenv("HOME");
878 pw = getpwuid(getuid());
884 return strdup("/etc/soft-token.rc");
886 if (asprintf(&fn, "%s/.soft-token.rc", home) < 0)
892 C_Initialize(CK_VOID_PTR a)
894 CK_C_INITIALIZE_ARGS_PTR args = a;
898 st_logf("Initialize\n");
900 OpenSSL_add_all_algorithms();
901 ERR_load_crypto_strings();
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]);
911 soft_token.flags.hardware_slot = 1;
912 soft_token.flags.app_error_fatal = 0;
913 soft_token.flags.login_done = 0;
915 soft_token.object.objs = NULL;
916 soft_token.object.num_objs = 0;
918 soft_token.logfile = NULL;
920 soft_token.logfile = stdout;
923 soft_token.logfile = fopen("/tmp/log-pkcs11.txt", "a");
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);
934 soft_token.next_session_handle = 1;
936 fn = get_rcfilename();
938 return CKR_DEVICE_MEMORY;
945 C_Finalize(CK_VOID_PTR args)
950 st_logf("Finalize\n");
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]);
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;
970 C_GetInfo(CK_INFO_PTR args)
972 st_logf("GetInfo\n");
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),
981 snprintf_fill((char *)args->libraryDescription,
982 sizeof(args->libraryDescription), ' ',
984 args->libraryVersion.major = 1;
985 args->libraryVersion.minor = 8;
990 extern CK_FUNCTION_LIST funcs;
993 C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
995 *ppFunctionList = &funcs;
1000 C_GetSlotList(CK_BBOOL tokenPresent,
1001 CK_SLOT_ID_PTR pSlotList,
1002 CK_ULONG_PTR pulCount)
1004 st_logf("GetSlotList: %s\n",
1005 tokenPresent ? "tokenPresent" : "token not Present");
1013 C_GetSlotInfo(CK_SLOT_ID slotID,
1014 CK_SLOT_INFO_PTR pInfo)
1016 st_logf("GetSlotInfo: slot: %d : %s\n", (int)slotID, has_session());
1018 memset(pInfo, 18, sizeof(*pInfo));
1021 return CKR_ARGUMENTS_BAD;
1023 snprintf_fill((char *)pInfo->slotDescription,
1024 sizeof(pInfo->slotDescription),
1026 "SoftToken (slot)");
1027 snprintf_fill((char *)pInfo->manufacturerID,
1028 sizeof(pInfo->manufacturerID),
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;
1043 C_GetTokenInfo(CK_SLOT_ID slotID,
1044 CK_TOKEN_INFO_PTR pInfo)
1046 st_logf("GetTokenInfo: %s\n", has_session());
1048 memset(pInfo, 19, sizeof(*pInfo));
1050 snprintf_fill((char *)pInfo->label,
1051 sizeof(pInfo->label),
1053 "SoftToken (token)");
1054 snprintf_fill((char *)pInfo->manufacturerID,
1055 sizeof(pInfo->manufacturerID),
1057 "SoftToken (token)");
1058 snprintf_fill((char *)pInfo->model,
1059 sizeof(pInfo->model),
1061 "SoftToken (token)");
1062 snprintf_fill((char *)pInfo->serialNumber,
1063 sizeof(pInfo->serialNumber),
1067 CKF_TOKEN_INITIALIZED |
1068 CKF_USER_PIN_INITIALIZED;
1070 if (soft_token.flags.login_done == 0)
1071 pInfo->flags |= CKF_LOGIN_REQUIRED;
1074 CKF_RESTORE_KEY_NOT_NEEDED |
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;
1095 C_GetMechanismList(CK_SLOT_ID slotID,
1096 CK_MECHANISM_TYPE_PTR pMechanismList,
1097 CK_ULONG_PTR pulCount)
1099 st_logf("GetMechanismList\n");
1102 if (pMechanismList == NULL_PTR)
1104 pMechanismList[0] = CKM_RSA_X_509;
1105 pMechanismList[1] = CKM_RSA_PKCS;
1111 C_GetMechanismInfo(CK_SLOT_ID slotID,
1112 CK_MECHANISM_TYPE type,
1113 CK_MECHANISM_INFO_PTR pInfo)
1115 st_logf("GetMechanismInfo: slot %d type: %d\n",
1116 (int)slotID, (int)type);
1117 return CKR_FUNCTION_NOT_SUPPORTED;
1121 C_InitToken(CK_SLOT_ID slotID,
1122 CK_UTF8CHAR_PTR pPin,
1124 CK_UTF8CHAR_PTR pLabel)
1126 st_logf("InitToken: slot %d\n", (int)slotID);
1127 return CKR_FUNCTION_NOT_SUPPORTED;
1131 C_OpenSession(CK_SLOT_ID slotID,
1133 CK_VOID_PTR pApplication,
1135 CK_SESSION_HANDLE_PTR phSession)
1139 st_logf("OpenSession: slot: %d\n", (int)slotID);
1141 if (soft_token.open_sessions == MAX_NUM_SESSION)
1142 return CKR_SESSION_COUNT;
1144 soft_token.application = pApplication;
1145 soft_token.notify = Notify;
1147 for (i = 0; i < MAX_NUM_SESSION; i++)
1148 if (soft_token.state[i].session_handle == CK_INVALID_HANDLE)
1150 if (i == MAX_NUM_SESSION)
1153 soft_token.open_sessions++;
1155 soft_token.state[i].session_handle = soft_token.next_session_handle++;
1156 *phSession = soft_token.state[i].session_handle;
1162 C_CloseSession(CK_SESSION_HANDLE hSession)
1164 struct session_state *state;
1165 st_logf("CloseSession\n");
1167 if (verify_session_handle(hSession, &state) != CKR_OK)
1168 application_error("closed session not open");
1170 close_session(state);
1176 C_CloseAllSessions(CK_SLOT_ID slotID)
1180 st_logf("CloseAllSessions\n");
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]);
1190 C_GetSessionInfo(CK_SESSION_HANDLE hSession,
1191 CK_SESSION_INFO_PTR pInfo)
1193 st_logf("GetSessionInfo\n");
1195 VERIFY_SESSION_HANDLE(hSession, NULL);
1197 memset(pInfo, 20, sizeof(*pInfo));
1200 if (soft_token.flags.login_done)
1201 pInfo->state = CKS_RO_USER_FUNCTIONS;
1203 pInfo->state = CKS_RO_PUBLIC_SESSION;
1204 pInfo->flags = CKF_SERIAL_SESSION;
1205 pInfo->ulDeviceError = 0;
1211 C_Login(CK_SESSION_HANDLE hSession,
1212 CK_USER_TYPE userType,
1213 CK_UTF8CHAR_PTR pPin,
1221 VERIFY_SESSION_HANDLE(hSession, NULL);
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);
1229 for (i = 0; i < soft_token.object.num_objs; i++) {
1230 struct st_object *o = soft_token.object.objs[i];
1233 if (o->type != STO_T_PRIVATE_KEY)
1236 if (o->u.private_key.key)
1239 f = fopen(o->u.private_key.file, "r");
1241 st_logf("can't open private file: %s\n", o->u.private_key.file);
1245 o->u.private_key.key = PEM_read_PrivateKey(f, NULL, NULL, pin);
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 */;
1255 /* XXX check keytype */
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);
1264 soft_token.flags.login_done = 1;
1268 return soft_token.flags.login_done ? CKR_OK : CKR_PIN_INCORRECT;
1272 C_Logout(CK_SESSION_HANDLE hSession)
1274 st_logf("Logout\n");
1275 VERIFY_SESSION_HANDLE(hSession, NULL);
1276 return CKR_FUNCTION_NOT_SUPPORTED;
1280 C_GetObjectSize(CK_SESSION_HANDLE hSession,
1281 CK_OBJECT_HANDLE hObject,
1282 CK_ULONG_PTR pulSize)
1284 st_logf("GetObjectSize\n");
1285 VERIFY_SESSION_HANDLE(hSession, NULL);
1286 return CKR_FUNCTION_NOT_SUPPORTED;
1290 C_GetAttributeValue(CK_SESSION_HANDLE hSession,
1291 CK_OBJECT_HANDLE hObject,
1292 CK_ATTRIBUTE_PTR pTemplate,
1295 struct session_state *state;
1296 struct st_object *obj;
1301 st_logf("GetAttributeValue: %lx\n",
1302 (unsigned long)HANDLE_OBJECT_ID(hObject));
1303 VERIFY_SESSION_HANDLE(hSession, &state);
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));
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;
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);
1324 pTemplate[i].ulValueLen = obj->attrs[j].attribute.ulValueLen;
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;
1338 C_FindObjectsInit(CK_SESSION_HANDLE hSession,
1339 CK_ATTRIBUTE_PTR pTemplate,
1342 struct session_state *state;
1344 st_logf("FindObjectsInit\n");
1346 VERIFY_SESSION_HANDLE(hSession, &state);
1348 if (state->find.next_object != -1) {
1349 application_error("application didn't do C_FindObjectsFinal\n");
1350 find_object_final(state);
1355 print_attributes(pTemplate, ulCount);
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;
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;
1373 state->find.num_attributes = ulCount;
1374 state->find.next_object = 0;
1376 st_logf("find all objects\n");
1377 state->find.attributes = NULL;
1378 state->find.num_attributes = 0;
1379 state->find.next_object = 0;
1386 C_FindObjects(CK_SESSION_HANDLE hSession,
1387 CK_OBJECT_HANDLE_PTR phObject,
1388 CK_ULONG ulMaxObjectCount,
1389 CK_ULONG_PTR pulObjectCount)
1391 struct session_state *state;
1394 st_logf("FindObjects\n");
1396 VERIFY_SESSION_HANDLE(hSession, &state);
1398 if (state->find.next_object == -1) {
1399 application_error("application didn't do C_FindObjectsInit\n");
1400 return CKR_ARGUMENTS_BAD;
1402 if (ulMaxObjectCount == 0) {
1403 application_error("application asked for 0 objects\n");
1404 return CKR_ARGUMENTS_BAD;
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;
1415 (*pulObjectCount)++;
1416 if (ulMaxObjectCount == 0)
1424 C_FindObjectsFinal(CK_SESSION_HANDLE hSession)
1426 struct session_state *state;
1428 st_logf("FindObjectsFinal\n");
1429 VERIFY_SESSION_HANDLE(hSession, &state);
1430 find_object_final(state);
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)
1444 if ((ret = object_handle_to_object(hKey, o)) != CKR_OK)
1447 ret = attributes_match(*o, attr_match, attr_match_len);
1449 application_error("called commonInit on key that doesn't "
1450 "support required attr");
1451 return CKR_ARGUMENTS_BAD;
1454 for (i = 0; i < mechs_len; i++)
1455 if (mechs[i] == pMechanism->mechanism)
1457 if (i == mechs_len) {
1458 application_error("called mech (%08lx) not supported\n",
1459 pMechanism->mechanism);
1460 return CKR_ARGUMENTS_BAD;
1467 dup_mechanism(CK_MECHANISM_PTR *dup, const CK_MECHANISM_PTR pMechanism)
1471 p = malloc(sizeof(*p));
1473 return CKR_DEVICE_MEMORY;
1478 memcpy(p, pMechanism, sizeof(*p));
1485 C_EncryptInit(CK_SESSION_HANDLE hSession,
1486 CK_MECHANISM_PTR pMechanism,
1487 CK_OBJECT_HANDLE hKey)
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) }
1495 struct st_object *o;
1498 st_logf("EncryptInit\n");
1499 VERIFY_SESSION_HANDLE(hSession, &state);
1501 ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
1502 mechs, sizeof(mechs)/sizeof(mechs[0]),
1503 pMechanism, hKey, &o);
1507 ret = dup_mechanism(&state->encrypt_mechanism, pMechanism);
1509 state->encrypt_object = OBJECT_ID(o);
1515 C_Encrypt(CK_SESSION_HANDLE hSession,
1518 CK_BYTE_PTR pEncryptedData,
1519 CK_ULONG_PTR pulEncryptedDataLen)
1521 struct session_state *state;
1522 struct st_object *o;
1523 void *buffer = NULL;
1525 size_t buffer_len = 0;
1527 EVP_PKEY_CTX *ctx = NULL;
1529 st_logf("Encrypt\n");
1531 VERIFY_SESSION_HANDLE(hSession, &state);
1533 if (state->encrypt_object == -1)
1534 return CKR_ARGUMENTS_BAD;
1536 o = soft_token.object.objs[state->encrypt_object];
1538 if (o->u.public_key == NULL) {
1539 st_logf("public key NULL\n");
1540 return CKR_ARGUMENTS_BAD;
1543 if (pulEncryptedDataLen == NULL) {
1544 st_logf("pulEncryptedDataLen NULL\n");
1545 ret = CKR_ARGUMENTS_BAD;
1549 if (pData == NULL) {
1550 st_logf("data NULL\n");
1551 ret = CKR_ARGUMENTS_BAD;
1555 switch(state->encrypt_mechanism->mechanism) {
1557 padding = RSA_PKCS1_PADDING;
1560 padding = RSA_NO_PADDING;
1563 ret = CKR_FUNCTION_NOT_SUPPORTED;
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;
1575 buffer = OPENSSL_malloc(buffer_len);
1576 if (buffer == NULL) {
1577 ret = CKR_DEVICE_MEMORY;
1581 if (EVP_PKEY_encrypt(ctx, buffer, &buffer_len, pData, ulDataLen) <= 0) {
1582 ret = CKR_DEVICE_ERROR;
1585 st_logf("Encrypt done\n");
1587 if (pEncryptedData != NULL)
1588 memcpy(pEncryptedData, buffer, buffer_len);
1589 *pulEncryptedDataLen = buffer_len;
1593 OPENSSL_cleanse(buffer, buffer_len);
1594 OPENSSL_free(buffer);
1595 EVP_PKEY_CTX_free(ctx);
1600 C_EncryptUpdate(CK_SESSION_HANDLE hSession,
1603 CK_BYTE_PTR pEncryptedPart,
1604 CK_ULONG_PTR pulEncryptedPartLen)
1606 st_logf("EncryptUpdate\n");
1607 VERIFY_SESSION_HANDLE(hSession, NULL);
1608 return CKR_FUNCTION_NOT_SUPPORTED;
1613 C_EncryptFinal(CK_SESSION_HANDLE hSession,
1614 CK_BYTE_PTR pLastEncryptedPart,
1615 CK_ULONG_PTR pulLastEncryptedPartLen)
1617 st_logf("EncryptFinal\n");
1618 VERIFY_SESSION_HANDLE(hSession, NULL);
1619 return CKR_FUNCTION_NOT_SUPPORTED;
1623 /* C_DecryptInit initializes a decryption operation. */
1625 C_DecryptInit(CK_SESSION_HANDLE hSession,
1626 CK_MECHANISM_PTR pMechanism,
1627 CK_OBJECT_HANDLE hKey)
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) }
1635 struct st_object *o;
1638 st_logf("DecryptInit\n");
1639 VERIFY_SESSION_HANDLE(hSession, &state);
1641 ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
1642 mechs, sizeof(mechs)/sizeof(mechs[0]),
1643 pMechanism, hKey, &o);
1647 ret = dup_mechanism(&state->decrypt_mechanism, pMechanism);
1649 state->decrypt_object = OBJECT_ID(o);
1656 C_Decrypt(CK_SESSION_HANDLE hSession,
1657 CK_BYTE_PTR pEncryptedData,
1658 CK_ULONG ulEncryptedDataLen,
1660 CK_ULONG_PTR pulDataLen)
1662 struct session_state *state;
1663 struct st_object *o;
1664 void *buffer = NULL;
1666 size_t buffer_len = 0;
1668 EVP_PKEY_CTX *ctx = NULL;
1670 st_logf("Decrypt\n");
1672 VERIFY_SESSION_HANDLE(hSession, &state);
1674 if (state->decrypt_object == -1)
1675 return CKR_ARGUMENTS_BAD;
1677 o = soft_token.object.objs[state->decrypt_object];
1679 if (o->u.private_key.key == NULL) {
1680 st_logf("private key NULL\n");
1681 return CKR_ARGUMENTS_BAD;
1684 if (pulDataLen == NULL) {
1685 st_logf("pulDataLen NULL\n");
1686 ret = CKR_ARGUMENTS_BAD;
1690 if (pEncryptedData == NULL_PTR) {
1691 st_logf("data NULL\n");
1692 ret = CKR_ARGUMENTS_BAD;
1696 switch(state->decrypt_mechanism->mechanism) {
1698 padding = RSA_PKCS1_PADDING;
1701 padding = RSA_NO_PADDING;
1704 ret = CKR_FUNCTION_NOT_SUPPORTED;
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;
1717 buffer = OPENSSL_malloc(buffer_len);
1718 if (buffer == NULL) {
1719 ret = CKR_DEVICE_MEMORY;
1723 if (EVP_PKEY_decrypt(ctx, buffer, &buffer_len, pEncryptedData,
1724 ulEncryptedDataLen) <= 0) {
1725 ret = CKR_DEVICE_ERROR;
1728 st_logf("Decrypt done\n");
1730 if (pData != NULL_PTR)
1731 memcpy(pData, buffer, buffer_len);
1732 *pulDataLen = buffer_len;
1736 OPENSSL_cleanse(buffer, buffer_len);
1737 OPENSSL_free(buffer);
1738 EVP_PKEY_CTX_free(ctx);
1744 C_DecryptUpdate(CK_SESSION_HANDLE hSession,
1745 CK_BYTE_PTR pEncryptedPart,
1746 CK_ULONG ulEncryptedPartLen,
1748 CK_ULONG_PTR pulPartLen)
1751 st_logf("DecryptUpdate\n");
1752 VERIFY_SESSION_HANDLE(hSession, NULL);
1753 return CKR_FUNCTION_NOT_SUPPORTED;
1758 C_DecryptFinal(CK_SESSION_HANDLE hSession,
1759 CK_BYTE_PTR pLastPart,
1760 CK_ULONG_PTR pulLastPartLen)
1762 st_logf("DecryptFinal\n");
1763 VERIFY_SESSION_HANDLE(hSession, NULL);
1764 return CKR_FUNCTION_NOT_SUPPORTED;
1768 C_DigestInit(CK_SESSION_HANDLE hSession,
1769 CK_MECHANISM_PTR pMechanism)
1771 st_logf("DigestInit\n");
1772 VERIFY_SESSION_HANDLE(hSession, NULL);
1773 return CKR_FUNCTION_NOT_SUPPORTED;
1777 C_SignInit(CK_SESSION_HANDLE hSession,
1778 CK_MECHANISM_PTR pMechanism,
1779 CK_OBJECT_HANDLE hKey)
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) }
1787 struct st_object *o;
1790 st_logf("SignInit\n");
1791 VERIFY_SESSION_HANDLE(hSession, &state);
1793 ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
1794 mechs, sizeof(mechs)/sizeof(mechs[0]),
1795 pMechanism, hKey, &o);
1799 ret = dup_mechanism(&state->sign_mechanism, pMechanism);
1801 state->sign_object = OBJECT_ID(o);
1807 C_Sign(CK_SESSION_HANDLE hSession,
1810 CK_BYTE_PTR pSignature,
1811 CK_ULONG_PTR pulSignatureLen)
1813 struct session_state *state;
1814 struct st_object *o;
1815 void *buffer = NULL;
1818 size_t buffer_len = 0;
1819 EVP_PKEY_CTX *ctx = NULL;
1822 VERIFY_SESSION_HANDLE(hSession, &state);
1824 if (state->sign_object == -1)
1825 return CKR_ARGUMENTS_BAD;
1827 o = soft_token.object.objs[state->sign_object];
1829 if (o->u.private_key.key == NULL) {
1830 st_logf("private key NULL\n");
1831 return CKR_ARGUMENTS_BAD;
1834 if (pulSignatureLen == NULL) {
1835 st_logf("signature len NULL\n");
1836 ret = CKR_ARGUMENTS_BAD;
1840 if (pData == NULL_PTR) {
1841 st_logf("data NULL\n");
1842 ret = CKR_ARGUMENTS_BAD;
1846 switch(state->sign_mechanism->mechanism) {
1848 padding = RSA_PKCS1_PADDING;
1851 padding = RSA_NO_PADDING;
1854 ret = CKR_FUNCTION_NOT_SUPPORTED;
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;
1866 buffer = OPENSSL_malloc(buffer_len);
1867 if (buffer == NULL) {
1868 ret = CKR_DEVICE_MEMORY;
1872 if (EVP_PKEY_sign(ctx, buffer, &buffer_len, pData, ulDataLen) <= 0) {
1873 ret = CKR_DEVICE_ERROR;
1876 st_logf("Sign done\n");
1878 if (pSignature != NULL)
1879 memcpy(pSignature, buffer, buffer_len);
1880 *pulSignatureLen = buffer_len;
1884 OPENSSL_cleanse(buffer, buffer_len);
1885 OPENSSL_free(buffer);
1886 EVP_PKEY_CTX_free(ctx);
1891 C_SignUpdate(CK_SESSION_HANDLE hSession,
1895 st_logf("SignUpdate\n");
1896 VERIFY_SESSION_HANDLE(hSession, NULL);
1897 return CKR_FUNCTION_NOT_SUPPORTED;
1902 C_SignFinal(CK_SESSION_HANDLE hSession,
1903 CK_BYTE_PTR pSignature,
1904 CK_ULONG_PTR pulSignatureLen)
1906 st_logf("SignUpdate\n");
1907 VERIFY_SESSION_HANDLE(hSession, NULL);
1908 return CKR_FUNCTION_NOT_SUPPORTED;
1912 C_VerifyInit(CK_SESSION_HANDLE hSession,
1913 CK_MECHANISM_PTR pMechanism,
1914 CK_OBJECT_HANDLE hKey)
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) }
1922 struct st_object *o;
1925 st_logf("VerifyInit\n");
1926 VERIFY_SESSION_HANDLE(hSession, &state);
1928 ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
1929 mechs, sizeof(mechs)/sizeof(mechs[0]),
1930 pMechanism, hKey, &o);
1934 ret = dup_mechanism(&state->verify_mechanism, pMechanism);
1936 state->verify_object = OBJECT_ID(o);
1942 C_Verify(CK_SESSION_HANDLE hSession,
1945 CK_BYTE_PTR pSignature,
1946 CK_ULONG ulSignatureLen)
1948 struct session_state *state;
1949 struct st_object *o;
1952 EVP_PKEY_CTX *ctx = NULL;
1954 st_logf("Verify\n");
1955 VERIFY_SESSION_HANDLE(hSession, &state);
1957 if (state->verify_object == -1)
1958 return CKR_ARGUMENTS_BAD;
1960 o = soft_token.object.objs[state->verify_object];
1962 if (o->u.public_key == NULL) {
1963 st_logf("public key NULL\n");
1964 return CKR_ARGUMENTS_BAD;
1967 if (pSignature == NULL) {
1968 st_logf("signature NULL\n");
1969 ret = CKR_ARGUMENTS_BAD;
1973 if (pData == NULL_PTR) {
1974 st_logf("data NULL\n");
1975 ret = CKR_ARGUMENTS_BAD;
1979 switch(state->verify_mechanism->mechanism) {
1981 padding = RSA_PKCS1_PADDING;
1984 padding = RSA_NO_PADDING;
1987 ret = CKR_FUNCTION_NOT_SUPPORTED;
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,
1996 ret = CKR_DEVICE_ERROR;
1999 st_logf("Verify done\n");
2003 EVP_PKEY_CTX_free(ctx);
2008 C_VerifyUpdate(CK_SESSION_HANDLE hSession,
2012 st_logf("VerifyUpdate\n");
2013 VERIFY_SESSION_HANDLE(hSession, NULL);
2014 return CKR_FUNCTION_NOT_SUPPORTED;
2018 C_VerifyFinal(CK_SESSION_HANDLE hSession,
2019 CK_BYTE_PTR pSignature,
2020 CK_ULONG ulSignatureLen)
2022 st_logf("VerifyFinal\n");
2023 VERIFY_SESSION_HANDLE(hSession, NULL);
2024 return CKR_FUNCTION_NOT_SUPPORTED;
2028 C_GenerateRandom(CK_SESSION_HANDLE hSession,
2029 CK_BYTE_PTR RandomData,
2030 CK_ULONG ulRandomLen)
2032 st_logf("GenerateRandom\n");
2033 VERIFY_SESSION_HANDLE(hSession, NULL);
2034 return CKR_FUNCTION_NOT_SUPPORTED;
2037 CK_FUNCTION_LIST funcs = {
2049 (void *)func_not_supported, /* C_InitPIN */
2050 (void *)func_not_supported, /* C_SetPIN */
2055 (void *)func_not_supported, /* C_GetOperationState */
2056 (void *)func_not_supported, /* C_SetOperationState */
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 */
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 */
2085 (void *)func_not_supported, /* C_SignRecoverInit */
2086 (void *)func_not_supported, /* C_SignRecover */
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 */
2104 (void *)func_not_supported, /* C_GetFunctionStatus */
2105 (void *)func_not_supported, /* C_CancelFunction */
2106 (void *)func_not_supported /* C_WaitForSlotEvent */