static int iso7816_update_binary(sc_card_t *card, unsigned int idx, const u8 *buf, size_t count, unsigned long flags) { sc_apdu_t apdu; int r; assert(count <= card->max_send_size); if (idx > 0x7fff) { sc_error(card->ctx, "invalid EF offset: 0x%X > 0x7FFF", idx); return SC_ERROR_OFFSET_TOO_LARGE; } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD6, (idx >> 8) & 0x7F, idx & 0xFF); apdu.lc = count; apdu.datalen = count; apdu.data = buf; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); SC_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Card returned error"); SC_FUNC_RETURN(card->ctx, 3, count); }
static int gp_select_applet(sc_card_t *card, const u8 *aid, size_t aid_len) { int r; u8 buf[SC_MAX_APDU_BUFFER_SIZE]; struct sc_context *ctx = card->ctx; struct sc_apdu apdu; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xa4, 0x04, 0x00); apdu.lc = aid_len; apdu.data = aid; apdu.datalen = aid_len; apdu.resp = buf; apdu.le = 256; apdu.resplen = sizeof(buf); r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); return SC_SUCCESS; }
static int iso7816_update_record(sc_card_t *card, unsigned int rec_nr, const u8 *buf, size_t count, unsigned long flags) { sc_apdu_t apdu; int r; if (count > 256) { sc_error(card->ctx, "Trying to send too many bytes\n"); return SC_ERROR_INVALID_ARGUMENTS; } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDC, rec_nr, 0); apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3; if (flags & SC_RECORD_BY_REC_NR) apdu.p2 |= 0x04; apdu.lc = count; apdu.datalen = count; apdu.data = buf; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); SC_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Card returned error"); SC_FUNC_RETURN(card->ctx, 3, count); }
static int myeid_encode_private_key(sc_profile_t *profile, sc_card_t *card, struct sc_pkcs15_prkey_rsa *rsa, u8 *key, size_t *keysize, int key_ref) { SC_FUNC_CALLED(card->ctx, 1); SC_FUNC_RETURN(card->ctx, 1, 0); }
/* * Store a private key */ static int miocos_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *object, struct sc_pkcs15_prkey *key) { struct sc_context *ctx = p15card->card->ctx; struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data; struct sc_pkcs15_prkey_rsa *rsa; struct sc_file *file = NULL; int r; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (object->type != SC_PKCS15_TYPE_PRKEY_RSA || key->algorithm != SC_ALGORITHM_RSA) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); rsa = &key->u.rsa; if (rsa->modulus.len != 128) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "store key with ID:%s and path:%s\n", sc_pkcs15_print_id(&key_info->id), sc_print_path(&key_info->path)); r = sc_select_file(p15card->card, &key_info->path, &file); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot store key: select key file failed"); r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "No authorisation to store private key"); r = miocos_update_private_key(profile, p15card->card, rsa); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); }
/* * Select the PIN reference */ static int myeid_select_pin_reference(sc_profile_t *profile, sc_card_t *card, sc_pkcs15_pin_info_t *pin_info) { sc_pkcs15_pin_info_t pin_info_prof; int type; SC_FUNC_CALLED(card->ctx, 1); if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) { type = SC_PKCS15INIT_SO_PIN; sc_debug(card->ctx, "PIN_FLAG_SO_PIN, ref (%d), tries_left (%d)\n", pin_info->reference,pin_info->tries_left); } else { type = SC_PKCS15INIT_USER_PIN; sc_debug(card->ctx, "PIN_FLAG_PIN, ref (%d), tries_left (%d)\n", pin_info->reference, pin_info->tries_left); } if (pin_info->reference <= 0 || pin_info->reference > MYEID_MAX_PINS) pin_info->reference = 1; SC_FUNC_RETURN(card->ctx, 1, 0); }
static int entersafe_init(sc_card_t *card) { unsigned int flags; SC_FUNC_CALLED(card->ctx, 1); card->name = "entersafe"; card->cla = 0x00; /*card->drv_data = NULL;*/ flags =SC_ALGORITHM_ONBOARD_KEY_GEN | SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_NONE; _sc_card_add_rsa_alg(card, 512, flags, 0x10001); _sc_card_add_rsa_alg(card, 768, flags, 0x10001); _sc_card_add_rsa_alg(card,1024, flags, 0x10001); _sc_card_add_rsa_alg(card,2048, flags, 0x10001); /*card->caps = SC_CARD_CAP_RNG|SC_CARD_CAP_APDU_EXT; */ card->caps = SC_CARD_CAP_RNG; card->drv_data = 0; /* we need read_binary&friends with max 224 bytes per read */ if (card->max_send_size > 0xE0) card->max_send_size = 0xE0; if (card->max_recv_size > 0xE0) card->max_recv_size = 0xE0; SC_FUNC_RETURN(card->ctx,4,SC_SUCCESS); }
int card_sync_card_to_virtual_fs_data_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; size_t card_data_length = 0; sc_path_t *path=NULL; SC_FUNC_CALLED(card->ctx, 1); if(!card || !virtual_file) return SC_ERROR_INVALID_ARGUMENTS; 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_file(card, path, &card_data, &card_data_length); if (r!=SC_SUCCESS) goto end; if (card_data_length>0) { r = virtual_file_data_update(virtual_file, 0, card_data, card_data_length); if(r != SC_SUCCESS) goto end; } end: if(card_data) { free(card_data); card_data = NULL; } SC_FUNC_RETURN(card->ctx, 1, r); }
static int entersafe_init(sc_card_t *card) { unsigned int flags; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); card->name = "entersafe"; card->cla = 0x00; card->drv_data = NULL; flags =SC_ALGORITHM_ONBOARD_KEY_GEN | SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_NONE; _sc_card_add_rsa_alg(card, 512, flags, 0); _sc_card_add_rsa_alg(card, 768, flags, 0); _sc_card_add_rsa_alg(card,1024, flags, 0); _sc_card_add_rsa_alg(card,2048, flags, 0); card->caps = SC_CARD_CAP_RNG; /* we need read_binary&friends with max 224 bytes per read */ card->max_send_size = 224; card->max_recv_size = 224; SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS); }
/* * Select a PIN reference */ static int gpk_select_pin_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_auth_info_t *auth_info) { int preferred, current; SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE); if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) return SC_ERROR_OBJECT_NOT_VALID; if ((current = auth_info->attrs.pin.reference) < 0) current = 0; if (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) { preferred = GPK_PIN_SCOPE | 0; } else { preferred = current | GPK_PIN_SCOPE; if (preferred & 1) preferred++; if (preferred < (GPK_PIN_SCOPE | 2)) preferred = GPK_PIN_SCOPE | 2; if (preferred > 15) return SC_ERROR_TOO_MANY_OBJECTS; } if (current > preferred) return SC_ERROR_TOO_MANY_OBJECTS; auth_info->attrs.pin.reference = preferred; SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, 0); }
/* * Lock the pin file */ static int gpk_lock_pinfile(struct sc_profile *profile, sc_pkcs15_card_t *p15card, sc_file_t *pinfile) { struct sc_path path; struct sc_file *parent = NULL; int r; SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE); /* Select the parent DF */ path = pinfile->path; if (path.len >= 2) path.len -= 2; if (path.len == 0) sc_format_path("3F00", &path); if ((r = sc_select_file(p15card->card, &path, &parent)) < 0) return r; /* Present PINs etc as necessary */ r = sc_pkcs15init_authenticate(profile, p15card, parent, SC_AC_OP_LOCK); if (r >= 0) r = gpk_lock(p15card->card, pinfile, SC_AC_OP_WRITE); sc_file_free(parent); SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r); }
int file_uncompress_data(struct sc_card *card, u8 * data, size_t length, u8 **uncompressed_data, size_t *uncompressed_data_length ) { size_t compressed_data_length; int r = SC_SUCCESS, pos=0; SC_FUNC_CALLED(card->ctx, 1); /* zlib header; uncompressed length + compressed length: always will be 8 bytes */ pos = 8; *uncompressed_data_length = lebytes2ulong(data); compressed_data_length = lebytes2ulong(data+4); *uncompressed_data = (u8 *) calloc(*uncompressed_data_length, sizeof(u8)); if (!*uncompressed_data) return SC_ERROR_OUT_OF_MEMORY; if(compressed_data_length < *uncompressed_data_length) { r = uncompress(*uncompressed_data, (unsigned long *)uncompressed_data_length, data+pos, length-pos); if(r!=Z_OK) { free(*uncompressed_data); return r; } r = SC_SUCCESS; } else { memcpy(*uncompressed_data, data+pos, *uncompressed_data_length); r = SC_SUCCESS; } SC_FUNC_RETURN(card->ctx, 1, r); }
static int entersafe_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *obj, sc_pkcs15_prkey_t *key) { sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data; sc_card_t *card = p15card->card; sc_entersafe_wkey_data data; sc_file_t *tfile; const sc_acl_entry_t *acl_entry; int r; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (key->algorithm != SC_ALGORITHM_RSA) /* ignore DSA keys */ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INVALID_ARGUMENTS); r = sc_profile_get_file(profile, "PKCS15-AODF", &tfile); if (r < 0) return r; acl_entry = sc_file_get_acl_entry(tfile, SC_AC_OP_UPDATE); if (acl_entry->method != SC_AC_NONE) { r = sc_pkcs15init_authenticate(profile, p15card, tfile, SC_AC_OP_UPDATE); if(r<0) r = SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; } sc_file_free(tfile); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "cant verify pin"); data.key_id = (u8) kinfo->key_reference; data.usage=0x22; data.key_data.rsa=&key->u.rsa; return sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data); }
static int entersafe_select_fid(sc_card_t *card, unsigned int id_hi, unsigned int id_lo, sc_file_t **file_out) { int r; sc_file_t *file=0; sc_path_t path; path.type=SC_PATH_TYPE_FILE_ID; path.value[0]=id_hi; path.value[1]=id_lo; path.len=2; r = iso_ops->select_file(card,&path,&file); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); /* update cache */ if (file->type == SC_FILE_TYPE_DF) { card->cache.current_path.type = SC_PATH_TYPE_PATH; card->cache.current_path.value[0] = 0x3f; card->cache.current_path.value[1] = 0x00; if (id_hi == 0x3f && id_lo == 0x00){ card->cache.current_path.len = 2; }else{ card->cache.current_path.len = 4; card->cache.current_path.value[2] = id_hi; card->cache.current_path.value[3] = id_lo; } } if (file_out) *file_out = file; SC_FUNC_RETURN(card->ctx, 2, SC_SUCCESS); }
/* * Select the PIN reference */ static int myeid_select_pin_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_auth_info_t *auth_info) { SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE); if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) return SC_ERROR_OBJECT_NOT_VALID; if (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) { sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "PIN_FLAG_SO_PIN, ref (%d), tries_left (%d)", auth_info->attrs.pin.reference, auth_info->tries_left); } else { sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "PIN_FLAG_PIN, ref (%d), tries_left (%d)", auth_info->attrs.pin.reference, auth_info->tries_left); } if (auth_info->attrs.pin.reference <= 0 || auth_info->attrs.pin.reference > MYEID_MAX_PINS) auth_info->attrs.pin.reference = 1; SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, 0); }
static int ctapi_connect(sc_reader_t *reader) { struct ctapi_private_data *priv = GET_PRIV_DATA(reader); char rv; u8 cmd[9], rbuf[256], sad, dad; unsigned short lr; int r; cmd[0] = CTBCS_CLA; cmd[1] = CTBCS_INS_REQUEST; cmd[2] = CTBCS_P1_INTERFACE1; cmd[3] = CTBCS_P2_REQUEST_GET_ATR; cmd[4] = 0x00; dad = 1; sad = 2; lr = 256; rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, 5, cmd, &lr, rbuf); if (rv || rbuf[lr-2] != 0x90) { sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "Error activating card: %d\n", rv); return SC_ERROR_TRANSMIT_FAILED; } if (lr < 2) SC_FUNC_RETURN(reader->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); lr -= 2; if (lr > SC_MAX_ATR_SIZE) return SC_ERROR_INTERNAL; reader->atr.len = lr; memcpy(reader->atr.value, rbuf, lr); r = _sc_parse_atr(reader); return 0; }
/* * Erase the card. */ static int myeid_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p15card) { struct sc_context *ctx = p15card->card->ctx; struct sc_cardctl_myeid_data_obj data_obj; struct sc_file *mf = NULL; unsigned char data[8]; int r; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); r = myeid_get_init_applet_data(profile, p15card, data, sizeof(data)); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Get init applet date error"); /* Select parent DF and verify PINs/key as necessary */ r = sc_select_file(p15card->card, sc_get_mf_path(), &mf); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot select MF"); /* ACLs are not actives if file is not in the operational state */ if (mf->status == SC_FILE_STATUS_ACTIVATED) r = sc_pkcs15init_authenticate(profile, p15card, mf, SC_AC_OP_DELETE); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "'DELETE' authentication failed on MF"); data_obj.P1 = 0x01; data_obj.P2 = 0xE0; data_obj.Data = data; data_obj.DataLen = sizeof(data); r = sc_card_ctl(p15card->card, SC_CARDCTL_MYEID_PUTDATA, &data_obj); SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r); }
static int sc_oberthur_parse_tokeninfo (struct sc_pkcs15_card *p15card, unsigned char *buff, size_t len, int postpone_allowed) { struct sc_context *ctx = p15card->card->ctx; char label[0x21]; unsigned flags; int ii; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (!buff || len < 0x24) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "Cannot parse token info"); memset(label, 0, sizeof(label)); memcpy(label, buff, 0x20); ii = 0x20; while (*(label + --ii)==' ' && ii) ; *(label + ii + 1) = '\0'; flags = *(buff + 0x22) * 0x100 + *(buff + 0x23); p15card->tokeninfo->label = strdup(label); p15card->tokeninfo->manufacturer_id = strdup("Oberthur/OpenSC"); if (flags & 0x01) p15card->tokeninfo->flags |= SC_PKCS15_TOKEN_PRN_GENERATION; sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "label %s", p15card->tokeninfo->label); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "manufacturer_id %s", p15card->tokeninfo->manufacturer_id); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); }
/* * Create private key file */ static int miocos_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *object) { struct sc_context *ctx = p15card->card->ctx; struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data; struct sc_file *file; int r; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (object->type != SC_PKCS15_TYPE_PRKEY_RSA) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); if (key_info->modulus_length != 1024) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "create private key ID:%s\n", sc_pkcs15_print_id(&key_info->id)); r = miocos_new_file(profile, p15card->card, SC_PKCS15_TYPE_PRKEY_RSA, key_info->key_reference, &file); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot create key: failed to allocate new key object"); memcpy(&file->path, &key_info->path, sizeof(file->path)); file->id = file->path.value[file->path.len - 2] * 0x100 + file->path.value[file->path.len - 1]; sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Path of private key file to create %s\n", sc_print_path(&file->path)); r = sc_pkcs15init_create_file(profile, p15card, file); sc_file_free(file); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); }
/* * Store a private key */ static int myeid_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *object, struct sc_pkcs15_prkey *prkey) { struct sc_context *ctx = p15card->card->ctx; struct sc_card *card = p15card->card; struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data; struct sc_cardctl_myeid_gen_store_key_info args; struct sc_file *file = NULL; int r, keybits = key_info->modulus_length; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (object->type != SC_PKCS15_TYPE_PRKEY_RSA) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "Store key failed: RSA only supported"); /* Check that the card supports the requested modulus length */ if (sc_card_find_rsa_alg(p15card->card, keybits) == NULL) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "Unsupported key size"); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "store MyEID key with ID:%s and path:%s", sc_pkcs15_print_id(&key_info->id), sc_print_path(&key_info->path)); r = sc_select_file(card, &key_info->path, &file); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot store MyEID key: select key file failed"); r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "No authorisation to store MyEID private key"); if (file) sc_file_free(file); /* Fill in data structure */ memset(&args, 0, sizeof(args)); args.mod_len = keybits; args.op_type = OP_TYPE_STORE; args.pubexp_len = prkey->u.rsa.exponent.len; args.pubexp = prkey->u.rsa.exponent.data; args.primep_len = prkey->u.rsa.p.len; args.primep = prkey->u.rsa.p.data; args.primeq_len = prkey->u.rsa.q.len; args.primeq = prkey->u.rsa.q.data; args.dp1_len = prkey->u.rsa.dmp1.len; args.dp1 = prkey->u.rsa.dmp1.data; args.dq1_len = prkey->u.rsa.dmq1.len; args.dq1 = prkey->u.rsa.dmq1.data; args.invq_len = prkey->u.rsa.iqmp.len; args.invq = prkey->u.rsa.iqmp.data; args.mod_len = prkey->u.rsa.modulus.len; args.mod = prkey->u.rsa.modulus.data; /* Store RSA key */ r = sc_card_ctl(card, SC_CARDCTL_MYEID_GENERATE_STORE_KEY, &args); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Card control 'MYEID_GENERATE_STORE_KEY' failed"); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); }
/* * Create a new PIN */ static int myeid_create_pin(struct sc_profile *profile, struct sc_pkcs15_card *p15card, struct sc_file *df, struct sc_pkcs15_object *pin_obj, const unsigned char *pin, size_t pin_len, const unsigned char *puk, size_t puk_len) { struct sc_context *ctx = p15card->card->ctx; unsigned char data[20]; struct sc_cardctl_myeid_data_obj data_obj; struct sc_pkcs15_auth_info *auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data; struct sc_pkcs15_auth_info puk_ainfo; int r; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PIN('%s',ref:%i,flags:0x%X,pin_len:%d,puk_len:%d)\n", pin_obj->label, auth_info->attrs.pin.reference, auth_info->attrs.pin.flags, pin_len, puk_len); if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) return SC_ERROR_OBJECT_NOT_VALID; if (auth_info->attrs.pin.reference >= MYEID_MAX_PINS) return SC_ERROR_INVALID_ARGUMENTS; if (pin == NULL || puk == NULL || pin_len < 4 || puk_len < 4) return SC_ERROR_INVALID_PIN_LENGTH; sc_profile_get_pin_info(profile, (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) ? SC_PKCS15INIT_SO_PUK : SC_PKCS15INIT_USER_PUK, &puk_ainfo); memset(data, 0, sizeof(data)); /* Make command to add a pin-record */ data_obj.P1 = 0x01; data_obj.P2 = auth_info->attrs.pin.reference; /* myeid pin number */ memset(data, auth_info->attrs.pin.pad_char, 8); memcpy(&data[0], (u8 *)pin, pin_len); /* copy pin */ memset(&data[8], puk_ainfo.attrs.pin.pad_char, 8); memcpy(&data[8], (u8 *)puk, puk_len); /* copy puk */ if(auth_info->tries_left > 0 && auth_info->tries_left < 15) data[16] = auth_info->tries_left; else data[16] = 5; /* default value */ if(puk_ainfo.tries_left > 0 && puk_ainfo.tries_left < 15) data[17] = puk_ainfo.tries_left; else data[17] = 5; /* default value */ data[18] = 0x00; data_obj.Data = data; data_obj.DataLen = 19; r = sc_card_ctl(p15card->card, SC_CARDCTL_MYEID_PUTDATA, &data_obj); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Initialize PIN failed"); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); }
int sc_pkcs15_get_card_objects_cond(struct sc_pkcs15_card *p15card, unsigned int type, int (* func)(struct sc_pkcs15_object *, void *), void *func_arg, struct sc_pkcs15_object **ret, size_t ret_size) { SC_FUNC_RETURN (p15card->card->ctx, 1, __sc_pkcs15_search_card_objects(p15card, 0, type, func, func_arg, ret, ret_size)); }
/* * 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_delete_file(sc_card_t *card, const sc_path_t *path) { int r; char pbuf[SC_MAX_PATH_STRING_SIZE]; assert(card != NULL); r = sc_path_print(pbuf, sizeof(pbuf), path); if (r != SC_SUCCESS) pbuf[0] = '\0'; sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "called; type=%d, path=%s", path->type, pbuf); if (card->ops->delete_file == NULL) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); r = card->ops->delete_file(card, path); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); }
static int myeid_encode_public_key(sc_profile_t *profile, sc_card_t *card, struct sc_pkcs15_prkey_rsa *rsa, u8 *key, size_t *keysize, int key_ref) { SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, 0); }
int sc_pkcs15_decode_cdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj, const u8 ** buf, size_t *buflen) { sc_context_t *ctx = p15card->card->ctx; struct sc_pkcs15_cert_info info; struct sc_asn1_entry asn1_cred_ident[3], asn1_com_cert_attr[4], asn1_x509_cert_attr[2], asn1_type_cert_attr[2], asn1_cert[2], asn1_x509_cert_value_choice[3]; struct sc_asn1_pkcs15_object cert_obj = { obj, asn1_com_cert_attr, NULL, asn1_type_cert_attr }; sc_pkcs15_der_t *der = &info.value; u8 id_value[128]; int id_type; size_t id_value_len = sizeof(id_value); int r; sc_copy_asn1_entry(c_asn1_cred_ident, asn1_cred_ident); sc_copy_asn1_entry(c_asn1_com_cert_attr, asn1_com_cert_attr); sc_copy_asn1_entry(c_asn1_x509_cert_attr, asn1_x509_cert_attr); sc_copy_asn1_entry(c_asn1_x509_cert_value_choice, asn1_x509_cert_value_choice); sc_copy_asn1_entry(c_asn1_type_cert_attr, asn1_type_cert_attr); sc_copy_asn1_entry(c_asn1_cert, asn1_cert); sc_format_asn1_entry(asn1_cred_ident + 0, &id_type, NULL, 0); sc_format_asn1_entry(asn1_cred_ident + 1, &id_value, &id_value_len, 0); sc_format_asn1_entry(asn1_com_cert_attr + 0, &info.id, NULL, 0); sc_format_asn1_entry(asn1_com_cert_attr + 1, &info.authority, NULL, 0); sc_format_asn1_entry(asn1_com_cert_attr + 2, asn1_cred_ident, NULL, 0); sc_format_asn1_entry(asn1_x509_cert_attr + 0, asn1_x509_cert_value_choice, NULL, 0); sc_format_asn1_entry(asn1_x509_cert_value_choice + 0, &info.path, NULL, 0); sc_format_asn1_entry(asn1_x509_cert_value_choice + 1, &der->value, &der->len, 0); sc_format_asn1_entry(asn1_type_cert_attr + 0, asn1_x509_cert_attr, NULL, 0); sc_format_asn1_entry(asn1_cert + 0, &cert_obj, NULL, 0); /* Fill in defaults */ memset(&info, 0, sizeof(info)); info.authority = 0; r = sc_asn1_decode(ctx, asn1_cert, *buf, *buflen, buf, buflen); /* In case of error, trash the cert value (direct coding) */ if (r < 0 && der->value) free(der->value); if (r == SC_ERROR_ASN1_END_OF_CONTENTS) return r; SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 decoding failed"); r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path); if (r < 0) return r; obj->type = SC_PKCS15_TYPE_CERT_X509; obj->data = malloc(sizeof(info)); if (obj->data == NULL) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); memcpy(obj->data, &info, sizeof(info)); return 0; }
/* * Create a new PIN */ static int myeid_create_pin_internal(sc_profile_t *profile, sc_card_t *card, int ignore_ac, sc_pkcs15_pin_info_t *pin_info, const u8 *pin, size_t pin_len, const u8 *puk, size_t puk_len) { u8 data[20]; int so_pin_ref; int r,type, puk_tries; struct sc_cardctl_myeid_data_obj data_obj; sc_file_t *pinfile = NULL; SC_FUNC_CALLED(card->ctx, 1); sc_debug(card->ctx, "pin (%d), pin_len (%d), puk_len(%d) \n", pin_info->reference, pin_len, puk_len); if (pin_info->reference >= MYEID_MAX_PINS) return SC_ERROR_INVALID_ARGUMENTS; if (pin == NULL || puk == NULL || pin_len < 4 || puk_len < 4) return SC_ERROR_INVALID_PIN_LENGTH; if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) type = SC_PKCS15INIT_SO_PIN; else type = SC_PKCS15INIT_USER_PIN; sc_debug(card->ctx, "pin type (%s)\n", (type == SC_PKCS15INIT_SO_PIN) ? "SO_PIN": "USER_PIN"); memset(data, 0xFF, sizeof(data)); /* Make command to add a pin-record */ data_obj.P1 = 01; data_obj.P2 = pin_info->reference; /* myeid pin number */ memcpy(&data[0], (u8 *)pin, pin_len); /* copy pin*/ memcpy(&data[8], (u8 *)puk, puk_len); /* copy puk */ data[16] = 0x00; data[17] = 0x00; data[18] = 0x00; data_obj.Data = data; data_obj.DataLen = 16; puk_tries = myeid_puk_retries(profile, pin_info); if(pin_info->tries_left > 0 && pin_info->tries_left < 15 && puk_tries > 0 && puk_tries < 15) { /* Optional PIN locking */ data[16] = (pin_info->tries_left & 0x0F); data[17] = (puk_tries & 0x0F); data_obj.DataLen = 19; } r = sc_card_ctl(card, SC_CARDCTL_MYEID_PUTDATA, &data_obj); SC_FUNC_RETURN(card->ctx, 1, r); }
static int starcos_select_aid(sc_card_t *card, u8 aid[16], size_t len, sc_file_t **file_out) { sc_apdu_t apdu; int r; size_t i = 0; sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x04, 0x0C); apdu.lc = len; apdu.data = (u8*)aid; apdu.datalen = len; apdu.resplen = 0; apdu.le = 0; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); /* check return value */ if (!(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) && apdu.sw1 != 0x61 ) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); /* update cache */ card->cache.current_path.type = SC_PATH_TYPE_DF_NAME; card->cache.current_path.len = len; memcpy(card->cache.current_path.value, aid, len); if (file_out) { sc_file_t *file = sc_file_new(); if (!file) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); file->type = SC_FILE_TYPE_DF; file->ef_structure = SC_FILE_EF_UNKNOWN; file->path.len = 0; file->size = 0; /* AID */ for (i = 0; i < len; i++) file->name[i] = aid[i]; file->namelen = len; file->id = 0x0000; file->magic = SC_FILE_MAGIC; *file_out = file; } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); }
static int entersafe_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df, sc_pkcs15_object_t *pin_obj, const unsigned char *pin, size_t pin_len, const unsigned char *puk, size_t puk_len) { struct sc_card *card = p15card->card; int r; sc_pkcs15_auth_info_t *auth_info = (sc_pkcs15_auth_info_t *) pin_obj->data; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) return SC_ERROR_OBJECT_NOT_VALID; {/*pin*/ sc_entersafe_wkey_data data; if (!pin || !pin_len || pin_len > 16) return SC_ERROR_INVALID_ARGUMENTS; data.key_id = auth_info->attrs.pin.reference; data.usage=0x0B; data.key_data.symmetric.EC=0x33; data.key_data.symmetric.ver=0x00; /* pad pin with 0 */ memset(data.key_data.symmetric.key_val, 0, sizeof(data.key_data.symmetric.key_val)); memcpy(data.key_data.symmetric.key_val, pin, pin_len); data.key_data.symmetric.key_len=16; r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data); /* Cache new PIN value. */ sc_pkcs15_pincache_add(p15card, pin_obj, pin, pin_len); } {/*puk*/ sc_entersafe_wkey_data data; if (!puk || !puk_len || puk_len > 16) return SC_ERROR_INVALID_ARGUMENTS; data.key_id = auth_info->attrs.pin.reference+1; data.usage=0x0B; data.key_data.symmetric.EC=0x33; data.key_data.symmetric.ver=0x00; /* pad pin with 0 */ memset(data.key_data.symmetric.key_val, 0, sizeof(data.key_data.symmetric.key_val)); memcpy(data.key_data.symmetric.key_val, puk, puk_len); data.key_data.symmetric.key_len=16; r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r); }
static int entersafe_select_aid(sc_card_t *card, const sc_path_t *in_path, sc_file_t **file_out) { int r = 0; if (card->cache.valid && card->cache.current_path.type == SC_PATH_TYPE_DF_NAME && card->cache.current_path.len == in_path->len && memcmp(card->cache.current_path.value, in_path->value, in_path->len)==0 ) { if(file_out) { *file_out = sc_file_new(); if(!file_out) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); } } else { r = iso_ops->select_file(card,in_path,file_out); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); /* update cache */ card->cache.current_path.type = SC_PATH_TYPE_DF_NAME; card->cache.current_path.len = in_path->len; memcpy(card->cache.current_path.value,in_path->value,in_path->len); } if (file_out) { sc_file_t *file = *file_out; assert(file); file->type = SC_FILE_TYPE_DF; file->ef_structure = SC_FILE_EF_UNKNOWN; file->path.len = 0; file->size = 0; /* AID */ memcpy(file->name,in_path->value,in_path->len); file->namelen = in_path->len; file->id = 0x0000; } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); }