1c19800e8SDoug Rabson /* 2c19800e8SDoug Rabson * Copyright (c) 2004 - 2008 Kungliga Tekniska H�gskolan 3c19800e8SDoug Rabson * (Royal Institute of Technology, Stockholm, Sweden). 4c19800e8SDoug Rabson * All rights reserved. 5c19800e8SDoug Rabson * 6c19800e8SDoug Rabson * Redistribution and use in source and binary forms, with or without 7c19800e8SDoug Rabson * modification, are permitted provided that the following conditions 8c19800e8SDoug Rabson * are met: 9c19800e8SDoug Rabson * 10c19800e8SDoug Rabson * 1. Redistributions of source code must retain the above copyright 11c19800e8SDoug Rabson * notice, this list of conditions and the following disclaimer. 12c19800e8SDoug Rabson * 13c19800e8SDoug Rabson * 2. Redistributions in binary form must reproduce the above copyright 14c19800e8SDoug Rabson * notice, this list of conditions and the following disclaimer in the 15c19800e8SDoug Rabson * documentation and/or other materials provided with the distribution. 16c19800e8SDoug Rabson * 17c19800e8SDoug Rabson * 3. Neither the name of the Institute nor the names of its contributors 18c19800e8SDoug Rabson * may be used to endorse or promote products derived from this software 19c19800e8SDoug Rabson * without specific prior written permission. 20c19800e8SDoug Rabson * 21c19800e8SDoug Rabson * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22c19800e8SDoug Rabson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23c19800e8SDoug Rabson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24c19800e8SDoug Rabson * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25c19800e8SDoug Rabson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26c19800e8SDoug Rabson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27c19800e8SDoug Rabson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28c19800e8SDoug Rabson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29c19800e8SDoug Rabson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30c19800e8SDoug Rabson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31c19800e8SDoug Rabson * SUCH DAMAGE. 32c19800e8SDoug Rabson */ 33c19800e8SDoug Rabson 34c19800e8SDoug Rabson #include "hx_locl.h" 35c19800e8SDoug Rabson #include "pkcs11.h" 36c19800e8SDoug Rabson 37c19800e8SDoug Rabson #define OBJECT_ID_MASK 0xfff 38c19800e8SDoug Rabson #define HANDLE_OBJECT_ID(h) ((h) & OBJECT_ID_MASK) 39c19800e8SDoug Rabson #define OBJECT_ID(obj) HANDLE_OBJECT_ID((obj)->object_handle) 40c19800e8SDoug Rabson 41c19800e8SDoug Rabson 42c19800e8SDoug Rabson struct st_attr { 43c19800e8SDoug Rabson CK_ATTRIBUTE attribute; 44c19800e8SDoug Rabson int secret; 45c19800e8SDoug Rabson }; 46c19800e8SDoug Rabson 47c19800e8SDoug Rabson struct st_object { 48c19800e8SDoug Rabson CK_OBJECT_HANDLE object_handle; 49c19800e8SDoug Rabson struct st_attr *attrs; 50c19800e8SDoug Rabson int num_attributes; 51c19800e8SDoug Rabson hx509_cert cert; 52c19800e8SDoug Rabson }; 53c19800e8SDoug Rabson 54c19800e8SDoug Rabson static struct soft_token { 55c19800e8SDoug Rabson CK_VOID_PTR application; 56c19800e8SDoug Rabson CK_NOTIFY notify; 57c19800e8SDoug Rabson char *config_file; 58c19800e8SDoug Rabson hx509_certs certs; 59c19800e8SDoug Rabson struct { 60c19800e8SDoug Rabson struct st_object **objs; 61c19800e8SDoug Rabson int num_objs; 62c19800e8SDoug Rabson } object; 63c19800e8SDoug Rabson struct { 64c19800e8SDoug Rabson int hardware_slot; 65c19800e8SDoug Rabson int app_error_fatal; 66c19800e8SDoug Rabson int login_done; 67c19800e8SDoug Rabson } flags; 68c19800e8SDoug Rabson int open_sessions; 69c19800e8SDoug Rabson struct session_state { 70c19800e8SDoug Rabson CK_SESSION_HANDLE session_handle; 71c19800e8SDoug Rabson 72c19800e8SDoug Rabson struct { 73c19800e8SDoug Rabson CK_ATTRIBUTE *attributes; 74c19800e8SDoug Rabson CK_ULONG num_attributes; 75c19800e8SDoug Rabson int next_object; 76c19800e8SDoug Rabson } find; 77c19800e8SDoug Rabson 78c19800e8SDoug Rabson int sign_object; 79c19800e8SDoug Rabson CK_MECHANISM_PTR sign_mechanism; 80c19800e8SDoug Rabson int verify_object; 81c19800e8SDoug Rabson CK_MECHANISM_PTR verify_mechanism; 82c19800e8SDoug Rabson } state[10]; 83c19800e8SDoug Rabson #define MAX_NUM_SESSION (sizeof(soft_token.state)/sizeof(soft_token.state[0])) 84c19800e8SDoug Rabson FILE *logfile; 85c19800e8SDoug Rabson } soft_token; 86c19800e8SDoug Rabson 87c19800e8SDoug Rabson static hx509_context context; 88c19800e8SDoug Rabson 89c19800e8SDoug Rabson static void 90c19800e8SDoug Rabson application_error(const char *fmt, ...) 91c19800e8SDoug Rabson { 92c19800e8SDoug Rabson va_list ap; 93c19800e8SDoug Rabson va_start(ap, fmt); 94c19800e8SDoug Rabson vprintf(fmt, ap); 95c19800e8SDoug Rabson va_end(ap); 96c19800e8SDoug Rabson if (soft_token.flags.app_error_fatal) 97c19800e8SDoug Rabson abort(); 98c19800e8SDoug Rabson } 99c19800e8SDoug Rabson 100c19800e8SDoug Rabson static void 101c19800e8SDoug Rabson st_logf(const char *fmt, ...) 102c19800e8SDoug Rabson { 103c19800e8SDoug Rabson va_list ap; 104c19800e8SDoug Rabson if (soft_token.logfile == NULL) 105c19800e8SDoug Rabson return; 106c19800e8SDoug Rabson va_start(ap, fmt); 107c19800e8SDoug Rabson vfprintf(soft_token.logfile, fmt, ap); 108c19800e8SDoug Rabson va_end(ap); 109c19800e8SDoug Rabson fflush(soft_token.logfile); 110c19800e8SDoug Rabson } 111c19800e8SDoug Rabson 112c19800e8SDoug Rabson static CK_RV 113c19800e8SDoug Rabson init_context(void) 114c19800e8SDoug Rabson { 115c19800e8SDoug Rabson if (context == NULL) { 116c19800e8SDoug Rabson int ret = hx509_context_init(&context); 117c19800e8SDoug Rabson if (ret) 118c19800e8SDoug Rabson return CKR_GENERAL_ERROR; 119c19800e8SDoug Rabson } 120c19800e8SDoug Rabson return CKR_OK; 121c19800e8SDoug Rabson } 122c19800e8SDoug Rabson 123c19800e8SDoug Rabson #define INIT_CONTEXT() { CK_RV icret = init_context(); if (icret) return icret; } 124c19800e8SDoug Rabson 125c19800e8SDoug Rabson static void 126c19800e8SDoug Rabson snprintf_fill(char *str, size_t size, char fillchar, const char *fmt, ...) 127c19800e8SDoug Rabson { 128c19800e8SDoug Rabson int len; 129c19800e8SDoug Rabson va_list ap; 130c19800e8SDoug Rabson len = vsnprintf(str, size, fmt, ap); 131c19800e8SDoug Rabson va_end(ap); 132c19800e8SDoug Rabson if (len < 0 || len > size) 133c19800e8SDoug Rabson return; 134c19800e8SDoug Rabson while(len < size) 135c19800e8SDoug Rabson str[len++] = fillchar; 136c19800e8SDoug Rabson } 137c19800e8SDoug Rabson 138c19800e8SDoug Rabson #ifndef TEST_APP 139c19800e8SDoug Rabson #define printf error_use_st_logf 140c19800e8SDoug Rabson #endif 141c19800e8SDoug Rabson 142c19800e8SDoug Rabson #define VERIFY_SESSION_HANDLE(s, state) \ 143c19800e8SDoug Rabson { \ 144c19800e8SDoug Rabson CK_RV ret; \ 145c19800e8SDoug Rabson ret = verify_session_handle(s, state); \ 146c19800e8SDoug Rabson if (ret != CKR_OK) { \ 147c19800e8SDoug Rabson /* return CKR_OK */; \ 148c19800e8SDoug Rabson } \ 149c19800e8SDoug Rabson } 150c19800e8SDoug Rabson 151c19800e8SDoug Rabson static CK_RV 152c19800e8SDoug Rabson verify_session_handle(CK_SESSION_HANDLE hSession, 153c19800e8SDoug Rabson struct session_state **state) 154c19800e8SDoug Rabson { 155c19800e8SDoug Rabson int i; 156c19800e8SDoug Rabson 157c19800e8SDoug Rabson for (i = 0; i < MAX_NUM_SESSION; i++){ 158c19800e8SDoug Rabson if (soft_token.state[i].session_handle == hSession) 159c19800e8SDoug Rabson break; 160c19800e8SDoug Rabson } 161c19800e8SDoug Rabson if (i == MAX_NUM_SESSION) { 162c19800e8SDoug Rabson application_error("use of invalid handle: 0x%08lx\n", 163c19800e8SDoug Rabson (unsigned long)hSession); 164c19800e8SDoug Rabson return CKR_SESSION_HANDLE_INVALID; 165c19800e8SDoug Rabson } 166c19800e8SDoug Rabson if (state) 167c19800e8SDoug Rabson *state = &soft_token.state[i]; 168c19800e8SDoug Rabson return CKR_OK; 169c19800e8SDoug Rabson } 170c19800e8SDoug Rabson 171c19800e8SDoug Rabson static CK_RV 172c19800e8SDoug Rabson object_handle_to_object(CK_OBJECT_HANDLE handle, 173c19800e8SDoug Rabson struct st_object **object) 174c19800e8SDoug Rabson { 175c19800e8SDoug Rabson int i = HANDLE_OBJECT_ID(handle); 176c19800e8SDoug Rabson 177c19800e8SDoug Rabson *object = NULL; 178c19800e8SDoug Rabson if (i >= soft_token.object.num_objs) 179c19800e8SDoug Rabson return CKR_ARGUMENTS_BAD; 180c19800e8SDoug Rabson if (soft_token.object.objs[i] == NULL) 181c19800e8SDoug Rabson return CKR_ARGUMENTS_BAD; 182c19800e8SDoug Rabson if (soft_token.object.objs[i]->object_handle != handle) 183c19800e8SDoug Rabson return CKR_ARGUMENTS_BAD; 184c19800e8SDoug Rabson *object = soft_token.object.objs[i]; 185c19800e8SDoug Rabson return CKR_OK; 186c19800e8SDoug Rabson } 187c19800e8SDoug Rabson 188c19800e8SDoug Rabson static int 189c19800e8SDoug Rabson attributes_match(const struct st_object *obj, 190c19800e8SDoug Rabson const CK_ATTRIBUTE *attributes, 191c19800e8SDoug Rabson CK_ULONG num_attributes) 192c19800e8SDoug Rabson { 193c19800e8SDoug Rabson CK_ULONG i; 194c19800e8SDoug Rabson int j; 195c19800e8SDoug Rabson 196c19800e8SDoug Rabson st_logf("attributes_match: %ld\n", (unsigned long)OBJECT_ID(obj)); 197c19800e8SDoug Rabson 198c19800e8SDoug Rabson for (i = 0; i < num_attributes; i++) { 199c19800e8SDoug Rabson int match = 0; 200c19800e8SDoug Rabson for (j = 0; j < obj->num_attributes; j++) { 201c19800e8SDoug Rabson if (attributes[i].type == obj->attrs[j].attribute.type && 202c19800e8SDoug Rabson attributes[i].ulValueLen == obj->attrs[j].attribute.ulValueLen && 203c19800e8SDoug Rabson memcmp(attributes[i].pValue, obj->attrs[j].attribute.pValue, 204c19800e8SDoug Rabson attributes[i].ulValueLen) == 0) { 205c19800e8SDoug Rabson match = 1; 206c19800e8SDoug Rabson break; 207c19800e8SDoug Rabson } 208c19800e8SDoug Rabson } 209c19800e8SDoug Rabson if (match == 0) { 210c19800e8SDoug Rabson st_logf("type %d attribute have no match\n", attributes[i].type); 211c19800e8SDoug Rabson return 0; 212c19800e8SDoug Rabson } 213c19800e8SDoug Rabson } 214c19800e8SDoug Rabson st_logf("attribute matches\n"); 215c19800e8SDoug Rabson return 1; 216c19800e8SDoug Rabson } 217c19800e8SDoug Rabson 218c19800e8SDoug Rabson static void 219c19800e8SDoug Rabson print_attributes(const CK_ATTRIBUTE *attributes, 220c19800e8SDoug Rabson CK_ULONG num_attributes) 221c19800e8SDoug Rabson { 222c19800e8SDoug Rabson CK_ULONG i; 223c19800e8SDoug Rabson 224c19800e8SDoug Rabson st_logf("find objects: attrs: %lu\n", (unsigned long)num_attributes); 225c19800e8SDoug Rabson 226c19800e8SDoug Rabson for (i = 0; i < num_attributes; i++) { 227c19800e8SDoug Rabson st_logf(" type: "); 228c19800e8SDoug Rabson switch (attributes[i].type) { 229c19800e8SDoug Rabson case CKA_TOKEN: { 230c19800e8SDoug Rabson CK_BBOOL *ck_true; 231c19800e8SDoug Rabson if (attributes[i].ulValueLen != sizeof(CK_BBOOL)) { 232c19800e8SDoug Rabson application_error("token attribute wrong length\n"); 233c19800e8SDoug Rabson break; 234c19800e8SDoug Rabson } 235c19800e8SDoug Rabson ck_true = attributes[i].pValue; 236c19800e8SDoug Rabson st_logf("token: %s", *ck_true ? "TRUE" : "FALSE"); 237c19800e8SDoug Rabson break; 238c19800e8SDoug Rabson } 239c19800e8SDoug Rabson case CKA_CLASS: { 240c19800e8SDoug Rabson CK_OBJECT_CLASS *class; 241c19800e8SDoug Rabson if (attributes[i].ulValueLen != sizeof(CK_ULONG)) { 242c19800e8SDoug Rabson application_error("class attribute wrong length\n"); 243c19800e8SDoug Rabson break; 244c19800e8SDoug Rabson } 245c19800e8SDoug Rabson class = attributes[i].pValue; 246c19800e8SDoug Rabson st_logf("class "); 247c19800e8SDoug Rabson switch (*class) { 248c19800e8SDoug Rabson case CKO_CERTIFICATE: 249c19800e8SDoug Rabson st_logf("certificate"); 250c19800e8SDoug Rabson break; 251c19800e8SDoug Rabson case CKO_PUBLIC_KEY: 252c19800e8SDoug Rabson st_logf("public key"); 253c19800e8SDoug Rabson break; 254c19800e8SDoug Rabson case CKO_PRIVATE_KEY: 255c19800e8SDoug Rabson st_logf("private key"); 256c19800e8SDoug Rabson break; 257c19800e8SDoug Rabson case CKO_SECRET_KEY: 258c19800e8SDoug Rabson st_logf("secret key"); 259c19800e8SDoug Rabson break; 260c19800e8SDoug Rabson case CKO_DOMAIN_PARAMETERS: 261c19800e8SDoug Rabson st_logf("domain parameters"); 262c19800e8SDoug Rabson break; 263c19800e8SDoug Rabson default: 264c19800e8SDoug Rabson st_logf("[class %lx]", (long unsigned)*class); 265c19800e8SDoug Rabson break; 266c19800e8SDoug Rabson } 267c19800e8SDoug Rabson break; 268c19800e8SDoug Rabson } 269c19800e8SDoug Rabson case CKA_PRIVATE: 270c19800e8SDoug Rabson st_logf("private"); 271c19800e8SDoug Rabson break; 272c19800e8SDoug Rabson case CKA_LABEL: 273c19800e8SDoug Rabson st_logf("label"); 274c19800e8SDoug Rabson break; 275c19800e8SDoug Rabson case CKA_APPLICATION: 276c19800e8SDoug Rabson st_logf("application"); 277c19800e8SDoug Rabson break; 278c19800e8SDoug Rabson case CKA_VALUE: 279c19800e8SDoug Rabson st_logf("value"); 280c19800e8SDoug Rabson break; 281c19800e8SDoug Rabson case CKA_ID: 282c19800e8SDoug Rabson st_logf("id"); 283c19800e8SDoug Rabson break; 284c19800e8SDoug Rabson default: 285c19800e8SDoug Rabson st_logf("[unknown 0x%08lx]", (unsigned long)attributes[i].type); 286c19800e8SDoug Rabson break; 287c19800e8SDoug Rabson } 288c19800e8SDoug Rabson st_logf("\n"); 289c19800e8SDoug Rabson } 290c19800e8SDoug Rabson } 291c19800e8SDoug Rabson 292c19800e8SDoug Rabson static struct st_object * 293c19800e8SDoug Rabson add_st_object(void) 294c19800e8SDoug Rabson { 295c19800e8SDoug Rabson struct st_object *o, **objs; 296c19800e8SDoug Rabson int i; 297c19800e8SDoug Rabson 298c19800e8SDoug Rabson o = malloc(sizeof(*o)); 299c19800e8SDoug Rabson if (o == NULL) 300c19800e8SDoug Rabson return NULL; 301c19800e8SDoug Rabson memset(o, 0, sizeof(*o)); 302c19800e8SDoug Rabson o->attrs = NULL; 303c19800e8SDoug Rabson o->num_attributes = 0; 304c19800e8SDoug Rabson 305c19800e8SDoug Rabson for (i = 0; i < soft_token.object.num_objs; i++) { 306c19800e8SDoug Rabson if (soft_token.object.objs == NULL) { 307c19800e8SDoug Rabson soft_token.object.objs[i] = o; 308c19800e8SDoug Rabson break; 309c19800e8SDoug Rabson } 310c19800e8SDoug Rabson } 311c19800e8SDoug Rabson if (i == soft_token.object.num_objs) { 312c19800e8SDoug Rabson objs = realloc(soft_token.object.objs, 313c19800e8SDoug Rabson (soft_token.object.num_objs + 1) * sizeof(soft_token.object.objs[0])); 314c19800e8SDoug Rabson if (objs == NULL) { 315c19800e8SDoug Rabson free(o); 316c19800e8SDoug Rabson return NULL; 317c19800e8SDoug Rabson } 318c19800e8SDoug Rabson soft_token.object.objs = objs; 319c19800e8SDoug Rabson soft_token.object.objs[soft_token.object.num_objs++] = o; 320c19800e8SDoug Rabson } 321c19800e8SDoug Rabson soft_token.object.objs[i]->object_handle = 322c19800e8SDoug Rabson (random() & (~OBJECT_ID_MASK)) | i; 323c19800e8SDoug Rabson 324c19800e8SDoug Rabson return o; 325c19800e8SDoug Rabson } 326c19800e8SDoug Rabson 327c19800e8SDoug Rabson static CK_RV 328c19800e8SDoug Rabson add_object_attribute(struct st_object *o, 329c19800e8SDoug Rabson int secret, 330c19800e8SDoug Rabson CK_ATTRIBUTE_TYPE type, 331c19800e8SDoug Rabson CK_VOID_PTR pValue, 332c19800e8SDoug Rabson CK_ULONG ulValueLen) 333c19800e8SDoug Rabson { 334c19800e8SDoug Rabson struct st_attr *a; 335c19800e8SDoug Rabson int i; 336c19800e8SDoug Rabson 337c19800e8SDoug Rabson i = o->num_attributes; 338c19800e8SDoug Rabson a = realloc(o->attrs, (i + 1) * sizeof(o->attrs[0])); 339c19800e8SDoug Rabson if (a == NULL) 340c19800e8SDoug Rabson return CKR_DEVICE_MEMORY; 341c19800e8SDoug Rabson o->attrs = a; 342c19800e8SDoug Rabson o->attrs[i].secret = secret; 343c19800e8SDoug Rabson o->attrs[i].attribute.type = type; 344c19800e8SDoug Rabson o->attrs[i].attribute.pValue = malloc(ulValueLen); 345c19800e8SDoug Rabson if (o->attrs[i].attribute.pValue == NULL && ulValueLen != 0) 346c19800e8SDoug Rabson return CKR_DEVICE_MEMORY; 347c19800e8SDoug Rabson memcpy(o->attrs[i].attribute.pValue, pValue, ulValueLen); 348c19800e8SDoug Rabson o->attrs[i].attribute.ulValueLen = ulValueLen; 349c19800e8SDoug Rabson o->num_attributes++; 350c19800e8SDoug Rabson 351c19800e8SDoug Rabson return CKR_OK; 352c19800e8SDoug Rabson } 353c19800e8SDoug Rabson 354c19800e8SDoug Rabson static CK_RV 355c19800e8SDoug Rabson add_pubkey_info(hx509_context hxctx, struct st_object *o, 356c19800e8SDoug Rabson CK_KEY_TYPE key_type, hx509_cert cert) 357c19800e8SDoug Rabson { 358c19800e8SDoug Rabson BIGNUM *num; 359c19800e8SDoug Rabson CK_BYTE *modulus = NULL; 360c19800e8SDoug Rabson size_t modulus_len = 0; 361c19800e8SDoug Rabson CK_ULONG modulus_bits = 0; 362c19800e8SDoug Rabson CK_BYTE *exponent = NULL; 363c19800e8SDoug Rabson size_t exponent_len = 0; 364c19800e8SDoug Rabson 365c19800e8SDoug Rabson if (key_type != CKK_RSA) 366c19800e8SDoug Rabson return CKR_OK; 367c19800e8SDoug Rabson if (_hx509_cert_private_key(cert) == NULL) 368c19800e8SDoug Rabson return CKR_OK; 369c19800e8SDoug Rabson 370c19800e8SDoug Rabson num = _hx509_private_key_get_internal(context, 371c19800e8SDoug Rabson _hx509_cert_private_key(cert), 372c19800e8SDoug Rabson "rsa-modulus"); 373c19800e8SDoug Rabson if (num == NULL) 374c19800e8SDoug Rabson return CKR_GENERAL_ERROR; 375c19800e8SDoug Rabson modulus_bits = BN_num_bits(num); 376c19800e8SDoug Rabson 377c19800e8SDoug Rabson modulus_len = BN_num_bytes(num); 378c19800e8SDoug Rabson modulus = malloc(modulus_len); 379c19800e8SDoug Rabson BN_bn2bin(num, modulus); 380c19800e8SDoug Rabson BN_free(num); 381c19800e8SDoug Rabson 382c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len); 383c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_MODULUS_BITS, 384c19800e8SDoug Rabson &modulus_bits, sizeof(modulus_bits)); 385c19800e8SDoug Rabson 386c19800e8SDoug Rabson free(modulus); 387c19800e8SDoug Rabson 388c19800e8SDoug Rabson num = _hx509_private_key_get_internal(context, 389c19800e8SDoug Rabson _hx509_cert_private_key(cert), 390c19800e8SDoug Rabson "rsa-exponent"); 391c19800e8SDoug Rabson if (num == NULL) 392c19800e8SDoug Rabson return CKR_GENERAL_ERROR; 393c19800e8SDoug Rabson 394c19800e8SDoug Rabson exponent_len = BN_num_bytes(num); 395c19800e8SDoug Rabson exponent = malloc(exponent_len); 396c19800e8SDoug Rabson BN_bn2bin(num, exponent); 397c19800e8SDoug Rabson BN_free(num); 398c19800e8SDoug Rabson 399c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT, 400c19800e8SDoug Rabson exponent, exponent_len); 401c19800e8SDoug Rabson 402c19800e8SDoug Rabson free(exponent); 403c19800e8SDoug Rabson 404c19800e8SDoug Rabson return CKR_OK; 405c19800e8SDoug Rabson } 406c19800e8SDoug Rabson 407c19800e8SDoug Rabson 408c19800e8SDoug Rabson struct foo { 409c19800e8SDoug Rabson char *label; 410c19800e8SDoug Rabson char *id; 411c19800e8SDoug Rabson }; 412c19800e8SDoug Rabson 413c19800e8SDoug Rabson static int 414c19800e8SDoug Rabson add_cert(hx509_context hxctx, void *ctx, hx509_cert cert) 415c19800e8SDoug Rabson { 416c19800e8SDoug Rabson struct foo *foo = (struct foo *)ctx; 417c19800e8SDoug Rabson struct st_object *o = NULL; 418c19800e8SDoug Rabson CK_OBJECT_CLASS type; 419c19800e8SDoug Rabson CK_BBOOL bool_true = CK_TRUE; 420c19800e8SDoug Rabson CK_BBOOL bool_false = CK_FALSE; 421c19800e8SDoug Rabson CK_CERTIFICATE_TYPE cert_type = CKC_X_509; 422c19800e8SDoug Rabson CK_KEY_TYPE key_type; 423c19800e8SDoug Rabson CK_MECHANISM_TYPE mech_type; 424c19800e8SDoug Rabson CK_RV ret = CKR_GENERAL_ERROR; 425c19800e8SDoug Rabson int hret; 426c19800e8SDoug Rabson heim_octet_string cert_data, subject_data, issuer_data, serial_data; 427c19800e8SDoug Rabson 428c19800e8SDoug Rabson st_logf("adding certificate\n"); 429c19800e8SDoug Rabson 430c19800e8SDoug Rabson serial_data.data = NULL; 431c19800e8SDoug Rabson serial_data.length = 0; 432c19800e8SDoug Rabson cert_data = subject_data = issuer_data = serial_data; 433c19800e8SDoug Rabson 434c19800e8SDoug Rabson hret = hx509_cert_binary(hxctx, cert, &cert_data); 435c19800e8SDoug Rabson if (hret) 436c19800e8SDoug Rabson goto out; 437c19800e8SDoug Rabson 438c19800e8SDoug Rabson { 439c19800e8SDoug Rabson hx509_name name; 440c19800e8SDoug Rabson 441c19800e8SDoug Rabson hret = hx509_cert_get_issuer(cert, &name); 442c19800e8SDoug Rabson if (hret) 443c19800e8SDoug Rabson goto out; 444c19800e8SDoug Rabson hret = hx509_name_binary(name, &issuer_data); 445c19800e8SDoug Rabson hx509_name_free(&name); 446c19800e8SDoug Rabson if (hret) 447c19800e8SDoug Rabson goto out; 448c19800e8SDoug Rabson 449c19800e8SDoug Rabson hret = hx509_cert_get_subject(cert, &name); 450c19800e8SDoug Rabson if (hret) 451c19800e8SDoug Rabson goto out; 452c19800e8SDoug Rabson hret = hx509_name_binary(name, &subject_data); 453c19800e8SDoug Rabson hx509_name_free(&name); 454c19800e8SDoug Rabson if (hret) 455c19800e8SDoug Rabson goto out; 456c19800e8SDoug Rabson } 457c19800e8SDoug Rabson 458c19800e8SDoug Rabson { 459c19800e8SDoug Rabson AlgorithmIdentifier alg; 460c19800e8SDoug Rabson 461c19800e8SDoug Rabson hret = hx509_cert_get_SPKI_AlgorithmIdentifier(context, cert, &alg); 462c19800e8SDoug Rabson if (hret) { 463c19800e8SDoug Rabson ret = CKR_DEVICE_MEMORY; 464c19800e8SDoug Rabson goto out; 465c19800e8SDoug Rabson } 466c19800e8SDoug Rabson 467c19800e8SDoug Rabson key_type = CKK_RSA; /* XXX */ 468c19800e8SDoug Rabson 469c19800e8SDoug Rabson free_AlgorithmIdentifier(&alg); 470c19800e8SDoug Rabson } 471c19800e8SDoug Rabson 472c19800e8SDoug Rabson 473c19800e8SDoug Rabson type = CKO_CERTIFICATE; 474c19800e8SDoug Rabson o = add_st_object(); 475c19800e8SDoug Rabson if (o == NULL) { 476c19800e8SDoug Rabson ret = CKR_DEVICE_MEMORY; 477c19800e8SDoug Rabson goto out; 478c19800e8SDoug Rabson } 479c19800e8SDoug Rabson 480c19800e8SDoug Rabson o->cert = hx509_cert_ref(cert); 481c19800e8SDoug Rabson 482c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_CLASS, &type, sizeof(type)); 483c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true)); 484c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false)); 485c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false)); 486c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_LABEL, foo->label, strlen(foo->label)); 487c19800e8SDoug Rabson 488c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type)); 489c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id)); 490c19800e8SDoug Rabson 491c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_SUBJECT, subject_data.data, subject_data.length); 492c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_ISSUER, issuer_data.data, issuer_data.length); 493c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_SERIAL_NUMBER, serial_data.data, serial_data.length); 494c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_VALUE, cert_data.data, cert_data.length); 495c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_TRUSTED, &bool_false, sizeof(bool_false)); 496c19800e8SDoug Rabson 497c19800e8SDoug Rabson st_logf("add cert ok: %lx\n", (unsigned long)OBJECT_ID(o)); 498c19800e8SDoug Rabson 499c19800e8SDoug Rabson type = CKO_PUBLIC_KEY; 500c19800e8SDoug Rabson o = add_st_object(); 501c19800e8SDoug Rabson if (o == NULL) { 502c19800e8SDoug Rabson ret = CKR_DEVICE_MEMORY; 503c19800e8SDoug Rabson goto out; 504c19800e8SDoug Rabson } 505c19800e8SDoug Rabson o->cert = hx509_cert_ref(cert); 506c19800e8SDoug Rabson 507c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_CLASS, &type, sizeof(type)); 508c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true)); 509c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false)); 510c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false)); 511c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_LABEL, foo->label, strlen(foo->label)); 512c19800e8SDoug Rabson 513c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type)); 514c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id)); 515c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_START_DATE, "", 1); /* XXX */ 516c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_END_DATE, "", 1); /* XXX */ 517c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false)); 518c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false)); 519c19800e8SDoug Rabson mech_type = CKM_RSA_X_509; 520c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type)); 521c19800e8SDoug Rabson 522c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_SUBJECT, subject_data.data, subject_data.length); 523c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_ENCRYPT, &bool_true, sizeof(bool_true)); 524c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_VERIFY, &bool_true, sizeof(bool_true)); 525c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_VERIFY_RECOVER, &bool_false, sizeof(bool_false)); 526c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_WRAP, &bool_true, sizeof(bool_true)); 527c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_TRUSTED, &bool_true, sizeof(bool_true)); 528c19800e8SDoug Rabson 529c19800e8SDoug Rabson add_pubkey_info(hxctx, o, key_type, cert); 530c19800e8SDoug Rabson 531c19800e8SDoug Rabson st_logf("add key ok: %lx\n", (unsigned long)OBJECT_ID(o)); 532c19800e8SDoug Rabson 533c19800e8SDoug Rabson if (hx509_cert_have_private_key(cert)) { 534c19800e8SDoug Rabson CK_FLAGS flags; 535c19800e8SDoug Rabson 536c19800e8SDoug Rabson type = CKO_PRIVATE_KEY; 537c19800e8SDoug Rabson o = add_st_object(); 538c19800e8SDoug Rabson if (o == NULL) { 539c19800e8SDoug Rabson ret = CKR_DEVICE_MEMORY; 540c19800e8SDoug Rabson goto out; 541c19800e8SDoug Rabson } 542c19800e8SDoug Rabson o->cert = hx509_cert_ref(cert); 543c19800e8SDoug Rabson 544c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_CLASS, &type, sizeof(type)); 545c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true)); 546c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_PRIVATE, &bool_true, sizeof(bool_false)); 547c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false)); 548c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_LABEL, foo->label, strlen(foo->label)); 549c19800e8SDoug Rabson 550c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type)); 551c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id)); 552c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_START_DATE, "", 1); /* XXX */ 553c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_END_DATE, "", 1); /* XXX */ 554c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false)); 555c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false)); 556c19800e8SDoug Rabson mech_type = CKM_RSA_X_509; 557c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type)); 558c19800e8SDoug Rabson 559c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_SUBJECT, subject_data.data, subject_data.length); 560c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_SENSITIVE, &bool_true, sizeof(bool_true)); 561c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_SECONDARY_AUTH, &bool_false, sizeof(bool_true)); 562c19800e8SDoug Rabson flags = 0; 563c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_AUTH_PIN_FLAGS, &flags, sizeof(flags)); 564c19800e8SDoug Rabson 565c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_DECRYPT, &bool_true, sizeof(bool_true)); 566c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_SIGN, &bool_true, sizeof(bool_true)); 567c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_SIGN_RECOVER, &bool_false, sizeof(bool_false)); 568c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_UNWRAP, &bool_true, sizeof(bool_true)); 569c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_EXTRACTABLE, &bool_true, sizeof(bool_true)); 570c19800e8SDoug Rabson add_object_attribute(o, 0, CKA_NEVER_EXTRACTABLE, &bool_false, sizeof(bool_false)); 571c19800e8SDoug Rabson 572c19800e8SDoug Rabson add_pubkey_info(hxctx, o, key_type, cert); 573c19800e8SDoug Rabson } 574c19800e8SDoug Rabson 575c19800e8SDoug Rabson ret = CKR_OK; 576c19800e8SDoug Rabson out: 577c19800e8SDoug Rabson if (ret != CKR_OK) { 578c19800e8SDoug Rabson st_logf("something went wrong when adding cert!\n"); 579c19800e8SDoug Rabson 580c19800e8SDoug Rabson /* XXX wack o */; 581c19800e8SDoug Rabson } 582c19800e8SDoug Rabson hx509_xfree(cert_data.data); 583c19800e8SDoug Rabson hx509_xfree(serial_data.data); 584c19800e8SDoug Rabson hx509_xfree(issuer_data.data); 585c19800e8SDoug Rabson hx509_xfree(subject_data.data); 586c19800e8SDoug Rabson 587c19800e8SDoug Rabson return 0; 588c19800e8SDoug Rabson } 589c19800e8SDoug Rabson 590c19800e8SDoug Rabson static CK_RV 591c19800e8SDoug Rabson add_certificate(const char *cert_file, 592c19800e8SDoug Rabson const char *pin, 593c19800e8SDoug Rabson char *id, 594c19800e8SDoug Rabson char *label) 595c19800e8SDoug Rabson { 596c19800e8SDoug Rabson hx509_certs certs; 597c19800e8SDoug Rabson hx509_lock lock = NULL; 598c19800e8SDoug Rabson int ret, flags = 0; 599c19800e8SDoug Rabson 600c19800e8SDoug Rabson struct foo foo; 601c19800e8SDoug Rabson foo.id = id; 602c19800e8SDoug Rabson foo.label = label; 603c19800e8SDoug Rabson 604c19800e8SDoug Rabson if (pin == NULL) 605c19800e8SDoug Rabson flags |= HX509_CERTS_UNPROTECT_ALL; 606c19800e8SDoug Rabson 607c19800e8SDoug Rabson if (pin) { 608c19800e8SDoug Rabson char *str; 609c19800e8SDoug Rabson asprintf(&str, "PASS:%s", pin); 610c19800e8SDoug Rabson 611c19800e8SDoug Rabson hx509_lock_init(context, &lock); 612c19800e8SDoug Rabson hx509_lock_command_string(lock, str); 613c19800e8SDoug Rabson 614c19800e8SDoug Rabson memset(str, 0, strlen(str)); 615c19800e8SDoug Rabson free(str); 616c19800e8SDoug Rabson } 617c19800e8SDoug Rabson 618c19800e8SDoug Rabson ret = hx509_certs_init(context, cert_file, flags, lock, &certs); 619c19800e8SDoug Rabson if (ret) { 620c19800e8SDoug Rabson st_logf("failed to open file %s\n", cert_file); 621c19800e8SDoug Rabson return CKR_GENERAL_ERROR; 622c19800e8SDoug Rabson } 623c19800e8SDoug Rabson 624c19800e8SDoug Rabson ret = hx509_certs_iter(context, certs, add_cert, &foo); 625c19800e8SDoug Rabson hx509_certs_free(&certs); 626c19800e8SDoug Rabson if (ret) { 627c19800e8SDoug Rabson st_logf("failed adding certs from file %s\n", cert_file); 628c19800e8SDoug Rabson return CKR_GENERAL_ERROR; 629c19800e8SDoug Rabson } 630c19800e8SDoug Rabson 631c19800e8SDoug Rabson return CKR_OK; 632c19800e8SDoug Rabson } 633c19800e8SDoug Rabson 634c19800e8SDoug Rabson static void 635c19800e8SDoug Rabson find_object_final(struct session_state *state) 636c19800e8SDoug Rabson { 637c19800e8SDoug Rabson if (state->find.attributes) { 638c19800e8SDoug Rabson CK_ULONG i; 639c19800e8SDoug Rabson 640c19800e8SDoug Rabson for (i = 0; i < state->find.num_attributes; i++) { 641c19800e8SDoug Rabson if (state->find.attributes[i].pValue) 642c19800e8SDoug Rabson free(state->find.attributes[i].pValue); 643c19800e8SDoug Rabson } 644c19800e8SDoug Rabson free(state->find.attributes); 645c19800e8SDoug Rabson state->find.attributes = NULL; 646c19800e8SDoug Rabson state->find.num_attributes = 0; 647c19800e8SDoug Rabson state->find.next_object = -1; 648c19800e8SDoug Rabson } 649c19800e8SDoug Rabson } 650c19800e8SDoug Rabson 651c19800e8SDoug Rabson static void 652c19800e8SDoug Rabson reset_crypto_state(struct session_state *state) 653c19800e8SDoug Rabson { 654c19800e8SDoug Rabson state->sign_object = -1; 655c19800e8SDoug Rabson if (state->sign_mechanism) 656c19800e8SDoug Rabson free(state->sign_mechanism); 657c19800e8SDoug Rabson state->sign_mechanism = NULL_PTR; 658c19800e8SDoug Rabson state->verify_object = -1; 659c19800e8SDoug Rabson if (state->verify_mechanism) 660c19800e8SDoug Rabson free(state->verify_mechanism); 661c19800e8SDoug Rabson state->verify_mechanism = NULL_PTR; 662c19800e8SDoug Rabson } 663c19800e8SDoug Rabson 664c19800e8SDoug Rabson static void 665c19800e8SDoug Rabson close_session(struct session_state *state) 666c19800e8SDoug Rabson { 667c19800e8SDoug Rabson if (state->find.attributes) { 668c19800e8SDoug Rabson application_error("application didn't do C_FindObjectsFinal\n"); 669c19800e8SDoug Rabson find_object_final(state); 670c19800e8SDoug Rabson } 671c19800e8SDoug Rabson 672c19800e8SDoug Rabson state->session_handle = CK_INVALID_HANDLE; 673c19800e8SDoug Rabson soft_token.application = NULL_PTR; 674c19800e8SDoug Rabson soft_token.notify = NULL_PTR; 675c19800e8SDoug Rabson reset_crypto_state(state); 676c19800e8SDoug Rabson } 677c19800e8SDoug Rabson 678c19800e8SDoug Rabson static const char * 679c19800e8SDoug Rabson has_session(void) 680c19800e8SDoug Rabson { 681c19800e8SDoug Rabson return soft_token.open_sessions > 0 ? "yes" : "no"; 682c19800e8SDoug Rabson } 683c19800e8SDoug Rabson 684c19800e8SDoug Rabson static CK_RV 685c19800e8SDoug Rabson read_conf_file(const char *fn, CK_USER_TYPE userType, const char *pin) 686c19800e8SDoug Rabson { 687c19800e8SDoug Rabson char buf[1024], *type, *s, *p; 688c19800e8SDoug Rabson int anchor; 689c19800e8SDoug Rabson FILE *f; 690c19800e8SDoug Rabson CK_RV ret = CKR_OK; 691c19800e8SDoug Rabson CK_RV failed = CKR_OK; 692c19800e8SDoug Rabson 693c19800e8SDoug Rabson f = fopen(fn, "r"); 694c19800e8SDoug Rabson if (f == NULL) { 695c19800e8SDoug Rabson st_logf("can't open configuration file %s\n", fn); 696c19800e8SDoug Rabson return CKR_GENERAL_ERROR; 697c19800e8SDoug Rabson } 698c19800e8SDoug Rabson 699c19800e8SDoug Rabson while(fgets(buf, sizeof(buf), f) != NULL) { 700c19800e8SDoug Rabson buf[strcspn(buf, "\n")] = '\0'; 701c19800e8SDoug Rabson 702c19800e8SDoug Rabson anchor = 0; 703c19800e8SDoug Rabson 704c19800e8SDoug Rabson st_logf("line: %s\n", buf); 705c19800e8SDoug Rabson 706c19800e8SDoug Rabson p = buf; 707c19800e8SDoug Rabson while (isspace(*p)) 708c19800e8SDoug Rabson p++; 709c19800e8SDoug Rabson if (*p == '#') 710c19800e8SDoug Rabson continue; 711c19800e8SDoug Rabson while (isspace(*p)) 712c19800e8SDoug Rabson p++; 713c19800e8SDoug Rabson 714c19800e8SDoug Rabson s = NULL; 715c19800e8SDoug Rabson type = strtok_r(p, "\t", &s); 716c19800e8SDoug Rabson if (type == NULL) 717c19800e8SDoug Rabson continue; 718c19800e8SDoug Rabson 719c19800e8SDoug Rabson if (strcasecmp("certificate", type) == 0) { 720c19800e8SDoug Rabson char *cert, *id, *label; 721c19800e8SDoug Rabson 722c19800e8SDoug Rabson id = strtok_r(NULL, "\t", &s); 723c19800e8SDoug Rabson if (id == NULL) { 724c19800e8SDoug Rabson st_logf("no id\n"); 725c19800e8SDoug Rabson continue; 726c19800e8SDoug Rabson } 727c19800e8SDoug Rabson st_logf("id: %s\n", id); 728c19800e8SDoug Rabson label = strtok_r(NULL, "\t", &s); 729c19800e8SDoug Rabson if (label == NULL) { 730c19800e8SDoug Rabson st_logf("no label\n"); 731c19800e8SDoug Rabson continue; 732c19800e8SDoug Rabson } 733c19800e8SDoug Rabson cert = strtok_r(NULL, "\t", &s); 734c19800e8SDoug Rabson if (cert == NULL) { 735c19800e8SDoug Rabson st_logf("no certfiicate store\n"); 736c19800e8SDoug Rabson continue; 737c19800e8SDoug Rabson } 738c19800e8SDoug Rabson 739c19800e8SDoug Rabson st_logf("adding: %s: %s in file %s\n", id, label, cert); 740c19800e8SDoug Rabson 741c19800e8SDoug Rabson ret = add_certificate(cert, pin, id, label); 742c19800e8SDoug Rabson if (ret) 743c19800e8SDoug Rabson failed = ret; 744c19800e8SDoug Rabson } else if (strcasecmp("debug", type) == 0) { 745c19800e8SDoug Rabson char *name; 746c19800e8SDoug Rabson 747c19800e8SDoug Rabson name = strtok_r(NULL, "\t", &s); 748c19800e8SDoug Rabson if (name == NULL) { 749c19800e8SDoug Rabson st_logf("no filename\n"); 750c19800e8SDoug Rabson continue; 751c19800e8SDoug Rabson } 752c19800e8SDoug Rabson 753c19800e8SDoug Rabson if (soft_token.logfile) 754c19800e8SDoug Rabson fclose(soft_token.logfile); 755c19800e8SDoug Rabson 756c19800e8SDoug Rabson if (strcasecmp(name, "stdout") == 0) 757c19800e8SDoug Rabson soft_token.logfile = stdout; 758c19800e8SDoug Rabson else 759c19800e8SDoug Rabson soft_token.logfile = fopen(name, "a"); 760c19800e8SDoug Rabson if (soft_token.logfile == NULL) 761c19800e8SDoug Rabson st_logf("failed to open file: %s\n", name); 762c19800e8SDoug Rabson 763c19800e8SDoug Rabson } else if (strcasecmp("app-fatal", type) == 0) { 764c19800e8SDoug Rabson char *name; 765c19800e8SDoug Rabson 766c19800e8SDoug Rabson name = strtok_r(NULL, "\t", &s); 767c19800e8SDoug Rabson if (name == NULL) { 768c19800e8SDoug Rabson st_logf("argument to app-fatal\n"); 769c19800e8SDoug Rabson continue; 770c19800e8SDoug Rabson } 771c19800e8SDoug Rabson 772c19800e8SDoug Rabson if (strcmp(name, "true") == 0 || strcmp(name, "on") == 0) 773c19800e8SDoug Rabson soft_token.flags.app_error_fatal = 1; 774c19800e8SDoug Rabson else if (strcmp(name, "false") == 0 || strcmp(name, "off") == 0) 775c19800e8SDoug Rabson soft_token.flags.app_error_fatal = 0; 776c19800e8SDoug Rabson else 777c19800e8SDoug Rabson st_logf("unknown app-fatal: %s\n", name); 778c19800e8SDoug Rabson 779c19800e8SDoug Rabson } else { 780c19800e8SDoug Rabson st_logf("unknown type: %s\n", type); 781c19800e8SDoug Rabson } 782c19800e8SDoug Rabson } 783c19800e8SDoug Rabson 784c19800e8SDoug Rabson fclose(f); 785c19800e8SDoug Rabson 786c19800e8SDoug Rabson return failed; 787c19800e8SDoug Rabson } 788c19800e8SDoug Rabson 789c19800e8SDoug Rabson static CK_RV 790c19800e8SDoug Rabson func_not_supported(void) 791c19800e8SDoug Rabson { 792c19800e8SDoug Rabson st_logf("function not supported\n"); 793c19800e8SDoug Rabson return CKR_FUNCTION_NOT_SUPPORTED; 794c19800e8SDoug Rabson } 795c19800e8SDoug Rabson 796c19800e8SDoug Rabson CK_RV 797c19800e8SDoug Rabson C_Initialize(CK_VOID_PTR a) 798c19800e8SDoug Rabson { 799c19800e8SDoug Rabson CK_C_INITIALIZE_ARGS_PTR args = a; 800c19800e8SDoug Rabson CK_RV ret; 801c19800e8SDoug Rabson int i; 802c19800e8SDoug Rabson 803c19800e8SDoug Rabson st_logf("Initialize\n"); 804c19800e8SDoug Rabson 805c19800e8SDoug Rabson INIT_CONTEXT(); 806c19800e8SDoug Rabson 807c19800e8SDoug Rabson OpenSSL_add_all_algorithms(); 808c19800e8SDoug Rabson 809c19800e8SDoug Rabson srandom(getpid() ^ time(NULL)); 810c19800e8SDoug Rabson 811c19800e8SDoug Rabson for (i = 0; i < MAX_NUM_SESSION; i++) { 812c19800e8SDoug Rabson soft_token.state[i].session_handle = CK_INVALID_HANDLE; 813c19800e8SDoug Rabson soft_token.state[i].find.attributes = NULL; 814c19800e8SDoug Rabson soft_token.state[i].find.num_attributes = 0; 815c19800e8SDoug Rabson soft_token.state[i].find.next_object = -1; 816c19800e8SDoug Rabson reset_crypto_state(&soft_token.state[i]); 817c19800e8SDoug Rabson } 818c19800e8SDoug Rabson 819c19800e8SDoug Rabson soft_token.flags.hardware_slot = 1; 820c19800e8SDoug Rabson soft_token.flags.app_error_fatal = 0; 821c19800e8SDoug Rabson soft_token.flags.login_done = 0; 822c19800e8SDoug Rabson 823c19800e8SDoug Rabson soft_token.object.objs = NULL; 824c19800e8SDoug Rabson soft_token.object.num_objs = 0; 825c19800e8SDoug Rabson 826c19800e8SDoug Rabson soft_token.logfile = NULL; 827c19800e8SDoug Rabson #if 0 828c19800e8SDoug Rabson soft_token.logfile = stdout; 829c19800e8SDoug Rabson #endif 830c19800e8SDoug Rabson #if 0 831c19800e8SDoug Rabson soft_token.logfile = fopen("/tmp/log-pkcs11.txt", "a"); 832c19800e8SDoug Rabson #endif 833c19800e8SDoug Rabson 834c19800e8SDoug Rabson if (a != NULL_PTR) { 835c19800e8SDoug Rabson st_logf("\tCreateMutex:\t%p\n", args->CreateMutex); 836c19800e8SDoug Rabson st_logf("\tDestroyMutext\t%p\n", args->DestroyMutex); 837c19800e8SDoug Rabson st_logf("\tLockMutext\t%p\n", args->LockMutex); 838c19800e8SDoug Rabson st_logf("\tUnlockMutext\t%p\n", args->UnlockMutex); 839c19800e8SDoug Rabson st_logf("\tFlags\t%04x\n", (unsigned int)args->flags); 840c19800e8SDoug Rabson } 841c19800e8SDoug Rabson 842c19800e8SDoug Rabson { 843c19800e8SDoug Rabson char *fn = NULL, *home = NULL; 844c19800e8SDoug Rabson 845c19800e8SDoug Rabson if (getuid() == geteuid()) { 846c19800e8SDoug Rabson fn = getenv("SOFTPKCS11RC"); 847c19800e8SDoug Rabson if (fn) 848c19800e8SDoug Rabson fn = strdup(fn); 849c19800e8SDoug Rabson home = getenv("HOME"); 850c19800e8SDoug Rabson } 851c19800e8SDoug Rabson if (fn == NULL && home == NULL) { 852c19800e8SDoug Rabson struct passwd *pw = getpwuid(getuid()); 853c19800e8SDoug Rabson if(pw != NULL) 854c19800e8SDoug Rabson home = pw->pw_dir; 855c19800e8SDoug Rabson } 856c19800e8SDoug Rabson if (fn == NULL) { 857c19800e8SDoug Rabson if (home) 858c19800e8SDoug Rabson asprintf(&fn, "%s/.soft-token.rc", home); 859c19800e8SDoug Rabson else 860c19800e8SDoug Rabson fn = strdup("/etc/soft-token.rc"); 861c19800e8SDoug Rabson } 862c19800e8SDoug Rabson 863c19800e8SDoug Rabson soft_token.config_file = fn; 864c19800e8SDoug Rabson } 865c19800e8SDoug Rabson 866c19800e8SDoug Rabson /* 867c19800e8SDoug Rabson * This operations doesn't return CKR_OK if any of the 868c19800e8SDoug Rabson * certificates failes to be unparsed (ie password protected). 869c19800e8SDoug Rabson */ 870c19800e8SDoug Rabson ret = read_conf_file(soft_token.config_file, CKU_USER, NULL); 871c19800e8SDoug Rabson if (ret == CKR_OK) 872c19800e8SDoug Rabson soft_token.flags.login_done = 1; 873c19800e8SDoug Rabson 874c19800e8SDoug Rabson return CKR_OK; 875c19800e8SDoug Rabson } 876c19800e8SDoug Rabson 877c19800e8SDoug Rabson CK_RV 878c19800e8SDoug Rabson C_Finalize(CK_VOID_PTR args) 879c19800e8SDoug Rabson { 880c19800e8SDoug Rabson int i; 881c19800e8SDoug Rabson 882c19800e8SDoug Rabson INIT_CONTEXT(); 883c19800e8SDoug Rabson 884c19800e8SDoug Rabson st_logf("Finalize\n"); 885c19800e8SDoug Rabson 886c19800e8SDoug Rabson for (i = 0; i < MAX_NUM_SESSION; i++) { 887c19800e8SDoug Rabson if (soft_token.state[i].session_handle != CK_INVALID_HANDLE) { 888c19800e8SDoug Rabson application_error("application finalized without " 889c19800e8SDoug Rabson "closing session\n"); 890c19800e8SDoug Rabson close_session(&soft_token.state[i]); 891c19800e8SDoug Rabson } 892c19800e8SDoug Rabson } 893c19800e8SDoug Rabson 894c19800e8SDoug Rabson return CKR_OK; 895c19800e8SDoug Rabson } 896c19800e8SDoug Rabson 897c19800e8SDoug Rabson CK_RV 898c19800e8SDoug Rabson C_GetInfo(CK_INFO_PTR args) 899c19800e8SDoug Rabson { 900c19800e8SDoug Rabson INIT_CONTEXT(); 901c19800e8SDoug Rabson 902c19800e8SDoug Rabson st_logf("GetInfo\n"); 903c19800e8SDoug Rabson 904c19800e8SDoug Rabson memset(args, 17, sizeof(*args)); 905c19800e8SDoug Rabson args->cryptokiVersion.major = 2; 906c19800e8SDoug Rabson args->cryptokiVersion.minor = 10; 907c19800e8SDoug Rabson snprintf_fill((char *)args->manufacturerID, 908c19800e8SDoug Rabson sizeof(args->manufacturerID), 909c19800e8SDoug Rabson ' ', 910c19800e8SDoug Rabson "Heimdal hx509 SoftToken"); 911c19800e8SDoug Rabson snprintf_fill((char *)args->libraryDescription, 912c19800e8SDoug Rabson sizeof(args->libraryDescription), ' ', 913c19800e8SDoug Rabson "Heimdal hx509 SoftToken"); 914c19800e8SDoug Rabson args->libraryVersion.major = 2; 915c19800e8SDoug Rabson args->libraryVersion.minor = 0; 916c19800e8SDoug Rabson 917c19800e8SDoug Rabson return CKR_OK; 918c19800e8SDoug Rabson } 919c19800e8SDoug Rabson 920c19800e8SDoug Rabson extern CK_FUNCTION_LIST funcs; 921c19800e8SDoug Rabson 922c19800e8SDoug Rabson CK_RV 923c19800e8SDoug Rabson C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) 924c19800e8SDoug Rabson { 925c19800e8SDoug Rabson INIT_CONTEXT(); 926c19800e8SDoug Rabson 927c19800e8SDoug Rabson *ppFunctionList = &funcs; 928c19800e8SDoug Rabson return CKR_OK; 929c19800e8SDoug Rabson } 930c19800e8SDoug Rabson 931c19800e8SDoug Rabson CK_RV 932c19800e8SDoug Rabson C_GetSlotList(CK_BBOOL tokenPresent, 933c19800e8SDoug Rabson CK_SLOT_ID_PTR pSlotList, 934c19800e8SDoug Rabson CK_ULONG_PTR pulCount) 935c19800e8SDoug Rabson { 936c19800e8SDoug Rabson INIT_CONTEXT(); 937c19800e8SDoug Rabson st_logf("GetSlotList: %s\n", 938c19800e8SDoug Rabson tokenPresent ? "tokenPresent" : "token not Present"); 939c19800e8SDoug Rabson if (pSlotList) 940c19800e8SDoug Rabson pSlotList[0] = 1; 941c19800e8SDoug Rabson *pulCount = 1; 942c19800e8SDoug Rabson return CKR_OK; 943c19800e8SDoug Rabson } 944c19800e8SDoug Rabson 945c19800e8SDoug Rabson CK_RV 946c19800e8SDoug Rabson C_GetSlotInfo(CK_SLOT_ID slotID, 947c19800e8SDoug Rabson CK_SLOT_INFO_PTR pInfo) 948c19800e8SDoug Rabson { 949c19800e8SDoug Rabson INIT_CONTEXT(); 950c19800e8SDoug Rabson st_logf("GetSlotInfo: slot: %d : %s\n", (int)slotID, has_session()); 951c19800e8SDoug Rabson 952c19800e8SDoug Rabson memset(pInfo, 18, sizeof(*pInfo)); 953c19800e8SDoug Rabson 954c19800e8SDoug Rabson if (slotID != 1) 955c19800e8SDoug Rabson return CKR_ARGUMENTS_BAD; 956c19800e8SDoug Rabson 957c19800e8SDoug Rabson snprintf_fill((char *)pInfo->slotDescription, 958c19800e8SDoug Rabson sizeof(pInfo->slotDescription), 959c19800e8SDoug Rabson ' ', 960c19800e8SDoug Rabson "Heimdal hx509 SoftToken (slot)"); 961c19800e8SDoug Rabson snprintf_fill((char *)pInfo->manufacturerID, 962c19800e8SDoug Rabson sizeof(pInfo->manufacturerID), 963c19800e8SDoug Rabson ' ', 964c19800e8SDoug Rabson "Heimdal hx509 SoftToken (slot)"); 965c19800e8SDoug Rabson pInfo->flags = CKF_TOKEN_PRESENT; 966c19800e8SDoug Rabson if (soft_token.flags.hardware_slot) 967c19800e8SDoug Rabson pInfo->flags |= CKF_HW_SLOT; 968c19800e8SDoug Rabson pInfo->hardwareVersion.major = 1; 969c19800e8SDoug Rabson pInfo->hardwareVersion.minor = 0; 970c19800e8SDoug Rabson pInfo->firmwareVersion.major = 1; 971c19800e8SDoug Rabson pInfo->firmwareVersion.minor = 0; 972c19800e8SDoug Rabson 973c19800e8SDoug Rabson return CKR_OK; 974c19800e8SDoug Rabson } 975c19800e8SDoug Rabson 976c19800e8SDoug Rabson CK_RV 977c19800e8SDoug Rabson C_GetTokenInfo(CK_SLOT_ID slotID, 978c19800e8SDoug Rabson CK_TOKEN_INFO_PTR pInfo) 979c19800e8SDoug Rabson { 980c19800e8SDoug Rabson INIT_CONTEXT(); 981c19800e8SDoug Rabson st_logf("GetTokenInfo: %s\n", has_session()); 982c19800e8SDoug Rabson 983c19800e8SDoug Rabson memset(pInfo, 19, sizeof(*pInfo)); 984c19800e8SDoug Rabson 985c19800e8SDoug Rabson snprintf_fill((char *)pInfo->label, 986c19800e8SDoug Rabson sizeof(pInfo->label), 987c19800e8SDoug Rabson ' ', 988c19800e8SDoug Rabson "Heimdal hx509 SoftToken (token)"); 989c19800e8SDoug Rabson snprintf_fill((char *)pInfo->manufacturerID, 990c19800e8SDoug Rabson sizeof(pInfo->manufacturerID), 991c19800e8SDoug Rabson ' ', 992c19800e8SDoug Rabson "Heimdal hx509 SoftToken (token)"); 993c19800e8SDoug Rabson snprintf_fill((char *)pInfo->model, 994c19800e8SDoug Rabson sizeof(pInfo->model), 995c19800e8SDoug Rabson ' ', 996c19800e8SDoug Rabson "Heimdal hx509 SoftToken (token)"); 997c19800e8SDoug Rabson snprintf_fill((char *)pInfo->serialNumber, 998c19800e8SDoug Rabson sizeof(pInfo->serialNumber), 999c19800e8SDoug Rabson ' ', 1000c19800e8SDoug Rabson "4711"); 1001c19800e8SDoug Rabson pInfo->flags = 1002c19800e8SDoug Rabson CKF_TOKEN_INITIALIZED | 1003c19800e8SDoug Rabson CKF_USER_PIN_INITIALIZED; 1004c19800e8SDoug Rabson 1005c19800e8SDoug Rabson if (soft_token.flags.login_done == 0) 1006c19800e8SDoug Rabson pInfo->flags |= CKF_LOGIN_REQUIRED; 1007c19800e8SDoug Rabson 1008c19800e8SDoug Rabson /* CFK_RNG | 1009c19800e8SDoug Rabson CKF_RESTORE_KEY_NOT_NEEDED | 1010c19800e8SDoug Rabson */ 1011c19800e8SDoug Rabson pInfo->ulMaxSessionCount = MAX_NUM_SESSION; 1012c19800e8SDoug Rabson pInfo->ulSessionCount = soft_token.open_sessions; 1013c19800e8SDoug Rabson pInfo->ulMaxRwSessionCount = MAX_NUM_SESSION; 1014c19800e8SDoug Rabson pInfo->ulRwSessionCount = soft_token.open_sessions; 1015c19800e8SDoug Rabson pInfo->ulMaxPinLen = 1024; 1016c19800e8SDoug Rabson pInfo->ulMinPinLen = 0; 1017c19800e8SDoug Rabson pInfo->ulTotalPublicMemory = 4711; 1018c19800e8SDoug Rabson pInfo->ulFreePublicMemory = 4712; 1019c19800e8SDoug Rabson pInfo->ulTotalPrivateMemory = 4713; 1020c19800e8SDoug Rabson pInfo->ulFreePrivateMemory = 4714; 1021c19800e8SDoug Rabson pInfo->hardwareVersion.major = 2; 1022c19800e8SDoug Rabson pInfo->hardwareVersion.minor = 0; 1023c19800e8SDoug Rabson pInfo->firmwareVersion.major = 2; 1024c19800e8SDoug Rabson pInfo->firmwareVersion.minor = 0; 1025c19800e8SDoug Rabson 1026c19800e8SDoug Rabson return CKR_OK; 1027c19800e8SDoug Rabson } 1028c19800e8SDoug Rabson 1029c19800e8SDoug Rabson CK_RV 1030c19800e8SDoug Rabson C_GetMechanismList(CK_SLOT_ID slotID, 1031c19800e8SDoug Rabson CK_MECHANISM_TYPE_PTR pMechanismList, 1032c19800e8SDoug Rabson CK_ULONG_PTR pulCount) 1033c19800e8SDoug Rabson { 1034c19800e8SDoug Rabson INIT_CONTEXT(); 1035c19800e8SDoug Rabson st_logf("GetMechanismList\n"); 1036c19800e8SDoug Rabson 1037c19800e8SDoug Rabson *pulCount = 1; 1038c19800e8SDoug Rabson if (pMechanismList == NULL_PTR) 1039c19800e8SDoug Rabson return CKR_OK; 1040c19800e8SDoug Rabson pMechanismList[1] = CKM_RSA_PKCS; 1041c19800e8SDoug Rabson 1042c19800e8SDoug Rabson return CKR_OK; 1043c19800e8SDoug Rabson } 1044c19800e8SDoug Rabson 1045c19800e8SDoug Rabson CK_RV 1046c19800e8SDoug Rabson C_GetMechanismInfo(CK_SLOT_ID slotID, 1047c19800e8SDoug Rabson CK_MECHANISM_TYPE type, 1048c19800e8SDoug Rabson CK_MECHANISM_INFO_PTR pInfo) 1049c19800e8SDoug Rabson { 1050c19800e8SDoug Rabson INIT_CONTEXT(); 1051c19800e8SDoug Rabson st_logf("GetMechanismInfo: slot %d type: %d\n", 1052c19800e8SDoug Rabson (int)slotID, (int)type); 1053c19800e8SDoug Rabson memset(pInfo, 0, sizeof(*pInfo)); 1054c19800e8SDoug Rabson 1055c19800e8SDoug Rabson return CKR_OK; 1056c19800e8SDoug Rabson } 1057c19800e8SDoug Rabson 1058c19800e8SDoug Rabson CK_RV 1059c19800e8SDoug Rabson C_InitToken(CK_SLOT_ID slotID, 1060c19800e8SDoug Rabson CK_UTF8CHAR_PTR pPin, 1061c19800e8SDoug Rabson CK_ULONG ulPinLen, 1062c19800e8SDoug Rabson CK_UTF8CHAR_PTR pLabel) 1063c19800e8SDoug Rabson { 1064c19800e8SDoug Rabson INIT_CONTEXT(); 1065c19800e8SDoug Rabson st_logf("InitToken: slot %d\n", (int)slotID); 1066c19800e8SDoug Rabson return CKR_FUNCTION_NOT_SUPPORTED; 1067c19800e8SDoug Rabson } 1068c19800e8SDoug Rabson 1069c19800e8SDoug Rabson CK_RV 1070c19800e8SDoug Rabson C_OpenSession(CK_SLOT_ID slotID, 1071c19800e8SDoug Rabson CK_FLAGS flags, 1072c19800e8SDoug Rabson CK_VOID_PTR pApplication, 1073c19800e8SDoug Rabson CK_NOTIFY Notify, 1074c19800e8SDoug Rabson CK_SESSION_HANDLE_PTR phSession) 1075c19800e8SDoug Rabson { 1076c19800e8SDoug Rabson int i; 1077c19800e8SDoug Rabson INIT_CONTEXT(); 1078c19800e8SDoug Rabson st_logf("OpenSession: slot: %d\n", (int)slotID); 1079c19800e8SDoug Rabson 1080c19800e8SDoug Rabson if (soft_token.open_sessions == MAX_NUM_SESSION) 1081c19800e8SDoug Rabson return CKR_SESSION_COUNT; 1082c19800e8SDoug Rabson 1083c19800e8SDoug Rabson soft_token.application = pApplication; 1084c19800e8SDoug Rabson soft_token.notify = Notify; 1085c19800e8SDoug Rabson 1086c19800e8SDoug Rabson for (i = 0; i < MAX_NUM_SESSION; i++) 1087c19800e8SDoug Rabson if (soft_token.state[i].session_handle == CK_INVALID_HANDLE) 1088c19800e8SDoug Rabson break; 1089c19800e8SDoug Rabson if (i == MAX_NUM_SESSION) 1090c19800e8SDoug Rabson abort(); 1091c19800e8SDoug Rabson 1092c19800e8SDoug Rabson soft_token.open_sessions++; 1093c19800e8SDoug Rabson 1094c19800e8SDoug Rabson soft_token.state[i].session_handle = 1095c19800e8SDoug Rabson (CK_SESSION_HANDLE)(random() & 0xfffff); 1096c19800e8SDoug Rabson *phSession = soft_token.state[i].session_handle; 1097c19800e8SDoug Rabson 1098c19800e8SDoug Rabson return CKR_OK; 1099c19800e8SDoug Rabson } 1100c19800e8SDoug Rabson 1101c19800e8SDoug Rabson CK_RV 1102c19800e8SDoug Rabson C_CloseSession(CK_SESSION_HANDLE hSession) 1103c19800e8SDoug Rabson { 1104c19800e8SDoug Rabson struct session_state *state; 1105c19800e8SDoug Rabson INIT_CONTEXT(); 1106c19800e8SDoug Rabson st_logf("CloseSession\n"); 1107c19800e8SDoug Rabson 1108c19800e8SDoug Rabson if (verify_session_handle(hSession, &state) != CKR_OK) 1109c19800e8SDoug Rabson application_error("closed session not open"); 1110c19800e8SDoug Rabson else 1111c19800e8SDoug Rabson close_session(state); 1112c19800e8SDoug Rabson 1113c19800e8SDoug Rabson return CKR_OK; 1114c19800e8SDoug Rabson } 1115c19800e8SDoug Rabson 1116c19800e8SDoug Rabson CK_RV 1117c19800e8SDoug Rabson C_CloseAllSessions(CK_SLOT_ID slotID) 1118c19800e8SDoug Rabson { 1119c19800e8SDoug Rabson int i; 1120c19800e8SDoug Rabson INIT_CONTEXT(); 1121c19800e8SDoug Rabson 1122c19800e8SDoug Rabson st_logf("CloseAllSessions\n"); 1123c19800e8SDoug Rabson 1124c19800e8SDoug Rabson for (i = 0; i < MAX_NUM_SESSION; i++) 1125c19800e8SDoug Rabson if (soft_token.state[i].session_handle != CK_INVALID_HANDLE) 1126c19800e8SDoug Rabson close_session(&soft_token.state[i]); 1127c19800e8SDoug Rabson 1128c19800e8SDoug Rabson return CKR_OK; 1129c19800e8SDoug Rabson } 1130c19800e8SDoug Rabson 1131c19800e8SDoug Rabson CK_RV 1132c19800e8SDoug Rabson C_GetSessionInfo(CK_SESSION_HANDLE hSession, 1133c19800e8SDoug Rabson CK_SESSION_INFO_PTR pInfo) 1134c19800e8SDoug Rabson { 1135c19800e8SDoug Rabson st_logf("GetSessionInfo\n"); 1136c19800e8SDoug Rabson INIT_CONTEXT(); 1137c19800e8SDoug Rabson 1138c19800e8SDoug Rabson VERIFY_SESSION_HANDLE(hSession, NULL); 1139c19800e8SDoug Rabson 1140c19800e8SDoug Rabson memset(pInfo, 20, sizeof(*pInfo)); 1141c19800e8SDoug Rabson 1142c19800e8SDoug Rabson pInfo->slotID = 1; 1143c19800e8SDoug Rabson if (soft_token.flags.login_done) 1144c19800e8SDoug Rabson pInfo->state = CKS_RO_USER_FUNCTIONS; 1145c19800e8SDoug Rabson else 1146c19800e8SDoug Rabson pInfo->state = CKS_RO_PUBLIC_SESSION; 1147c19800e8SDoug Rabson pInfo->flags = CKF_SERIAL_SESSION; 1148c19800e8SDoug Rabson pInfo->ulDeviceError = 0; 1149c19800e8SDoug Rabson 1150c19800e8SDoug Rabson return CKR_OK; 1151c19800e8SDoug Rabson } 1152c19800e8SDoug Rabson 1153c19800e8SDoug Rabson CK_RV 1154c19800e8SDoug Rabson C_Login(CK_SESSION_HANDLE hSession, 1155c19800e8SDoug Rabson CK_USER_TYPE userType, 1156c19800e8SDoug Rabson CK_UTF8CHAR_PTR pPin, 1157c19800e8SDoug Rabson CK_ULONG ulPinLen) 1158c19800e8SDoug Rabson { 1159c19800e8SDoug Rabson char *pin = NULL; 1160c19800e8SDoug Rabson CK_RV ret; 1161c19800e8SDoug Rabson INIT_CONTEXT(); 1162c19800e8SDoug Rabson 1163c19800e8SDoug Rabson st_logf("Login\n"); 1164c19800e8SDoug Rabson 1165c19800e8SDoug Rabson VERIFY_SESSION_HANDLE(hSession, NULL); 1166c19800e8SDoug Rabson 1167c19800e8SDoug Rabson if (pPin != NULL_PTR) { 1168c19800e8SDoug Rabson asprintf(&pin, "%.*s", (int)ulPinLen, pPin); 1169c19800e8SDoug Rabson st_logf("type: %d password: %s\n", (int)userType, pin); 1170c19800e8SDoug Rabson } 1171c19800e8SDoug Rabson 1172c19800e8SDoug Rabson /* 1173c19800e8SDoug Rabson * Login 1174c19800e8SDoug Rabson */ 1175c19800e8SDoug Rabson 1176c19800e8SDoug Rabson ret = read_conf_file(soft_token.config_file, userType, pin); 1177c19800e8SDoug Rabson if (ret == CKR_OK) 1178c19800e8SDoug Rabson soft_token.flags.login_done = 1; 1179c19800e8SDoug Rabson 1180c19800e8SDoug Rabson free(pin); 1181c19800e8SDoug Rabson 1182c19800e8SDoug Rabson return soft_token.flags.login_done ? CKR_OK : CKR_PIN_INCORRECT; 1183c19800e8SDoug Rabson } 1184c19800e8SDoug Rabson 1185c19800e8SDoug Rabson CK_RV 1186c19800e8SDoug Rabson C_Logout(CK_SESSION_HANDLE hSession) 1187c19800e8SDoug Rabson { 1188c19800e8SDoug Rabson st_logf("Logout\n"); 1189c19800e8SDoug Rabson INIT_CONTEXT(); 1190c19800e8SDoug Rabson 1191c19800e8SDoug Rabson VERIFY_SESSION_HANDLE(hSession, NULL); 1192c19800e8SDoug Rabson return CKR_FUNCTION_NOT_SUPPORTED; 1193c19800e8SDoug Rabson } 1194c19800e8SDoug Rabson 1195c19800e8SDoug Rabson CK_RV 1196c19800e8SDoug Rabson C_GetObjectSize(CK_SESSION_HANDLE hSession, 1197c19800e8SDoug Rabson CK_OBJECT_HANDLE hObject, 1198c19800e8SDoug Rabson CK_ULONG_PTR pulSize) 1199c19800e8SDoug Rabson { 1200c19800e8SDoug Rabson st_logf("GetObjectSize\n"); 1201c19800e8SDoug Rabson INIT_CONTEXT(); 1202c19800e8SDoug Rabson 1203c19800e8SDoug Rabson VERIFY_SESSION_HANDLE(hSession, NULL); 1204c19800e8SDoug Rabson return CKR_FUNCTION_NOT_SUPPORTED; 1205c19800e8SDoug Rabson } 1206c19800e8SDoug Rabson 1207c19800e8SDoug Rabson CK_RV 1208c19800e8SDoug Rabson C_GetAttributeValue(CK_SESSION_HANDLE hSession, 1209c19800e8SDoug Rabson CK_OBJECT_HANDLE hObject, 1210c19800e8SDoug Rabson CK_ATTRIBUTE_PTR pTemplate, 1211c19800e8SDoug Rabson CK_ULONG ulCount) 1212c19800e8SDoug Rabson { 1213c19800e8SDoug Rabson struct session_state *state; 1214c19800e8SDoug Rabson struct st_object *obj; 1215c19800e8SDoug Rabson CK_ULONG i; 1216c19800e8SDoug Rabson CK_RV ret; 1217c19800e8SDoug Rabson int j; 1218c19800e8SDoug Rabson 1219c19800e8SDoug Rabson INIT_CONTEXT(); 1220c19800e8SDoug Rabson 1221c19800e8SDoug Rabson st_logf("GetAttributeValue: %lx\n", 1222c19800e8SDoug Rabson (unsigned long)HANDLE_OBJECT_ID(hObject)); 1223c19800e8SDoug Rabson VERIFY_SESSION_HANDLE(hSession, &state); 1224c19800e8SDoug Rabson 1225c19800e8SDoug Rabson if ((ret = object_handle_to_object(hObject, &obj)) != CKR_OK) { 1226c19800e8SDoug Rabson st_logf("object not found: %lx\n", 1227c19800e8SDoug Rabson (unsigned long)HANDLE_OBJECT_ID(hObject)); 1228c19800e8SDoug Rabson return ret; 1229c19800e8SDoug Rabson } 1230c19800e8SDoug Rabson 1231c19800e8SDoug Rabson for (i = 0; i < ulCount; i++) { 1232c19800e8SDoug Rabson st_logf(" getting 0x%08lx\n", (unsigned long)pTemplate[i].type); 1233c19800e8SDoug Rabson for (j = 0; j < obj->num_attributes; j++) { 1234c19800e8SDoug Rabson if (obj->attrs[j].secret) { 1235c19800e8SDoug Rabson pTemplate[i].ulValueLen = (CK_ULONG)-1; 1236c19800e8SDoug Rabson break; 1237c19800e8SDoug Rabson } 1238c19800e8SDoug Rabson if (pTemplate[i].type == obj->attrs[j].attribute.type) { 1239c19800e8SDoug Rabson if (pTemplate[i].pValue != NULL_PTR && obj->attrs[j].secret == 0) { 1240c19800e8SDoug Rabson if (pTemplate[i].ulValueLen >= obj->attrs[j].attribute.ulValueLen) 1241c19800e8SDoug Rabson memcpy(pTemplate[i].pValue, obj->attrs[j].attribute.pValue, 1242c19800e8SDoug Rabson obj->attrs[j].attribute.ulValueLen); 1243c19800e8SDoug Rabson } 1244c19800e8SDoug Rabson pTemplate[i].ulValueLen = obj->attrs[j].attribute.ulValueLen; 1245c19800e8SDoug Rabson break; 1246c19800e8SDoug Rabson } 1247c19800e8SDoug Rabson } 1248c19800e8SDoug Rabson if (j == obj->num_attributes) { 1249c19800e8SDoug Rabson st_logf("key type: 0x%08lx not found\n", (unsigned long)pTemplate[i].type); 1250c19800e8SDoug Rabson pTemplate[i].ulValueLen = (CK_ULONG)-1; 1251c19800e8SDoug Rabson } 1252c19800e8SDoug Rabson 1253c19800e8SDoug Rabson } 1254c19800e8SDoug Rabson return CKR_OK; 1255c19800e8SDoug Rabson } 1256c19800e8SDoug Rabson 1257c19800e8SDoug Rabson CK_RV 1258c19800e8SDoug Rabson C_FindObjectsInit(CK_SESSION_HANDLE hSession, 1259c19800e8SDoug Rabson CK_ATTRIBUTE_PTR pTemplate, 1260c19800e8SDoug Rabson CK_ULONG ulCount) 1261c19800e8SDoug Rabson { 1262c19800e8SDoug Rabson struct session_state *state; 1263c19800e8SDoug Rabson 1264c19800e8SDoug Rabson st_logf("FindObjectsInit\n"); 1265c19800e8SDoug Rabson 1266c19800e8SDoug Rabson INIT_CONTEXT(); 1267c19800e8SDoug Rabson 1268c19800e8SDoug Rabson VERIFY_SESSION_HANDLE(hSession, &state); 1269c19800e8SDoug Rabson 1270c19800e8SDoug Rabson if (state->find.next_object != -1) { 1271c19800e8SDoug Rabson application_error("application didn't do C_FindObjectsFinal\n"); 1272c19800e8SDoug Rabson find_object_final(state); 1273c19800e8SDoug Rabson } 1274c19800e8SDoug Rabson if (ulCount) { 1275c19800e8SDoug Rabson CK_ULONG i; 1276c19800e8SDoug Rabson 1277c19800e8SDoug Rabson print_attributes(pTemplate, ulCount); 1278c19800e8SDoug Rabson 1279c19800e8SDoug Rabson state->find.attributes = 1280c19800e8SDoug Rabson calloc(1, ulCount * sizeof(state->find.attributes[0])); 1281c19800e8SDoug Rabson if (state->find.attributes == NULL) 1282c19800e8SDoug Rabson return CKR_DEVICE_MEMORY; 1283c19800e8SDoug Rabson for (i = 0; i < ulCount; i++) { 1284c19800e8SDoug Rabson state->find.attributes[i].pValue = 1285c19800e8SDoug Rabson malloc(pTemplate[i].ulValueLen); 1286c19800e8SDoug Rabson if (state->find.attributes[i].pValue == NULL) { 1287c19800e8SDoug Rabson find_object_final(state); 1288c19800e8SDoug Rabson return CKR_DEVICE_MEMORY; 1289c19800e8SDoug Rabson } 1290c19800e8SDoug Rabson memcpy(state->find.attributes[i].pValue, 1291c19800e8SDoug Rabson pTemplate[i].pValue, pTemplate[i].ulValueLen); 1292c19800e8SDoug Rabson state->find.attributes[i].type = pTemplate[i].type; 1293c19800e8SDoug Rabson state->find.attributes[i].ulValueLen = pTemplate[i].ulValueLen; 1294c19800e8SDoug Rabson } 1295c19800e8SDoug Rabson state->find.num_attributes = ulCount; 1296c19800e8SDoug Rabson state->find.next_object = 0; 1297c19800e8SDoug Rabson } else { 1298c19800e8SDoug Rabson st_logf("find all objects\n"); 1299c19800e8SDoug Rabson state->find.attributes = NULL; 1300c19800e8SDoug Rabson state->find.num_attributes = 0; 1301c19800e8SDoug Rabson state->find.next_object = 0; 1302c19800e8SDoug Rabson } 1303c19800e8SDoug Rabson 1304c19800e8SDoug Rabson return CKR_OK; 1305c19800e8SDoug Rabson } 1306c19800e8SDoug Rabson 1307c19800e8SDoug Rabson CK_RV 1308c19800e8SDoug Rabson C_FindObjects(CK_SESSION_HANDLE hSession, 1309c19800e8SDoug Rabson CK_OBJECT_HANDLE_PTR phObject, 1310c19800e8SDoug Rabson CK_ULONG ulMaxObjectCount, 1311c19800e8SDoug Rabson CK_ULONG_PTR pulObjectCount) 1312c19800e8SDoug Rabson { 1313c19800e8SDoug Rabson struct session_state *state; 1314c19800e8SDoug Rabson int i; 1315c19800e8SDoug Rabson 1316c19800e8SDoug Rabson INIT_CONTEXT(); 1317c19800e8SDoug Rabson 1318c19800e8SDoug Rabson st_logf("FindObjects\n"); 1319c19800e8SDoug Rabson 1320c19800e8SDoug Rabson VERIFY_SESSION_HANDLE(hSession, &state); 1321c19800e8SDoug Rabson 1322c19800e8SDoug Rabson if (state->find.next_object == -1) { 1323c19800e8SDoug Rabson application_error("application didn't do C_FindObjectsInit\n"); 1324c19800e8SDoug Rabson return CKR_ARGUMENTS_BAD; 1325c19800e8SDoug Rabson } 1326c19800e8SDoug Rabson if (ulMaxObjectCount == 0) { 1327c19800e8SDoug Rabson application_error("application asked for 0 objects\n"); 1328c19800e8SDoug Rabson return CKR_ARGUMENTS_BAD; 1329c19800e8SDoug Rabson } 1330c19800e8SDoug Rabson *pulObjectCount = 0; 1331c19800e8SDoug Rabson for (i = state->find.next_object; i < soft_token.object.num_objs; i++) { 1332c19800e8SDoug Rabson st_logf("FindObjects: %d\n", i); 1333c19800e8SDoug Rabson state->find.next_object = i + 1; 1334c19800e8SDoug Rabson if (attributes_match(soft_token.object.objs[i], 1335c19800e8SDoug Rabson state->find.attributes, 1336c19800e8SDoug Rabson state->find.num_attributes)) { 1337c19800e8SDoug Rabson *phObject++ = soft_token.object.objs[i]->object_handle; 1338c19800e8SDoug Rabson ulMaxObjectCount--; 1339c19800e8SDoug Rabson (*pulObjectCount)++; 1340c19800e8SDoug Rabson if (ulMaxObjectCount == 0) 1341c19800e8SDoug Rabson break; 1342c19800e8SDoug Rabson } 1343c19800e8SDoug Rabson } 1344c19800e8SDoug Rabson return CKR_OK; 1345c19800e8SDoug Rabson } 1346c19800e8SDoug Rabson 1347c19800e8SDoug Rabson CK_RV 1348c19800e8SDoug Rabson C_FindObjectsFinal(CK_SESSION_HANDLE hSession) 1349c19800e8SDoug Rabson { 1350c19800e8SDoug Rabson struct session_state *state; 1351c19800e8SDoug Rabson 1352c19800e8SDoug Rabson INIT_CONTEXT(); 1353c19800e8SDoug Rabson 1354c19800e8SDoug Rabson st_logf("FindObjectsFinal\n"); 1355c19800e8SDoug Rabson VERIFY_SESSION_HANDLE(hSession, &state); 1356c19800e8SDoug Rabson find_object_final(state); 1357c19800e8SDoug Rabson return CKR_OK; 1358c19800e8SDoug Rabson } 1359c19800e8SDoug Rabson 1360c19800e8SDoug Rabson static CK_RV 1361c19800e8SDoug Rabson commonInit(CK_ATTRIBUTE *attr_match, int attr_match_len, 1362c19800e8SDoug Rabson const CK_MECHANISM_TYPE *mechs, int mechs_len, 1363c19800e8SDoug Rabson const CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, 1364c19800e8SDoug Rabson struct st_object **o) 1365c19800e8SDoug Rabson { 1366c19800e8SDoug Rabson CK_RV ret; 1367c19800e8SDoug Rabson int i; 1368c19800e8SDoug Rabson 1369c19800e8SDoug Rabson *o = NULL; 1370c19800e8SDoug Rabson if ((ret = object_handle_to_object(hKey, o)) != CKR_OK) 1371c19800e8SDoug Rabson return ret; 1372c19800e8SDoug Rabson 1373c19800e8SDoug Rabson ret = attributes_match(*o, attr_match, attr_match_len); 1374c19800e8SDoug Rabson if (!ret) { 1375c19800e8SDoug Rabson application_error("called commonInit on key that doesn't " 1376c19800e8SDoug Rabson "support required attr"); 1377c19800e8SDoug Rabson return CKR_ARGUMENTS_BAD; 1378c19800e8SDoug Rabson } 1379c19800e8SDoug Rabson 1380c19800e8SDoug Rabson for (i = 0; i < mechs_len; i++) 1381c19800e8SDoug Rabson if (mechs[i] == pMechanism->mechanism) 1382c19800e8SDoug Rabson break; 1383c19800e8SDoug Rabson if (i == mechs_len) { 1384c19800e8SDoug Rabson application_error("called mech (%08lx) not supported\n", 1385c19800e8SDoug Rabson pMechanism->mechanism); 1386c19800e8SDoug Rabson return CKR_ARGUMENTS_BAD; 1387c19800e8SDoug Rabson } 1388c19800e8SDoug Rabson return CKR_OK; 1389c19800e8SDoug Rabson } 1390c19800e8SDoug Rabson 1391c19800e8SDoug Rabson 1392c19800e8SDoug Rabson static CK_RV 1393c19800e8SDoug Rabson dup_mechanism(CK_MECHANISM_PTR *dup, const CK_MECHANISM_PTR pMechanism) 1394c19800e8SDoug Rabson { 1395c19800e8SDoug Rabson CK_MECHANISM_PTR p; 1396c19800e8SDoug Rabson 1397c19800e8SDoug Rabson p = malloc(sizeof(*p)); 1398c19800e8SDoug Rabson if (p == NULL) 1399c19800e8SDoug Rabson return CKR_DEVICE_MEMORY; 1400c19800e8SDoug Rabson 1401c19800e8SDoug Rabson if (*dup) 1402c19800e8SDoug Rabson free(*dup); 1403c19800e8SDoug Rabson *dup = p; 1404c19800e8SDoug Rabson memcpy(p, pMechanism, sizeof(*p)); 1405c19800e8SDoug Rabson 1406c19800e8SDoug Rabson return CKR_OK; 1407c19800e8SDoug Rabson } 1408c19800e8SDoug Rabson 1409c19800e8SDoug Rabson CK_RV 1410c19800e8SDoug Rabson C_DigestInit(CK_SESSION_HANDLE hSession, 1411c19800e8SDoug Rabson CK_MECHANISM_PTR pMechanism) 1412c19800e8SDoug Rabson { 1413c19800e8SDoug Rabson st_logf("DigestInit\n"); 1414c19800e8SDoug Rabson INIT_CONTEXT(); 1415c19800e8SDoug Rabson VERIFY_SESSION_HANDLE(hSession, NULL); 1416c19800e8SDoug Rabson return CKR_FUNCTION_NOT_SUPPORTED; 1417c19800e8SDoug Rabson } 1418c19800e8SDoug Rabson 1419c19800e8SDoug Rabson CK_RV 1420c19800e8SDoug Rabson C_SignInit(CK_SESSION_HANDLE hSession, 1421c19800e8SDoug Rabson CK_MECHANISM_PTR pMechanism, 1422c19800e8SDoug Rabson CK_OBJECT_HANDLE hKey) 1423c19800e8SDoug Rabson { 1424c19800e8SDoug Rabson struct session_state *state; 1425c19800e8SDoug Rabson CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS }; 1426c19800e8SDoug Rabson CK_BBOOL bool_true = CK_TRUE; 1427c19800e8SDoug Rabson CK_ATTRIBUTE attr[] = { 1428c19800e8SDoug Rabson { CKA_SIGN, &bool_true, sizeof(bool_true) } 1429c19800e8SDoug Rabson }; 1430c19800e8SDoug Rabson struct st_object *o; 1431c19800e8SDoug Rabson CK_RV ret; 1432c19800e8SDoug Rabson 1433c19800e8SDoug Rabson INIT_CONTEXT(); 1434c19800e8SDoug Rabson st_logf("SignInit\n"); 1435c19800e8SDoug Rabson VERIFY_SESSION_HANDLE(hSession, &state); 1436c19800e8SDoug Rabson 1437c19800e8SDoug Rabson ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]), 1438c19800e8SDoug Rabson mechs, sizeof(mechs)/sizeof(mechs[0]), 1439c19800e8SDoug Rabson pMechanism, hKey, &o); 1440c19800e8SDoug Rabson if (ret) 1441c19800e8SDoug Rabson return ret; 1442c19800e8SDoug Rabson 1443c19800e8SDoug Rabson ret = dup_mechanism(&state->sign_mechanism, pMechanism); 1444c19800e8SDoug Rabson if (ret == CKR_OK) 1445c19800e8SDoug Rabson state->sign_object = OBJECT_ID(o); 1446c19800e8SDoug Rabson 1447c19800e8SDoug Rabson return CKR_OK; 1448c19800e8SDoug Rabson } 1449c19800e8SDoug Rabson 1450c19800e8SDoug Rabson CK_RV 1451c19800e8SDoug Rabson C_Sign(CK_SESSION_HANDLE hSession, 1452c19800e8SDoug Rabson CK_BYTE_PTR pData, 1453c19800e8SDoug Rabson CK_ULONG ulDataLen, 1454c19800e8SDoug Rabson CK_BYTE_PTR pSignature, 1455c19800e8SDoug Rabson CK_ULONG_PTR pulSignatureLen) 1456c19800e8SDoug Rabson { 1457c19800e8SDoug Rabson struct session_state *state; 1458c19800e8SDoug Rabson struct st_object *o; 1459c19800e8SDoug Rabson CK_RV ret; 1460c19800e8SDoug Rabson uint hret; 1461c19800e8SDoug Rabson const AlgorithmIdentifier *alg; 1462c19800e8SDoug Rabson heim_octet_string sig, data; 1463c19800e8SDoug Rabson 1464c19800e8SDoug Rabson INIT_CONTEXT(); 1465c19800e8SDoug Rabson st_logf("Sign\n"); 1466c19800e8SDoug Rabson VERIFY_SESSION_HANDLE(hSession, &state); 1467c19800e8SDoug Rabson 1468c19800e8SDoug Rabson sig.data = NULL; 1469c19800e8SDoug Rabson sig.length = 0; 1470c19800e8SDoug Rabson 1471c19800e8SDoug Rabson if (state->sign_object == -1) 1472c19800e8SDoug Rabson return CKR_ARGUMENTS_BAD; 1473c19800e8SDoug Rabson 1474c19800e8SDoug Rabson if (pulSignatureLen == NULL) { 1475c19800e8SDoug Rabson st_logf("signature len NULL\n"); 1476c19800e8SDoug Rabson ret = CKR_ARGUMENTS_BAD; 1477c19800e8SDoug Rabson goto out; 1478c19800e8SDoug Rabson } 1479c19800e8SDoug Rabson 1480c19800e8SDoug Rabson if (pData == NULL_PTR) { 1481c19800e8SDoug Rabson st_logf("data NULL\n"); 1482c19800e8SDoug Rabson ret = CKR_ARGUMENTS_BAD; 1483c19800e8SDoug Rabson goto out; 1484c19800e8SDoug Rabson } 1485c19800e8SDoug Rabson 1486c19800e8SDoug Rabson o = soft_token.object.objs[state->sign_object]; 1487c19800e8SDoug Rabson 1488c19800e8SDoug Rabson if (hx509_cert_have_private_key(o->cert) == 0) { 1489c19800e8SDoug Rabson st_logf("private key NULL\n"); 1490c19800e8SDoug Rabson return CKR_ARGUMENTS_BAD; 1491c19800e8SDoug Rabson } 1492c19800e8SDoug Rabson 1493c19800e8SDoug Rabson switch(state->sign_mechanism->mechanism) { 1494c19800e8SDoug Rabson case CKM_RSA_PKCS: 1495c19800e8SDoug Rabson alg = hx509_signature_rsa_pkcs1_x509(); 1496c19800e8SDoug Rabson break; 1497c19800e8SDoug Rabson default: 1498c19800e8SDoug Rabson ret = CKR_FUNCTION_NOT_SUPPORTED; 1499c19800e8SDoug Rabson goto out; 1500c19800e8SDoug Rabson } 1501c19800e8SDoug Rabson 1502c19800e8SDoug Rabson data.data = pData; 1503c19800e8SDoug Rabson data.length = ulDataLen; 1504c19800e8SDoug Rabson 1505c19800e8SDoug Rabson hret = _hx509_create_signature(context, 1506c19800e8SDoug Rabson _hx509_cert_private_key(o->cert), 1507c19800e8SDoug Rabson alg, 1508c19800e8SDoug Rabson &data, 1509c19800e8SDoug Rabson NULL, 1510c19800e8SDoug Rabson &sig); 1511c19800e8SDoug Rabson if (hret) { 1512c19800e8SDoug Rabson ret = CKR_DEVICE_ERROR; 1513c19800e8SDoug Rabson goto out; 1514c19800e8SDoug Rabson } 1515c19800e8SDoug Rabson *pulSignatureLen = sig.length; 1516c19800e8SDoug Rabson 1517c19800e8SDoug Rabson if (pSignature != NULL_PTR) 1518c19800e8SDoug Rabson memcpy(pSignature, sig.data, sig.length); 1519c19800e8SDoug Rabson 1520c19800e8SDoug Rabson ret = CKR_OK; 1521c19800e8SDoug Rabson out: 1522c19800e8SDoug Rabson if (sig.data) { 1523c19800e8SDoug Rabson memset(sig.data, 0, sig.length); 1524c19800e8SDoug Rabson der_free_octet_string(&sig); 1525c19800e8SDoug Rabson } 1526c19800e8SDoug Rabson return ret; 1527c19800e8SDoug Rabson } 1528c19800e8SDoug Rabson 1529c19800e8SDoug Rabson CK_RV 1530c19800e8SDoug Rabson C_SignUpdate(CK_SESSION_HANDLE hSession, 1531c19800e8SDoug Rabson CK_BYTE_PTR pPart, 1532c19800e8SDoug Rabson CK_ULONG ulPartLen) 1533c19800e8SDoug Rabson { 1534c19800e8SDoug Rabson INIT_CONTEXT(); 1535c19800e8SDoug Rabson st_logf("SignUpdate\n"); 1536c19800e8SDoug Rabson VERIFY_SESSION_HANDLE(hSession, NULL); 1537c19800e8SDoug Rabson return CKR_FUNCTION_NOT_SUPPORTED; 1538c19800e8SDoug Rabson } 1539c19800e8SDoug Rabson 1540c19800e8SDoug Rabson 1541c19800e8SDoug Rabson CK_RV 1542c19800e8SDoug Rabson C_SignFinal(CK_SESSION_HANDLE hSession, 1543c19800e8SDoug Rabson CK_BYTE_PTR pSignature, 1544c19800e8SDoug Rabson CK_ULONG_PTR pulSignatureLen) 1545c19800e8SDoug Rabson { 1546c19800e8SDoug Rabson INIT_CONTEXT(); 1547c19800e8SDoug Rabson st_logf("SignUpdate\n"); 1548c19800e8SDoug Rabson VERIFY_SESSION_HANDLE(hSession, NULL); 1549c19800e8SDoug Rabson return CKR_FUNCTION_NOT_SUPPORTED; 1550c19800e8SDoug Rabson } 1551c19800e8SDoug Rabson 1552c19800e8SDoug Rabson CK_RV 1553c19800e8SDoug Rabson C_VerifyInit(CK_SESSION_HANDLE hSession, 1554c19800e8SDoug Rabson CK_MECHANISM_PTR pMechanism, 1555c19800e8SDoug Rabson CK_OBJECT_HANDLE hKey) 1556c19800e8SDoug Rabson { 1557c19800e8SDoug Rabson struct session_state *state; 1558c19800e8SDoug Rabson CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS }; 1559c19800e8SDoug Rabson CK_BBOOL bool_true = CK_TRUE; 1560c19800e8SDoug Rabson CK_ATTRIBUTE attr[] = { 1561c19800e8SDoug Rabson { CKA_VERIFY, &bool_true, sizeof(bool_true) } 1562c19800e8SDoug Rabson }; 1563c19800e8SDoug Rabson struct st_object *o; 1564c19800e8SDoug Rabson CK_RV ret; 1565c19800e8SDoug Rabson 1566c19800e8SDoug Rabson INIT_CONTEXT(); 1567c19800e8SDoug Rabson st_logf("VerifyInit\n"); 1568c19800e8SDoug Rabson VERIFY_SESSION_HANDLE(hSession, &state); 1569c19800e8SDoug Rabson 1570c19800e8SDoug Rabson ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]), 1571c19800e8SDoug Rabson mechs, sizeof(mechs)/sizeof(mechs[0]), 1572c19800e8SDoug Rabson pMechanism, hKey, &o); 1573c19800e8SDoug Rabson if (ret) 1574c19800e8SDoug Rabson return ret; 1575c19800e8SDoug Rabson 1576c19800e8SDoug Rabson ret = dup_mechanism(&state->verify_mechanism, pMechanism); 1577c19800e8SDoug Rabson if (ret == CKR_OK) 1578c19800e8SDoug Rabson state->verify_object = OBJECT_ID(o); 1579c19800e8SDoug Rabson 1580c19800e8SDoug Rabson return ret; 1581c19800e8SDoug Rabson } 1582c19800e8SDoug Rabson 1583c19800e8SDoug Rabson CK_RV 1584c19800e8SDoug Rabson C_Verify(CK_SESSION_HANDLE hSession, 1585c19800e8SDoug Rabson CK_BYTE_PTR pData, 1586c19800e8SDoug Rabson CK_ULONG ulDataLen, 1587c19800e8SDoug Rabson CK_BYTE_PTR pSignature, 1588c19800e8SDoug Rabson CK_ULONG ulSignatureLen) 1589c19800e8SDoug Rabson { 1590c19800e8SDoug Rabson struct session_state *state; 1591c19800e8SDoug Rabson struct st_object *o; 1592c19800e8SDoug Rabson const AlgorithmIdentifier *alg; 1593c19800e8SDoug Rabson CK_RV ret; 1594c19800e8SDoug Rabson int hret; 1595c19800e8SDoug Rabson heim_octet_string data, sig; 1596c19800e8SDoug Rabson 1597c19800e8SDoug Rabson INIT_CONTEXT(); 1598c19800e8SDoug Rabson st_logf("Verify\n"); 1599c19800e8SDoug Rabson VERIFY_SESSION_HANDLE(hSession, &state); 1600c19800e8SDoug Rabson 1601c19800e8SDoug Rabson if (state->verify_object == -1) 1602c19800e8SDoug Rabson return CKR_ARGUMENTS_BAD; 1603c19800e8SDoug Rabson 1604c19800e8SDoug Rabson o = soft_token.object.objs[state->verify_object]; 1605c19800e8SDoug Rabson 1606c19800e8SDoug Rabson switch(state->verify_mechanism->mechanism) { 1607c19800e8SDoug Rabson case CKM_RSA_PKCS: 1608c19800e8SDoug Rabson alg = hx509_signature_rsa_pkcs1_x509(); 1609c19800e8SDoug Rabson break; 1610c19800e8SDoug Rabson default: 1611c19800e8SDoug Rabson ret = CKR_FUNCTION_NOT_SUPPORTED; 1612c19800e8SDoug Rabson goto out; 1613c19800e8SDoug Rabson } 1614c19800e8SDoug Rabson 1615c19800e8SDoug Rabson sig.data = pData; 1616c19800e8SDoug Rabson sig.length = ulDataLen; 1617c19800e8SDoug Rabson data.data = pSignature; 1618c19800e8SDoug Rabson data.length = ulSignatureLen; 1619c19800e8SDoug Rabson 1620c19800e8SDoug Rabson hret = _hx509_verify_signature(context, 1621c19800e8SDoug Rabson _hx509_get_cert(o->cert), 1622c19800e8SDoug Rabson alg, 1623c19800e8SDoug Rabson &data, 1624c19800e8SDoug Rabson &sig); 1625c19800e8SDoug Rabson if (hret) { 1626c19800e8SDoug Rabson ret = CKR_GENERAL_ERROR; 1627c19800e8SDoug Rabson goto out; 1628c19800e8SDoug Rabson } 1629c19800e8SDoug Rabson ret = CKR_OK; 1630c19800e8SDoug Rabson 1631c19800e8SDoug Rabson out: 1632c19800e8SDoug Rabson return ret; 1633c19800e8SDoug Rabson } 1634c19800e8SDoug Rabson 1635c19800e8SDoug Rabson 1636c19800e8SDoug Rabson CK_RV 1637c19800e8SDoug Rabson C_VerifyUpdate(CK_SESSION_HANDLE hSession, 1638c19800e8SDoug Rabson CK_BYTE_PTR pPart, 1639c19800e8SDoug Rabson CK_ULONG ulPartLen) 1640c19800e8SDoug Rabson { 1641c19800e8SDoug Rabson INIT_CONTEXT(); 1642c19800e8SDoug Rabson st_logf("VerifyUpdate\n"); 1643c19800e8SDoug Rabson VERIFY_SESSION_HANDLE(hSession, NULL); 1644c19800e8SDoug Rabson return CKR_FUNCTION_NOT_SUPPORTED; 1645c19800e8SDoug Rabson } 1646c19800e8SDoug Rabson 1647c19800e8SDoug Rabson CK_RV 1648c19800e8SDoug Rabson C_VerifyFinal(CK_SESSION_HANDLE hSession, 1649c19800e8SDoug Rabson CK_BYTE_PTR pSignature, 1650c19800e8SDoug Rabson CK_ULONG ulSignatureLen) 1651c19800e8SDoug Rabson { 1652c19800e8SDoug Rabson INIT_CONTEXT(); 1653c19800e8SDoug Rabson st_logf("VerifyFinal\n"); 1654c19800e8SDoug Rabson VERIFY_SESSION_HANDLE(hSession, NULL); 1655c19800e8SDoug Rabson return CKR_FUNCTION_NOT_SUPPORTED; 1656c19800e8SDoug Rabson } 1657c19800e8SDoug Rabson 1658c19800e8SDoug Rabson CK_RV 1659c19800e8SDoug Rabson C_GenerateRandom(CK_SESSION_HANDLE hSession, 1660c19800e8SDoug Rabson CK_BYTE_PTR RandomData, 1661c19800e8SDoug Rabson CK_ULONG ulRandomLen) 1662c19800e8SDoug Rabson { 1663c19800e8SDoug Rabson INIT_CONTEXT(); 1664c19800e8SDoug Rabson st_logf("GenerateRandom\n"); 1665c19800e8SDoug Rabson VERIFY_SESSION_HANDLE(hSession, NULL); 1666c19800e8SDoug Rabson return CKR_FUNCTION_NOT_SUPPORTED; 1667c19800e8SDoug Rabson } 1668c19800e8SDoug Rabson 1669c19800e8SDoug Rabson 1670c19800e8SDoug Rabson CK_FUNCTION_LIST funcs = { 1671c19800e8SDoug Rabson { 2, 11 }, 1672c19800e8SDoug Rabson C_Initialize, 1673c19800e8SDoug Rabson C_Finalize, 1674c19800e8SDoug Rabson C_GetInfo, 1675c19800e8SDoug Rabson C_GetFunctionList, 1676c19800e8SDoug Rabson C_GetSlotList, 1677c19800e8SDoug Rabson C_GetSlotInfo, 1678c19800e8SDoug Rabson C_GetTokenInfo, 1679c19800e8SDoug Rabson C_GetMechanismList, 1680c19800e8SDoug Rabson C_GetMechanismInfo, 1681c19800e8SDoug Rabson C_InitToken, 1682c19800e8SDoug Rabson (void *)func_not_supported, /* C_InitPIN */ 1683c19800e8SDoug Rabson (void *)func_not_supported, /* C_SetPIN */ 1684c19800e8SDoug Rabson C_OpenSession, 1685c19800e8SDoug Rabson C_CloseSession, 1686c19800e8SDoug Rabson C_CloseAllSessions, 1687c19800e8SDoug Rabson C_GetSessionInfo, 1688c19800e8SDoug Rabson (void *)func_not_supported, /* C_GetOperationState */ 1689c19800e8SDoug Rabson (void *)func_not_supported, /* C_SetOperationState */ 1690c19800e8SDoug Rabson C_Login, 1691c19800e8SDoug Rabson C_Logout, 1692c19800e8SDoug Rabson (void *)func_not_supported, /* C_CreateObject */ 1693c19800e8SDoug Rabson (void *)func_not_supported, /* C_CopyObject */ 1694c19800e8SDoug Rabson (void *)func_not_supported, /* C_DestroyObject */ 1695c19800e8SDoug Rabson (void *)func_not_supported, /* C_GetObjectSize */ 1696c19800e8SDoug Rabson C_GetAttributeValue, 1697c19800e8SDoug Rabson (void *)func_not_supported, /* C_SetAttributeValue */ 1698c19800e8SDoug Rabson C_FindObjectsInit, 1699c19800e8SDoug Rabson C_FindObjects, 1700c19800e8SDoug Rabson C_FindObjectsFinal, 1701c19800e8SDoug Rabson (void *)func_not_supported, /* C_EncryptInit, */ 1702c19800e8SDoug Rabson (void *)func_not_supported, /* C_Encrypt, */ 1703c19800e8SDoug Rabson (void *)func_not_supported, /* C_EncryptUpdate, */ 1704c19800e8SDoug Rabson (void *)func_not_supported, /* C_EncryptFinal, */ 1705c19800e8SDoug Rabson (void *)func_not_supported, /* C_DecryptInit, */ 1706c19800e8SDoug Rabson (void *)func_not_supported, /* C_Decrypt, */ 1707c19800e8SDoug Rabson (void *)func_not_supported, /* C_DecryptUpdate, */ 1708c19800e8SDoug Rabson (void *)func_not_supported, /* C_DecryptFinal, */ 1709c19800e8SDoug Rabson C_DigestInit, 1710c19800e8SDoug Rabson (void *)func_not_supported, /* C_Digest */ 1711c19800e8SDoug Rabson (void *)func_not_supported, /* C_DigestUpdate */ 1712c19800e8SDoug Rabson (void *)func_not_supported, /* C_DigestKey */ 1713c19800e8SDoug Rabson (void *)func_not_supported, /* C_DigestFinal */ 1714c19800e8SDoug Rabson C_SignInit, 1715c19800e8SDoug Rabson C_Sign, 1716c19800e8SDoug Rabson C_SignUpdate, 1717c19800e8SDoug Rabson C_SignFinal, 1718c19800e8SDoug Rabson (void *)func_not_supported, /* C_SignRecoverInit */ 1719c19800e8SDoug Rabson (void *)func_not_supported, /* C_SignRecover */ 1720c19800e8SDoug Rabson C_VerifyInit, 1721c19800e8SDoug Rabson C_Verify, 1722c19800e8SDoug Rabson C_VerifyUpdate, 1723c19800e8SDoug Rabson C_VerifyFinal, 1724c19800e8SDoug Rabson (void *)func_not_supported, /* C_VerifyRecoverInit */ 1725c19800e8SDoug Rabson (void *)func_not_supported, /* C_VerifyRecover */ 1726c19800e8SDoug Rabson (void *)func_not_supported, /* C_DigestEncryptUpdate */ 1727c19800e8SDoug Rabson (void *)func_not_supported, /* C_DecryptDigestUpdate */ 1728c19800e8SDoug Rabson (void *)func_not_supported, /* C_SignEncryptUpdate */ 1729c19800e8SDoug Rabson (void *)func_not_supported, /* C_DecryptVerifyUpdate */ 1730c19800e8SDoug Rabson (void *)func_not_supported, /* C_GenerateKey */ 1731c19800e8SDoug Rabson (void *)func_not_supported, /* C_GenerateKeyPair */ 1732c19800e8SDoug Rabson (void *)func_not_supported, /* C_WrapKey */ 1733c19800e8SDoug Rabson (void *)func_not_supported, /* C_UnwrapKey */ 1734c19800e8SDoug Rabson (void *)func_not_supported, /* C_DeriveKey */ 1735c19800e8SDoug Rabson (void *)func_not_supported, /* C_SeedRandom */ 1736c19800e8SDoug Rabson C_GenerateRandom, 1737c19800e8SDoug Rabson (void *)func_not_supported, /* C_GetFunctionStatus */ 1738c19800e8SDoug Rabson (void *)func_not_supported, /* C_CancelFunction */ 1739c19800e8SDoug Rabson (void *)func_not_supported /* C_WaitForSlotEvent */ 1740c19800e8SDoug Rabson }; 1741