sim: When decoding SW, take application specific SW into account

So far we only looked at SW definitions of the card profile. However,
if we have a currently selected application, we also must check
that application for SW definitions.

This breaks ABI and API all over the place, but as there are no
known users beyond osmo-sim-test, this is acceptable.

Change-Id: I3a1d60898529c173f73587e34c155660ba5f5fb1
This commit is contained in:
Harald Welte 2020-03-22 10:30:10 +01:00 committed by laforge
parent c9eab828ea
commit 3a6bedf1e5
4 changed files with 46 additions and 21 deletions

View File

@ -9,3 +9,4 @@
#library what description / commit summary line
gsm API/ABI change l1sap.h, added struct members to ph_data_param and ph_tch_param
sim API/ABI change new osim_file_desc_find_aid()
sim API/ABI change all over the place

View File

@ -309,6 +309,7 @@ osim_app_profile_find_by_name(const char *name);
const struct osim_card_app_profile *
osim_app_profile_find_by_aid(const uint8_t *aid, uint8_t aid_len);
const struct osim_card_sw *osim_app_profile_find_sw(const struct osim_card_app_profile *ap, uint16_t sw_in);
/*! A card profile (e.g. SIM card */
struct osim_card_profile {
@ -319,15 +320,13 @@ struct osim_card_profile {
const struct osim_card_sw **sws;
};
const struct osim_card_sw *osim_find_sw(const struct osim_card_profile *cp,
uint16_t sw);
enum osim_card_sw_class osim_sw_class(const struct osim_card_profile *cp,
uint16_t sw_in);
const struct osim_card_sw *osim_cprof_find_sw(const struct osim_card_profile *cp, uint16_t sw_in);
struct osim_card_hdl;
char *osim_print_sw_buf(char *buf, size_t buf_len, const struct osim_card_hdl *ch, uint16_t sw_in);
char *osim_print_sw(const struct osim_card_hdl *ch, uint16_t sw_in);
char *osim_print_sw_c(const void *ctx, const struct osim_card_hdl *ch, uint16_t sw_in);
struct osim_chan_hdl;
enum osim_card_sw_class osim_sw_class(const struct osim_chan_hdl *ch, uint16_t sw_in);
char *osim_print_sw_buf(char *buf, size_t buf_len, const struct osim_chan_hdl *ch, uint16_t sw_in);
char *osim_print_sw(const struct osim_chan_hdl *ch, uint16_t sw_in);
char *osim_print_sw_c(const void *ctx, const struct osim_chan_hdl *ch, uint16_t sw_in);
extern const struct tlv_definition ts102221_fcp_tlv_def;
extern const struct value_string ts102221_fcp_vals[14];

View File

@ -367,14 +367,19 @@ struct msgb *osim_new_apdumsg(uint8_t cla, uint8_t ins, uint8_t p1,
}
char *osim_print_sw_buf(char *buf, size_t buf_len, const struct osim_card_hdl *ch, uint16_t sw_in)
char *osim_print_sw_buf(char *buf, size_t buf_len, const struct osim_chan_hdl *ch, uint16_t sw_in)
{
const struct osim_card_sw *csw;
const struct osim_card_sw *csw = NULL;
if (!ch || !ch->prof)
if (!ch)
goto ret_def;
csw = osim_find_sw(ch->prof, sw_in);
if (ch->cur_app && ch->cur_app->prof)
csw = osim_app_profile_find_sw(ch->cur_app->prof, sw_in);
if (!csw && ch->card->prof)
csw = osim_cprof_find_sw(ch->card->prof, sw_in);
if (!csw)
goto ret_def;
@ -397,13 +402,13 @@ ret_def:
return buf;
}
char *osim_print_sw(const struct osim_card_hdl *ch, uint16_t sw_in)
char *osim_print_sw(const struct osim_chan_hdl *ch, uint16_t sw_in)
{
static __thread char sw_print_buf[256];
return osim_print_sw_buf(sw_print_buf, sizeof(sw_print_buf), ch, sw_in);
}
char *osim_print_sw_c(const void *ctx, const struct osim_card_hdl *ch, uint16_t sw_in)
char *osim_print_sw_c(const void *ctx, const struct osim_chan_hdl *ch, uint16_t sw_in)
{
char *buf = talloc_size(ctx, 256);
if (!buf)
@ -411,8 +416,8 @@ char *osim_print_sw_c(const void *ctx, const struct osim_card_hdl *ch, uint16_t
return osim_print_sw_buf(buf, 256, ch, sw_in);
}
const struct osim_card_sw *osim_find_sw(const struct osim_card_profile *cp,
uint16_t sw_in)
/*! Find status word within given card profile */
const struct osim_card_sw *osim_cprof_find_sw(const struct osim_card_profile *cp, uint16_t sw_in)
{
const struct osim_card_sw **sw_lists = cp->sws;
const struct osim_card_sw *sw_list, *sw;
@ -426,10 +431,30 @@ const struct osim_card_sw *osim_find_sw(const struct osim_card_profile *cp,
return NULL;
}
enum osim_card_sw_class osim_sw_class(const struct osim_card_profile *cp,
uint16_t sw_in)
/*! Find application-specific status word within given card application profile */
const struct osim_card_sw *osim_app_profile_find_sw(const struct osim_card_app_profile *ap, uint16_t sw_in)
{
const struct osim_card_sw *csw = osim_find_sw(cp, sw_in);
const struct osim_card_sw *sw_list = ap->sw, *sw;
for (sw = sw_list; sw->code != 0 && sw->mask != 0; sw++) {
if ((sw_in & sw->mask) == sw->code)
return sw;
}
return NULL;
}
enum osim_card_sw_class osim_sw_class(const struct osim_chan_hdl *ch, uint16_t sw_in)
{
const struct osim_card_sw *csw = NULL;
OSMO_ASSERT(ch);
OSMO_ASSERT(ch->card);
if (ch->cur_app && ch->cur_app->prof)
csw = osim_app_profile_find_sw(ch->cur_app->prof, sw_in);
if (!csw && ch->card->prof)
csw = osim_cprof_find_sw(ch->card->prof, sw_in);
if (!csw)
return SW_CLS_NONE;

View File

@ -411,7 +411,7 @@ static int dump_file(struct osim_chan_hdl *chan, const char *short_name, uint16_
fclose(f_data);
return -EIO;
}
printf("SW: %s\n", osim_print_sw(chan->card, msgb_apdu_sw(msg)));
printf("SW: %s\n", osim_print_sw(chan, msgb_apdu_sw(msg)));
hex = osmo_hexdump_nospc(msgb_apdu_de(rmsg), msgb_apdu_le(rmsg));
printf("Rec %03u: %s\n", i+1, hex);
@ -593,7 +593,7 @@ static void iterate_apps(struct osim_chan_hdl *chan)
osmo_hexdump_nospc(cah->aid, cah->aid_len));
continue;
}
printf("SW: %s\n", osim_print_sw(chan->card, msgb_apdu_sw(msg)));
printf("SW: %s\n", osim_print_sw(chan, msgb_apdu_sw(msg)));
chan->cur_app = cah;
chan->cwd = cap->adf;