CK_RV create_slot(sc_reader_t *reader) { struct sc_pkcs11_slot *slot; if (list_size(&virtual_slots) >= sc_pkcs11_conf.max_virtual_slots) return CKR_FUNCTION_FAILED; slot = (struct sc_pkcs11_slot *)calloc(1, sizeof(struct sc_pkcs11_slot)); if (!slot) return CKR_HOST_MEMORY; list_append(&virtual_slots, slot); slot->login_user = -1; slot->id = (CK_SLOT_ID) list_locate(&virtual_slots, slot); sc_debug(context, SC_LOG_DEBUG_NORMAL, "Creating slot with id 0x%lx", slot->id); list_init(&slot->objects); list_attributes_seeker(&slot->objects, object_list_seeker); init_slot_info(&slot->slot_info); if (reader != NULL) { slot->reader = reader; strcpy_bp(slot->slot_info.slotDescription, reader->name, 64); } return CKR_OK; }
void init_stkl20(struct lu_phy_attr *lu) { smc_pm.name = "mhVTL - STK L20/40/80 series emulation"; smc_pm.library_has_map = TRUE; smc_pm.library_has_barcode_reader = TRUE; smc_pm.library_has_playground = TRUE; /* Follow L20 SCSI Reference Manual */ smc_pm.start_picker = 0x0001; smc_pm.start_map = 0x000a; /* 10d - 55d */ smc_pm.start_drive = 0x01f4; /* 500d - 519d */ smc_pm.start_storage = 0x03e8; /* 1000d - 1677d */ smc_pm.lu = lu; smc_personality_module_register(&smc_pm); init_slot_info(lu); update_stk_l_vpd_80(lu); update_stk_l_vpd_83(lu); init_smc_log_pages(lu); init_smc_mode_pages(lu); /* FIXME: Need to add page 0x2d - Drive Configuration Page */ add_smc_mode_page_drive_configuration(lu); }
void init_scalar_smc(struct lu_phy_attr *lu) { int h, m, sec; int day, month, year; smc_pm.name = "mhVTL - Scalar emulation"; smc_pm.library_has_map = TRUE; smc_pm.library_has_barcode_reader = TRUE; smc_pm.library_has_playground = FALSE; smc_pm.dvcid_serial_only = FALSE; smc_pm.start_picker = 0x0001; smc_pm.start_map = 0x0010; smc_pm.start_drive = 0x0100; smc_pm.start_storage = 0x1000; smc_pm.lu = lu; smc_personality_module_register(&smc_pm); init_slot_info(lu); /* Reference Quantum 6-00423013 SCSI Reference - Rev A */ ymd(&year, &month, &day, &h, &m, &sec); /* Controller firmware build date */ sprintf((char *)&lu->inquiry[36], "%04d-%02d-%02d %02d:%02d:%02d", year, month, day, h, m, sec); lu->inquiry[55] = 0x01; /* Contains barcode scanner : BarC */ init_smc_log_pages(lu); init_smc_mode_pages(lu); }
void init_hp_eml_smc(struct lu_phy_attr *lu) { smc_pm.name = "mhVTL - HP EML E-Series emulation"; smc_pm.lu = lu; smc_personality_module_register(&smc_pm); init_slot_info(lu); update_eml_vpd_80(lu); update_eml_vpd_83(lu); init_smc_log_pages(lu); init_smc_mode_pages(lu); }
CK_RV create_slot(sc_reader_t *reader) { /* find unused virtual hotplug slots */ struct sc_pkcs11_slot *slot = reader_get_slot(NULL); /* create a new slot if no empty slot is available */ if (!slot) { if (list_size(&virtual_slots) >= sc_pkcs11_conf.max_virtual_slots) return CKR_FUNCTION_FAILED; slot = (struct sc_pkcs11_slot *)calloc(1, sizeof(struct sc_pkcs11_slot)); if (!slot) return CKR_HOST_MEMORY; list_append(&virtual_slots, slot); if (0 != list_init(&slot->objects)) { return CKR_HOST_MEMORY; } list_attributes_seeker(&slot->objects, object_list_seeker); if (0 != list_init(&slot->logins)) { return CKR_HOST_MEMORY; } } else { /* reuse the old list of logins/objects since they should be empty */ list_t logins = slot->logins; list_t objects = slot->objects; memset(slot, 0, sizeof *slot); slot->logins = logins; slot->objects = objects; } slot->login_user = -1; slot->id = (CK_SLOT_ID) list_locate(&virtual_slots, slot); init_slot_info(&slot->slot_info, reader); sc_log(context, "Initializing slot with id 0x%lx", slot->id); if (reader != NULL) { slot->reader = reader; strcpy_bp(slot->slot_info.manufacturerID, reader->vendor, 32); strcpy_bp(slot->slot_info.slotDescription, reader->name, 64); slot->slot_info.hardwareVersion.major = reader->version_major; slot->slot_info.hardwareVersion.minor = reader->version_minor; } return CKR_OK; }
void empty_slot(struct sc_pkcs11_slot *slot) { if (slot) { if (slot->flags & SC_PKCS11_SLOT_FLAG_SEEN) { /* Keep the slot visible to the application. The slot's state has * already been reset by `slot_token_removed()`, lists have been * emptied. We replace the reader with a virtual hotplug slot. */ slot->reader = NULL; init_slot_info(&slot->slot_info, NULL); } else { list_destroy(&slot->objects); list_destroy(&slot->logins); list_delete(&virtual_slots, slot); free(slot); } } }
void init_stklxx(struct lu_phy_attr *lu) { smc_pm.name = "mhVTL - STK L series emulation"; smc_pm.library_has_map = TRUE; smc_pm.library_has_barcode_reader = TRUE; smc_pm.library_has_playground = TRUE; /* Follow L700e/L180 SCSI Reference Manual - 8th Edition */ smc_pm.start_picker = 0x0001; smc_pm.start_map = 0x0010; smc_pm.start_drive = 0x01f0; smc_pm.start_storage = 0x0400; smc_pm.lu = lu; smc_personality_module_register(&smc_pm); init_slot_info(lu); update_stk_l_vpd_80(lu); update_stk_l_vpd_83(lu); init_smc_log_pages(lu); init_smc_mode_pages(lu); }
void init_stkslxx(struct lu_phy_attr *lu) { smc_pm.name = "mhVTL - STK SL series emulation"; smc_pm.library_has_map = TRUE; smc_pm.library_has_barcode_reader = TRUE; smc_pm.library_has_playground = TRUE; /* Follow Streamline SL500 Interface Reference Manual - 2th Edition */ smc_pm.start_picker = 0x0001; smc_pm.start_map = 0x000a; /* 10d - 55d */ smc_pm.start_drive = 0x01f4; /* 500d - 518d */ smc_pm.start_storage = 0x03e8; /* 1000d - 1628d */ smc_pm.lu = lu; smc_personality_module_register(&smc_pm); init_slot_info(lu); update_stk_l_vpd_80(lu); update_stk_l_vpd_83(lu); init_smc_log_pages(lu); init_smc_mode_pages(lu); }
void init_hp_msl_smc(struct lu_phy_attr *lu) { smc_pm.name = "mhVTL - HP MSL Series emulation"; smc_pm.lu = lu; smc_pm.start_picker = 0x0001; smc_pm.start_storage = 0x0020; smc_pm.start_drive = 0x01e0; smc_pm.start_map = 0x01c0; smc_pm.dvcid_len = 20, smc_pm.dvcid_serial_only = TRUE, smc_pm.no_dvcid_flag = TRUE, lu->inquiry[2] = 2; /* Set SCSI-2 Approved Version */ smc_personality_module_register(&smc_pm); init_slot_info(lu); update_eml_vpd_80(lu); update_eml_vpd_83(lu); init_smc_log_pages(lu); init_smc_mode_pages(lu); }
CK_RV card_detect(sc_reader_t *reader) { struct sc_pkcs11_card *p11card = NULL; int free_p11card = 0; int rc; CK_RV rv; unsigned int i; int j; sc_log(context, "%s: Detecting smart card", reader->name); /* Check if someone inserted a card */ again: rc = sc_detect_card_presence(reader); if (rc < 0) { sc_log(context, "%s: failed, %s", reader->name, sc_strerror(rc)); return sc_to_cryptoki_error(rc, NULL); } if (rc == 0) { sc_log(context, "%s: card absent", reader->name); card_removed(reader); /* Release all resources */ return CKR_TOKEN_NOT_PRESENT; } /* If the card was changed, disconnect the current one */ if (rc & SC_READER_CARD_CHANGED) { sc_log(context, "%s: Card changed", reader->name); /* The following should never happen - but if it * does we'll be stuck in an endless loop. * So better be fussy. if (!retry--) return CKR_TOKEN_NOT_PRESENT; */ card_removed(reader); goto again; } /* Locate a slot related to the reader */ for (i=0; i<list_size(&virtual_slots); i++) { sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i); if (slot->reader == reader) { p11card = slot->p11card; break; } } /* Detect the card if it's not known already */ if (p11card == NULL) { sc_log(context, "%s: First seen the card ", reader->name); p11card = (struct sc_pkcs11_card *)calloc(1, sizeof(struct sc_pkcs11_card)); if (!p11card) return CKR_HOST_MEMORY; free_p11card = 1; p11card->reader = reader; } if (p11card->card == NULL) { sc_log(context, "%s: Connecting ... ", reader->name); rc = sc_connect_card(reader, &p11card->card); if (rc != SC_SUCCESS) { sc_log(context, "%s: SC connect card error %i", reader->name, rc); rv = sc_to_cryptoki_error(rc, NULL); goto fail; } /* escape commands are only guaranteed to be working with a card * inserted. That's why by now, after sc_connect_card() the reader's * metadata may have changed. We re-initialize the metadata for every * slot of this reader here. */ if (reader->flags & SC_READER_ENABLE_ESCAPE) { for (i = 0; i<list_size(&virtual_slots); i++) { sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i); if (slot->reader == reader) init_slot_info(&slot->slot_info, reader); } } sc_log(context, "%s: Connected SC card %p", reader->name, p11card->card); } /* Detect the framework */ if (p11card->framework == NULL) { struct sc_app_info *app_generic = sc_pkcs15_get_application_by_type(p11card->card, "generic"); sc_log(context, "%s: Detecting Framework. %i on-card applications", reader->name, p11card->card->app_count); sc_log(context, "%s: generic application %s", reader->name, app_generic ? app_generic->label : "<none>"); for (i = 0; frameworks[i]; i++) if (frameworks[i]->bind != NULL) break; /*TODO: only first framework is used: pkcs15init framework is not reachable here */ if (frameworks[i] == NULL) { rv = CKR_GENERAL_ERROR; goto fail; } p11card->framework = frameworks[i]; /* Initialize framework */ sc_log(context, "%s: Detected framework %d. Creating tokens.", reader->name, i); /* Bind 'generic' application or (emulated?) card without applications */ if (app_generic || !p11card->card->app_count) { scconf_block *conf_block = NULL; int enable_InitToken = 0; conf_block = sc_match_atr_block(p11card->card->ctx, NULL, &p11card->reader->atr); if (!conf_block) /* check default block */ conf_block = sc_get_conf_block(context, "framework", "pkcs15", 1); enable_InitToken = scconf_get_bool(conf_block, "pkcs11_enable_InitToken", 0); sc_log(context, "%s: Try to bind 'generic' token.", reader->name); rv = frameworks[i]->bind(p11card, app_generic); if (rv == CKR_TOKEN_NOT_RECOGNIZED && enable_InitToken) { sc_log(context, "%s: 'InitToken' enabled -- accept non-binded card", reader->name); rv = CKR_OK; } if (rv != CKR_OK) { sc_log(context, "%s: cannot bind 'generic' token: rv 0x%lX", reader->name, rv); goto fail; } sc_log(context, "%s: Creating 'generic' token.", reader->name); rv = frameworks[i]->create_tokens(p11card, app_generic); if (rv != CKR_OK) { sc_log(context, "%s: create 'generic' token error 0x%lX", reader->name, rv); goto fail; } } /* Now bind the rest of applications that are not 'generic' */ for (j = 0; j < p11card->card->app_count; j++) { struct sc_app_info *app_info = p11card->card->app[j]; char *app_name = app_info ? app_info->label : "<anonymous>"; if (app_generic && app_generic == p11card->card->app[j]) continue; sc_log(context, "%s: Binding %s token.", reader->name, app_name); rv = frameworks[i]->bind(p11card, app_info); if (rv != CKR_OK) { sc_log(context, "%s: bind %s token error Ox%lX", reader->name, app_name, rv); continue; } sc_log(context, "%s: Creating %s token.", reader->name, app_name); rv = frameworks[i]->create_tokens(p11card, app_info); if (rv != CKR_OK) { sc_log(context, "%s: create %s token error 0x%lX", reader->name, app_name, rv); goto fail; } } } sc_log(context, "%s: Detection ended", reader->name); return CKR_OK; fail: if (free_p11card) { if (p11card->framework) p11card->framework->unbind(p11card); if (p11card->card != NULL) sc_disconnect_card(p11card->card); free(p11card); } return rv; }
/*ARGSUSED*/ CK_RV SC_InitToken( CK_SLOT_ID sid, CK_CHAR_PTR pPin, CK_ULONG ulPinLen, CK_CHAR_PTR pLabel) { CK_RV rc = CKR_OK; CK_BYTE hash_sha[SHA1_DIGEST_LENGTH]; TOKEN_DATA newtoken; TSS_HCONTEXT hContext = 0; if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (sid != TPM_SLOTID) { rc = CKR_SLOT_ID_INVALID; goto done; } if (! pPin || ! pLabel) { rc = CKR_ARGUMENTS_BAD; goto done; } if (open_tss_context(&hContext)) { rc = CKR_FUNCTION_FAILED; goto done; } rc = load_token_data(hContext, &newtoken); if (rc != CKR_OK) { goto done; } if (newtoken.token_info.flags & CKF_SO_PIN_LOCKED) { rc = CKR_PIN_LOCKED; goto done; } rc = token_specific.t_verify_so_pin(hContext, pPin, ulPinLen); if (rc != CKR_OK) { rc = CKR_PIN_INCORRECT; goto done; } /* * Before we reconstruct all the data, we should delete the * token objects from the filesystem. * * Construct a string to delete the token objects. */ (void) object_mgr_destroy_token_objects(hContext); (void) init_token_data(hContext, &newtoken); (void) init_slot_info(&newtoken); /* change the label */ (void) strncpy((char *)newtoken.token_info.label, (char *)pLabel, sizeof (newtoken.token_info.label)); (void) memcpy(newtoken.so_pin_sha, hash_sha, SHA1_DIGEST_LENGTH); newtoken.token_info.flags |= CKF_TOKEN_INITIALIZED; rc = save_token_data(&newtoken); done: if (hContext) (void) Tspi_Context_Close(hContext); return (rc); }
CK_RV ST_Initialize(void *FunctionList, CK_SLOT_ID SlotNumber, unsigned char *Correlator) { CK_RV rc = CKR_OK; struct ST_FCN_LIST *flist = (struct ST_FCN_LIST *)FunctionList; TSS_HCONTEXT hContext = 0; stlogterm(); stloginit(); if (st_Initialized() == TRUE) { return (CKR_OK); } // assume that the upper API prevents multiple calls of initialize // since that only happens on C_Initialize and that is the // resonsibility of the upper layer.. initialized = FALSE; // check for other completing this before creating mutexes... // make sure that the same process tried to to the init... // thread issues should be caught up above... if (st_Initialized() == TRUE) { goto done; } Fork_Initializer(); (void) pthread_mutex_init(&pkcs_mutex, NULL); (void) pthread_mutex_init(&obj_list_mutex, NULL); (void) pthread_rwlock_init(&obj_list_rw_mutex, NULL); (void) pthread_mutex_init(&sess_list_mutex, NULL); (void) pthread_mutex_init(&login_mutex, NULL); if (st_Initialized() == FALSE) { if ((rc = attach_shm()) != CKR_OK) goto done; nv_token_data = &global_shm->nv_token_data; initialized = TRUE; initedpid = getpid(); SC_SetFunctionList(); if (flist != NULL) (*flist) = function_list; /* Always call the token_specific_init function.... */ rc = token_specific.t_init((char *)Correlator, SlotNumber, &hContext); if (rc != 0) { /* * The token could not be initialized, return OK, but * present no slots. */ rc = CKR_OK; goto done; } else { /* Mark the token as available */ global_shm->token_available = TRUE; } } rc = load_token_data(hContext, nv_token_data); if (rc != CKR_OK) { goto done; } rc = load_public_token_objects(); if (rc != CKR_OK) goto done; (void) XProcLock(xproclock); global_shm->publ_loaded = TRUE; (void) XProcUnLock(xproclock); init_slot_info(nv_token_data); done: if (hContext) Tspi_Context_Close(hContext); return (rc); }