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