Path: blob/main/crypto/heimdal/lib/hx509/softp11.c
34878 views
/*1* Copyright (c) 2004 - 2008 Kungliga Tekniska Högskolan2* (Royal Institute of Technology, Stockholm, Sweden).3* All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8*9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11*12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* 3. Neither the name of the Institute nor the names of its contributors17* may be used to endorse or promote products derived from this software18* without specific prior written permission.19*20* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND21* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE23* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE24* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL25* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS26* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)27* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT28* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY29* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF30* SUCH DAMAGE.31*/3233#define CRYPTOKI_EXPORTS 13435#include "hx_locl.h"36#include "pkcs11.h"3738#define OBJECT_ID_MASK 0xfff39#define HANDLE_OBJECT_ID(h) ((h) & OBJECT_ID_MASK)40#define OBJECT_ID(obj) HANDLE_OBJECT_ID((obj)->object_handle)4142#ifndef HAVE_RANDOM43#define random() rand()44#define srandom(s) srand(s)45#endif4647#ifdef _WIN3248#include <shlobj.h>49#endif5051struct st_attr {52CK_ATTRIBUTE attribute;53int secret;54};5556struct st_object {57CK_OBJECT_HANDLE object_handle;58struct st_attr *attrs;59int num_attributes;60hx509_cert cert;61};6263static struct soft_token {64CK_VOID_PTR application;65CK_NOTIFY notify;66char *config_file;67hx509_certs certs;68struct {69struct st_object **objs;70int num_objs;71} object;72struct {73int hardware_slot;74int app_error_fatal;75int login_done;76} flags;77int open_sessions;78struct session_state {79CK_SESSION_HANDLE session_handle;8081struct {82CK_ATTRIBUTE *attributes;83CK_ULONG num_attributes;84int next_object;85} find;8687int sign_object;88CK_MECHANISM_PTR sign_mechanism;89int verify_object;90CK_MECHANISM_PTR verify_mechanism;91} state[10];92#define MAX_NUM_SESSION (sizeof(soft_token.state)/sizeof(soft_token.state[0]))93FILE *logfile;94} soft_token;9596static hx509_context context;9798static void99application_error(const char *fmt, ...)100{101va_list ap;102va_start(ap, fmt);103vprintf(fmt, ap);104va_end(ap);105if (soft_token.flags.app_error_fatal)106abort();107}108109static void110st_logf(const char *fmt, ...)111{112va_list ap;113if (soft_token.logfile == NULL)114return;115va_start(ap, fmt);116vfprintf(soft_token.logfile, fmt, ap);117va_end(ap);118fflush(soft_token.logfile);119}120121static CK_RV122init_context(void)123{124if (context == NULL) {125int ret = hx509_context_init(&context);126if (ret)127return CKR_GENERAL_ERROR;128}129return CKR_OK;130}131132#define INIT_CONTEXT() { CK_RV icret = init_context(); if (icret) return icret; }133134static void135snprintf_fill(char *str, size_t size, char fillchar, const char *fmt, ...)136{137int len;138va_list ap;139va_start(ap, fmt);140len = vsnprintf(str, size, fmt, ap);141va_end(ap);142if (len < 0 || (size_t)len > size)143return;144while ((size_t)len < size)145str[len++] = fillchar;146}147148#ifndef TEST_APP149#define printf error_use_st_logf150#endif151152#define VERIFY_SESSION_HANDLE(s, state) \153{ \154CK_RV xret; \155xret = verify_session_handle(s, state); \156if (xret != CKR_OK) { \157/* return CKR_OK */; \158} \159}160161static CK_RV162verify_session_handle(CK_SESSION_HANDLE hSession,163struct session_state **state)164{165size_t i;166167for (i = 0; i < MAX_NUM_SESSION; i++){168if (soft_token.state[i].session_handle == hSession)169break;170}171if (i == MAX_NUM_SESSION) {172application_error("use of invalid handle: 0x%08lx\n",173(unsigned long)hSession);174return CKR_SESSION_HANDLE_INVALID;175}176if (state)177*state = &soft_token.state[i];178return CKR_OK;179}180181static CK_RV182object_handle_to_object(CK_OBJECT_HANDLE handle,183struct st_object **object)184{185int i = HANDLE_OBJECT_ID(handle);186187*object = NULL;188if (i >= soft_token.object.num_objs)189return CKR_ARGUMENTS_BAD;190if (soft_token.object.objs[i] == NULL)191return CKR_ARGUMENTS_BAD;192if (soft_token.object.objs[i]->object_handle != handle)193return CKR_ARGUMENTS_BAD;194*object = soft_token.object.objs[i];195return CKR_OK;196}197198static int199attributes_match(const struct st_object *obj,200const CK_ATTRIBUTE *attributes,201CK_ULONG num_attributes)202{203CK_ULONG i;204int j;205206st_logf("attributes_match: %ld\n", (unsigned long)OBJECT_ID(obj));207208for (i = 0; i < num_attributes; i++) {209int match = 0;210for (j = 0; j < obj->num_attributes; j++) {211if (attributes[i].type == obj->attrs[j].attribute.type &&212attributes[i].ulValueLen == obj->attrs[j].attribute.ulValueLen &&213memcmp(attributes[i].pValue, obj->attrs[j].attribute.pValue,214attributes[i].ulValueLen) == 0) {215match = 1;216break;217}218}219if (match == 0) {220st_logf("type %d attribute have no match\n", attributes[i].type);221return 0;222}223}224st_logf("attribute matches\n");225return 1;226}227228static void229print_attributes(const CK_ATTRIBUTE *attributes,230CK_ULONG num_attributes)231{232CK_ULONG i;233234st_logf("find objects: attrs: %lu\n", (unsigned long)num_attributes);235236for (i = 0; i < num_attributes; i++) {237st_logf(" type: ");238switch (attributes[i].type) {239case CKA_TOKEN: {240CK_BBOOL *ck_true;241if (attributes[i].ulValueLen != sizeof(CK_BBOOL)) {242application_error("token attribute wrong length\n");243break;244}245ck_true = attributes[i].pValue;246st_logf("token: %s", *ck_true ? "TRUE" : "FALSE");247break;248}249case CKA_CLASS: {250CK_OBJECT_CLASS *class;251if (attributes[i].ulValueLen != sizeof(CK_ULONG)) {252application_error("class attribute wrong length\n");253break;254}255class = attributes[i].pValue;256st_logf("class ");257switch (*class) {258case CKO_CERTIFICATE:259st_logf("certificate");260break;261case CKO_PUBLIC_KEY:262st_logf("public key");263break;264case CKO_PRIVATE_KEY:265st_logf("private key");266break;267case CKO_SECRET_KEY:268st_logf("secret key");269break;270case CKO_DOMAIN_PARAMETERS:271st_logf("domain parameters");272break;273default:274st_logf("[class %lx]", (long unsigned)*class);275break;276}277break;278}279case CKA_PRIVATE:280st_logf("private");281break;282case CKA_LABEL:283st_logf("label");284break;285case CKA_APPLICATION:286st_logf("application");287break;288case CKA_VALUE:289st_logf("value");290break;291case CKA_ID:292st_logf("id");293break;294default:295st_logf("[unknown 0x%08lx]", (unsigned long)attributes[i].type);296break;297}298st_logf("\n");299}300}301302static struct st_object *303add_st_object(void)304{305struct st_object *o, **objs;306int i;307308o = calloc(1, sizeof(*o));309if (o == NULL)310return NULL;311312for (i = 0; i < soft_token.object.num_objs; i++) {313if (soft_token.object.objs == NULL) {314soft_token.object.objs[i] = o;315break;316}317}318if (i == soft_token.object.num_objs) {319objs = realloc(soft_token.object.objs,320(soft_token.object.num_objs + 1) * sizeof(soft_token.object.objs[0]));321if (objs == NULL) {322free(o);323return NULL;324}325soft_token.object.objs = objs;326soft_token.object.objs[soft_token.object.num_objs++] = o;327}328soft_token.object.objs[i]->object_handle =329(random() & (~OBJECT_ID_MASK)) | i;330331return o;332}333334static CK_RV335add_object_attribute(struct st_object *o,336int secret,337CK_ATTRIBUTE_TYPE type,338CK_VOID_PTR pValue,339CK_ULONG ulValueLen)340{341struct st_attr *a;342int i;343344if (pValue == NULL && ulValueLen)345return CKR_ARGUMENTS_BAD;346347i = o->num_attributes;348a = realloc(o->attrs, (i + 1) * sizeof(o->attrs[0]));349if (a == NULL)350return CKR_DEVICE_MEMORY;351o->attrs = a;352o->attrs[i].secret = secret;353o->attrs[i].attribute.type = type;354o->attrs[i].attribute.pValue = malloc(ulValueLen);355if (o->attrs[i].attribute.pValue == NULL && ulValueLen != 0)356return CKR_DEVICE_MEMORY;357if (ulValueLen)358memcpy(o->attrs[i].attribute.pValue, pValue, ulValueLen);359o->attrs[i].attribute.ulValueLen = ulValueLen;360o->num_attributes++;361362return CKR_OK;363}364365static CK_RV366add_pubkey_info(hx509_context hxctx, struct st_object *o,367CK_KEY_TYPE key_type, hx509_cert cert)368{369BIGNUM *num;370CK_BYTE *modulus = NULL;371size_t modulus_len = 0;372CK_ULONG modulus_bits = 0;373CK_BYTE *exponent = NULL;374size_t exponent_len = 0;375376if (key_type != CKK_RSA)377return CKR_OK;378if (_hx509_cert_private_key(cert) == NULL)379return CKR_OK;380381num = _hx509_private_key_get_internal(context,382_hx509_cert_private_key(cert),383"rsa-modulus");384if (num == NULL)385return CKR_GENERAL_ERROR;386modulus_bits = BN_num_bits(num);387388modulus_len = BN_num_bytes(num);389modulus = malloc(modulus_len);390BN_bn2bin(num, modulus);391BN_free(num);392393add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len);394add_object_attribute(o, 0, CKA_MODULUS_BITS,395&modulus_bits, sizeof(modulus_bits));396397free(modulus);398399num = _hx509_private_key_get_internal(context,400_hx509_cert_private_key(cert),401"rsa-exponent");402if (num == NULL)403return CKR_GENERAL_ERROR;404405exponent_len = BN_num_bytes(num);406exponent = malloc(exponent_len);407BN_bn2bin(num, exponent);408BN_free(num);409410add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT,411exponent, exponent_len);412413free(exponent);414415return CKR_OK;416}417418419struct foo {420char *label;421char *id;422};423424static int425add_cert(hx509_context hxctx, void *ctx, hx509_cert cert)426{427static char empty[] = "";428struct foo *foo = (struct foo *)ctx;429struct st_object *o = NULL;430CK_OBJECT_CLASS type;431CK_BBOOL bool_true = CK_TRUE;432CK_BBOOL bool_false = CK_FALSE;433CK_CERTIFICATE_TYPE cert_type = CKC_X_509;434CK_KEY_TYPE key_type;435CK_MECHANISM_TYPE mech_type;436CK_RV ret = CKR_GENERAL_ERROR;437int hret;438heim_octet_string cert_data, subject_data, issuer_data, serial_data;439440st_logf("adding certificate\n");441442serial_data.data = NULL;443serial_data.length = 0;444cert_data = subject_data = issuer_data = serial_data;445446hret = hx509_cert_binary(hxctx, cert, &cert_data);447if (hret)448goto out;449450{451hx509_name name;452453hret = hx509_cert_get_issuer(cert, &name);454if (hret)455goto out;456hret = hx509_name_binary(name, &issuer_data);457hx509_name_free(&name);458if (hret)459goto out;460461hret = hx509_cert_get_subject(cert, &name);462if (hret)463goto out;464hret = hx509_name_binary(name, &subject_data);465hx509_name_free(&name);466if (hret)467goto out;468}469470{471AlgorithmIdentifier alg;472473hret = hx509_cert_get_SPKI_AlgorithmIdentifier(context, cert, &alg);474if (hret) {475ret = CKR_DEVICE_MEMORY;476goto out;477}478479key_type = CKK_RSA; /* XXX */480481free_AlgorithmIdentifier(&alg);482}483484485type = CKO_CERTIFICATE;486o = add_st_object();487if (o == NULL) {488ret = CKR_DEVICE_MEMORY;489goto out;490}491492o->cert = hx509_cert_ref(cert);493494add_object_attribute(o, 0, CKA_CLASS, &type, sizeof(type));495add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true));496add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false));497add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false));498add_object_attribute(o, 0, CKA_LABEL, foo->label, strlen(foo->label));499500add_object_attribute(o, 0, CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type));501add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id));502503add_object_attribute(o, 0, CKA_SUBJECT, subject_data.data, subject_data.length);504add_object_attribute(o, 0, CKA_ISSUER, issuer_data.data, issuer_data.length);505add_object_attribute(o, 0, CKA_SERIAL_NUMBER, serial_data.data, serial_data.length);506add_object_attribute(o, 0, CKA_VALUE, cert_data.data, cert_data.length);507add_object_attribute(o, 0, CKA_TRUSTED, &bool_false, sizeof(bool_false));508509st_logf("add cert ok: %lx\n", (unsigned long)OBJECT_ID(o));510511type = CKO_PUBLIC_KEY;512o = add_st_object();513if (o == NULL) {514ret = CKR_DEVICE_MEMORY;515goto out;516}517o->cert = hx509_cert_ref(cert);518519add_object_attribute(o, 0, CKA_CLASS, &type, sizeof(type));520add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true));521add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false));522add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false));523add_object_attribute(o, 0, CKA_LABEL, foo->label, strlen(foo->label));524525add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type));526add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id));527add_object_attribute(o, 0, CKA_START_DATE, empty, 1); /* XXX */528add_object_attribute(o, 0, CKA_END_DATE, empty, 1); /* XXX */529add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false));530add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false));531mech_type = CKM_RSA_X_509;532add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type));533534add_object_attribute(o, 0, CKA_SUBJECT, subject_data.data, subject_data.length);535add_object_attribute(o, 0, CKA_ENCRYPT, &bool_true, sizeof(bool_true));536add_object_attribute(o, 0, CKA_VERIFY, &bool_true, sizeof(bool_true));537add_object_attribute(o, 0, CKA_VERIFY_RECOVER, &bool_false, sizeof(bool_false));538add_object_attribute(o, 0, CKA_WRAP, &bool_true, sizeof(bool_true));539add_object_attribute(o, 0, CKA_TRUSTED, &bool_true, sizeof(bool_true));540541add_pubkey_info(hxctx, o, key_type, cert);542543st_logf("add key ok: %lx\n", (unsigned long)OBJECT_ID(o));544545if (hx509_cert_have_private_key(cert)) {546CK_FLAGS flags;547548type = CKO_PRIVATE_KEY;549o = add_st_object();550if (o == NULL) {551ret = CKR_DEVICE_MEMORY;552goto out;553}554o->cert = hx509_cert_ref(cert);555556add_object_attribute(o, 0, CKA_CLASS, &type, sizeof(type));557add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true));558add_object_attribute(o, 0, CKA_PRIVATE, &bool_true, sizeof(bool_false));559add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false));560add_object_attribute(o, 0, CKA_LABEL, foo->label, strlen(foo->label));561562add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type));563add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id));564add_object_attribute(o, 0, CKA_START_DATE, empty, 1); /* XXX */565add_object_attribute(o, 0, CKA_END_DATE, empty, 1); /* XXX */566add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false));567add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false));568mech_type = CKM_RSA_X_509;569add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type));570571add_object_attribute(o, 0, CKA_SUBJECT, subject_data.data, subject_data.length);572add_object_attribute(o, 0, CKA_SENSITIVE, &bool_true, sizeof(bool_true));573add_object_attribute(o, 0, CKA_SECONDARY_AUTH, &bool_false, sizeof(bool_true));574flags = 0;575add_object_attribute(o, 0, CKA_AUTH_PIN_FLAGS, &flags, sizeof(flags));576577add_object_attribute(o, 0, CKA_DECRYPT, &bool_true, sizeof(bool_true));578add_object_attribute(o, 0, CKA_SIGN, &bool_true, sizeof(bool_true));579add_object_attribute(o, 0, CKA_SIGN_RECOVER, &bool_false, sizeof(bool_false));580add_object_attribute(o, 0, CKA_UNWRAP, &bool_true, sizeof(bool_true));581add_object_attribute(o, 0, CKA_EXTRACTABLE, &bool_true, sizeof(bool_true));582add_object_attribute(o, 0, CKA_NEVER_EXTRACTABLE, &bool_false, sizeof(bool_false));583584add_pubkey_info(hxctx, o, key_type, cert);585}586587ret = CKR_OK;588out:589if (ret != CKR_OK) {590st_logf("something went wrong when adding cert!\n");591592/* XXX wack o */;593}594hx509_xfree(cert_data.data);595hx509_xfree(serial_data.data);596hx509_xfree(issuer_data.data);597hx509_xfree(subject_data.data);598599return 0;600}601602static CK_RV603add_certificate(const char *cert_file,604const char *pin,605char *id,606char *label)607{608hx509_certs certs;609hx509_lock lock = NULL;610int ret, flags = 0;611612struct foo foo;613foo.id = id;614foo.label = label;615616if (pin == NULL)617flags |= HX509_CERTS_UNPROTECT_ALL;618619if (pin) {620char *str;621asprintf(&str, "PASS:%s", pin);622623hx509_lock_init(context, &lock);624hx509_lock_command_string(lock, str);625626memset(str, 0, strlen(str));627free(str);628}629630ret = hx509_certs_init(context, cert_file, flags, lock, &certs);631if (ret) {632st_logf("failed to open file %s\n", cert_file);633return CKR_GENERAL_ERROR;634}635636ret = hx509_certs_iter_f(context, certs, add_cert, &foo);637hx509_certs_free(&certs);638if (ret) {639st_logf("failed adding certs from file %s\n", cert_file);640return CKR_GENERAL_ERROR;641}642643return CKR_OK;644}645646static void647find_object_final(struct session_state *state)648{649if (state->find.attributes) {650CK_ULONG i;651652for (i = 0; i < state->find.num_attributes; i++) {653if (state->find.attributes[i].pValue)654free(state->find.attributes[i].pValue);655}656free(state->find.attributes);657state->find.attributes = NULL;658state->find.num_attributes = 0;659state->find.next_object = -1;660}661}662663static void664reset_crypto_state(struct session_state *state)665{666state->sign_object = -1;667if (state->sign_mechanism)668free(state->sign_mechanism);669state->sign_mechanism = NULL_PTR;670state->verify_object = -1;671if (state->verify_mechanism)672free(state->verify_mechanism);673state->verify_mechanism = NULL_PTR;674}675676static void677close_session(struct session_state *state)678{679if (state->find.attributes) {680application_error("application didn't do C_FindObjectsFinal\n");681find_object_final(state);682}683684state->session_handle = CK_INVALID_HANDLE;685soft_token.application = NULL_PTR;686soft_token.notify = NULL_PTR;687reset_crypto_state(state);688}689690static const char *691has_session(void)692{693return soft_token.open_sessions > 0 ? "yes" : "no";694}695696static CK_RV697read_conf_file(const char *fn, CK_USER_TYPE userType, const char *pin)698{699char buf[1024], *type, *s, *p;700FILE *f;701CK_RV ret = CKR_OK;702CK_RV failed = CKR_OK;703704if (fn == NULL) {705st_logf("Can't open configuration file. No file specified\n");706return CKR_GENERAL_ERROR;707}708709f = fopen(fn, "r");710if (f == NULL) {711st_logf("can't open configuration file %s\n", fn);712return CKR_GENERAL_ERROR;713}714rk_cloexec_file(f);715716while(fgets(buf, sizeof(buf), f) != NULL) {717buf[strcspn(buf, "\n")] = '\0';718719st_logf("line: %s\n", buf);720721p = buf;722while (isspace((unsigned char)*p))723p++;724if (*p == '#')725continue;726while (isspace((unsigned char)*p))727p++;728729s = NULL;730type = strtok_r(p, "\t", &s);731if (type == NULL)732continue;733734if (strcasecmp("certificate", type) == 0) {735char *cert, *id, *label;736737id = strtok_r(NULL, "\t", &s);738if (id == NULL) {739st_logf("no id\n");740continue;741}742st_logf("id: %s\n", id);743label = strtok_r(NULL, "\t", &s);744if (label == NULL) {745st_logf("no label\n");746continue;747}748cert = strtok_r(NULL, "\t", &s);749if (cert == NULL) {750st_logf("no certfiicate store\n");751continue;752}753754st_logf("adding: %s: %s in file %s\n", id, label, cert);755756ret = add_certificate(cert, pin, id, label);757if (ret)758failed = ret;759} else if (strcasecmp("debug", type) == 0) {760char *name;761762name = strtok_r(NULL, "\t", &s);763if (name == NULL) {764st_logf("no filename\n");765continue;766}767768if (soft_token.logfile)769fclose(soft_token.logfile);770771if (strcasecmp(name, "stdout") == 0)772soft_token.logfile = stdout;773else {774soft_token.logfile = fopen(name, "a");775if (soft_token.logfile)776rk_cloexec_file(soft_token.logfile);777}778if (soft_token.logfile == NULL)779st_logf("failed to open file: %s\n", name);780781} else if (strcasecmp("app-fatal", type) == 0) {782char *name;783784name = strtok_r(NULL, "\t", &s);785if (name == NULL) {786st_logf("argument to app-fatal\n");787continue;788}789790if (strcmp(name, "true") == 0 || strcmp(name, "on") == 0)791soft_token.flags.app_error_fatal = 1;792else if (strcmp(name, "false") == 0 || strcmp(name, "off") == 0)793soft_token.flags.app_error_fatal = 0;794else795st_logf("unknown app-fatal: %s\n", name);796797} else {798st_logf("unknown type: %s\n", type);799}800}801802fclose(f);803804return failed;805}806807static CK_RV808func_not_supported(void)809{810st_logf("function not supported\n");811return CKR_FUNCTION_NOT_SUPPORTED;812}813814static char *815get_config_file_for_user(void)816{817char *fn = NULL;818819#ifndef _WIN32820char *home = NULL;821822if (!issuid()) {823fn = getenv("SOFTPKCS11RC");824if (fn)825fn = strdup(fn);826home = getenv("HOME");827}828if (fn == NULL && home == NULL) {829struct passwd *pw = getpwuid(getuid());830if(pw != NULL)831home = pw->pw_dir;832}833if (fn == NULL) {834if (home)835asprintf(&fn, "%s/.soft-token.rc", home);836else837fn = strdup("/etc/soft-token.rc");838}839#else /* Windows */840841char appdatafolder[MAX_PATH];842843fn = getenv("SOFTPKCS11RC");844845/* Retrieve the roaming AppData folder for the current user. The846current user is the user account represented by the current847thread token. */848849if (fn == NULL &&850SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, appdatafolder))) {851852asprintf(&fn, "%s\\.soft-token.rc", appdatafolder);853}854855#endif /* _WIN32 */856857return fn;858}859860861CK_RV CK_SPEC862C_Initialize(CK_VOID_PTR a)863{864CK_C_INITIALIZE_ARGS_PTR args = a;865CK_RV ret;866size_t i;867868st_logf("Initialize\n");869870INIT_CONTEXT();871872OpenSSL_add_all_algorithms();873874srandom(getpid() ^ (int) time(NULL));875876for (i = 0; i < MAX_NUM_SESSION; i++) {877soft_token.state[i].session_handle = CK_INVALID_HANDLE;878soft_token.state[i].find.attributes = NULL;879soft_token.state[i].find.num_attributes = 0;880soft_token.state[i].find.next_object = -1;881reset_crypto_state(&soft_token.state[i]);882}883884soft_token.flags.hardware_slot = 1;885soft_token.flags.app_error_fatal = 0;886soft_token.flags.login_done = 0;887888soft_token.object.objs = NULL;889soft_token.object.num_objs = 0;890891soft_token.logfile = NULL;892#if 0893soft_token.logfile = stdout;894#endif895#if 0896soft_token.logfile = fopen("/tmp/log-pkcs11.txt", "a");897#endif898899if (a != NULL_PTR) {900st_logf("\tCreateMutex:\t%p\n", args->CreateMutex);901st_logf("\tDestroyMutext\t%p\n", args->DestroyMutex);902st_logf("\tLockMutext\t%p\n", args->LockMutex);903st_logf("\tUnlockMutext\t%p\n", args->UnlockMutex);904st_logf("\tFlags\t%04x\n", (unsigned int)args->flags);905}906907soft_token.config_file = get_config_file_for_user();908909/*910* This operations doesn't return CKR_OK if any of the911* certificates failes to be unparsed (ie password protected).912*/913ret = read_conf_file(soft_token.config_file, CKU_USER, NULL);914if (ret == CKR_OK)915soft_token.flags.login_done = 1;916917return CKR_OK;918}919920CK_RV921C_Finalize(CK_VOID_PTR args)922{923size_t i;924925INIT_CONTEXT();926927st_logf("Finalize\n");928929for (i = 0; i < MAX_NUM_SESSION; i++) {930if (soft_token.state[i].session_handle != CK_INVALID_HANDLE) {931application_error("application finalized without "932"closing session\n");933close_session(&soft_token.state[i]);934}935}936937return CKR_OK;938}939940CK_RV941C_GetInfo(CK_INFO_PTR args)942{943INIT_CONTEXT();944945st_logf("GetInfo\n");946947memset(args, 17, sizeof(*args));948args->cryptokiVersion.major = 2;949args->cryptokiVersion.minor = 10;950snprintf_fill((char *)args->manufacturerID,951sizeof(args->manufacturerID),952' ',953"Heimdal hx509 SoftToken");954snprintf_fill((char *)args->libraryDescription,955sizeof(args->libraryDescription), ' ',956"Heimdal hx509 SoftToken");957args->libraryVersion.major = 2;958args->libraryVersion.minor = 0;959960return CKR_OK;961}962963extern CK_FUNCTION_LIST funcs;964965CK_RV966C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)967{968INIT_CONTEXT();969970*ppFunctionList = &funcs;971return CKR_OK;972}973974CK_RV975C_GetSlotList(CK_BBOOL tokenPresent,976CK_SLOT_ID_PTR pSlotList,977CK_ULONG_PTR pulCount)978{979INIT_CONTEXT();980st_logf("GetSlotList: %s\n",981tokenPresent ? "tokenPresent" : "token not Present");982if (pSlotList)983pSlotList[0] = 1;984*pulCount = 1;985return CKR_OK;986}987988CK_RV989C_GetSlotInfo(CK_SLOT_ID slotID,990CK_SLOT_INFO_PTR pInfo)991{992INIT_CONTEXT();993st_logf("GetSlotInfo: slot: %d : %s\n", (int)slotID, has_session());994995memset(pInfo, 18, sizeof(*pInfo));996997if (slotID != 1)998return CKR_ARGUMENTS_BAD;9991000snprintf_fill((char *)pInfo->slotDescription,1001sizeof(pInfo->slotDescription),1002' ',1003"Heimdal hx509 SoftToken (slot)");1004snprintf_fill((char *)pInfo->manufacturerID,1005sizeof(pInfo->manufacturerID),1006' ',1007"Heimdal hx509 SoftToken (slot)");1008pInfo->flags = CKF_TOKEN_PRESENT;1009if (soft_token.flags.hardware_slot)1010pInfo->flags |= CKF_HW_SLOT;1011pInfo->hardwareVersion.major = 1;1012pInfo->hardwareVersion.minor = 0;1013pInfo->firmwareVersion.major = 1;1014pInfo->firmwareVersion.minor = 0;10151016return CKR_OK;1017}10181019CK_RV1020C_GetTokenInfo(CK_SLOT_ID slotID,1021CK_TOKEN_INFO_PTR pInfo)1022{1023INIT_CONTEXT();1024st_logf("GetTokenInfo: %s\n", has_session());10251026memset(pInfo, 19, sizeof(*pInfo));10271028snprintf_fill((char *)pInfo->label,1029sizeof(pInfo->label),1030' ',1031"Heimdal hx509 SoftToken (token)");1032snprintf_fill((char *)pInfo->manufacturerID,1033sizeof(pInfo->manufacturerID),1034' ',1035"Heimdal hx509 SoftToken (token)");1036snprintf_fill((char *)pInfo->model,1037sizeof(pInfo->model),1038' ',1039"Heimdal hx509 SoftToken (token)");1040snprintf_fill((char *)pInfo->serialNumber,1041sizeof(pInfo->serialNumber),1042' ',1043"4711");1044pInfo->flags =1045CKF_TOKEN_INITIALIZED |1046CKF_USER_PIN_INITIALIZED;10471048if (soft_token.flags.login_done == 0)1049pInfo->flags |= CKF_LOGIN_REQUIRED;10501051/* CFK_RNG |1052CKF_RESTORE_KEY_NOT_NEEDED |1053*/1054pInfo->ulMaxSessionCount = MAX_NUM_SESSION;1055pInfo->ulSessionCount = soft_token.open_sessions;1056pInfo->ulMaxRwSessionCount = MAX_NUM_SESSION;1057pInfo->ulRwSessionCount = soft_token.open_sessions;1058pInfo->ulMaxPinLen = 1024;1059pInfo->ulMinPinLen = 0;1060pInfo->ulTotalPublicMemory = 4711;1061pInfo->ulFreePublicMemory = 4712;1062pInfo->ulTotalPrivateMemory = 4713;1063pInfo->ulFreePrivateMemory = 4714;1064pInfo->hardwareVersion.major = 2;1065pInfo->hardwareVersion.minor = 0;1066pInfo->firmwareVersion.major = 2;1067pInfo->firmwareVersion.minor = 0;10681069return CKR_OK;1070}10711072CK_RV1073C_GetMechanismList(CK_SLOT_ID slotID,1074CK_MECHANISM_TYPE_PTR pMechanismList,1075CK_ULONG_PTR pulCount)1076{1077INIT_CONTEXT();1078st_logf("GetMechanismList\n");10791080*pulCount = 1;1081if (pMechanismList == NULL_PTR)1082return CKR_OK;1083pMechanismList[1] = CKM_RSA_PKCS;10841085return CKR_OK;1086}10871088CK_RV1089C_GetMechanismInfo(CK_SLOT_ID slotID,1090CK_MECHANISM_TYPE type,1091CK_MECHANISM_INFO_PTR pInfo)1092{1093INIT_CONTEXT();1094st_logf("GetMechanismInfo: slot %d type: %d\n",1095(int)slotID, (int)type);1096memset(pInfo, 0, sizeof(*pInfo));10971098return CKR_OK;1099}11001101CK_RV1102C_InitToken(CK_SLOT_ID slotID,1103CK_UTF8CHAR_PTR pPin,1104CK_ULONG ulPinLen,1105CK_UTF8CHAR_PTR pLabel)1106{1107INIT_CONTEXT();1108st_logf("InitToken: slot %d\n", (int)slotID);1109return CKR_FUNCTION_NOT_SUPPORTED;1110}11111112CK_RV1113C_OpenSession(CK_SLOT_ID slotID,1114CK_FLAGS flags,1115CK_VOID_PTR pApplication,1116CK_NOTIFY Notify,1117CK_SESSION_HANDLE_PTR phSession)1118{1119size_t i;1120INIT_CONTEXT();1121st_logf("OpenSession: slot: %d\n", (int)slotID);11221123if (soft_token.open_sessions == MAX_NUM_SESSION)1124return CKR_SESSION_COUNT;11251126soft_token.application = pApplication;1127soft_token.notify = Notify;11281129for (i = 0; i < MAX_NUM_SESSION; i++)1130if (soft_token.state[i].session_handle == CK_INVALID_HANDLE)1131break;1132if (i == MAX_NUM_SESSION)1133abort();11341135soft_token.open_sessions++;11361137soft_token.state[i].session_handle =1138(CK_SESSION_HANDLE)(random() & 0xfffff);1139*phSession = soft_token.state[i].session_handle;11401141return CKR_OK;1142}11431144CK_RV1145C_CloseSession(CK_SESSION_HANDLE hSession)1146{1147struct session_state *state;1148INIT_CONTEXT();1149st_logf("CloseSession\n");11501151if (verify_session_handle(hSession, &state) != CKR_OK)1152application_error("closed session not open");1153else1154close_session(state);11551156return CKR_OK;1157}11581159CK_RV1160C_CloseAllSessions(CK_SLOT_ID slotID)1161{1162size_t i;1163INIT_CONTEXT();11641165st_logf("CloseAllSessions\n");11661167for (i = 0; i < MAX_NUM_SESSION; i++)1168if (soft_token.state[i].session_handle != CK_INVALID_HANDLE)1169close_session(&soft_token.state[i]);11701171return CKR_OK;1172}11731174CK_RV1175C_GetSessionInfo(CK_SESSION_HANDLE hSession,1176CK_SESSION_INFO_PTR pInfo)1177{1178st_logf("GetSessionInfo\n");1179INIT_CONTEXT();11801181VERIFY_SESSION_HANDLE(hSession, NULL);11821183memset(pInfo, 20, sizeof(*pInfo));11841185pInfo->slotID = 1;1186if (soft_token.flags.login_done)1187pInfo->state = CKS_RO_USER_FUNCTIONS;1188else1189pInfo->state = CKS_RO_PUBLIC_SESSION;1190pInfo->flags = CKF_SERIAL_SESSION;1191pInfo->ulDeviceError = 0;11921193return CKR_OK;1194}11951196CK_RV1197C_Login(CK_SESSION_HANDLE hSession,1198CK_USER_TYPE userType,1199CK_UTF8CHAR_PTR pPin,1200CK_ULONG ulPinLen)1201{1202char *pin = NULL;1203CK_RV ret;1204INIT_CONTEXT();12051206st_logf("Login\n");12071208VERIFY_SESSION_HANDLE(hSession, NULL);12091210if (pPin != NULL_PTR) {1211asprintf(&pin, "%.*s", (int)ulPinLen, pPin);1212st_logf("type: %d password: %s\n", (int)userType, pin);1213}12141215/*1216* Login1217*/12181219ret = read_conf_file(soft_token.config_file, userType, pin);1220if (ret == CKR_OK)1221soft_token.flags.login_done = 1;12221223free(pin);12241225return soft_token.flags.login_done ? CKR_OK : CKR_PIN_INCORRECT;1226}12271228CK_RV1229C_Logout(CK_SESSION_HANDLE hSession)1230{1231st_logf("Logout\n");1232INIT_CONTEXT();12331234VERIFY_SESSION_HANDLE(hSession, NULL);1235return CKR_FUNCTION_NOT_SUPPORTED;1236}12371238CK_RV1239C_GetObjectSize(CK_SESSION_HANDLE hSession,1240CK_OBJECT_HANDLE hObject,1241CK_ULONG_PTR pulSize)1242{1243st_logf("GetObjectSize\n");1244INIT_CONTEXT();12451246VERIFY_SESSION_HANDLE(hSession, NULL);1247return CKR_FUNCTION_NOT_SUPPORTED;1248}12491250CK_RV1251C_GetAttributeValue(CK_SESSION_HANDLE hSession,1252CK_OBJECT_HANDLE hObject,1253CK_ATTRIBUTE_PTR pTemplate,1254CK_ULONG ulCount)1255{1256struct session_state *state;1257struct st_object *obj;1258CK_ULONG i;1259CK_RV ret;1260int j;12611262INIT_CONTEXT();12631264st_logf("GetAttributeValue: %lx\n",1265(unsigned long)HANDLE_OBJECT_ID(hObject));1266VERIFY_SESSION_HANDLE(hSession, &state);12671268if ((ret = object_handle_to_object(hObject, &obj)) != CKR_OK) {1269st_logf("object not found: %lx\n",1270(unsigned long)HANDLE_OBJECT_ID(hObject));1271return ret;1272}12731274for (i = 0; i < ulCount; i++) {1275st_logf(" getting 0x%08lx\n", (unsigned long)pTemplate[i].type);1276for (j = 0; j < obj->num_attributes; j++) {1277if (obj->attrs[j].secret) {1278pTemplate[i].ulValueLen = (CK_ULONG)-1;1279break;1280}1281if (pTemplate[i].type == obj->attrs[j].attribute.type) {1282if (pTemplate[i].pValue != NULL_PTR && obj->attrs[j].secret == 0) {1283if (pTemplate[i].ulValueLen >= obj->attrs[j].attribute.ulValueLen)1284memcpy(pTemplate[i].pValue, obj->attrs[j].attribute.pValue,1285obj->attrs[j].attribute.ulValueLen);1286}1287pTemplate[i].ulValueLen = obj->attrs[j].attribute.ulValueLen;1288break;1289}1290}1291if (j == obj->num_attributes) {1292st_logf("key type: 0x%08lx not found\n", (unsigned long)pTemplate[i].type);1293pTemplate[i].ulValueLen = (CK_ULONG)-1;1294}12951296}1297return CKR_OK;1298}12991300CK_RV1301C_FindObjectsInit(CK_SESSION_HANDLE hSession,1302CK_ATTRIBUTE_PTR pTemplate,1303CK_ULONG ulCount)1304{1305struct session_state *state;13061307st_logf("FindObjectsInit\n");13081309INIT_CONTEXT();13101311VERIFY_SESSION_HANDLE(hSession, &state);13121313if (state->find.next_object != -1) {1314application_error("application didn't do C_FindObjectsFinal\n");1315find_object_final(state);1316}1317if (ulCount) {1318CK_ULONG i;13191320print_attributes(pTemplate, ulCount);13211322state->find.attributes =1323calloc(1, ulCount * sizeof(state->find.attributes[0]));1324if (state->find.attributes == NULL)1325return CKR_DEVICE_MEMORY;1326for (i = 0; i < ulCount; i++) {1327state->find.attributes[i].pValue =1328malloc(pTemplate[i].ulValueLen);1329if (state->find.attributes[i].pValue == NULL) {1330find_object_final(state);1331return CKR_DEVICE_MEMORY;1332}1333memcpy(state->find.attributes[i].pValue,1334pTemplate[i].pValue, pTemplate[i].ulValueLen);1335state->find.attributes[i].type = pTemplate[i].type;1336state->find.attributes[i].ulValueLen = pTemplate[i].ulValueLen;1337}1338state->find.num_attributes = ulCount;1339state->find.next_object = 0;1340} else {1341st_logf("find all objects\n");1342state->find.attributes = NULL;1343state->find.num_attributes = 0;1344state->find.next_object = 0;1345}13461347return CKR_OK;1348}13491350CK_RV1351C_FindObjects(CK_SESSION_HANDLE hSession,1352CK_OBJECT_HANDLE_PTR phObject,1353CK_ULONG ulMaxObjectCount,1354CK_ULONG_PTR pulObjectCount)1355{1356struct session_state *state;1357int i;13581359INIT_CONTEXT();13601361st_logf("FindObjects\n");13621363VERIFY_SESSION_HANDLE(hSession, &state);13641365if (state->find.next_object == -1) {1366application_error("application didn't do C_FindObjectsInit\n");1367return CKR_ARGUMENTS_BAD;1368}1369if (ulMaxObjectCount == 0) {1370application_error("application asked for 0 objects\n");1371return CKR_ARGUMENTS_BAD;1372}1373*pulObjectCount = 0;1374for (i = state->find.next_object; i < soft_token.object.num_objs; i++) {1375st_logf("FindObjects: %d\n", i);1376state->find.next_object = i + 1;1377if (attributes_match(soft_token.object.objs[i],1378state->find.attributes,1379state->find.num_attributes)) {1380*phObject++ = soft_token.object.objs[i]->object_handle;1381ulMaxObjectCount--;1382(*pulObjectCount)++;1383if (ulMaxObjectCount == 0)1384break;1385}1386}1387return CKR_OK;1388}13891390CK_RV1391C_FindObjectsFinal(CK_SESSION_HANDLE hSession)1392{1393struct session_state *state;13941395INIT_CONTEXT();13961397st_logf("FindObjectsFinal\n");1398VERIFY_SESSION_HANDLE(hSession, &state);1399find_object_final(state);1400return CKR_OK;1401}14021403static CK_RV1404commonInit(CK_ATTRIBUTE *attr_match, int attr_match_len,1405const CK_MECHANISM_TYPE *mechs, int mechs_len,1406const CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey,1407struct st_object **o)1408{1409CK_RV ret;1410int i;14111412*o = NULL;1413if ((ret = object_handle_to_object(hKey, o)) != CKR_OK)1414return ret;14151416ret = attributes_match(*o, attr_match, attr_match_len);1417if (!ret) {1418application_error("called commonInit on key that doesn't "1419"support required attr");1420return CKR_ARGUMENTS_BAD;1421}14221423for (i = 0; i < mechs_len; i++)1424if (mechs[i] == pMechanism->mechanism)1425break;1426if (i == mechs_len) {1427application_error("called mech (%08lx) not supported\n",1428pMechanism->mechanism);1429return CKR_ARGUMENTS_BAD;1430}1431return CKR_OK;1432}143314341435static CK_RV1436dup_mechanism(CK_MECHANISM_PTR *dp, const CK_MECHANISM_PTR pMechanism)1437{1438CK_MECHANISM_PTR p;14391440p = malloc(sizeof(*p));1441if (p == NULL)1442return CKR_DEVICE_MEMORY;14431444if (*dp)1445free(*dp);1446*dp = p;1447memcpy(p, pMechanism, sizeof(*p));14481449return CKR_OK;1450}14511452CK_RV1453C_DigestInit(CK_SESSION_HANDLE hSession,1454CK_MECHANISM_PTR pMechanism)1455{1456st_logf("DigestInit\n");1457INIT_CONTEXT();1458VERIFY_SESSION_HANDLE(hSession, NULL);1459return CKR_FUNCTION_NOT_SUPPORTED;1460}14611462CK_RV1463C_SignInit(CK_SESSION_HANDLE hSession,1464CK_MECHANISM_PTR pMechanism,1465CK_OBJECT_HANDLE hKey)1466{1467struct session_state *state;1468CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS };1469CK_BBOOL bool_true = CK_TRUE;1470CK_ATTRIBUTE attr[] = {1471{ CKA_SIGN, &bool_true, sizeof(bool_true) }1472};1473struct st_object *o;1474CK_RV ret;14751476INIT_CONTEXT();1477st_logf("SignInit\n");1478VERIFY_SESSION_HANDLE(hSession, &state);14791480ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),1481mechs, sizeof(mechs)/sizeof(mechs[0]),1482pMechanism, hKey, &o);1483if (ret)1484return ret;14851486ret = dup_mechanism(&state->sign_mechanism, pMechanism);1487if (ret == CKR_OK)1488state->sign_object = OBJECT_ID(o);14891490return CKR_OK;1491}14921493CK_RV1494C_Sign(CK_SESSION_HANDLE hSession,1495CK_BYTE_PTR pData,1496CK_ULONG ulDataLen,1497CK_BYTE_PTR pSignature,1498CK_ULONG_PTR pulSignatureLen)1499{1500struct session_state *state;1501struct st_object *o;1502CK_RV ret;1503int hret;1504const AlgorithmIdentifier *alg;1505heim_octet_string sig, data;15061507INIT_CONTEXT();1508st_logf("Sign\n");1509VERIFY_SESSION_HANDLE(hSession, &state);15101511sig.data = NULL;1512sig.length = 0;15131514if (state->sign_object == -1)1515return CKR_ARGUMENTS_BAD;15161517if (pulSignatureLen == NULL) {1518st_logf("signature len NULL\n");1519ret = CKR_ARGUMENTS_BAD;1520goto out;1521}15221523if (pData == NULL_PTR) {1524st_logf("data NULL\n");1525ret = CKR_ARGUMENTS_BAD;1526goto out;1527}15281529o = soft_token.object.objs[state->sign_object];15301531if (hx509_cert_have_private_key(o->cert) == 0) {1532st_logf("private key NULL\n");1533return CKR_ARGUMENTS_BAD;1534}15351536switch(state->sign_mechanism->mechanism) {1537case CKM_RSA_PKCS:1538alg = hx509_signature_rsa_pkcs1_x509();1539break;1540default:1541ret = CKR_FUNCTION_NOT_SUPPORTED;1542goto out;1543}15441545data.data = pData;1546data.length = ulDataLen;15471548hret = _hx509_create_signature(context,1549_hx509_cert_private_key(o->cert),1550alg,1551&data,1552NULL,1553&sig);1554if (hret) {1555ret = CKR_DEVICE_ERROR;1556goto out;1557}1558*pulSignatureLen = sig.length;15591560if (pSignature != NULL_PTR)1561memcpy(pSignature, sig.data, sig.length);15621563ret = CKR_OK;1564out:1565if (sig.data) {1566memset(sig.data, 0, sig.length);1567der_free_octet_string(&sig);1568}1569return ret;1570}15711572CK_RV1573C_SignUpdate(CK_SESSION_HANDLE hSession,1574CK_BYTE_PTR pPart,1575CK_ULONG ulPartLen)1576{1577INIT_CONTEXT();1578st_logf("SignUpdate\n");1579VERIFY_SESSION_HANDLE(hSession, NULL);1580return CKR_FUNCTION_NOT_SUPPORTED;1581}158215831584CK_RV1585C_SignFinal(CK_SESSION_HANDLE hSession,1586CK_BYTE_PTR pSignature,1587CK_ULONG_PTR pulSignatureLen)1588{1589INIT_CONTEXT();1590st_logf("SignUpdate\n");1591VERIFY_SESSION_HANDLE(hSession, NULL);1592return CKR_FUNCTION_NOT_SUPPORTED;1593}15941595CK_RV1596C_VerifyInit(CK_SESSION_HANDLE hSession,1597CK_MECHANISM_PTR pMechanism,1598CK_OBJECT_HANDLE hKey)1599{1600struct session_state *state;1601CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS };1602CK_BBOOL bool_true = CK_TRUE;1603CK_ATTRIBUTE attr[] = {1604{ CKA_VERIFY, &bool_true, sizeof(bool_true) }1605};1606struct st_object *o;1607CK_RV ret;16081609INIT_CONTEXT();1610st_logf("VerifyInit\n");1611VERIFY_SESSION_HANDLE(hSession, &state);16121613ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),1614mechs, sizeof(mechs)/sizeof(mechs[0]),1615pMechanism, hKey, &o);1616if (ret)1617return ret;16181619ret = dup_mechanism(&state->verify_mechanism, pMechanism);1620if (ret == CKR_OK)1621state->verify_object = OBJECT_ID(o);16221623return ret;1624}16251626CK_RV1627C_Verify(CK_SESSION_HANDLE hSession,1628CK_BYTE_PTR pData,1629CK_ULONG ulDataLen,1630CK_BYTE_PTR pSignature,1631CK_ULONG ulSignatureLen)1632{1633struct session_state *state;1634struct st_object *o;1635const AlgorithmIdentifier *alg;1636CK_RV ret;1637int hret;1638heim_octet_string data, sig;16391640INIT_CONTEXT();1641st_logf("Verify\n");1642VERIFY_SESSION_HANDLE(hSession, &state);16431644if (state->verify_object == -1)1645return CKR_ARGUMENTS_BAD;16461647o = soft_token.object.objs[state->verify_object];16481649switch(state->verify_mechanism->mechanism) {1650case CKM_RSA_PKCS:1651alg = hx509_signature_rsa_pkcs1_x509();1652break;1653default:1654ret = CKR_FUNCTION_NOT_SUPPORTED;1655goto out;1656}16571658sig.data = pData;1659sig.length = ulDataLen;1660data.data = pSignature;1661data.length = ulSignatureLen;16621663hret = _hx509_verify_signature(context,1664o->cert,1665alg,1666&data,1667&sig);1668if (hret) {1669ret = CKR_GENERAL_ERROR;1670goto out;1671}1672ret = CKR_OK;16731674out:1675return ret;1676}167716781679CK_RV1680C_VerifyUpdate(CK_SESSION_HANDLE hSession,1681CK_BYTE_PTR pPart,1682CK_ULONG ulPartLen)1683{1684INIT_CONTEXT();1685st_logf("VerifyUpdate\n");1686VERIFY_SESSION_HANDLE(hSession, NULL);1687return CKR_FUNCTION_NOT_SUPPORTED;1688}16891690CK_RV1691C_VerifyFinal(CK_SESSION_HANDLE hSession,1692CK_BYTE_PTR pSignature,1693CK_ULONG ulSignatureLen)1694{1695INIT_CONTEXT();1696st_logf("VerifyFinal\n");1697VERIFY_SESSION_HANDLE(hSession, NULL);1698return CKR_FUNCTION_NOT_SUPPORTED;1699}17001701CK_RV1702C_GenerateRandom(CK_SESSION_HANDLE hSession,1703CK_BYTE_PTR RandomData,1704CK_ULONG ulRandomLen)1705{1706INIT_CONTEXT();1707st_logf("GenerateRandom\n");1708VERIFY_SESSION_HANDLE(hSession, NULL);1709return CKR_FUNCTION_NOT_SUPPORTED;1710}171117121713CK_FUNCTION_LIST funcs = {1714{ 2, 11 },1715C_Initialize,1716C_Finalize,1717C_GetInfo,1718C_GetFunctionList,1719C_GetSlotList,1720C_GetSlotInfo,1721C_GetTokenInfo,1722C_GetMechanismList,1723C_GetMechanismInfo,1724C_InitToken,1725(void *)func_not_supported, /* C_InitPIN */1726(void *)func_not_supported, /* C_SetPIN */1727C_OpenSession,1728C_CloseSession,1729C_CloseAllSessions,1730C_GetSessionInfo,1731(void *)func_not_supported, /* C_GetOperationState */1732(void *)func_not_supported, /* C_SetOperationState */1733C_Login,1734C_Logout,1735(void *)func_not_supported, /* C_CreateObject */1736(void *)func_not_supported, /* C_CopyObject */1737(void *)func_not_supported, /* C_DestroyObject */1738(void *)func_not_supported, /* C_GetObjectSize */1739C_GetAttributeValue,1740(void *)func_not_supported, /* C_SetAttributeValue */1741C_FindObjectsInit,1742C_FindObjects,1743C_FindObjectsFinal,1744(void *)func_not_supported, /* C_EncryptInit, */1745(void *)func_not_supported, /* C_Encrypt, */1746(void *)func_not_supported, /* C_EncryptUpdate, */1747(void *)func_not_supported, /* C_EncryptFinal, */1748(void *)func_not_supported, /* C_DecryptInit, */1749(void *)func_not_supported, /* C_Decrypt, */1750(void *)func_not_supported, /* C_DecryptUpdate, */1751(void *)func_not_supported, /* C_DecryptFinal, */1752C_DigestInit,1753(void *)func_not_supported, /* C_Digest */1754(void *)func_not_supported, /* C_DigestUpdate */1755(void *)func_not_supported, /* C_DigestKey */1756(void *)func_not_supported, /* C_DigestFinal */1757C_SignInit,1758C_Sign,1759C_SignUpdate,1760C_SignFinal,1761(void *)func_not_supported, /* C_SignRecoverInit */1762(void *)func_not_supported, /* C_SignRecover */1763C_VerifyInit,1764C_Verify,1765C_VerifyUpdate,1766C_VerifyFinal,1767(void *)func_not_supported, /* C_VerifyRecoverInit */1768(void *)func_not_supported, /* C_VerifyRecover */1769(void *)func_not_supported, /* C_DigestEncryptUpdate */1770(void *)func_not_supported, /* C_DecryptDigestUpdate */1771(void *)func_not_supported, /* C_SignEncryptUpdate */1772(void *)func_not_supported, /* C_DecryptVerifyUpdate */1773(void *)func_not_supported, /* C_GenerateKey */1774(void *)func_not_supported, /* C_GenerateKeyPair */1775(void *)func_not_supported, /* C_WrapKey */1776(void *)func_not_supported, /* C_UnwrapKey */1777(void *)func_not_supported, /* C_DeriveKey */1778(void *)func_not_supported, /* C_SeedRandom */1779C_GenerateRandom,1780(void *)func_not_supported, /* C_GetFunctionStatus */1781(void *)func_not_supported, /* C_CancelFunction */1782(void *)func_not_supported /* C_WaitForSlotEvent */1783};178417851786