static int entersafe_create_ef(sc_card_t *card, sc_entersafe_create_data * data) { int r; sc_apdu_t apdu; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x02, 0x00); apdu.cla = 0x84; apdu.data = (u8*)&data->data.ef; apdu.lc = apdu.datalen = sizeof(data->data.ef); r = entersafe_transmit_apdu(card, &apdu,init_key,sizeof(init_key),0,1); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); }
/* * Create a DF */ static int setcos_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df) { struct sc_context *ctx = p15card->card->ctx; int r; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); r = sc_pkcs15init_fixup_file(profile, p15card, df); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "SetCOS file ACL fixup failed"); r = sc_create_file(p15card->card, df); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "SetCOS create file failed"); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); }
/* * Create a new PIN inside a DF */ static int cflex_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df, sc_pkcs15_object_t *pin_obj, const u8 *pin, size_t pin_len, const u8 *puk, size_t puk_len) { struct sc_context *ctx = p15card->card->ctx; sc_pkcs15_auth_info_t *auth_info = (sc_pkcs15_auth_info_t *) pin_obj->data; struct sc_pkcs15_pin_attributes *pin_attrs = &auth_info->attrs.pin; sc_file_t *dummies[2]; int ndummies, pin_type, puk_type, r; sc_file_t *file; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) return SC_ERROR_OBJECT_NOT_VALID; /* If the profile doesn't specify a reference for this PIN, guess */ if (pin_attrs->flags & SC_PKCS15_PIN_FLAG_SO_PIN) { pin_type = SC_PKCS15INIT_SO_PIN; puk_type = SC_PKCS15INIT_SO_PUK; if (pin_attrs->reference != 2) return SC_ERROR_INVALID_ARGUMENTS; } else { pin_type = SC_PKCS15INIT_USER_PIN; puk_type = SC_PKCS15INIT_USER_PUK; if (pin_attrs->reference != 1) return SC_ERROR_INVALID_ARGUMENTS; } /* Get file definition from the profile */ if (sc_profile_get_file(profile, (pin_attrs->reference == 1)? "CHV1" : "CHV2", &file) < 0 && sc_profile_get_file(profile, "CHV", &file) < 0) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_FILE_NOT_FOUND, "profile does not define pin file ACLs"); ndummies = cflex_create_dummy_chvs(profile, p15card, file, SC_AC_OP_CREATE, dummies); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, ndummies, "Unable to create dummy CHV file"); r = cflex_create_pin_file(profile, p15card, &df->path, pin_attrs->reference, pin, pin_len, sc_profile_get_pin_retries(profile, pin_type), puk, puk_len, sc_profile_get_pin_retries(profile, puk_type), NULL, 0); cflex_delete_dummy_chvs(profile, p15card, ndummies, dummies); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); }
CK_RV session_get_operation(struct sc_pkcs11_session * session, int type, sc_pkcs11_operation_t ** operation) { sc_pkcs11_operation_t *op; SC_FUNC_CALLED(context, SC_LOG_DEBUG_NORMAL); if (type < 0 || type >= SC_PKCS11_OPERATION_MAX) return CKR_ARGUMENTS_BAD; if (!(op = session->operation[type])) return CKR_OPERATION_NOT_INITIALIZED; if (operation) *operation = op; return CKR_OK; }
int sc_card_ctl(sc_card_t *card, unsigned long cmd, void *args) { int r = SC_ERROR_NOT_SUPPORTED; assert(card != NULL); SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); if (card->ops->card_ctl != NULL) r = card->ops->card_ctl(card, cmd, args); /* suppress "not supported" error messages */ if (r == SC_ERROR_NOT_SUPPORTED) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "card_ctl(%lu) not supported", cmd); return r; } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); }
/* * Create a faux pin file */ static int cflex_create_empty_pin_file(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_path_t *path, int ref, sc_file_t **file_ret) { int r; SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_NORMAL); *file_ret = NULL; r = cflex_create_pin_file(profile, p15card, path, ref, dummy_pin_value, sizeof(dummy_pin_value), 8, NULL, 0, 0, file_ret, 1); if (r == SC_ERROR_FILE_ALREADY_EXISTS) SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE, r); SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE, r); }
int sc_release_context(sc_context_t *ctx) { unsigned int i; if (ctx == NULL) { return SC_ERROR_INVALID_ARGUMENTS; } SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); while (list_size(&ctx->readers)) { sc_reader_t *rdr = (sc_reader_t *) list_get_at(&ctx->readers, 0); _sc_delete_reader(ctx, rdr); } if (ctx->reader_driver->ops->finish != NULL) ctx->reader_driver->ops->finish(ctx); for (i = 0; ctx->card_drivers[i]; i++) { struct sc_card_driver *drv = ctx->card_drivers[i]; if (drv->atr_map) _sc_free_atr(ctx, drv); if (drv->dll) sc_dlclose(drv->dll); } if (ctx->preferred_language != NULL) free(ctx->preferred_language); if (ctx->mutex != NULL) { int r = sc_mutex_destroy(ctx, ctx->mutex); if (r != SC_SUCCESS) { sc_log(ctx, "unable to destroy mutex"); return r; } } if (ctx->conf != NULL) scconf_free(ctx->conf); if (ctx->debug_file && (ctx->debug_file != stdout && ctx->debug_file != stderr)) fclose(ctx->debug_file); if (ctx->debug_filename != NULL) free(ctx->debug_filename); if (ctx->app_name != NULL) free(ctx->app_name); list_destroy(&ctx->readers); sc_mem_clear(ctx, sizeof(*ctx)); free(ctx); return SC_SUCCESS; }
int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *p15card, sc_pkcs15emu_opt_t *opts) { sc_card_t *card = p15card->card; sc_context_t *ctx = card->ctx; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) return sc_pkcs15emu_piv_init(p15card); else { int r = piv_detect_card(p15card); if (r) return SC_ERROR_WRONG_CARD; return sc_pkcs15emu_piv_init(p15card); } }
static int sc_hsm_emu_update_any_df(struct sc_profile *profile, struct sc_pkcs15_card *p15card, unsigned op, struct sc_pkcs15_object *object) { struct sc_context *ctx = p15card->card->ctx; int rv = SC_ERROR_NOT_SUPPORTED; SC_FUNC_CALLED(ctx, 1); switch(op) { case SC_AC_OP_ERASE: sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Update DF; erase object('%s',type:%X)", object->label, object->type); switch(object->type & SC_PKCS15_TYPE_CLASS_MASK) { case SC_PKCS15_TYPE_PRKEY: rv = sc_hsm_delete_ef(p15card, PRKD_PREFIX, ((struct sc_pkcs15_prkey_info *)object->data)->key_reference); break; case SC_PKCS15_TYPE_PUBKEY: rv = SC_SUCCESS; break; case SC_PKCS15_TYPE_CERT: rv = sc_hsm_emu_delete_cd(profile, p15card, object); break; case SC_PKCS15_TYPE_DATA_OBJECT: rv = sc_hsm_delete_ef(p15card, DCOD_PREFIX, ((struct sc_pkcs15_data_info *)object->data)->path.value[1]); break; } break; case SC_AC_OP_UPDATE: case SC_AC_OP_CREATE: sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Update DF; create object('%s',type:%X)", object->label, object->type); switch(object->type & SC_PKCS15_TYPE_CLASS_MASK) { case SC_PKCS15_TYPE_PUBKEY: rv = SC_SUCCESS; break; case SC_PKCS15_TYPE_PRKEY: rv = sc_hsm_emu_update_prkd(profile, p15card, object); break; case SC_PKCS15_TYPE_CERT: rv = sc_hsm_emu_update_cd(profile, p15card, object); break; case SC_PKCS15_TYPE_DATA_OBJECT: rv = sc_hsm_emu_update_dcod(profile, p15card, object); break; } break; } SC_FUNC_RETURN(ctx, 1, rv); }
int card_sync_card_to_virtual_fs_certificate_file_callback( sc_card_t *card, struct _virtual_file_t *virtual_file, virtual_fs_t *virtual_fs ) { int r = SC_SUCCESS; unsigned char *card_data = NULL; unsigned char *uncompressed_data = NULL; size_t card_data_length = 0; size_t uncompressed_data_length = 0; sc_path_t *path=NULL; SC_FUNC_CALLED(card->ctx, 1); if(!card || !virtual_file) return SC_ERROR_INVALID_ARGUMENTS; path=NULL; path = map_path_to_path_find(DRVDATA(card)->virtual_fs_to_card_path_map, &virtual_file->path); if(!path) { r = SC_ERROR_OBJECT_NOT_FOUND; goto end; } /* get file */ r = card_helper_read_certificate_file(card, path, &card_data, &card_data_length); if (r!=SC_SUCCESS) goto end; if (card_data_length>0) { r = file_uncompress_data(card, card_data, card_data_length, &uncompressed_data, &uncompressed_data_length); if(r < 0) goto end; r = virtual_file_data_update(virtual_file, 0, uncompressed_data, uncompressed_data_length); if(r != SC_SUCCESS) goto end; } end: if(card_data) { free(card_data); card_data = NULL; } if(uncompressed_data) { free(uncompressed_data); uncompressed_data = NULL; } SC_FUNC_RETURN(card->ctx, 1, r); }
int card_sync_virtual_fs_to_card_filter_pukey( sc_card_t *card, struct _virtual_file_t *virtual_file, virtual_fs_t *virtual_fs, sc_pkcs15_object_t *obj ) { int r = SC_SUCCESS; struct sc_pkcs15_pubkey_info *pukey = NULL; sc_pkcs15_der_t *der = NULL; sc_path_t *path = NULL; sc_pkcs15_id_t *ckaid = NULL; SC_FUNC_CALLED(card->ctx, 1); if(!card || !virtual_file) return SC_ERROR_INVALID_ARGUMENTS; pukey = (struct sc_pkcs15_pubkey_info *) obj->data; if(pukey) { sc_pkcs15_free_object_content(obj); /* try to find an old der if present */ der = map_id_to_der_find(DRVDATA(card)->pukdf_card_ckaid_to_card_der_map, &pukey->id); if(der) { sc_der_copy(&obj->content, der); } path = map_path_to_path_find(DRVDATA(card)->virtual_fs_to_card_path_map, &pukey->path); if(path) { /* replace path data */ memcpy(&pukey->path, path, sizeof(sc_path_t)); } ckaid = map_opensc_id_to_id_find(DRVDATA(card)->virtual_fs_to_card_ckaid_map, &pukey->id); if(ckaid) { /* replace ckaid */ memcpy(&pukey->id, ckaid, sizeof(struct sc_pkcs15_id)); } /* add manual flags */ pukey->native = 0x01; pukey->access_flags |= SC_PKCS15_PRKEY_ACCESS_LOCAL; pukey->access_flags |= SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE; pukey->key_reference = pukey->path.value[pukey->path.len-1]; } else { sc_debug(card->ctx,SC_LOG_DEBUG_VERBOSE, "Pointer to pukey info was empty"); } SC_FUNC_RETURN(card->ctx, 1, r); }
static int myeid_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) { struct sc_path path; struct sc_file *file = NULL; int r; SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE); sc_format_path("3F00", &path); r = sc_select_file(p15card->card, &path, &file); if (file) sc_file_free(file); SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r); }
static int entersafe_create_file(sc_card_t *card, sc_file_t *file) { SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (file->type == SC_FILE_TYPE_WORKING_EF) { sc_entersafe_create_data data; memset(&data,0,sizeof(data)); data.data.ef.file_id[0] = (file->id>>8)&0xFF; data.data.ef.file_id[1] = file->id&0xFF; data.data.ef.size[0] = (file->size>>8)&0xFF; data.data.ef.size[1] = file->size&0xFF; memset(data.data.ef.ac,ENTERSAFE_AC_ALWAYS,sizeof(data.data.ef.ac)); data.data.ef.ac[0] = process_acl_entry(file,SC_AC_OP_READ,ENTERSAFE_AC_ALWAYS); data.data.ef.ac[1] = process_acl_entry(file,SC_AC_OP_UPDATE,ENTERSAFE_AC_ALWAYS); return entersafe_create_ef(card, &data); } else
int sc_pkcs15emu_oberthur_init_ex(struct sc_pkcs15_card * p15card, struct sc_pkcs15emu_opt * opts) { int rv; SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE); if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) { rv = sc_pkcs15emu_oberthur_init(p15card); } else { rv = oberthur_detect_card(p15card); if (!rv) rv = sc_pkcs15emu_oberthur_init(p15card); } SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, rv); }
/* Add a PIN to the PIN cache related to the card. Some operations can trigger re-authentication later. */ void sc_pkcs15_pincache_add(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *pin_obj, const u8 *pin, size_t pinlen) { struct sc_context *ctx = p15card->card->ctx; struct sc_pkcs15_auth_info *auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data; struct sc_pkcs15_object *obj = NULL; int r; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); if (!p15card->opts.use_pin_cache) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PIN caching not enabled"); return; } /* If the PIN protects an object with user consent, don't cache it */ obj = p15card->obj_list; while (obj != NULL) { /* Compare 'sc_pkcs15_object.auth_id' with 'sc_pkcs15_pin_info.auth_id'. * In accordance with PKCS#15 "6.1.8 CommonObjectAttributes" and * "6.1.16 CommonAuthenticationObjectAttributes" with the exception that * "CommonObjectAttributes.accessControlRules" are not taken into account. */ if (sc_pkcs15_compare_id(&obj->auth_id, &auth_info->auth_id)) { /* Caching is refused, if the protected object requires user consent */ if (obj->user_consent > 0) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "caching refused (user consent)"); return; } } obj = obj->next; } r = sc_pkcs15_allocate_object_content(pin_obj, pin, pinlen); if (r != SC_SUCCESS) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Failed to allocate object content"); return; } pin_obj->usage_counter = 0; sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PIN(%s) cached", pin_obj->label); }
static int pcsc_unlock(sc_reader_t *reader, sc_slot_info_t *slot) { long rv; struct pcsc_slot_data *pslot = GET_SLOT_DATA(slot); struct pcsc_private_data *priv = GET_PRIV_DATA(reader); SC_FUNC_CALLED(reader->ctx, 3); assert(pslot != NULL); rv = priv->gpriv->SCardEndTransaction(pslot->pcsc_card, priv->gpriv->transaction_reset ? SCARD_RESET_CARD : SCARD_LEAVE_CARD); pslot->locked = 0; if (rv != SCARD_S_SUCCESS) { PCSC_ERROR(reader->ctx, "SCardEndTransaction failed", rv); return pcsc_ret_to_error(rv); } return SC_SUCCESS; }
/* * Erase the card via rm */ static int cflex_erase_card(struct sc_profile *profile, sc_pkcs15_card_t *p15card) { struct sc_context *ctx = p15card->card->ctx; sc_file_t *df = profile->df_info->file, *dir, *userpinfile = NULL; int r; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); /* Delete EF(DIR). This may not be very nice * against other applications that use this file, but * extremely useful for testing :) * Note we need to delete if before the DF because we create * it *after* the DF. * */ if (sc_profile_get_file(profile, "DIR", &dir) >= 0) { r = cflex_delete_file(profile, p15card, dir); sc_file_free(dir); if (r < 0 && r != SC_ERROR_FILE_NOT_FOUND) goto out; } r=cflex_delete_file(profile, p15card, df); /* If the user pin file isn't in a sub-DF of the pkcs15 DF, delete it */ if (sc_profile_get_file(profile, "pinfile-1", &userpinfile) >= 0 && userpinfile->path.len <= profile->df_info->file->path.len + 2 && memcmp(userpinfile->path.value, profile->df_info->file->path.value, userpinfile->path.len) != 0) { r = cflex_delete_file(profile, p15card, userpinfile); sc_file_free(userpinfile); userpinfile=NULL; } out: /* Forget all cached keys, the pin files on card are all gone. */ if (userpinfile) sc_file_free(userpinfile); sc_free_apps(p15card->card); if (r == SC_ERROR_FILE_NOT_FOUND) r=0; SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); }
int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid, sc_pkcs15emu_opt_t *opts) { sc_card_t *card = p15card->card; SC_FUNC_CALLED(card->ctx, 1); /* Check card */ if (!(opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)) { if (! ( (card->type > SC_CARD_TYPE_ITACNS_BASE && card->type < SC_CARD_TYPE_ITACNS_BASE + 1000) || card->type == SC_CARD_TYPE_CARDOS_CIE_V1) ) return SC_ERROR_WRONG_CARD; } /* Init card */ return itacns_init(p15card); }
/* * Create a DF */ static int myeid_create_dir(sc_profile_t *profile, sc_card_t *card, sc_file_t *df) { int r=0; struct sc_file *file; SC_FUNC_CALLED(card->ctx, 1); if (!profile || !card || !df) return SC_ERROR_INVALID_ARGUMENTS; sc_debug(card->ctx, "id (%x)\n",df->id); if(df->id == 0x5015) { sc_debug(card->ctx, "only Select (%x)\n",df->id); r = sc_select_file(card, &df->path, NULL); } SC_FUNC_RETURN(card->ctx, 1, r); }
/* Validate the PIN code associated with an object */ int sc_pkcs15_pincache_revalidate(struct sc_pkcs15_card *p15card, const sc_pkcs15_object_t *obj) { struct sc_context *ctx = p15card->card->ctx; sc_pkcs15_object_t *pin_obj; int r; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); if (!p15card->opts.use_pin_cache) return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; if (obj->user_consent) return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; if (p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD) return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; r = sc_pkcs15_find_pin_by_auth_id(p15card, &obj->auth_id, &pin_obj); if (r != SC_SUCCESS) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Could not find pin object for auth_id %s", sc_pkcs15_print_id(&obj->auth_id)); return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; } if (pin_obj->usage_counter >= p15card->opts.pin_cache_counter) { sc_pkcs15_free_object_content(pin_obj); return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; } if (!pin_obj->content.value || !pin_obj->content.len) return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; pin_obj->usage_counter++; r = sc_pkcs15_verify_pin(p15card, pin_obj, pin_obj->content.value, pin_obj->content.len); if (r != SC_SUCCESS) { /* Ensure that wrong PIN isn't used again */ sc_pkcs15_free_object_content(pin_obj); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Verify PIN error %i", r); return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; } SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); }
static int itacns_add_prkey(sc_pkcs15_card_t *p15card, const sc_pkcs15_id_t *id, const char *label, int type, unsigned int modulus_length, int usage, const sc_path_t *path, int ref, const sc_pkcs15_id_t *auth_id, int obj_flags) { sc_pkcs15_prkey_info_t info; sc_pkcs15_object_t obj; SC_FUNC_CALLED(p15card->card->ctx, 1); if(type != SC_PKCS15_TYPE_PRKEY_RSA) { sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Cannot add a private key of a type other than RSA"); return 1; } memset(&info, 0, sizeof(info)); memset(&obj, 0, sizeof(obj)); info.id = *id; info.modulus_length = modulus_length; info.usage = usage; info.native = 1; info.key_reference = ref; info.access_flags = SC_PKCS15_PRKEY_ACCESS_SENSITIVE | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE | SC_PKCS15_PRKEY_ACCESS_LOCAL; if (path) info.path = *path; obj.flags = obj_flags; strlcpy(obj.label, label, sizeof(obj.label)); if (auth_id != NULL) obj.auth_id = *auth_id; return sc_pkcs15emu_add_rsa_prkey(p15card, &obj, &info); }
static int gemsafe_process_fci(struct sc_card *card, struct sc_file *file, const u8 *buf, size_t len) { int r; size_t tlen; const u8 *tag = NULL, *p = buf; const char *type; struct sc_context *ctx = card->ctx; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); r = iso_ops->process_fci(card, file, buf, len); if (r < 0) return r; sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "processing GemSAFE V1 specific FCI information\n"); tag = sc_asn1_find_tag(ctx, p, len, 0x82, &tlen); if (!tag) { /* no FDB => we have a DF */ type = "DF"; file->type = SC_FILE_TYPE_DF; } else { type = "EF"; file->type = SC_FILE_TYPE_WORKING_EF; } sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "file type: %s\n", type); tag = sc_asn1_find_tag(ctx, p, len, 0x8C, &tlen); if (tag) { r = gemsafe_setacl(card, file, tag, strcmp(type, "DF") ? 0 : 1); if (r < 0) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "unable to set ACL\n"); return SC_ERROR_INTERNAL; } } else sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "error: AM and SC bytes missing\n"); return SC_SUCCESS; }
static int openct_reader_unlock(sc_reader_t *reader, sc_slot_info_t *slot) { struct driver_data *data = (struct driver_data *) reader->drv_data; struct slot_data *slot_data = (struct slot_data *) slot->drv_data; int rc; SC_FUNC_CALLED(reader->ctx, 1); /* Not connected */ if (data->h == NULL) return 0; rc = ct_card_unlock(data->h, slot->id, slot_data->excl_lock); /* We couldn't care less */ if (rc == IFD_ERROR_NOT_CONNECTED) return 0; return openct_error(reader, rc); }
static int myeid_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) { struct sc_path path; struct sc_file *file = NULL; int r; SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE); sc_format_path("3F00", &path); r = sc_select_file(p15card->card, &path, &file); p15card->tokeninfo->flags = SC_PKCS15_TOKEN_PRN_GENERATION | SC_PKCS15_TOKEN_EID_COMPLIANT; if (file) sc_file_free(file); SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r); }
static int sc_oberthur_parse_publicinfo (struct sc_pkcs15_card *p15card, unsigned char *buff, size_t len, int postpone_allowed) { struct sc_context *ctx = p15card->card->ctx; size_t ii; int rv; SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE); for (ii=0; ii<len; ii+=5) { unsigned int file_id, size; if(*(buff+ii) != 0xFF) continue; file_id = 0x100 * *(buff+ii + 1) + *(buff+ii + 2); size = 0x100 * *(buff+ii + 3) + *(buff+ii + 4); sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "add public object(file-id:%04X,size:%X)", file_id, size); switch (*(buff+ii + 1)) { case BASE_ID_PUB_RSA : rv = sc_pkcs15emu_oberthur_add_pubkey(p15card, file_id, size); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot parse public key info"); break; case BASE_ID_CERT : rv = sc_pkcs15emu_oberthur_add_cert(p15card, file_id); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot parse certificate info"); break; case BASE_ID_PUB_DES : break; case BASE_ID_PUB_DATA : rv = sc_pkcs15emu_oberthur_add_data(p15card, file_id, size, 0); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot parse data info"); break; default: SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Public object parse error"); } } SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); }
/* * Create a new DF * This will usually be the application DF */ static int gpk_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df) { struct sc_file *pinfile; int r, locked; SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE); if (sc_card_ctl(p15card->card, SC_CARDCTL_GPK_IS_LOCKED, &locked) == 0 && locked) { sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "This card is already personalized, unable to " "create PKCS#15 structure."); return SC_ERROR_NOT_SUPPORTED; } /* Create the DF. */ r = sc_pkcs15init_create_file(profile, p15card, df); if (r < 0) return r; /* See if there's a file called "pinfile" that resides within * this DF. If so, create it */ if (sc_profile_get_file(profile, "pinfile", &pinfile) >= 0) { /* Build the pin file's path from the DF path + its * file ID */ pinfile->path = df->path; sc_append_file_id(&pinfile->path, pinfile->id); r = gpk_init_pinfile(profile, p15card, pinfile); sc_file_free(pinfile); if (r < 0) return r; /* TODO: What for it was used ? for (i = 0; i < GPK_MAX_PINS; i++) * sc_keycache_put_pin(&df->path, GPK_PIN_SCOPE|i, (const u8 *) " "); */ } SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r); }
int sc_disconnect_card(sc_card_t *card) { sc_context_t *ctx; ctx = card->ctx; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); assert(card->lock_count == 0); if (card->ops->finish) { int r = card->ops->finish(card); if (r) sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "card driver finish() failed: %s", sc_strerror(r)); } if (card->reader->ops->disconnect) { int r = card->reader->ops->disconnect(card->reader); if (r) sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "disconnect() failed: %s", sc_strerror(r)); } sc_card_free(card); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, 0); }
/* * Called when releasing a reader. release() has to * deallocate the private data. Other fields will be * freed by OpenSC. */ static int openct_reader_release(sc_reader_t *reader) { struct driver_data *data = (struct driver_data *) reader->drv_data; int i; SC_FUNC_CALLED(reader->ctx, 1); if (data) { if (data->h) ct_reader_disconnect(data->h); sc_mem_clear(data, sizeof(*data)); reader->drv_data = NULL; free(data); } for (i = 0; i < SC_MAX_SLOTS; i++) { if(reader->slot[i].drv_data) free(reader->slot[i].drv_data); } return SC_NO_ERROR; }
static int itacns_add_pin(sc_pkcs15_card_t *p15card, char *label, int id, int auth_id, int reference, sc_path_t *path, int flags) { struct sc_pkcs15_auth_info pin_info; struct sc_pkcs15_object pin_obj; SC_FUNC_CALLED(p15card->card->ctx, 1); memset(&pin_info, 0, sizeof(pin_info)); pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; pin_info.auth_id.len = 1; pin_info.auth_id.value[0] = id; pin_info.attrs.pin.reference = reference; pin_info.attrs.pin.flags = flags; pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC; pin_info.attrs.pin.min_length = 5; pin_info.attrs.pin.stored_length = 8; pin_info.attrs.pin.max_length = 8; pin_info.attrs.pin.pad_char = 0xff; pin_info.logged_in = SC_PIN_STATE_UNKNOWN; if(path) pin_info.path = *path; memset(&pin_obj, 0, sizeof(pin_obj)); strlcpy(pin_obj.label, label, sizeof(pin_obj.label)); pin_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE | (auth_id ? SC_PKCS15_CO_FLAG_MODIFIABLE : 0); if (auth_id) { pin_obj.auth_id.len = 1; pin_obj.auth_id.value[0] = auth_id; } else pin_obj.auth_id.len = 0; return sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); }
static int entersafe_create_mf(sc_card_t *card, sc_entersafe_create_data * data) { int r; sc_apdu_t apdu; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); memcpy(data->data.df.init_key, init_key, sizeof(init_key)); sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0xE0,0x00,0x00); apdu.cla=0x84; apdu.data=(u8*)&data->data.df; apdu.datalen=apdu.lc=sizeof(data->data.df); switch(card->type) { case SC_CARD_TYPE_ENTERSAFE_3K: { r = entersafe_transmit_apdu(card, &apdu,trans_code_3k,sizeof(trans_code_3k),0,1); }break; case SC_CARD_TYPE_ENTERSAFE_FTCOS_PK_01C: case SC_CARD_TYPE_ENTERSAFE_EJAVA_PK_01C: case SC_CARD_TYPE_ENTERSAFE_EJAVA_PK_01C_T0: case SC_CARD_TYPE_ENTERSAFE_EJAVA_H10CR_PK_01C_T1: case SC_CARD_TYPE_ENTERSAFE_EJAVA_D11CR_PK_01C_T1: case SC_CARD_TYPE_ENTERSAFE_EJAVA_C21C_PK_01C_T1: case SC_CARD_TYPE_ENTERSAFE_EJAVA_A22CR_PK_01C_T1: case SC_CARD_TYPE_ENTERSAFE_EJAVA_A40CR_PK_01C_T1: { r = entersafe_transmit_apdu(card, &apdu,trans_code_ftcos_pk_01c,sizeof(trans_code_ftcos_pk_01c),0,1); }break; default: { r = SC_ERROR_INTERNAL; }break; } SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); }