softp11.c revision 178825
1178825Sdfr/* 2178825Sdfr * Copyright (c) 2004 - 2008 Kungliga Tekniska H�gskolan 3178825Sdfr * (Royal Institute of Technology, Stockholm, Sweden). 4178825Sdfr * All rights reserved. 5178825Sdfr * 6178825Sdfr * Redistribution and use in source and binary forms, with or without 7178825Sdfr * modification, are permitted provided that the following conditions 8178825Sdfr * are met: 9178825Sdfr * 10178825Sdfr * 1. Redistributions of source code must retain the above copyright 11178825Sdfr * notice, this list of conditions and the following disclaimer. 12178825Sdfr * 13178825Sdfr * 2. Redistributions in binary form must reproduce the above copyright 14178825Sdfr * notice, this list of conditions and the following disclaimer in the 15178825Sdfr * documentation and/or other materials provided with the distribution. 16178825Sdfr * 17178825Sdfr * 3. Neither the name of the Institute nor the names of its contributors 18178825Sdfr * may be used to endorse or promote products derived from this software 19178825Sdfr * without specific prior written permission. 20178825Sdfr * 21178825Sdfr * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22178825Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23178825Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24178825Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25178825Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26178825Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27178825Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28178825Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29178825Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30178825Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31178825Sdfr * SUCH DAMAGE. 32178825Sdfr */ 33178825Sdfr 34178825Sdfr#include "hx_locl.h" 35178825Sdfr#include "pkcs11.h" 36178825Sdfr 37178825Sdfr#define OBJECT_ID_MASK 0xfff 38178825Sdfr#define HANDLE_OBJECT_ID(h) ((h) & OBJECT_ID_MASK) 39178825Sdfr#define OBJECT_ID(obj) HANDLE_OBJECT_ID((obj)->object_handle) 40178825Sdfr 41178825Sdfr 42178825Sdfrstruct st_attr { 43178825Sdfr CK_ATTRIBUTE attribute; 44178825Sdfr int secret; 45178825Sdfr}; 46178825Sdfr 47178825Sdfrstruct st_object { 48178825Sdfr CK_OBJECT_HANDLE object_handle; 49178825Sdfr struct st_attr *attrs; 50178825Sdfr int num_attributes; 51178825Sdfr hx509_cert cert; 52178825Sdfr}; 53178825Sdfr 54178825Sdfrstatic struct soft_token { 55178825Sdfr CK_VOID_PTR application; 56178825Sdfr CK_NOTIFY notify; 57178825Sdfr char *config_file; 58178825Sdfr hx509_certs certs; 59178825Sdfr struct { 60178825Sdfr struct st_object **objs; 61178825Sdfr int num_objs; 62178825Sdfr } object; 63178825Sdfr struct { 64178825Sdfr int hardware_slot; 65178825Sdfr int app_error_fatal; 66178825Sdfr int login_done; 67178825Sdfr } flags; 68178825Sdfr int open_sessions; 69178825Sdfr struct session_state { 70178825Sdfr CK_SESSION_HANDLE session_handle; 71178825Sdfr 72178825Sdfr struct { 73178825Sdfr CK_ATTRIBUTE *attributes; 74178825Sdfr CK_ULONG num_attributes; 75178825Sdfr int next_object; 76178825Sdfr } find; 77178825Sdfr 78178825Sdfr int sign_object; 79178825Sdfr CK_MECHANISM_PTR sign_mechanism; 80178825Sdfr int verify_object; 81178825Sdfr CK_MECHANISM_PTR verify_mechanism; 82178825Sdfr } state[10]; 83178825Sdfr#define MAX_NUM_SESSION (sizeof(soft_token.state)/sizeof(soft_token.state[0])) 84178825Sdfr FILE *logfile; 85178825Sdfr} soft_token; 86178825Sdfr 87178825Sdfrstatic hx509_context context; 88178825Sdfr 89178825Sdfrstatic void 90178825Sdfrapplication_error(const char *fmt, ...) 91178825Sdfr{ 92178825Sdfr va_list ap; 93178825Sdfr va_start(ap, fmt); 94178825Sdfr vprintf(fmt, ap); 95178825Sdfr va_end(ap); 96178825Sdfr if (soft_token.flags.app_error_fatal) 97178825Sdfr abort(); 98178825Sdfr} 99178825Sdfr 100178825Sdfrstatic void 101178825Sdfrst_logf(const char *fmt, ...) 102178825Sdfr{ 103178825Sdfr va_list ap; 104178825Sdfr if (soft_token.logfile == NULL) 105178825Sdfr return; 106178825Sdfr va_start(ap, fmt); 107178825Sdfr vfprintf(soft_token.logfile, fmt, ap); 108178825Sdfr va_end(ap); 109178825Sdfr fflush(soft_token.logfile); 110178825Sdfr} 111178825Sdfr 112178825Sdfrstatic CK_RV 113178825Sdfrinit_context(void) 114178825Sdfr{ 115178825Sdfr if (context == NULL) { 116178825Sdfr int ret = hx509_context_init(&context); 117178825Sdfr if (ret) 118178825Sdfr return CKR_GENERAL_ERROR; 119178825Sdfr } 120178825Sdfr return CKR_OK; 121178825Sdfr} 122178825Sdfr 123178825Sdfr#define INIT_CONTEXT() { CK_RV icret = init_context(); if (icret) return icret; } 124178825Sdfr 125178825Sdfrstatic void 126178825Sdfrsnprintf_fill(char *str, size_t size, char fillchar, const char *fmt, ...) 127178825Sdfr{ 128178825Sdfr int len; 129178825Sdfr va_list ap; 130178825Sdfr len = vsnprintf(str, size, fmt, ap); 131178825Sdfr va_end(ap); 132178825Sdfr if (len < 0 || len > size) 133178825Sdfr return; 134178825Sdfr while(len < size) 135178825Sdfr str[len++] = fillchar; 136178825Sdfr} 137178825Sdfr 138178825Sdfr#ifndef TEST_APP 139178825Sdfr#define printf error_use_st_logf 140178825Sdfr#endif 141178825Sdfr 142178825Sdfr#define VERIFY_SESSION_HANDLE(s, state) \ 143178825Sdfr{ \ 144178825Sdfr CK_RV ret; \ 145178825Sdfr ret = verify_session_handle(s, state); \ 146178825Sdfr if (ret != CKR_OK) { \ 147178825Sdfr /* return CKR_OK */; \ 148178825Sdfr } \ 149178825Sdfr} 150178825Sdfr 151178825Sdfrstatic CK_RV 152178825Sdfrverify_session_handle(CK_SESSION_HANDLE hSession, 153178825Sdfr struct session_state **state) 154178825Sdfr{ 155178825Sdfr int i; 156178825Sdfr 157178825Sdfr for (i = 0; i < MAX_NUM_SESSION; i++){ 158178825Sdfr if (soft_token.state[i].session_handle == hSession) 159178825Sdfr break; 160178825Sdfr } 161178825Sdfr if (i == MAX_NUM_SESSION) { 162178825Sdfr application_error("use of invalid handle: 0x%08lx\n", 163178825Sdfr (unsigned long)hSession); 164178825Sdfr return CKR_SESSION_HANDLE_INVALID; 165178825Sdfr } 166178825Sdfr if (state) 167178825Sdfr *state = &soft_token.state[i]; 168178825Sdfr return CKR_OK; 169178825Sdfr} 170178825Sdfr 171178825Sdfrstatic CK_RV 172178825Sdfrobject_handle_to_object(CK_OBJECT_HANDLE handle, 173178825Sdfr struct st_object **object) 174178825Sdfr{ 175178825Sdfr int i = HANDLE_OBJECT_ID(handle); 176178825Sdfr 177178825Sdfr *object = NULL; 178178825Sdfr if (i >= soft_token.object.num_objs) 179178825Sdfr return CKR_ARGUMENTS_BAD; 180178825Sdfr if (soft_token.object.objs[i] == NULL) 181178825Sdfr return CKR_ARGUMENTS_BAD; 182178825Sdfr if (soft_token.object.objs[i]->object_handle != handle) 183178825Sdfr return CKR_ARGUMENTS_BAD; 184178825Sdfr *object = soft_token.object.objs[i]; 185178825Sdfr return CKR_OK; 186178825Sdfr} 187178825Sdfr 188178825Sdfrstatic int 189178825Sdfrattributes_match(const struct st_object *obj, 190178825Sdfr const CK_ATTRIBUTE *attributes, 191178825Sdfr CK_ULONG num_attributes) 192178825Sdfr{ 193178825Sdfr CK_ULONG i; 194178825Sdfr int j; 195178825Sdfr 196178825Sdfr st_logf("attributes_match: %ld\n", (unsigned long)OBJECT_ID(obj)); 197178825Sdfr 198178825Sdfr for (i = 0; i < num_attributes; i++) { 199178825Sdfr int match = 0; 200178825Sdfr for (j = 0; j < obj->num_attributes; j++) { 201178825Sdfr if (attributes[i].type == obj->attrs[j].attribute.type && 202178825Sdfr attributes[i].ulValueLen == obj->attrs[j].attribute.ulValueLen && 203178825Sdfr memcmp(attributes[i].pValue, obj->attrs[j].attribute.pValue, 204178825Sdfr attributes[i].ulValueLen) == 0) { 205178825Sdfr match = 1; 206178825Sdfr break; 207178825Sdfr } 208178825Sdfr } 209178825Sdfr if (match == 0) { 210178825Sdfr st_logf("type %d attribute have no match\n", attributes[i].type); 211178825Sdfr return 0; 212178825Sdfr } 213178825Sdfr } 214178825Sdfr st_logf("attribute matches\n"); 215178825Sdfr return 1; 216178825Sdfr} 217178825Sdfr 218178825Sdfrstatic void 219178825Sdfrprint_attributes(const CK_ATTRIBUTE *attributes, 220178825Sdfr CK_ULONG num_attributes) 221178825Sdfr{ 222178825Sdfr CK_ULONG i; 223178825Sdfr 224178825Sdfr st_logf("find objects: attrs: %lu\n", (unsigned long)num_attributes); 225178825Sdfr 226178825Sdfr for (i = 0; i < num_attributes; i++) { 227178825Sdfr st_logf(" type: "); 228178825Sdfr switch (attributes[i].type) { 229178825Sdfr case CKA_TOKEN: { 230178825Sdfr CK_BBOOL *ck_true; 231178825Sdfr if (attributes[i].ulValueLen != sizeof(CK_BBOOL)) { 232178825Sdfr application_error("token attribute wrong length\n"); 233178825Sdfr break; 234178825Sdfr } 235178825Sdfr ck_true = attributes[i].pValue; 236178825Sdfr st_logf("token: %s", *ck_true ? "TRUE" : "FALSE"); 237178825Sdfr break; 238178825Sdfr } 239178825Sdfr case CKA_CLASS: { 240178825Sdfr CK_OBJECT_CLASS *class; 241178825Sdfr if (attributes[i].ulValueLen != sizeof(CK_ULONG)) { 242178825Sdfr application_error("class attribute wrong length\n"); 243178825Sdfr break; 244178825Sdfr } 245178825Sdfr class = attributes[i].pValue; 246178825Sdfr st_logf("class "); 247178825Sdfr switch (*class) { 248178825Sdfr case CKO_CERTIFICATE: 249178825Sdfr st_logf("certificate"); 250178825Sdfr break; 251178825Sdfr case CKO_PUBLIC_KEY: 252178825Sdfr st_logf("public key"); 253178825Sdfr break; 254178825Sdfr case CKO_PRIVATE_KEY: 255178825Sdfr st_logf("private key"); 256178825Sdfr break; 257178825Sdfr case CKO_SECRET_KEY: 258178825Sdfr st_logf("secret key"); 259178825Sdfr break; 260178825Sdfr case CKO_DOMAIN_PARAMETERS: 261178825Sdfr st_logf("domain parameters"); 262178825Sdfr break; 263178825Sdfr default: 264178825Sdfr st_logf("[class %lx]", (long unsigned)*class); 265178825Sdfr break; 266178825Sdfr } 267178825Sdfr break; 268178825Sdfr } 269178825Sdfr case CKA_PRIVATE: 270178825Sdfr st_logf("private"); 271178825Sdfr break; 272178825Sdfr case CKA_LABEL: 273178825Sdfr st_logf("label"); 274178825Sdfr break; 275178825Sdfr case CKA_APPLICATION: 276178825Sdfr st_logf("application"); 277178825Sdfr break; 278178825Sdfr case CKA_VALUE: 279178825Sdfr st_logf("value"); 280178825Sdfr break; 281178825Sdfr case CKA_ID: 282178825Sdfr st_logf("id"); 283178825Sdfr break; 284178825Sdfr default: 285178825Sdfr st_logf("[unknown 0x%08lx]", (unsigned long)attributes[i].type); 286178825Sdfr break; 287178825Sdfr } 288178825Sdfr st_logf("\n"); 289178825Sdfr } 290178825Sdfr} 291178825Sdfr 292178825Sdfrstatic struct st_object * 293178825Sdfradd_st_object(void) 294178825Sdfr{ 295178825Sdfr struct st_object *o, **objs; 296178825Sdfr int i; 297178825Sdfr 298178825Sdfr o = malloc(sizeof(*o)); 299178825Sdfr if (o == NULL) 300178825Sdfr return NULL; 301178825Sdfr memset(o, 0, sizeof(*o)); 302178825Sdfr o->attrs = NULL; 303178825Sdfr o->num_attributes = 0; 304178825Sdfr 305178825Sdfr for (i = 0; i < soft_token.object.num_objs; i++) { 306178825Sdfr if (soft_token.object.objs == NULL) { 307178825Sdfr soft_token.object.objs[i] = o; 308178825Sdfr break; 309178825Sdfr } 310178825Sdfr } 311178825Sdfr if (i == soft_token.object.num_objs) { 312178825Sdfr objs = realloc(soft_token.object.objs, 313178825Sdfr (soft_token.object.num_objs + 1) * sizeof(soft_token.object.objs[0])); 314178825Sdfr if (objs == NULL) { 315178825Sdfr free(o); 316178825Sdfr return NULL; 317178825Sdfr } 318178825Sdfr soft_token.object.objs = objs; 319178825Sdfr soft_token.object.objs[soft_token.object.num_objs++] = o; 320178825Sdfr } 321178825Sdfr soft_token.object.objs[i]->object_handle = 322178825Sdfr (random() & (~OBJECT_ID_MASK)) | i; 323178825Sdfr 324178825Sdfr return o; 325178825Sdfr} 326178825Sdfr 327178825Sdfrstatic CK_RV 328178825Sdfradd_object_attribute(struct st_object *o, 329178825Sdfr int secret, 330178825Sdfr CK_ATTRIBUTE_TYPE type, 331178825Sdfr CK_VOID_PTR pValue, 332178825Sdfr CK_ULONG ulValueLen) 333178825Sdfr{ 334178825Sdfr struct st_attr *a; 335178825Sdfr int i; 336178825Sdfr 337178825Sdfr i = o->num_attributes; 338178825Sdfr a = realloc(o->attrs, (i + 1) * sizeof(o->attrs[0])); 339178825Sdfr if (a == NULL) 340178825Sdfr return CKR_DEVICE_MEMORY; 341178825Sdfr o->attrs = a; 342178825Sdfr o->attrs[i].secret = secret; 343178825Sdfr o->attrs[i].attribute.type = type; 344178825Sdfr o->attrs[i].attribute.pValue = malloc(ulValueLen); 345178825Sdfr if (o->attrs[i].attribute.pValue == NULL && ulValueLen != 0) 346178825Sdfr return CKR_DEVICE_MEMORY; 347178825Sdfr memcpy(o->attrs[i].attribute.pValue, pValue, ulValueLen); 348178825Sdfr o->attrs[i].attribute.ulValueLen = ulValueLen; 349178825Sdfr o->num_attributes++; 350178825Sdfr 351178825Sdfr return CKR_OK; 352178825Sdfr} 353178825Sdfr 354178825Sdfrstatic CK_RV 355178825Sdfradd_pubkey_info(hx509_context hxctx, struct st_object *o, 356178825Sdfr CK_KEY_TYPE key_type, hx509_cert cert) 357178825Sdfr{ 358178825Sdfr BIGNUM *num; 359178825Sdfr CK_BYTE *modulus = NULL; 360178825Sdfr size_t modulus_len = 0; 361178825Sdfr CK_ULONG modulus_bits = 0; 362178825Sdfr CK_BYTE *exponent = NULL; 363178825Sdfr size_t exponent_len = 0; 364178825Sdfr 365178825Sdfr if (key_type != CKK_RSA) 366178825Sdfr return CKR_OK; 367178825Sdfr if (_hx509_cert_private_key(cert) == NULL) 368178825Sdfr return CKR_OK; 369178825Sdfr 370178825Sdfr num = _hx509_private_key_get_internal(context, 371178825Sdfr _hx509_cert_private_key(cert), 372178825Sdfr "rsa-modulus"); 373178825Sdfr if (num == NULL) 374178825Sdfr return CKR_GENERAL_ERROR; 375178825Sdfr modulus_bits = BN_num_bits(num); 376178825Sdfr 377178825Sdfr modulus_len = BN_num_bytes(num); 378178825Sdfr modulus = malloc(modulus_len); 379178825Sdfr BN_bn2bin(num, modulus); 380178825Sdfr BN_free(num); 381178825Sdfr 382178825Sdfr add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len); 383178825Sdfr add_object_attribute(o, 0, CKA_MODULUS_BITS, 384178825Sdfr &modulus_bits, sizeof(modulus_bits)); 385178825Sdfr 386178825Sdfr free(modulus); 387178825Sdfr 388178825Sdfr num = _hx509_private_key_get_internal(context, 389178825Sdfr _hx509_cert_private_key(cert), 390178825Sdfr "rsa-exponent"); 391178825Sdfr if (num == NULL) 392178825Sdfr return CKR_GENERAL_ERROR; 393178825Sdfr 394178825Sdfr exponent_len = BN_num_bytes(num); 395178825Sdfr exponent = malloc(exponent_len); 396178825Sdfr BN_bn2bin(num, exponent); 397178825Sdfr BN_free(num); 398178825Sdfr 399178825Sdfr add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT, 400178825Sdfr exponent, exponent_len); 401178825Sdfr 402178825Sdfr free(exponent); 403178825Sdfr 404178825Sdfr return CKR_OK; 405178825Sdfr} 406178825Sdfr 407178825Sdfr 408178825Sdfrstruct foo { 409178825Sdfr char *label; 410178825Sdfr char *id; 411178825Sdfr}; 412178825Sdfr 413178825Sdfrstatic int 414178825Sdfradd_cert(hx509_context hxctx, void *ctx, hx509_cert cert) 415178825Sdfr{ 416178825Sdfr struct foo *foo = (struct foo *)ctx; 417178825Sdfr struct st_object *o = NULL; 418178825Sdfr CK_OBJECT_CLASS type; 419178825Sdfr CK_BBOOL bool_true = CK_TRUE; 420178825Sdfr CK_BBOOL bool_false = CK_FALSE; 421178825Sdfr CK_CERTIFICATE_TYPE cert_type = CKC_X_509; 422178825Sdfr CK_KEY_TYPE key_type; 423178825Sdfr CK_MECHANISM_TYPE mech_type; 424178825Sdfr CK_RV ret = CKR_GENERAL_ERROR; 425178825Sdfr int hret; 426178825Sdfr heim_octet_string cert_data, subject_data, issuer_data, serial_data; 427178825Sdfr 428178825Sdfr st_logf("adding certificate\n"); 429178825Sdfr 430178825Sdfr serial_data.data = NULL; 431178825Sdfr serial_data.length = 0; 432178825Sdfr cert_data = subject_data = issuer_data = serial_data; 433178825Sdfr 434178825Sdfr hret = hx509_cert_binary(hxctx, cert, &cert_data); 435178825Sdfr if (hret) 436178825Sdfr goto out; 437178825Sdfr 438178825Sdfr { 439178825Sdfr hx509_name name; 440178825Sdfr 441178825Sdfr hret = hx509_cert_get_issuer(cert, &name); 442178825Sdfr if (hret) 443178825Sdfr goto out; 444178825Sdfr hret = hx509_name_binary(name, &issuer_data); 445178825Sdfr hx509_name_free(&name); 446178825Sdfr if (hret) 447178825Sdfr goto out; 448178825Sdfr 449178825Sdfr hret = hx509_cert_get_subject(cert, &name); 450178825Sdfr if (hret) 451178825Sdfr goto out; 452178825Sdfr hret = hx509_name_binary(name, &subject_data); 453178825Sdfr hx509_name_free(&name); 454178825Sdfr if (hret) 455178825Sdfr goto out; 456178825Sdfr } 457178825Sdfr 458178825Sdfr { 459178825Sdfr AlgorithmIdentifier alg; 460178825Sdfr 461178825Sdfr hret = hx509_cert_get_SPKI_AlgorithmIdentifier(context, cert, &alg); 462178825Sdfr if (hret) { 463178825Sdfr ret = CKR_DEVICE_MEMORY; 464178825Sdfr goto out; 465178825Sdfr } 466178825Sdfr 467178825Sdfr key_type = CKK_RSA; /* XXX */ 468178825Sdfr 469178825Sdfr free_AlgorithmIdentifier(&alg); 470178825Sdfr } 471178825Sdfr 472178825Sdfr 473178825Sdfr type = CKO_CERTIFICATE; 474178825Sdfr o = add_st_object(); 475178825Sdfr if (o == NULL) { 476178825Sdfr ret = CKR_DEVICE_MEMORY; 477178825Sdfr goto out; 478178825Sdfr } 479178825Sdfr 480178825Sdfr o->cert = hx509_cert_ref(cert); 481178825Sdfr 482178825Sdfr add_object_attribute(o, 0, CKA_CLASS, &type, sizeof(type)); 483178825Sdfr add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true)); 484178825Sdfr add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false)); 485178825Sdfr add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false)); 486178825Sdfr add_object_attribute(o, 0, CKA_LABEL, foo->label, strlen(foo->label)); 487178825Sdfr 488178825Sdfr add_object_attribute(o, 0, CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type)); 489178825Sdfr add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id)); 490178825Sdfr 491178825Sdfr add_object_attribute(o, 0, CKA_SUBJECT, subject_data.data, subject_data.length); 492178825Sdfr add_object_attribute(o, 0, CKA_ISSUER, issuer_data.data, issuer_data.length); 493178825Sdfr add_object_attribute(o, 0, CKA_SERIAL_NUMBER, serial_data.data, serial_data.length); 494178825Sdfr add_object_attribute(o, 0, CKA_VALUE, cert_data.data, cert_data.length); 495178825Sdfr add_object_attribute(o, 0, CKA_TRUSTED, &bool_false, sizeof(bool_false)); 496178825Sdfr 497178825Sdfr st_logf("add cert ok: %lx\n", (unsigned long)OBJECT_ID(o)); 498178825Sdfr 499178825Sdfr type = CKO_PUBLIC_KEY; 500178825Sdfr o = add_st_object(); 501178825Sdfr if (o == NULL) { 502178825Sdfr ret = CKR_DEVICE_MEMORY; 503178825Sdfr goto out; 504178825Sdfr } 505178825Sdfr o->cert = hx509_cert_ref(cert); 506178825Sdfr 507178825Sdfr add_object_attribute(o, 0, CKA_CLASS, &type, sizeof(type)); 508178825Sdfr add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true)); 509178825Sdfr add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false)); 510178825Sdfr add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false)); 511178825Sdfr add_object_attribute(o, 0, CKA_LABEL, foo->label, strlen(foo->label)); 512178825Sdfr 513178825Sdfr add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type)); 514178825Sdfr add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id)); 515178825Sdfr add_object_attribute(o, 0, CKA_START_DATE, "", 1); /* XXX */ 516178825Sdfr add_object_attribute(o, 0, CKA_END_DATE, "", 1); /* XXX */ 517178825Sdfr add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false)); 518178825Sdfr add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false)); 519178825Sdfr mech_type = CKM_RSA_X_509; 520178825Sdfr add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type)); 521178825Sdfr 522178825Sdfr add_object_attribute(o, 0, CKA_SUBJECT, subject_data.data, subject_data.length); 523178825Sdfr add_object_attribute(o, 0, CKA_ENCRYPT, &bool_true, sizeof(bool_true)); 524178825Sdfr add_object_attribute(o, 0, CKA_VERIFY, &bool_true, sizeof(bool_true)); 525178825Sdfr add_object_attribute(o, 0, CKA_VERIFY_RECOVER, &bool_false, sizeof(bool_false)); 526178825Sdfr add_object_attribute(o, 0, CKA_WRAP, &bool_true, sizeof(bool_true)); 527178825Sdfr add_object_attribute(o, 0, CKA_TRUSTED, &bool_true, sizeof(bool_true)); 528178825Sdfr 529178825Sdfr add_pubkey_info(hxctx, o, key_type, cert); 530178825Sdfr 531178825Sdfr st_logf("add key ok: %lx\n", (unsigned long)OBJECT_ID(o)); 532178825Sdfr 533178825Sdfr if (hx509_cert_have_private_key(cert)) { 534178825Sdfr CK_FLAGS flags; 535178825Sdfr 536178825Sdfr type = CKO_PRIVATE_KEY; 537178825Sdfr o = add_st_object(); 538178825Sdfr if (o == NULL) { 539178825Sdfr ret = CKR_DEVICE_MEMORY; 540178825Sdfr goto out; 541178825Sdfr } 542178825Sdfr o->cert = hx509_cert_ref(cert); 543178825Sdfr 544178825Sdfr add_object_attribute(o, 0, CKA_CLASS, &type, sizeof(type)); 545178825Sdfr add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true)); 546178825Sdfr add_object_attribute(o, 0, CKA_PRIVATE, &bool_true, sizeof(bool_false)); 547178825Sdfr add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false)); 548178825Sdfr add_object_attribute(o, 0, CKA_LABEL, foo->label, strlen(foo->label)); 549178825Sdfr 550178825Sdfr add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type)); 551178825Sdfr add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id)); 552178825Sdfr add_object_attribute(o, 0, CKA_START_DATE, "", 1); /* XXX */ 553178825Sdfr add_object_attribute(o, 0, CKA_END_DATE, "", 1); /* XXX */ 554178825Sdfr add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false)); 555178825Sdfr add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false)); 556178825Sdfr mech_type = CKM_RSA_X_509; 557178825Sdfr add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type)); 558178825Sdfr 559178825Sdfr add_object_attribute(o, 0, CKA_SUBJECT, subject_data.data, subject_data.length); 560178825Sdfr add_object_attribute(o, 0, CKA_SENSITIVE, &bool_true, sizeof(bool_true)); 561178825Sdfr add_object_attribute(o, 0, CKA_SECONDARY_AUTH, &bool_false, sizeof(bool_true)); 562178825Sdfr flags = 0; 563178825Sdfr add_object_attribute(o, 0, CKA_AUTH_PIN_FLAGS, &flags, sizeof(flags)); 564178825Sdfr 565178825Sdfr add_object_attribute(o, 0, CKA_DECRYPT, &bool_true, sizeof(bool_true)); 566178825Sdfr add_object_attribute(o, 0, CKA_SIGN, &bool_true, sizeof(bool_true)); 567178825Sdfr add_object_attribute(o, 0, CKA_SIGN_RECOVER, &bool_false, sizeof(bool_false)); 568178825Sdfr add_object_attribute(o, 0, CKA_UNWRAP, &bool_true, sizeof(bool_true)); 569178825Sdfr add_object_attribute(o, 0, CKA_EXTRACTABLE, &bool_true, sizeof(bool_true)); 570178825Sdfr add_object_attribute(o, 0, CKA_NEVER_EXTRACTABLE, &bool_false, sizeof(bool_false)); 571178825Sdfr 572178825Sdfr add_pubkey_info(hxctx, o, key_type, cert); 573178825Sdfr } 574178825Sdfr 575178825Sdfr ret = CKR_OK; 576178825Sdfr out: 577178825Sdfr if (ret != CKR_OK) { 578178825Sdfr st_logf("something went wrong when adding cert!\n"); 579178825Sdfr 580178825Sdfr /* XXX wack o */; 581178825Sdfr } 582178825Sdfr hx509_xfree(cert_data.data); 583178825Sdfr hx509_xfree(serial_data.data); 584178825Sdfr hx509_xfree(issuer_data.data); 585178825Sdfr hx509_xfree(subject_data.data); 586178825Sdfr 587178825Sdfr return 0; 588178825Sdfr} 589178825Sdfr 590178825Sdfrstatic CK_RV 591178825Sdfradd_certificate(const char *cert_file, 592178825Sdfr const char *pin, 593178825Sdfr char *id, 594178825Sdfr char *label) 595178825Sdfr{ 596178825Sdfr hx509_certs certs; 597178825Sdfr hx509_lock lock = NULL; 598178825Sdfr int ret, flags = 0; 599178825Sdfr 600178825Sdfr struct foo foo; 601178825Sdfr foo.id = id; 602178825Sdfr foo.label = label; 603178825Sdfr 604178825Sdfr if (pin == NULL) 605178825Sdfr flags |= HX509_CERTS_UNPROTECT_ALL; 606178825Sdfr 607178825Sdfr if (pin) { 608178825Sdfr char *str; 609178825Sdfr asprintf(&str, "PASS:%s", pin); 610178825Sdfr 611178825Sdfr hx509_lock_init(context, &lock); 612178825Sdfr hx509_lock_command_string(lock, str); 613178825Sdfr 614178825Sdfr memset(str, 0, strlen(str)); 615178825Sdfr free(str); 616178825Sdfr } 617178825Sdfr 618178825Sdfr ret = hx509_certs_init(context, cert_file, flags, lock, &certs); 619178825Sdfr if (ret) { 620178825Sdfr st_logf("failed to open file %s\n", cert_file); 621178825Sdfr return CKR_GENERAL_ERROR; 622178825Sdfr } 623178825Sdfr 624178825Sdfr ret = hx509_certs_iter(context, certs, add_cert, &foo); 625178825Sdfr hx509_certs_free(&certs); 626178825Sdfr if (ret) { 627178825Sdfr st_logf("failed adding certs from file %s\n", cert_file); 628178825Sdfr return CKR_GENERAL_ERROR; 629178825Sdfr } 630178825Sdfr 631178825Sdfr return CKR_OK; 632178825Sdfr} 633178825Sdfr 634178825Sdfrstatic void 635178825Sdfrfind_object_final(struct session_state *state) 636178825Sdfr{ 637178825Sdfr if (state->find.attributes) { 638178825Sdfr CK_ULONG i; 639178825Sdfr 640178825Sdfr for (i = 0; i < state->find.num_attributes; i++) { 641178825Sdfr if (state->find.attributes[i].pValue) 642178825Sdfr free(state->find.attributes[i].pValue); 643178825Sdfr } 644178825Sdfr free(state->find.attributes); 645178825Sdfr state->find.attributes = NULL; 646178825Sdfr state->find.num_attributes = 0; 647178825Sdfr state->find.next_object = -1; 648178825Sdfr } 649178825Sdfr} 650178825Sdfr 651178825Sdfrstatic void 652178825Sdfrreset_crypto_state(struct session_state *state) 653178825Sdfr{ 654178825Sdfr state->sign_object = -1; 655178825Sdfr if (state->sign_mechanism) 656178825Sdfr free(state->sign_mechanism); 657178825Sdfr state->sign_mechanism = NULL_PTR; 658178825Sdfr state->verify_object = -1; 659178825Sdfr if (state->verify_mechanism) 660178825Sdfr free(state->verify_mechanism); 661178825Sdfr state->verify_mechanism = NULL_PTR; 662178825Sdfr} 663178825Sdfr 664178825Sdfrstatic void 665178825Sdfrclose_session(struct session_state *state) 666178825Sdfr{ 667178825Sdfr if (state->find.attributes) { 668178825Sdfr application_error("application didn't do C_FindObjectsFinal\n"); 669178825Sdfr find_object_final(state); 670178825Sdfr } 671178825Sdfr 672178825Sdfr state->session_handle = CK_INVALID_HANDLE; 673178825Sdfr soft_token.application = NULL_PTR; 674178825Sdfr soft_token.notify = NULL_PTR; 675178825Sdfr reset_crypto_state(state); 676178825Sdfr} 677178825Sdfr 678178825Sdfrstatic const char * 679178825Sdfrhas_session(void) 680178825Sdfr{ 681178825Sdfr return soft_token.open_sessions > 0 ? "yes" : "no"; 682178825Sdfr} 683178825Sdfr 684178825Sdfrstatic CK_RV 685178825Sdfrread_conf_file(const char *fn, CK_USER_TYPE userType, const char *pin) 686178825Sdfr{ 687178825Sdfr char buf[1024], *type, *s, *p; 688178825Sdfr int anchor; 689178825Sdfr FILE *f; 690178825Sdfr CK_RV ret = CKR_OK; 691178825Sdfr CK_RV failed = CKR_OK; 692178825Sdfr 693178825Sdfr f = fopen(fn, "r"); 694178825Sdfr if (f == NULL) { 695178825Sdfr st_logf("can't open configuration file %s\n", fn); 696178825Sdfr return CKR_GENERAL_ERROR; 697178825Sdfr } 698178825Sdfr 699178825Sdfr while(fgets(buf, sizeof(buf), f) != NULL) { 700178825Sdfr buf[strcspn(buf, "\n")] = '\0'; 701178825Sdfr 702178825Sdfr anchor = 0; 703178825Sdfr 704178825Sdfr st_logf("line: %s\n", buf); 705178825Sdfr 706178825Sdfr p = buf; 707178825Sdfr while (isspace(*p)) 708178825Sdfr p++; 709178825Sdfr if (*p == '#') 710178825Sdfr continue; 711178825Sdfr while (isspace(*p)) 712178825Sdfr p++; 713178825Sdfr 714178825Sdfr s = NULL; 715178825Sdfr type = strtok_r(p, "\t", &s); 716178825Sdfr if (type == NULL) 717178825Sdfr continue; 718178825Sdfr 719178825Sdfr if (strcasecmp("certificate", type) == 0) { 720178825Sdfr char *cert, *id, *label; 721178825Sdfr 722178825Sdfr id = strtok_r(NULL, "\t", &s); 723178825Sdfr if (id == NULL) { 724178825Sdfr st_logf("no id\n"); 725178825Sdfr continue; 726178825Sdfr } 727178825Sdfr st_logf("id: %s\n", id); 728178825Sdfr label = strtok_r(NULL, "\t", &s); 729178825Sdfr if (label == NULL) { 730178825Sdfr st_logf("no label\n"); 731178825Sdfr continue; 732178825Sdfr } 733178825Sdfr cert = strtok_r(NULL, "\t", &s); 734178825Sdfr if (cert == NULL) { 735178825Sdfr st_logf("no certfiicate store\n"); 736178825Sdfr continue; 737178825Sdfr } 738178825Sdfr 739178825Sdfr st_logf("adding: %s: %s in file %s\n", id, label, cert); 740178825Sdfr 741178825Sdfr ret = add_certificate(cert, pin, id, label); 742178825Sdfr if (ret) 743178825Sdfr failed = ret; 744178825Sdfr } else if (strcasecmp("debug", type) == 0) { 745178825Sdfr char *name; 746178825Sdfr 747178825Sdfr name = strtok_r(NULL, "\t", &s); 748178825Sdfr if (name == NULL) { 749178825Sdfr st_logf("no filename\n"); 750178825Sdfr continue; 751178825Sdfr } 752178825Sdfr 753178825Sdfr if (soft_token.logfile) 754178825Sdfr fclose(soft_token.logfile); 755178825Sdfr 756178825Sdfr if (strcasecmp(name, "stdout") == 0) 757178825Sdfr soft_token.logfile = stdout; 758178825Sdfr else 759178825Sdfr soft_token.logfile = fopen(name, "a"); 760178825Sdfr if (soft_token.logfile == NULL) 761178825Sdfr st_logf("failed to open file: %s\n", name); 762178825Sdfr 763178825Sdfr } else if (strcasecmp("app-fatal", type) == 0) { 764178825Sdfr char *name; 765178825Sdfr 766178825Sdfr name = strtok_r(NULL, "\t", &s); 767178825Sdfr if (name == NULL) { 768178825Sdfr st_logf("argument to app-fatal\n"); 769178825Sdfr continue; 770178825Sdfr } 771178825Sdfr 772178825Sdfr if (strcmp(name, "true") == 0 || strcmp(name, "on") == 0) 773178825Sdfr soft_token.flags.app_error_fatal = 1; 774178825Sdfr else if (strcmp(name, "false") == 0 || strcmp(name, "off") == 0) 775178825Sdfr soft_token.flags.app_error_fatal = 0; 776178825Sdfr else 777178825Sdfr st_logf("unknown app-fatal: %s\n", name); 778178825Sdfr 779178825Sdfr } else { 780178825Sdfr st_logf("unknown type: %s\n", type); 781178825Sdfr } 782178825Sdfr } 783178825Sdfr 784178825Sdfr fclose(f); 785178825Sdfr 786178825Sdfr return failed; 787178825Sdfr} 788178825Sdfr 789178825Sdfrstatic CK_RV 790178825Sdfrfunc_not_supported(void) 791178825Sdfr{ 792178825Sdfr st_logf("function not supported\n"); 793178825Sdfr return CKR_FUNCTION_NOT_SUPPORTED; 794178825Sdfr} 795178825Sdfr 796178825SdfrCK_RV 797178825SdfrC_Initialize(CK_VOID_PTR a) 798178825Sdfr{ 799178825Sdfr CK_C_INITIALIZE_ARGS_PTR args = a; 800178825Sdfr CK_RV ret; 801178825Sdfr int i; 802178825Sdfr 803178825Sdfr st_logf("Initialize\n"); 804178825Sdfr 805178825Sdfr INIT_CONTEXT(); 806178825Sdfr 807178825Sdfr OpenSSL_add_all_algorithms(); 808178825Sdfr 809178825Sdfr srandom(getpid() ^ time(NULL)); 810178825Sdfr 811178825Sdfr for (i = 0; i < MAX_NUM_SESSION; i++) { 812178825Sdfr soft_token.state[i].session_handle = CK_INVALID_HANDLE; 813178825Sdfr soft_token.state[i].find.attributes = NULL; 814178825Sdfr soft_token.state[i].find.num_attributes = 0; 815178825Sdfr soft_token.state[i].find.next_object = -1; 816178825Sdfr reset_crypto_state(&soft_token.state[i]); 817178825Sdfr } 818178825Sdfr 819178825Sdfr soft_token.flags.hardware_slot = 1; 820178825Sdfr soft_token.flags.app_error_fatal = 0; 821178825Sdfr soft_token.flags.login_done = 0; 822178825Sdfr 823178825Sdfr soft_token.object.objs = NULL; 824178825Sdfr soft_token.object.num_objs = 0; 825178825Sdfr 826178825Sdfr soft_token.logfile = NULL; 827178825Sdfr#if 0 828178825Sdfr soft_token.logfile = stdout; 829178825Sdfr#endif 830178825Sdfr#if 0 831178825Sdfr soft_token.logfile = fopen("/tmp/log-pkcs11.txt", "a"); 832178825Sdfr#endif 833178825Sdfr 834178825Sdfr if (a != NULL_PTR) { 835178825Sdfr st_logf("\tCreateMutex:\t%p\n", args->CreateMutex); 836178825Sdfr st_logf("\tDestroyMutext\t%p\n", args->DestroyMutex); 837178825Sdfr st_logf("\tLockMutext\t%p\n", args->LockMutex); 838178825Sdfr st_logf("\tUnlockMutext\t%p\n", args->UnlockMutex); 839178825Sdfr st_logf("\tFlags\t%04x\n", (unsigned int)args->flags); 840178825Sdfr } 841178825Sdfr 842178825Sdfr { 843178825Sdfr char *fn = NULL, *home = NULL; 844178825Sdfr 845178825Sdfr if (getuid() == geteuid()) { 846178825Sdfr fn = getenv("SOFTPKCS11RC"); 847178825Sdfr if (fn) 848178825Sdfr fn = strdup(fn); 849178825Sdfr home = getenv("HOME"); 850178825Sdfr } 851178825Sdfr if (fn == NULL && home == NULL) { 852178825Sdfr struct passwd *pw = getpwuid(getuid()); 853178825Sdfr if(pw != NULL) 854178825Sdfr home = pw->pw_dir; 855178825Sdfr } 856178825Sdfr if (fn == NULL) { 857178825Sdfr if (home) 858178825Sdfr asprintf(&fn, "%s/.soft-token.rc", home); 859178825Sdfr else 860178825Sdfr fn = strdup("/etc/soft-token.rc"); 861178825Sdfr } 862178825Sdfr 863178825Sdfr soft_token.config_file = fn; 864178825Sdfr } 865178825Sdfr 866178825Sdfr /* 867178825Sdfr * This operations doesn't return CKR_OK if any of the 868178825Sdfr * certificates failes to be unparsed (ie password protected). 869178825Sdfr */ 870178825Sdfr ret = read_conf_file(soft_token.config_file, CKU_USER, NULL); 871178825Sdfr if (ret == CKR_OK) 872178825Sdfr soft_token.flags.login_done = 1; 873178825Sdfr 874178825Sdfr return CKR_OK; 875178825Sdfr} 876178825Sdfr 877178825SdfrCK_RV 878178825SdfrC_Finalize(CK_VOID_PTR args) 879178825Sdfr{ 880178825Sdfr int i; 881178825Sdfr 882178825Sdfr INIT_CONTEXT(); 883178825Sdfr 884178825Sdfr st_logf("Finalize\n"); 885178825Sdfr 886178825Sdfr for (i = 0; i < MAX_NUM_SESSION; i++) { 887178825Sdfr if (soft_token.state[i].session_handle != CK_INVALID_HANDLE) { 888178825Sdfr application_error("application finalized without " 889178825Sdfr "closing session\n"); 890178825Sdfr close_session(&soft_token.state[i]); 891178825Sdfr } 892178825Sdfr } 893178825Sdfr 894178825Sdfr return CKR_OK; 895178825Sdfr} 896178825Sdfr 897178825SdfrCK_RV 898178825SdfrC_GetInfo(CK_INFO_PTR args) 899178825Sdfr{ 900178825Sdfr INIT_CONTEXT(); 901178825Sdfr 902178825Sdfr st_logf("GetInfo\n"); 903178825Sdfr 904178825Sdfr memset(args, 17, sizeof(*args)); 905178825Sdfr args->cryptokiVersion.major = 2; 906178825Sdfr args->cryptokiVersion.minor = 10; 907178825Sdfr snprintf_fill((char *)args->manufacturerID, 908178825Sdfr sizeof(args->manufacturerID), 909178825Sdfr ' ', 910178825Sdfr "Heimdal hx509 SoftToken"); 911178825Sdfr snprintf_fill((char *)args->libraryDescription, 912178825Sdfr sizeof(args->libraryDescription), ' ', 913178825Sdfr "Heimdal hx509 SoftToken"); 914178825Sdfr args->libraryVersion.major = 2; 915178825Sdfr args->libraryVersion.minor = 0; 916178825Sdfr 917178825Sdfr return CKR_OK; 918178825Sdfr} 919178825Sdfr 920178825Sdfrextern CK_FUNCTION_LIST funcs; 921178825Sdfr 922178825SdfrCK_RV 923178825SdfrC_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) 924178825Sdfr{ 925178825Sdfr INIT_CONTEXT(); 926178825Sdfr 927178825Sdfr *ppFunctionList = &funcs; 928178825Sdfr return CKR_OK; 929178825Sdfr} 930178825Sdfr 931178825SdfrCK_RV 932178825SdfrC_GetSlotList(CK_BBOOL tokenPresent, 933178825Sdfr CK_SLOT_ID_PTR pSlotList, 934178825Sdfr CK_ULONG_PTR pulCount) 935178825Sdfr{ 936178825Sdfr INIT_CONTEXT(); 937178825Sdfr st_logf("GetSlotList: %s\n", 938178825Sdfr tokenPresent ? "tokenPresent" : "token not Present"); 939178825Sdfr if (pSlotList) 940178825Sdfr pSlotList[0] = 1; 941178825Sdfr *pulCount = 1; 942178825Sdfr return CKR_OK; 943178825Sdfr} 944178825Sdfr 945178825SdfrCK_RV 946178825SdfrC_GetSlotInfo(CK_SLOT_ID slotID, 947178825Sdfr CK_SLOT_INFO_PTR pInfo) 948178825Sdfr{ 949178825Sdfr INIT_CONTEXT(); 950178825Sdfr st_logf("GetSlotInfo: slot: %d : %s\n", (int)slotID, has_session()); 951178825Sdfr 952178825Sdfr memset(pInfo, 18, sizeof(*pInfo)); 953178825Sdfr 954178825Sdfr if (slotID != 1) 955178825Sdfr return CKR_ARGUMENTS_BAD; 956178825Sdfr 957178825Sdfr snprintf_fill((char *)pInfo->slotDescription, 958178825Sdfr sizeof(pInfo->slotDescription), 959178825Sdfr ' ', 960178825Sdfr "Heimdal hx509 SoftToken (slot)"); 961178825Sdfr snprintf_fill((char *)pInfo->manufacturerID, 962178825Sdfr sizeof(pInfo->manufacturerID), 963178825Sdfr ' ', 964178825Sdfr "Heimdal hx509 SoftToken (slot)"); 965178825Sdfr pInfo->flags = CKF_TOKEN_PRESENT; 966178825Sdfr if (soft_token.flags.hardware_slot) 967178825Sdfr pInfo->flags |= CKF_HW_SLOT; 968178825Sdfr pInfo->hardwareVersion.major = 1; 969178825Sdfr pInfo->hardwareVersion.minor = 0; 970178825Sdfr pInfo->firmwareVersion.major = 1; 971178825Sdfr pInfo->firmwareVersion.minor = 0; 972178825Sdfr 973178825Sdfr return CKR_OK; 974178825Sdfr} 975178825Sdfr 976178825SdfrCK_RV 977178825SdfrC_GetTokenInfo(CK_SLOT_ID slotID, 978178825Sdfr CK_TOKEN_INFO_PTR pInfo) 979178825Sdfr{ 980178825Sdfr INIT_CONTEXT(); 981178825Sdfr st_logf("GetTokenInfo: %s\n", has_session()); 982178825Sdfr 983178825Sdfr memset(pInfo, 19, sizeof(*pInfo)); 984178825Sdfr 985178825Sdfr snprintf_fill((char *)pInfo->label, 986178825Sdfr sizeof(pInfo->label), 987178825Sdfr ' ', 988178825Sdfr "Heimdal hx509 SoftToken (token)"); 989178825Sdfr snprintf_fill((char *)pInfo->manufacturerID, 990178825Sdfr sizeof(pInfo->manufacturerID), 991178825Sdfr ' ', 992178825Sdfr "Heimdal hx509 SoftToken (token)"); 993178825Sdfr snprintf_fill((char *)pInfo->model, 994178825Sdfr sizeof(pInfo->model), 995178825Sdfr ' ', 996178825Sdfr "Heimdal hx509 SoftToken (token)"); 997178825Sdfr snprintf_fill((char *)pInfo->serialNumber, 998178825Sdfr sizeof(pInfo->serialNumber), 999178825Sdfr ' ', 1000178825Sdfr "4711"); 1001178825Sdfr pInfo->flags = 1002178825Sdfr CKF_TOKEN_INITIALIZED | 1003178825Sdfr CKF_USER_PIN_INITIALIZED; 1004178825Sdfr 1005178825Sdfr if (soft_token.flags.login_done == 0) 1006178825Sdfr pInfo->flags |= CKF_LOGIN_REQUIRED; 1007178825Sdfr 1008178825Sdfr /* CFK_RNG | 1009178825Sdfr CKF_RESTORE_KEY_NOT_NEEDED | 1010178825Sdfr */ 1011178825Sdfr pInfo->ulMaxSessionCount = MAX_NUM_SESSION; 1012178825Sdfr pInfo->ulSessionCount = soft_token.open_sessions; 1013178825Sdfr pInfo->ulMaxRwSessionCount = MAX_NUM_SESSION; 1014178825Sdfr pInfo->ulRwSessionCount = soft_token.open_sessions; 1015178825Sdfr pInfo->ulMaxPinLen = 1024; 1016178825Sdfr pInfo->ulMinPinLen = 0; 1017178825Sdfr pInfo->ulTotalPublicMemory = 4711; 1018178825Sdfr pInfo->ulFreePublicMemory = 4712; 1019178825Sdfr pInfo->ulTotalPrivateMemory = 4713; 1020178825Sdfr pInfo->ulFreePrivateMemory = 4714; 1021178825Sdfr pInfo->hardwareVersion.major = 2; 1022178825Sdfr pInfo->hardwareVersion.minor = 0; 1023178825Sdfr pInfo->firmwareVersion.major = 2; 1024178825Sdfr pInfo->firmwareVersion.minor = 0; 1025178825Sdfr 1026178825Sdfr return CKR_OK; 1027178825Sdfr} 1028178825Sdfr 1029178825SdfrCK_RV 1030178825SdfrC_GetMechanismList(CK_SLOT_ID slotID, 1031178825Sdfr CK_MECHANISM_TYPE_PTR pMechanismList, 1032178825Sdfr CK_ULONG_PTR pulCount) 1033178825Sdfr{ 1034178825Sdfr INIT_CONTEXT(); 1035178825Sdfr st_logf("GetMechanismList\n"); 1036178825Sdfr 1037178825Sdfr *pulCount = 1; 1038178825Sdfr if (pMechanismList == NULL_PTR) 1039178825Sdfr return CKR_OK; 1040178825Sdfr pMechanismList[1] = CKM_RSA_PKCS; 1041178825Sdfr 1042178825Sdfr return CKR_OK; 1043178825Sdfr} 1044178825Sdfr 1045178825SdfrCK_RV 1046178825SdfrC_GetMechanismInfo(CK_SLOT_ID slotID, 1047178825Sdfr CK_MECHANISM_TYPE type, 1048178825Sdfr CK_MECHANISM_INFO_PTR pInfo) 1049178825Sdfr{ 1050178825Sdfr INIT_CONTEXT(); 1051178825Sdfr st_logf("GetMechanismInfo: slot %d type: %d\n", 1052178825Sdfr (int)slotID, (int)type); 1053178825Sdfr memset(pInfo, 0, sizeof(*pInfo)); 1054178825Sdfr 1055178825Sdfr return CKR_OK; 1056178825Sdfr} 1057178825Sdfr 1058178825SdfrCK_RV 1059178825SdfrC_InitToken(CK_SLOT_ID slotID, 1060178825Sdfr CK_UTF8CHAR_PTR pPin, 1061178825Sdfr CK_ULONG ulPinLen, 1062178825Sdfr CK_UTF8CHAR_PTR pLabel) 1063178825Sdfr{ 1064178825Sdfr INIT_CONTEXT(); 1065178825Sdfr st_logf("InitToken: slot %d\n", (int)slotID); 1066178825Sdfr return CKR_FUNCTION_NOT_SUPPORTED; 1067178825Sdfr} 1068178825Sdfr 1069178825SdfrCK_RV 1070178825SdfrC_OpenSession(CK_SLOT_ID slotID, 1071178825Sdfr CK_FLAGS flags, 1072178825Sdfr CK_VOID_PTR pApplication, 1073178825Sdfr CK_NOTIFY Notify, 1074178825Sdfr CK_SESSION_HANDLE_PTR phSession) 1075178825Sdfr{ 1076178825Sdfr int i; 1077178825Sdfr INIT_CONTEXT(); 1078178825Sdfr st_logf("OpenSession: slot: %d\n", (int)slotID); 1079178825Sdfr 1080178825Sdfr if (soft_token.open_sessions == MAX_NUM_SESSION) 1081178825Sdfr return CKR_SESSION_COUNT; 1082178825Sdfr 1083178825Sdfr soft_token.application = pApplication; 1084178825Sdfr soft_token.notify = Notify; 1085178825Sdfr 1086178825Sdfr for (i = 0; i < MAX_NUM_SESSION; i++) 1087178825Sdfr if (soft_token.state[i].session_handle == CK_INVALID_HANDLE) 1088178825Sdfr break; 1089178825Sdfr if (i == MAX_NUM_SESSION) 1090178825Sdfr abort(); 1091178825Sdfr 1092178825Sdfr soft_token.open_sessions++; 1093178825Sdfr 1094178825Sdfr soft_token.state[i].session_handle = 1095178825Sdfr (CK_SESSION_HANDLE)(random() & 0xfffff); 1096178825Sdfr *phSession = soft_token.state[i].session_handle; 1097178825Sdfr 1098178825Sdfr return CKR_OK; 1099178825Sdfr} 1100178825Sdfr 1101178825SdfrCK_RV 1102178825SdfrC_CloseSession(CK_SESSION_HANDLE hSession) 1103178825Sdfr{ 1104178825Sdfr struct session_state *state; 1105178825Sdfr INIT_CONTEXT(); 1106178825Sdfr st_logf("CloseSession\n"); 1107178825Sdfr 1108178825Sdfr if (verify_session_handle(hSession, &state) != CKR_OK) 1109178825Sdfr application_error("closed session not open"); 1110178825Sdfr else 1111178825Sdfr close_session(state); 1112178825Sdfr 1113178825Sdfr return CKR_OK; 1114178825Sdfr} 1115178825Sdfr 1116178825SdfrCK_RV 1117178825SdfrC_CloseAllSessions(CK_SLOT_ID slotID) 1118178825Sdfr{ 1119178825Sdfr int i; 1120178825Sdfr INIT_CONTEXT(); 1121178825Sdfr 1122178825Sdfr st_logf("CloseAllSessions\n"); 1123178825Sdfr 1124178825Sdfr for (i = 0; i < MAX_NUM_SESSION; i++) 1125178825Sdfr if (soft_token.state[i].session_handle != CK_INVALID_HANDLE) 1126178825Sdfr close_session(&soft_token.state[i]); 1127178825Sdfr 1128178825Sdfr return CKR_OK; 1129178825Sdfr} 1130178825Sdfr 1131178825SdfrCK_RV 1132178825SdfrC_GetSessionInfo(CK_SESSION_HANDLE hSession, 1133178825Sdfr CK_SESSION_INFO_PTR pInfo) 1134178825Sdfr{ 1135178825Sdfr st_logf("GetSessionInfo\n"); 1136178825Sdfr INIT_CONTEXT(); 1137178825Sdfr 1138178825Sdfr VERIFY_SESSION_HANDLE(hSession, NULL); 1139178825Sdfr 1140178825Sdfr memset(pInfo, 20, sizeof(*pInfo)); 1141178825Sdfr 1142178825Sdfr pInfo->slotID = 1; 1143178825Sdfr if (soft_token.flags.login_done) 1144178825Sdfr pInfo->state = CKS_RO_USER_FUNCTIONS; 1145178825Sdfr else 1146178825Sdfr pInfo->state = CKS_RO_PUBLIC_SESSION; 1147178825Sdfr pInfo->flags = CKF_SERIAL_SESSION; 1148178825Sdfr pInfo->ulDeviceError = 0; 1149178825Sdfr 1150178825Sdfr return CKR_OK; 1151178825Sdfr} 1152178825Sdfr 1153178825SdfrCK_RV 1154178825SdfrC_Login(CK_SESSION_HANDLE hSession, 1155178825Sdfr CK_USER_TYPE userType, 1156178825Sdfr CK_UTF8CHAR_PTR pPin, 1157178825Sdfr CK_ULONG ulPinLen) 1158178825Sdfr{ 1159178825Sdfr char *pin = NULL; 1160178825Sdfr CK_RV ret; 1161178825Sdfr INIT_CONTEXT(); 1162178825Sdfr 1163178825Sdfr st_logf("Login\n"); 1164178825Sdfr 1165178825Sdfr VERIFY_SESSION_HANDLE(hSession, NULL); 1166178825Sdfr 1167178825Sdfr if (pPin != NULL_PTR) { 1168178825Sdfr asprintf(&pin, "%.*s", (int)ulPinLen, pPin); 1169178825Sdfr st_logf("type: %d password: %s\n", (int)userType, pin); 1170178825Sdfr } 1171178825Sdfr 1172178825Sdfr /* 1173178825Sdfr * Login 1174178825Sdfr */ 1175178825Sdfr 1176178825Sdfr ret = read_conf_file(soft_token.config_file, userType, pin); 1177178825Sdfr if (ret == CKR_OK) 1178178825Sdfr soft_token.flags.login_done = 1; 1179178825Sdfr 1180178825Sdfr free(pin); 1181178825Sdfr 1182178825Sdfr return soft_token.flags.login_done ? CKR_OK : CKR_PIN_INCORRECT; 1183178825Sdfr} 1184178825Sdfr 1185178825SdfrCK_RV 1186178825SdfrC_Logout(CK_SESSION_HANDLE hSession) 1187178825Sdfr{ 1188178825Sdfr st_logf("Logout\n"); 1189178825Sdfr INIT_CONTEXT(); 1190178825Sdfr 1191178825Sdfr VERIFY_SESSION_HANDLE(hSession, NULL); 1192178825Sdfr return CKR_FUNCTION_NOT_SUPPORTED; 1193178825Sdfr} 1194178825Sdfr 1195178825SdfrCK_RV 1196178825SdfrC_GetObjectSize(CK_SESSION_HANDLE hSession, 1197178825Sdfr CK_OBJECT_HANDLE hObject, 1198178825Sdfr CK_ULONG_PTR pulSize) 1199178825Sdfr{ 1200178825Sdfr st_logf("GetObjectSize\n"); 1201178825Sdfr INIT_CONTEXT(); 1202178825Sdfr 1203178825Sdfr VERIFY_SESSION_HANDLE(hSession, NULL); 1204178825Sdfr return CKR_FUNCTION_NOT_SUPPORTED; 1205178825Sdfr} 1206178825Sdfr 1207178825SdfrCK_RV 1208178825SdfrC_GetAttributeValue(CK_SESSION_HANDLE hSession, 1209178825Sdfr CK_OBJECT_HANDLE hObject, 1210178825Sdfr CK_ATTRIBUTE_PTR pTemplate, 1211178825Sdfr CK_ULONG ulCount) 1212178825Sdfr{ 1213178825Sdfr struct session_state *state; 1214178825Sdfr struct st_object *obj; 1215178825Sdfr CK_ULONG i; 1216178825Sdfr CK_RV ret; 1217178825Sdfr int j; 1218178825Sdfr 1219178825Sdfr INIT_CONTEXT(); 1220178825Sdfr 1221178825Sdfr st_logf("GetAttributeValue: %lx\n", 1222178825Sdfr (unsigned long)HANDLE_OBJECT_ID(hObject)); 1223178825Sdfr VERIFY_SESSION_HANDLE(hSession, &state); 1224178825Sdfr 1225178825Sdfr if ((ret = object_handle_to_object(hObject, &obj)) != CKR_OK) { 1226178825Sdfr st_logf("object not found: %lx\n", 1227178825Sdfr (unsigned long)HANDLE_OBJECT_ID(hObject)); 1228178825Sdfr return ret; 1229178825Sdfr } 1230178825Sdfr 1231178825Sdfr for (i = 0; i < ulCount; i++) { 1232178825Sdfr st_logf(" getting 0x%08lx\n", (unsigned long)pTemplate[i].type); 1233178825Sdfr for (j = 0; j < obj->num_attributes; j++) { 1234178825Sdfr if (obj->attrs[j].secret) { 1235178825Sdfr pTemplate[i].ulValueLen = (CK_ULONG)-1; 1236178825Sdfr break; 1237178825Sdfr } 1238178825Sdfr if (pTemplate[i].type == obj->attrs[j].attribute.type) { 1239178825Sdfr if (pTemplate[i].pValue != NULL_PTR && obj->attrs[j].secret == 0) { 1240178825Sdfr if (pTemplate[i].ulValueLen >= obj->attrs[j].attribute.ulValueLen) 1241178825Sdfr memcpy(pTemplate[i].pValue, obj->attrs[j].attribute.pValue, 1242178825Sdfr obj->attrs[j].attribute.ulValueLen); 1243178825Sdfr } 1244178825Sdfr pTemplate[i].ulValueLen = obj->attrs[j].attribute.ulValueLen; 1245178825Sdfr break; 1246178825Sdfr } 1247178825Sdfr } 1248178825Sdfr if (j == obj->num_attributes) { 1249178825Sdfr st_logf("key type: 0x%08lx not found\n", (unsigned long)pTemplate[i].type); 1250178825Sdfr pTemplate[i].ulValueLen = (CK_ULONG)-1; 1251178825Sdfr } 1252178825Sdfr 1253178825Sdfr } 1254178825Sdfr return CKR_OK; 1255178825Sdfr} 1256178825Sdfr 1257178825SdfrCK_RV 1258178825SdfrC_FindObjectsInit(CK_SESSION_HANDLE hSession, 1259178825Sdfr CK_ATTRIBUTE_PTR pTemplate, 1260178825Sdfr CK_ULONG ulCount) 1261178825Sdfr{ 1262178825Sdfr struct session_state *state; 1263178825Sdfr 1264178825Sdfr st_logf("FindObjectsInit\n"); 1265178825Sdfr 1266178825Sdfr INIT_CONTEXT(); 1267178825Sdfr 1268178825Sdfr VERIFY_SESSION_HANDLE(hSession, &state); 1269178825Sdfr 1270178825Sdfr if (state->find.next_object != -1) { 1271178825Sdfr application_error("application didn't do C_FindObjectsFinal\n"); 1272178825Sdfr find_object_final(state); 1273178825Sdfr } 1274178825Sdfr if (ulCount) { 1275178825Sdfr CK_ULONG i; 1276178825Sdfr 1277178825Sdfr print_attributes(pTemplate, ulCount); 1278178825Sdfr 1279178825Sdfr state->find.attributes = 1280178825Sdfr calloc(1, ulCount * sizeof(state->find.attributes[0])); 1281178825Sdfr if (state->find.attributes == NULL) 1282178825Sdfr return CKR_DEVICE_MEMORY; 1283178825Sdfr for (i = 0; i < ulCount; i++) { 1284178825Sdfr state->find.attributes[i].pValue = 1285178825Sdfr malloc(pTemplate[i].ulValueLen); 1286178825Sdfr if (state->find.attributes[i].pValue == NULL) { 1287178825Sdfr find_object_final(state); 1288178825Sdfr return CKR_DEVICE_MEMORY; 1289178825Sdfr } 1290178825Sdfr memcpy(state->find.attributes[i].pValue, 1291178825Sdfr pTemplate[i].pValue, pTemplate[i].ulValueLen); 1292178825Sdfr state->find.attributes[i].type = pTemplate[i].type; 1293178825Sdfr state->find.attributes[i].ulValueLen = pTemplate[i].ulValueLen; 1294178825Sdfr } 1295178825Sdfr state->find.num_attributes = ulCount; 1296178825Sdfr state->find.next_object = 0; 1297178825Sdfr } else { 1298178825Sdfr st_logf("find all objects\n"); 1299178825Sdfr state->find.attributes = NULL; 1300178825Sdfr state->find.num_attributes = 0; 1301178825Sdfr state->find.next_object = 0; 1302178825Sdfr } 1303178825Sdfr 1304178825Sdfr return CKR_OK; 1305178825Sdfr} 1306178825Sdfr 1307178825SdfrCK_RV 1308178825SdfrC_FindObjects(CK_SESSION_HANDLE hSession, 1309178825Sdfr CK_OBJECT_HANDLE_PTR phObject, 1310178825Sdfr CK_ULONG ulMaxObjectCount, 1311178825Sdfr CK_ULONG_PTR pulObjectCount) 1312178825Sdfr{ 1313178825Sdfr struct session_state *state; 1314178825Sdfr int i; 1315178825Sdfr 1316178825Sdfr INIT_CONTEXT(); 1317178825Sdfr 1318178825Sdfr st_logf("FindObjects\n"); 1319178825Sdfr 1320178825Sdfr VERIFY_SESSION_HANDLE(hSession, &state); 1321178825Sdfr 1322178825Sdfr if (state->find.next_object == -1) { 1323178825Sdfr application_error("application didn't do C_FindObjectsInit\n"); 1324178825Sdfr return CKR_ARGUMENTS_BAD; 1325178825Sdfr } 1326178825Sdfr if (ulMaxObjectCount == 0) { 1327178825Sdfr application_error("application asked for 0 objects\n"); 1328178825Sdfr return CKR_ARGUMENTS_BAD; 1329178825Sdfr } 1330178825Sdfr *pulObjectCount = 0; 1331178825Sdfr for (i = state->find.next_object; i < soft_token.object.num_objs; i++) { 1332178825Sdfr st_logf("FindObjects: %d\n", i); 1333178825Sdfr state->find.next_object = i + 1; 1334178825Sdfr if (attributes_match(soft_token.object.objs[i], 1335178825Sdfr state->find.attributes, 1336178825Sdfr state->find.num_attributes)) { 1337178825Sdfr *phObject++ = soft_token.object.objs[i]->object_handle; 1338178825Sdfr ulMaxObjectCount--; 1339178825Sdfr (*pulObjectCount)++; 1340178825Sdfr if (ulMaxObjectCount == 0) 1341178825Sdfr break; 1342178825Sdfr } 1343178825Sdfr } 1344178825Sdfr return CKR_OK; 1345178825Sdfr} 1346178825Sdfr 1347178825SdfrCK_RV 1348178825SdfrC_FindObjectsFinal(CK_SESSION_HANDLE hSession) 1349178825Sdfr{ 1350178825Sdfr struct session_state *state; 1351178825Sdfr 1352178825Sdfr INIT_CONTEXT(); 1353178825Sdfr 1354178825Sdfr st_logf("FindObjectsFinal\n"); 1355178825Sdfr VERIFY_SESSION_HANDLE(hSession, &state); 1356178825Sdfr find_object_final(state); 1357178825Sdfr return CKR_OK; 1358178825Sdfr} 1359178825Sdfr 1360178825Sdfrstatic CK_RV 1361178825SdfrcommonInit(CK_ATTRIBUTE *attr_match, int attr_match_len, 1362178825Sdfr const CK_MECHANISM_TYPE *mechs, int mechs_len, 1363178825Sdfr const CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, 1364178825Sdfr struct st_object **o) 1365178825Sdfr{ 1366178825Sdfr CK_RV ret; 1367178825Sdfr int i; 1368178825Sdfr 1369178825Sdfr *o = NULL; 1370178825Sdfr if ((ret = object_handle_to_object(hKey, o)) != CKR_OK) 1371178825Sdfr return ret; 1372178825Sdfr 1373178825Sdfr ret = attributes_match(*o, attr_match, attr_match_len); 1374178825Sdfr if (!ret) { 1375178825Sdfr application_error("called commonInit on key that doesn't " 1376178825Sdfr "support required attr"); 1377178825Sdfr return CKR_ARGUMENTS_BAD; 1378178825Sdfr } 1379178825Sdfr 1380178825Sdfr for (i = 0; i < mechs_len; i++) 1381178825Sdfr if (mechs[i] == pMechanism->mechanism) 1382178825Sdfr break; 1383178825Sdfr if (i == mechs_len) { 1384178825Sdfr application_error("called mech (%08lx) not supported\n", 1385178825Sdfr pMechanism->mechanism); 1386178825Sdfr return CKR_ARGUMENTS_BAD; 1387178825Sdfr } 1388178825Sdfr return CKR_OK; 1389178825Sdfr} 1390178825Sdfr 1391178825Sdfr 1392178825Sdfrstatic CK_RV 1393178825Sdfrdup_mechanism(CK_MECHANISM_PTR *dup, const CK_MECHANISM_PTR pMechanism) 1394178825Sdfr{ 1395178825Sdfr CK_MECHANISM_PTR p; 1396178825Sdfr 1397178825Sdfr p = malloc(sizeof(*p)); 1398178825Sdfr if (p == NULL) 1399178825Sdfr return CKR_DEVICE_MEMORY; 1400178825Sdfr 1401178825Sdfr if (*dup) 1402178825Sdfr free(*dup); 1403178825Sdfr *dup = p; 1404178825Sdfr memcpy(p, pMechanism, sizeof(*p)); 1405178825Sdfr 1406178825Sdfr return CKR_OK; 1407178825Sdfr} 1408178825Sdfr 1409178825SdfrCK_RV 1410178825SdfrC_DigestInit(CK_SESSION_HANDLE hSession, 1411178825Sdfr CK_MECHANISM_PTR pMechanism) 1412178825Sdfr{ 1413178825Sdfr st_logf("DigestInit\n"); 1414178825Sdfr INIT_CONTEXT(); 1415178825Sdfr VERIFY_SESSION_HANDLE(hSession, NULL); 1416178825Sdfr return CKR_FUNCTION_NOT_SUPPORTED; 1417178825Sdfr} 1418178825Sdfr 1419178825SdfrCK_RV 1420178825SdfrC_SignInit(CK_SESSION_HANDLE hSession, 1421178825Sdfr CK_MECHANISM_PTR pMechanism, 1422178825Sdfr CK_OBJECT_HANDLE hKey) 1423178825Sdfr{ 1424178825Sdfr struct session_state *state; 1425178825Sdfr CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS }; 1426178825Sdfr CK_BBOOL bool_true = CK_TRUE; 1427178825Sdfr CK_ATTRIBUTE attr[] = { 1428178825Sdfr { CKA_SIGN, &bool_true, sizeof(bool_true) } 1429178825Sdfr }; 1430178825Sdfr struct st_object *o; 1431178825Sdfr CK_RV ret; 1432178825Sdfr 1433178825Sdfr INIT_CONTEXT(); 1434178825Sdfr st_logf("SignInit\n"); 1435178825Sdfr VERIFY_SESSION_HANDLE(hSession, &state); 1436178825Sdfr 1437178825Sdfr ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]), 1438178825Sdfr mechs, sizeof(mechs)/sizeof(mechs[0]), 1439178825Sdfr pMechanism, hKey, &o); 1440178825Sdfr if (ret) 1441178825Sdfr return ret; 1442178825Sdfr 1443178825Sdfr ret = dup_mechanism(&state->sign_mechanism, pMechanism); 1444178825Sdfr if (ret == CKR_OK) 1445178825Sdfr state->sign_object = OBJECT_ID(o); 1446178825Sdfr 1447178825Sdfr return CKR_OK; 1448178825Sdfr} 1449178825Sdfr 1450178825SdfrCK_RV 1451178825SdfrC_Sign(CK_SESSION_HANDLE hSession, 1452178825Sdfr CK_BYTE_PTR pData, 1453178825Sdfr CK_ULONG ulDataLen, 1454178825Sdfr CK_BYTE_PTR pSignature, 1455178825Sdfr CK_ULONG_PTR pulSignatureLen) 1456178825Sdfr{ 1457178825Sdfr struct session_state *state; 1458178825Sdfr struct st_object *o; 1459178825Sdfr CK_RV ret; 1460178825Sdfr uint hret; 1461178825Sdfr const AlgorithmIdentifier *alg; 1462178825Sdfr heim_octet_string sig, data; 1463178825Sdfr 1464178825Sdfr INIT_CONTEXT(); 1465178825Sdfr st_logf("Sign\n"); 1466178825Sdfr VERIFY_SESSION_HANDLE(hSession, &state); 1467178825Sdfr 1468178825Sdfr sig.data = NULL; 1469178825Sdfr sig.length = 0; 1470178825Sdfr 1471178825Sdfr if (state->sign_object == -1) 1472178825Sdfr return CKR_ARGUMENTS_BAD; 1473178825Sdfr 1474178825Sdfr if (pulSignatureLen == NULL) { 1475178825Sdfr st_logf("signature len NULL\n"); 1476178825Sdfr ret = CKR_ARGUMENTS_BAD; 1477178825Sdfr goto out; 1478178825Sdfr } 1479178825Sdfr 1480178825Sdfr if (pData == NULL_PTR) { 1481178825Sdfr st_logf("data NULL\n"); 1482178825Sdfr ret = CKR_ARGUMENTS_BAD; 1483178825Sdfr goto out; 1484178825Sdfr } 1485178825Sdfr 1486178825Sdfr o = soft_token.object.objs[state->sign_object]; 1487178825Sdfr 1488178825Sdfr if (hx509_cert_have_private_key(o->cert) == 0) { 1489178825Sdfr st_logf("private key NULL\n"); 1490178825Sdfr return CKR_ARGUMENTS_BAD; 1491178825Sdfr } 1492178825Sdfr 1493178825Sdfr switch(state->sign_mechanism->mechanism) { 1494178825Sdfr case CKM_RSA_PKCS: 1495178825Sdfr alg = hx509_signature_rsa_pkcs1_x509(); 1496178825Sdfr break; 1497178825Sdfr default: 1498178825Sdfr ret = CKR_FUNCTION_NOT_SUPPORTED; 1499178825Sdfr goto out; 1500178825Sdfr } 1501178825Sdfr 1502178825Sdfr data.data = pData; 1503178825Sdfr data.length = ulDataLen; 1504178825Sdfr 1505178825Sdfr hret = _hx509_create_signature(context, 1506178825Sdfr _hx509_cert_private_key(o->cert), 1507178825Sdfr alg, 1508178825Sdfr &data, 1509178825Sdfr NULL, 1510178825Sdfr &sig); 1511178825Sdfr if (hret) { 1512178825Sdfr ret = CKR_DEVICE_ERROR; 1513178825Sdfr goto out; 1514178825Sdfr } 1515178825Sdfr *pulSignatureLen = sig.length; 1516178825Sdfr 1517178825Sdfr if (pSignature != NULL_PTR) 1518178825Sdfr memcpy(pSignature, sig.data, sig.length); 1519178825Sdfr 1520178825Sdfr ret = CKR_OK; 1521178825Sdfr out: 1522178825Sdfr if (sig.data) { 1523178825Sdfr memset(sig.data, 0, sig.length); 1524178825Sdfr der_free_octet_string(&sig); 1525178825Sdfr } 1526178825Sdfr return ret; 1527178825Sdfr} 1528178825Sdfr 1529178825SdfrCK_RV 1530178825SdfrC_SignUpdate(CK_SESSION_HANDLE hSession, 1531178825Sdfr CK_BYTE_PTR pPart, 1532178825Sdfr CK_ULONG ulPartLen) 1533178825Sdfr{ 1534178825Sdfr INIT_CONTEXT(); 1535178825Sdfr st_logf("SignUpdate\n"); 1536178825Sdfr VERIFY_SESSION_HANDLE(hSession, NULL); 1537178825Sdfr return CKR_FUNCTION_NOT_SUPPORTED; 1538178825Sdfr} 1539178825Sdfr 1540178825Sdfr 1541178825SdfrCK_RV 1542178825SdfrC_SignFinal(CK_SESSION_HANDLE hSession, 1543178825Sdfr CK_BYTE_PTR pSignature, 1544178825Sdfr CK_ULONG_PTR pulSignatureLen) 1545178825Sdfr{ 1546178825Sdfr INIT_CONTEXT(); 1547178825Sdfr st_logf("SignUpdate\n"); 1548178825Sdfr VERIFY_SESSION_HANDLE(hSession, NULL); 1549178825Sdfr return CKR_FUNCTION_NOT_SUPPORTED; 1550178825Sdfr} 1551178825Sdfr 1552178825SdfrCK_RV 1553178825SdfrC_VerifyInit(CK_SESSION_HANDLE hSession, 1554178825Sdfr CK_MECHANISM_PTR pMechanism, 1555178825Sdfr CK_OBJECT_HANDLE hKey) 1556178825Sdfr{ 1557178825Sdfr struct session_state *state; 1558178825Sdfr CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS }; 1559178825Sdfr CK_BBOOL bool_true = CK_TRUE; 1560178825Sdfr CK_ATTRIBUTE attr[] = { 1561178825Sdfr { CKA_VERIFY, &bool_true, sizeof(bool_true) } 1562178825Sdfr }; 1563178825Sdfr struct st_object *o; 1564178825Sdfr CK_RV ret; 1565178825Sdfr 1566178825Sdfr INIT_CONTEXT(); 1567178825Sdfr st_logf("VerifyInit\n"); 1568178825Sdfr VERIFY_SESSION_HANDLE(hSession, &state); 1569178825Sdfr 1570178825Sdfr ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]), 1571178825Sdfr mechs, sizeof(mechs)/sizeof(mechs[0]), 1572178825Sdfr pMechanism, hKey, &o); 1573178825Sdfr if (ret) 1574178825Sdfr return ret; 1575178825Sdfr 1576178825Sdfr ret = dup_mechanism(&state->verify_mechanism, pMechanism); 1577178825Sdfr if (ret == CKR_OK) 1578178825Sdfr state->verify_object = OBJECT_ID(o); 1579178825Sdfr 1580178825Sdfr return ret; 1581178825Sdfr} 1582178825Sdfr 1583178825SdfrCK_RV 1584178825SdfrC_Verify(CK_SESSION_HANDLE hSession, 1585178825Sdfr CK_BYTE_PTR pData, 1586178825Sdfr CK_ULONG ulDataLen, 1587178825Sdfr CK_BYTE_PTR pSignature, 1588178825Sdfr CK_ULONG ulSignatureLen) 1589178825Sdfr{ 1590178825Sdfr struct session_state *state; 1591178825Sdfr struct st_object *o; 1592178825Sdfr const AlgorithmIdentifier *alg; 1593178825Sdfr CK_RV ret; 1594178825Sdfr int hret; 1595178825Sdfr heim_octet_string data, sig; 1596178825Sdfr 1597178825Sdfr INIT_CONTEXT(); 1598178825Sdfr st_logf("Verify\n"); 1599178825Sdfr VERIFY_SESSION_HANDLE(hSession, &state); 1600178825Sdfr 1601178825Sdfr if (state->verify_object == -1) 1602178825Sdfr return CKR_ARGUMENTS_BAD; 1603178825Sdfr 1604178825Sdfr o = soft_token.object.objs[state->verify_object]; 1605178825Sdfr 1606178825Sdfr switch(state->verify_mechanism->mechanism) { 1607178825Sdfr case CKM_RSA_PKCS: 1608178825Sdfr alg = hx509_signature_rsa_pkcs1_x509(); 1609178825Sdfr break; 1610178825Sdfr default: 1611178825Sdfr ret = CKR_FUNCTION_NOT_SUPPORTED; 1612178825Sdfr goto out; 1613178825Sdfr } 1614178825Sdfr 1615178825Sdfr sig.data = pData; 1616178825Sdfr sig.length = ulDataLen; 1617178825Sdfr data.data = pSignature; 1618178825Sdfr data.length = ulSignatureLen; 1619178825Sdfr 1620178825Sdfr hret = _hx509_verify_signature(context, 1621178825Sdfr _hx509_get_cert(o->cert), 1622178825Sdfr alg, 1623178825Sdfr &data, 1624178825Sdfr &sig); 1625178825Sdfr if (hret) { 1626178825Sdfr ret = CKR_GENERAL_ERROR; 1627178825Sdfr goto out; 1628178825Sdfr } 1629178825Sdfr ret = CKR_OK; 1630178825Sdfr 1631178825Sdfr out: 1632178825Sdfr return ret; 1633178825Sdfr} 1634178825Sdfr 1635178825Sdfr 1636178825SdfrCK_RV 1637178825SdfrC_VerifyUpdate(CK_SESSION_HANDLE hSession, 1638178825Sdfr CK_BYTE_PTR pPart, 1639178825Sdfr CK_ULONG ulPartLen) 1640178825Sdfr{ 1641178825Sdfr INIT_CONTEXT(); 1642178825Sdfr st_logf("VerifyUpdate\n"); 1643178825Sdfr VERIFY_SESSION_HANDLE(hSession, NULL); 1644178825Sdfr return CKR_FUNCTION_NOT_SUPPORTED; 1645178825Sdfr} 1646178825Sdfr 1647178825SdfrCK_RV 1648178825SdfrC_VerifyFinal(CK_SESSION_HANDLE hSession, 1649178825Sdfr CK_BYTE_PTR pSignature, 1650178825Sdfr CK_ULONG ulSignatureLen) 1651178825Sdfr{ 1652178825Sdfr INIT_CONTEXT(); 1653178825Sdfr st_logf("VerifyFinal\n"); 1654178825Sdfr VERIFY_SESSION_HANDLE(hSession, NULL); 1655178825Sdfr return CKR_FUNCTION_NOT_SUPPORTED; 1656178825Sdfr} 1657178825Sdfr 1658178825SdfrCK_RV 1659178825SdfrC_GenerateRandom(CK_SESSION_HANDLE hSession, 1660178825Sdfr CK_BYTE_PTR RandomData, 1661178825Sdfr CK_ULONG ulRandomLen) 1662178825Sdfr{ 1663178825Sdfr INIT_CONTEXT(); 1664178825Sdfr st_logf("GenerateRandom\n"); 1665178825Sdfr VERIFY_SESSION_HANDLE(hSession, NULL); 1666178825Sdfr return CKR_FUNCTION_NOT_SUPPORTED; 1667178825Sdfr} 1668178825Sdfr 1669178825Sdfr 1670178825SdfrCK_FUNCTION_LIST funcs = { 1671178825Sdfr { 2, 11 }, 1672178825Sdfr C_Initialize, 1673178825Sdfr C_Finalize, 1674178825Sdfr C_GetInfo, 1675178825Sdfr C_GetFunctionList, 1676178825Sdfr C_GetSlotList, 1677178825Sdfr C_GetSlotInfo, 1678178825Sdfr C_GetTokenInfo, 1679178825Sdfr C_GetMechanismList, 1680178825Sdfr C_GetMechanismInfo, 1681178825Sdfr C_InitToken, 1682178825Sdfr (void *)func_not_supported, /* C_InitPIN */ 1683178825Sdfr (void *)func_not_supported, /* C_SetPIN */ 1684178825Sdfr C_OpenSession, 1685178825Sdfr C_CloseSession, 1686178825Sdfr C_CloseAllSessions, 1687178825Sdfr C_GetSessionInfo, 1688178825Sdfr (void *)func_not_supported, /* C_GetOperationState */ 1689178825Sdfr (void *)func_not_supported, /* C_SetOperationState */ 1690178825Sdfr C_Login, 1691178825Sdfr C_Logout, 1692178825Sdfr (void *)func_not_supported, /* C_CreateObject */ 1693178825Sdfr (void *)func_not_supported, /* C_CopyObject */ 1694178825Sdfr (void *)func_not_supported, /* C_DestroyObject */ 1695178825Sdfr (void *)func_not_supported, /* C_GetObjectSize */ 1696178825Sdfr C_GetAttributeValue, 1697178825Sdfr (void *)func_not_supported, /* C_SetAttributeValue */ 1698178825Sdfr C_FindObjectsInit, 1699178825Sdfr C_FindObjects, 1700178825Sdfr C_FindObjectsFinal, 1701178825Sdfr (void *)func_not_supported, /* C_EncryptInit, */ 1702178825Sdfr (void *)func_not_supported, /* C_Encrypt, */ 1703178825Sdfr (void *)func_not_supported, /* C_EncryptUpdate, */ 1704178825Sdfr (void *)func_not_supported, /* C_EncryptFinal, */ 1705178825Sdfr (void *)func_not_supported, /* C_DecryptInit, */ 1706178825Sdfr (void *)func_not_supported, /* C_Decrypt, */ 1707178825Sdfr (void *)func_not_supported, /* C_DecryptUpdate, */ 1708178825Sdfr (void *)func_not_supported, /* C_DecryptFinal, */ 1709178825Sdfr C_DigestInit, 1710178825Sdfr (void *)func_not_supported, /* C_Digest */ 1711178825Sdfr (void *)func_not_supported, /* C_DigestUpdate */ 1712178825Sdfr (void *)func_not_supported, /* C_DigestKey */ 1713178825Sdfr (void *)func_not_supported, /* C_DigestFinal */ 1714178825Sdfr C_SignInit, 1715178825Sdfr C_Sign, 1716178825Sdfr C_SignUpdate, 1717178825Sdfr C_SignFinal, 1718178825Sdfr (void *)func_not_supported, /* C_SignRecoverInit */ 1719178825Sdfr (void *)func_not_supported, /* C_SignRecover */ 1720178825Sdfr C_VerifyInit, 1721178825Sdfr C_Verify, 1722178825Sdfr C_VerifyUpdate, 1723178825Sdfr C_VerifyFinal, 1724178825Sdfr (void *)func_not_supported, /* C_VerifyRecoverInit */ 1725178825Sdfr (void *)func_not_supported, /* C_VerifyRecover */ 1726178825Sdfr (void *)func_not_supported, /* C_DigestEncryptUpdate */ 1727178825Sdfr (void *)func_not_supported, /* C_DecryptDigestUpdate */ 1728178825Sdfr (void *)func_not_supported, /* C_SignEncryptUpdate */ 1729178825Sdfr (void *)func_not_supported, /* C_DecryptVerifyUpdate */ 1730178825Sdfr (void *)func_not_supported, /* C_GenerateKey */ 1731178825Sdfr (void *)func_not_supported, /* C_GenerateKeyPair */ 1732178825Sdfr (void *)func_not_supported, /* C_WrapKey */ 1733178825Sdfr (void *)func_not_supported, /* C_UnwrapKey */ 1734178825Sdfr (void *)func_not_supported, /* C_DeriveKey */ 1735178825Sdfr (void *)func_not_supported, /* C_SeedRandom */ 1736178825Sdfr C_GenerateRandom, 1737178825Sdfr (void *)func_not_supported, /* C_GetFunctionStatus */ 1738178825Sdfr (void *)func_not_supported, /* C_CancelFunction */ 1739178825Sdfr (void *)func_not_supported /* C_WaitForSlotEvent */ 1740178825Sdfr}; 1741