Change in libosmocore[master]: sim: re-structure how we support cards + applications

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Sat Mar 21 13:17:12 UTC 2020


laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/17555 )


Change subject: sim: re-structure how we support cards + applications
......................................................................

sim: re-structure how we support cards + applications

Before this change, a card application (USIM, ISIM, ...) didn't
exist as a separate concept from a card profile.  This meant,
we had a manual combination of UICC card profile with USIM application,
and another one of UICC card profile and ISIM application.  But what
if there's a combined USIM+ISIM?

In reality, applications exist as separate objects, on top of an
ETSI UICC.  Lets therefore register all known applications to the
osim library core, and add code to osmo-sim-test which dynamically
detects all applications present on a given card (by reading EF.DIR).

Change-Id: Ic4b4ac433a9976842b30a017fb0fc347d87201cd
---
M include/osmocom/sim/sim.h
M src/sim/card_fs_isim.c
M src/sim/card_fs_uicc.c
M src/sim/card_fs_usim.c
M src/sim/core.c
M src/sim/reader_pcsc.c
M src/sim/sim_int.h
M utils/osmo-sim-test.c
8 files changed, 321 insertions(+), 122 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/55/17555/1

diff --git a/include/osmocom/sim/sim.h b/include/osmocom/sim/sim.h
index 5440d85..33ebdd7 100644
--- a/include/osmocom/sim/sim.h
+++ b/include/osmocom/sim/sim.h
@@ -9,6 +9,7 @@
 #include <osmocom/core/linuxlist.h>
 
 #define APDU_HDR_LEN	5
+#define MAX_AID_LEN	16 /* Table 13.2 of TS 102 221 */
 
 /*! command-response pairs cases
  *
@@ -66,6 +67,8 @@
 #define msgb_apdu_dc(__x)	((__x)->l2h + sizeof(struct osim_apdu_cmd_hdr))
 #define msgb_apdu_de(__x)	((__x)->l2h + sizeof(struct osim_apdu_cmd_hdr) + msgb_apdu_lc(__x))
 
+int osim_init(void *ctx);
+
 /* FILES */
 
 struct osim_file;
@@ -285,6 +288,28 @@
 	.class = SW_CLS_NONE, .u.str = NULL		\
 }
 
+/*! A card application (e.g. USIM, ISIM, HPSIM) */
+struct osim_card_app_profile {
+	/*! entry in the global list of card application profiles */
+	struct llist_head list;
+	/*! human-readable name */
+	const char *name;
+	/*! AID of this application, as used in EF.DIR */
+	uint8_t aid[MAX_AID_LEN];
+	uint8_t aid_len;
+	/*! file system description */
+	struct osim_file_desc *adf;
+	/*! Status words defined by application */
+	const struct osim_card_sw *sw;
+};
+
+const struct osim_card_app_profile *
+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);
+
+
 /*! A card profile (e.g. SIM card */
 struct osim_card_profile {
 	const char *name;
@@ -357,6 +382,19 @@
 	struct osim_card_hdl *card;
 };
 
+/*! descriptor for a given application present on a card */
+struct osim_card_app_hdl {
+	/*! member in card list of applications */
+	struct llist_head list;
+	/*! AID of the application */
+	uint8_t aid[MAX_AID_LEN];
+	uint8_t aid_len;
+	/*! application label from EF_DIR */
+	char *label;
+	/*! application profile (if any known) */
+	const struct osim_card_app_profile *prof;
+};
+
 struct osim_card_hdl {
 	/*! member in global list of cards */
 	struct llist_head list;
@@ -369,6 +407,9 @@
 
 	/*! list of channels for this card */
 	struct llist_head channels;
+
+	/*! list of applications found on card */
+	struct llist_head apps;
 };
 
 struct osim_chan_hdl {
@@ -376,9 +417,15 @@
 	struct llist_head list;
 	/*! card to which this channel belongs */
 	struct osim_card_hdl *card;
+	/*! current working directory */
 	const struct osim_file_desc *cwd;
+	/*! currently selected application (if any) */
+	struct osim_card_app_hdl *cur_app;
 };
 
+int osim_card_hdl_add_app(struct osim_card_hdl *ch, const uint8_t *aid, uint8_t aid_len,
+			  const char *label);
+
 /* reader.c */
 int osim_transceive_apdu(struct osim_chan_hdl *st, struct msgb *amsg);
 struct osim_reader_hdl *osim_reader_open(enum osim_reader_driver drv, int idx,
diff --git a/src/sim/card_fs_isim.c b/src/sim/card_fs_isim.c
index e6ba0d0..2970c45 100644
--- a/src/sim/card_fs_isim.c
+++ b/src/sim/card_fs_isim.c
@@ -43,12 +43,6 @@
 	OSIM_CARD_SW_LAST
 };
 
-static const struct osim_card_sw *isim_card_sws[] = {
-	ts31_103_sw,
-	ts102221_uicc_sw,
-	NULL
-};
-
 /* TS 31.103 Version 11.2.0 Release 11 / Chapoter 4.2 */
 static const struct osim_file_desc isim_ef_in_adf_isim[] = {
 	EF_TRANSP_N(0x6F02, 0x02, "EF.IMPI", 0, 1, 256,
@@ -86,23 +80,21 @@
 /* Annex E - TS 101 220 */
 static const uint8_t adf_isim_aid[] = { 0xA0, 0x00, 0x00, 0x00, 0x87, 0x10, 0x04 };
 
-struct osim_card_profile *osim_cprof_isim(void *ctx)
+struct osim_card_app_profile *osim_aprof_isim(void *ctx)
 {
-	struct osim_card_profile *cprof;
-	struct osim_file_desc *mf;
+	struct osim_card_app_profile *aprof;
+	struct osim_file_desc *iadf;
 
-	cprof = talloc_zero(ctx, struct osim_card_profile);
-	cprof->name = "3GPP ISIM";
-	cprof->sws = isim_card_sws;
-
-	mf = alloc_df(cprof, 0x3f00, "MF");
-
-	cprof->mf = mf;
+	aprof = talloc_zero(ctx, struct osim_card_app_profile);
+	aprof->name = "3GPP ISIM";
+	aprof->sw = ts31_103_sw;
+	aprof->aid_len = sizeof(adf_isim_aid);
+	memcpy(aprof->aid, adf_isim_aid, aprof->aid_len);
 
 	/* ADF.USIM with its EF siblings */
-	add_adf_with_ef(mf, adf_isim_aid, sizeof(adf_isim_aid),
-			"ADF.ISIM", isim_ef_in_adf_isim,
-			ARRAY_SIZE(isim_ef_in_adf_isim));
+	iadf = alloc_adf_with_ef(aprof, adf_isim_aid, sizeof(adf_isim_aid), "ADF.ISIM",
+				 isim_ef_in_adf_isim, ARRAY_SIZE(isim_ef_in_adf_isim));
+	aprof->adf = iadf;
 
-	return cprof;
+	return aprof;
 }
diff --git a/src/sim/card_fs_uicc.c b/src/sim/card_fs_uicc.c
index af6061c..c73fc9a 100644
--- a/src/sim/card_fs_uicc.c
+++ b/src/sim/card_fs_uicc.c
@@ -1,7 +1,7 @@
 /*! \file card_fs_uicc.c
  * ETSI UICC specific structures / routines. */
 /*
- * (C) 2012 by Harald Welte <laforge at gnumonks.org>
+ * (C) 2012-2020 by Harald Welte <laforge at gnumonks.org>
  *
  * All Rights Reserved
  *
@@ -25,8 +25,12 @@
 
 
 #include <osmocom/sim/sim.h>
+#include <osmocom/core/talloc.h>
 #include <osmocom/gsm/tlv.h>
 
+#include "sim_int.h"
+#include "gsm_int.h"
+
 /* TS 102 221 V10.0.0 / 10.2.1 */
 const struct osim_card_sw ts102221_uicc_sw[] = {
 	{
@@ -171,6 +175,23 @@
 	OSIM_CARD_SW_LAST
 };
 
+static const struct osim_card_sw *uicc_card_sws[] = {
+	ts102221_uicc_sw,
+	NULL
+};
+
+/* TS 102 221 Chapter 13.1 */
+static const struct osim_file_desc uicc_ef_in_mf[] = {
+	EF_LIN_FIX_N(0x2f00, SFI_NONE, "EF.DIR", 0, 1, 32,
+			"Application directory"),
+	EF_TRANSP_N(0x2FE2, SFI_NONE, "EF.ICCID", 0, 10, 10,
+			"ICC Identification"),
+	EF_TRANSP_N(0x2F05, SFI_NONE, "EF.PL", 0, 2, 20,
+			"Preferred Languages"),
+	EF_LIN_FIX_N(0x2F06, SFI_NONE, "EF.ARR", F_OPTIONAL, 1, 256,
+			"Access Rule Reference"),
+};
+
 const struct value_string ts102221_fcp_vals[14] = {
 	{ UICC_FCP_T_FCP,		"File control parameters" },
 	{ UICC_FCP_T_FILE_SIZE,		"File size" },
@@ -209,3 +230,30 @@
 
 /* Annex E - TS 101 220 */
 static const uint8_t __attribute__((__unused__)) adf_uicc_aid[] = { 0xA0, 0x00, 0x00, 0x00, 0x87, 0x10, 0x01 };
+
+struct osim_card_profile *osim_cprof_uicc(void *ctx)
+{
+	struct osim_card_profile *cprof;
+	struct osim_file_desc *mf;
+	int rc;
+
+	cprof = talloc_zero(ctx, struct osim_card_profile);
+	cprof->name = "3GPP UICC";
+	cprof->sws = uicc_card_sws; // FIXME: extend later
+
+	mf = alloc_df(cprof, 0x3f00, "MF");
+
+	cprof->mf = mf;
+
+	/* Core UICC Files */
+	add_filedesc(mf, uicc_ef_in_mf, ARRAY_SIZE(uicc_ef_in_mf));
+
+	/* DF.TELECOM hierarchy as sub-directory of MF */
+	rc = osim_int_cprof_add_telecom(mf);
+	if (rc != 0) {
+		talloc_free(cprof);
+		return NULL;
+	}
+
+	return cprof;
+}
diff --git a/src/sim/card_fs_usim.c b/src/sim/card_fs_usim.c
index 3b33c0f..97f712a 100644
--- a/src/sim/card_fs_usim.c
+++ b/src/sim/card_fs_usim.c
@@ -1,7 +1,7 @@
 /*! \file card_fs_usim.c
  * 3GPP USIM specific structures / routines. */
 /*
- * (C) 2012-2014 by Harald Welte <laforge at gnumonks.org>
+ * (C) 2012-2020 by Harald Welte <laforge at gnumonks.org>
  *
  * All Rights Reserved
  *
@@ -47,24 +47,6 @@
 	OSIM_CARD_SW_LAST
 };
 
-static const struct osim_card_sw *usim_card_sws[] = {
-	ts31_102_sw,
-	ts102221_uicc_sw,
-	NULL
-};
-
-/* TS 102 221 Chapter 13.1 */
-static const struct osim_file_desc uicc_ef_in_mf[] = {
-	EF_LIN_FIX_N(0x2f00, SFI_NONE, "EF.DIR", 0, 1, 32,
-			"Application directory"),
-	EF_TRANSP_N(0x2FE2, SFI_NONE, "EF.ICCID", 0, 10, 10,
-			"ICC Identification"),
-	EF_TRANSP_N(0x2F05, SFI_NONE, "EF.PL", 0, 2, 20,
-			"Preferred Languages"),
-	EF_LIN_FIX_N(0x2F06, SFI_NONE, "EF.ARR", F_OPTIONAL, 1, 256,
-			"Access Rule Reference"),
-};
-
 /* 31.102 Chapter 4.4.3 */
 static const struct osim_file_desc usim_ef_in_df_gsm_access[] = {
 	EF_TRANSP_N(0x4f20, 0x01, "EF.Kc", 0, 9, 9,
@@ -330,27 +312,21 @@
 /* Annex E - TS 101 220 */
 static const uint8_t adf_usim_aid[] = { 0xA0, 0x00, 0x00, 0x00, 0x87, 0x10, 0x02 };
 
-struct osim_card_profile *osim_cprof_usim(void *ctx)
+struct osim_card_app_profile *osim_aprof_usim(void *ctx)
 {
-	struct osim_card_profile *cprof;
-	struct osim_file_desc *mf, *uadf;
-	int rc;
+	struct osim_card_app_profile *aprof;
+	struct osim_file_desc *uadf;
 
-	cprof = talloc_zero(ctx, struct osim_card_profile);
-	cprof->name = "3GPP USIM";
-	cprof->sws = usim_card_sws;
-
-	mf = alloc_df(cprof, 0x3f00, "MF");
-
-	cprof->mf = mf;
-
-	/* Core UICC Files */
-	add_filedesc(mf, uicc_ef_in_mf, ARRAY_SIZE(uicc_ef_in_mf));
+	aprof = talloc_zero(ctx, struct osim_card_app_profile);
+	aprof->name = "3GPP USIM";
+	aprof->sw = ts31_102_sw;
+	aprof->aid_len = sizeof(adf_usim_aid);
+	memcpy(aprof->aid, adf_usim_aid, aprof->aid_len);
 
 	/* ADF.USIM with its EF siblings */
-	uadf = add_adf_with_ef(mf, adf_usim_aid, sizeof(adf_usim_aid),
-				"ADF.USIM", usim_ef_in_adf_usim,
-				ARRAY_SIZE(usim_ef_in_adf_usim));
+	uadf = alloc_adf_with_ef(aprof, adf_usim_aid, sizeof(adf_usim_aid),
+				 "ADF.USIM", usim_ef_in_adf_usim, ARRAY_SIZE(usim_ef_in_adf_usim));
+	aprof->adf = uadf;
 
 	/* DFs under ADF.USIM */
 	add_df_with_ef(uadf, 0x5F3A, "DF.PHONEBOOK", NULL, 0);
@@ -369,13 +345,14 @@
 	/* OMA BCAST Smart Card Profile */
 	add_df_with_ef(uadf, 0x5F80, "DF.BCAST", NULL, 0);
 
-	/* DF.GSM and DF.TELECOM hierarchy as sub-directory of MF */
+#if 0
+	/* DF.GSM as sub-directory of MF */
 	rc = osim_int_cprof_add_gsm(mf);
-	rc |= osim_int_cprof_add_telecom(mf);
 	if (rc != 0) {
 		talloc_free(cprof);
 		return NULL;
 	}
+#endif
 
-	return cprof;
+	return aprof;
 }
diff --git a/src/sim/core.c b/src/sim/core.c
index 4360ff1..80a168f 100644
--- a/src/sim/core.c
+++ b/src/sim/core.c
@@ -1,7 +1,7 @@
 /*! \file core.c
  * Core routines for SIM/UICC/USIM access. */
 /*
- * (C) 2012 by Harald Welte <laforge at gnumonks.org>
+ * (C) 2012-2020 by Harald Welte <laforge at gnumonks.org>
  *
  * All Rights Reserved
  *
@@ -27,10 +27,13 @@
 #include <stdlib.h>
 #include <stdint.h>
 #include <string.h>
+#include <errno.h>
 
 #include <osmocom/core/talloc.h>
 #include <osmocom/sim/sim.h>
 
+#include "sim_int.h"
+
 struct osim_decoded_data *osim_file_decode(struct osim_file *file,
 					   int len, uint8_t *data)
 {
@@ -154,21 +157,19 @@
 }
 
 struct osim_file_desc *
-add_adf_with_ef(struct osim_file_desc *parent,
+alloc_adf_with_ef(void *ctx,
 		const uint8_t *adf_name, uint8_t adf_name_len,
 		const char *name, const struct osim_file_desc *in,
 		int num)
 {
 	struct osim_file_desc *df;
 
-	df = alloc_df(parent, 0xffff, name);
+	df = alloc_df(ctx, 0xffff, name);
 	if (!df)
 		return NULL;
 	df->type = TYPE_ADF;
 	df->df_name = adf_name;
 	df->df_name_len = adf_name_len;
-	df->parent = parent;
-	llist_add_tail(&df->list, &parent->child_list);
 	add_filedesc(df, in, num);
 
 	return df;
@@ -229,6 +230,88 @@
 }
 
 
+/***********************************************************************
+ * Application Profiles + Applications
+ ***********************************************************************/
+
+static LLIST_HEAD(g_app_profiles);
+
+/*! Register an application profile. Typically called at early start-up. */
+void osim_app_profile_register(struct osim_card_app_profile *aprof)
+{
+	OSMO_ASSERT(!osim_app_profile_find_by_name(aprof->name));
+	OSMO_ASSERT(!osim_app_profile_find_by_aid(aprof->aid, aprof->aid_len));
+	llist_add_tail(&aprof->list, &g_app_profiles);
+}
+
+/*! Find any registered application profile based on its name (e.g. "ADF.USIM") */
+const struct osim_card_app_profile *
+osim_app_profile_find_by_name(const char *name)
+{
+	struct osim_card_app_profile *ap;
+
+	llist_for_each_entry(ap, &g_app_profiles, list) {
+		if (!strcmp(name, ap->name))
+			return ap;
+	}
+	return NULL;
+}
+
+/*! Find any registered application profile based on its AID */
+const struct osim_card_app_profile *
+osim_app_profile_find_by_aid(const uint8_t *aid, uint8_t aid_len)
+{
+	struct osim_card_app_profile *ap;
+
+	llist_for_each_entry(ap, &g_app_profiles, list) {
+		if (ap->aid_len > aid_len)
+			continue;
+		if (!memcmp(ap->aid, aid, ap->aid_len))
+			return ap;
+	}
+	return NULL;
+}
+
+struct osim_card_app_hdl *
+osim_card_hdl_find_app(struct osim_card_hdl *ch, const uint8_t *aid, uint8_t aid_len)
+{
+	struct osim_card_app_hdl *ah;
+
+	if (aid_len > MAX_AID_LEN)
+		return NULL;
+
+	llist_for_each_entry(ah, &ch->apps, list) {
+		if (!memcmp(ah->aid, aid, aid_len))
+			return ah;
+	}
+	return NULL;
+}
+
+/*! Add an application to a given card */
+int osim_card_hdl_add_app(struct osim_card_hdl *ch, const uint8_t *aid, uint8_t aid_len,
+			  const char *label)
+{
+	struct osim_card_app_hdl *ah;
+
+	if (aid_len > MAX_AID_LEN)
+		return -EINVAL;
+
+	if (osim_card_hdl_find_app(ch, aid, aid_len))
+		return -EEXIST;
+
+	ah = talloc_zero(ch, struct osim_card_app_hdl);
+	if (!ah)
+		return -ENOMEM;
+
+	memcpy(ah->aid, aid, aid_len);
+	ah->aid_len = aid_len;
+	ah->prof = osim_app_profile_find_by_aid(ah->aid, ah->aid_len);
+	if (label)
+		ah->label = talloc_strdup(ah, label);
+	llist_add_tail(&ah->list, &ch->apps);
+	return 0;
+}
+
 /*! Generate an APDU message and initialize APDU command header
  *  \param[in] cla CLASS byte
  *  \param[in] ins INSTRUCTION byte
@@ -365,3 +448,11 @@
 
 	return 0;
 }
+
+int osim_init(void *ctx)
+{
+	osim_app_profile_register(osim_aprof_usim(ctx));
+	osim_app_profile_register(osim_aprof_isim(ctx));
+
+	return 0;
+}
diff --git a/src/sim/reader_pcsc.c b/src/sim/reader_pcsc.c
index 04a8622..c37380a 100644
--- a/src/sim/reader_pcsc.c
+++ b/src/sim/reader_pcsc.c
@@ -121,6 +121,7 @@
 
 	card = talloc_zero(rh, struct osim_card_hdl);
 	INIT_LLIST_HEAD(&card->channels);
+	INIT_LLIST_HEAD(&card->apps);
 	card->reader = rh;
 	rh->card = card;
 
diff --git a/src/sim/sim_int.h b/src/sim/sim_int.h
index 885011e..99a2242 100644
--- a/src/sim/sim_int.h
+++ b/src/sim/sim_int.h
@@ -12,8 +12,6 @@
 element_alloc_sub(struct osim_decoded_element *ee, const char *name,
 	      enum osim_element_type type, enum osim_element_repr repr);
 
-extern const struct osim_card_sw ts102221_uicc_sw[0];
-
 int default_decode(struct osim_decoded_data *dd,
 		   const struct osim_file_desc *desc,
 		   int len, uint8_t *data);
@@ -26,11 +24,14 @@
 		const struct osim_file_desc *in, int num);
 
 struct osim_file_desc *
-add_adf_with_ef(struct osim_file_desc *parent,
-		const uint8_t *adf_name, uint8_t adf_name_len,
-		const char *name, const struct osim_file_desc *in,
-		int num);
+alloc_adf_with_ef(void *ctx, const uint8_t *adf_name, uint8_t adf_name_len,
+		  const char *name, const struct osim_file_desc *in, int num);
 
 extern const struct osim_reader_ops pcsc_reader_ops;
 
+void osim_app_profile_register(struct osim_card_app_profile *aprof);
+
+struct osim_card_app_profile *osim_aprof_usim(void *ctx);
+struct osim_card_app_profile *osim_aprof_isim(void *ctx);
+
 #endif
diff --git a/utils/osmo-sim-test.c b/utils/osmo-sim-test.c
index a6ecfcf..78d6665 100644
--- a/utils/osmo-sim-test.c
+++ b/utils/osmo-sim-test.c
@@ -241,49 +241,59 @@
 	return 0;
 }
 
-extern struct osim_card_profile *osim_cprof_sim(void *ctx);
-extern struct osim_card_profile *osim_cprof_usim(void *ctx);
-extern struct osim_card_profile *osim_cprof_isim(void *ctx);
-
-static struct msgb *try_select_adf_usim(struct osim_chan_hdl *st)
+/*! scan an UICC for all installed apps; allocate osim_card_app_hdl for each of them */
+static int osim_uicc_scan_apps(struct osim_chan_hdl *st)
 {
 	struct tlv_parsed tp;
 	struct osim_fcp_fd_decoded ofd;
-	struct msgb *msg, *msg2;
+	struct msgb *msg;
 	uint8_t *cur;
 	int rc, i;
 
+	/* we don't know where we currently might be; go back to MF */
+	msg = select_file(st, 0x3f00);
+	if (!msg)
+		return -EIO;
+	if (msgb_apdu_sw(msg) != 0x9000)
+		return -msgb_apdu_sw(msg);
+
+	/* select EF.DIR */
 	msg = select_file(st, 0x2f00);
 	if (!msg)
-		return NULL;
+		return -EIO;
 	/* return status word in case of error */
 	if (msgb_apdu_sw(msg) != 0x9000)
-		return msg;
+		return -msgb_apdu_sw(msg);
 
+	/* various FCP related sanity checks */
 	rc = tlv_parse(&tp, &ts102221_fcp_tlv_def, msgb_apdu_de(msg)+2, msgb_apdu_le(msg)-2, 0, 0);
 	if (rc < 0) {
+		fprintf(stderr, "Error decoding EF.DIR FCP TLV\n");
 		msgb_free(msg);
-		return NULL;
+		return -EINVAL;
 	}
 
 	dump_fcp_template(&tp);
 
 	if (!TLVP_PRESENT(&tp, UICC_FCP_T_FILE_DESC) ||
 	    TLVP_LEN(&tp, UICC_FCP_T_FILE_DESC) < 5) {
+		fprintf(stderr, "No EF.DIR FCP file description\n");
 		msgb_free(msg);
-		return NULL;
+		return -EINVAL;
 	}
 
 	rc = osim_fcp_fd_decode(&ofd, TLVP_VAL(&tp, UICC_FCP_T_FILE_DESC),
 				TLVP_LEN(&tp, UICC_FCP_T_FILE_DESC));
 	if (rc < 0) {
+		fprintf(stderr, "Error decoding EF.DIR FCP file description\n");
 		msgb_free(msg);
-		return NULL;
+		return -EINVAL;
 	}
 
 	if (ofd.type != TYPE_EF || ofd.ef_type != EF_TYPE_RECORD_FIXED) {
+		fprintf(stderr, "EF.DIR is not a fixed record EF!?!\n");
 		msgb_free(msg);
-		return NULL;
+		return -EINVAL;
 	}
 
 	msgb_free(msg);
@@ -291,39 +301,46 @@
 	printf("ofd rec_len = %u, num_rec = %u\n", ofd.rec_len, ofd.num_rec);
 
 	for (i = 0; i < ofd.num_rec; i++) {
+		const uint8_t *aid;
+		uint8_t aid_len;
 		msg = read_record_nr(st, i+1, ofd.rec_len);
-		if (!msg)
-			return NULL;
+		if (!msg) {
+			fprintf(stderr, "Error reading Record %u of EF.DIR, skipping\n", i+1);
+			continue;
+		}
+
+		/* Entries look like this:
+		 * 61194f10 a0000000871002ffffffff8907090000 5005 5553696d31 ffffffffffffffffffffff */
 
 		cur = msgb_apdu_de(msg);
 		if (msgb_apdu_le(msg) < 5) {
+			fprintf(stderr, "Record length %u too short for EF.DIR, skipping\n", msgb_apdu_le(msg));
 			msgb_free(msg);
-			return NULL;
+			continue;
 		}
 
 		if (cur[0] != 0x61 || cur[1] < 0x03 || cur[1] > 0x7f ||
 		    cur[2] != 0x4F || cur[3] < 0x01 || cur[3] > 0x10) {
+			fprintf(stderr, "Unexpected/unknown record in EF.DIR: %s, skipping\n",
+				osmo_hexdump_nospc(msgb_apdu_de(msg), msgb_apdu_le(msg)));
 			msgb_free(msg);
-			return NULL;
+			continue;
 		}
+		aid_len = cur[3];
+		aid = cur+4;
 
-		/* FIXME: actually check if it is an AID that we support, or
-		 * iterate until we find one that we support */
-
-		msg2 = select_adf(st, cur+4, cur[3]);
-
-		/* attach the USIM profile, FIXME: do this based on AID match */
-		st->card->prof = osim_cprof_usim(st->card);
-		st->cwd = osim_file_desc_find_name(st->card->prof->mf, "ADF.USIM");
-
-		msgb_free(msg);
-
-		return msg2;
+		/* FIXME: parse / pass label*/
+		printf("Detected AID %s\n", osmo_hexdump_nospc(aid, aid_len));
+		osim_card_hdl_add_app(st->card, aid, aid_len, NULL);
 	}
 
-	return NULL;
+	return i;
 }
 
+
+extern struct osim_card_profile *osim_cprof_sim(void *ctx);
+extern struct osim_card_profile *osim_cprof_uicc(void *ctx);
+
 static int dump_file(struct osim_chan_hdl *chan, const char *short_name, uint16_t fid)
 {
 	struct tlv_parsed tp;
@@ -556,16 +573,49 @@
 	}
 }
 
+static void iterate_apps(struct osim_chan_hdl *chan)
+{
+	struct osim_card_app_hdl *cah;
+
+	llist_for_each_entry(cah, &chan->card->apps, list) {
+		const struct osim_card_app_profile *cap = cah->prof;
+		struct msgb *msg;
+
+		if (!cap) {
+			fprintf(stderr, "Unknown AID %s; skipping\n",
+				osmo_hexdump_nospc(cah->aid, cah->aid_len));
+			continue;
+		}
+
+		msg = select_adf(chan, cah->aid, cah->aid_len);
+		if (!msg) {
+			fprintf(stderr, "Error selectiong ADF for AID %s; skipping\n",
+				osmo_hexdump_nospc(cah->aid, cah->aid_len));
+			continue;
+		}
+		printf("SW: %s\n", osim_print_sw(chan->card, msgb_apdu_sw(msg)));
+		chan->cur_app = cah;
+		chan->cwd = cap->adf;
+
+		if (g_output_dir)
+			mkdir_and_chdir(cap->adf->short_name, 0750);
+
+		iterate_fs(chan);
+	}
+}
+
 
 int main(int argc, char **argv)
 {
 	struct osim_reader_hdl *reader;
 	struct osim_card_hdl *card;
 	struct osim_chan_hdl *chan;
-	struct msgb *msg;
+	int rc;
 
 	handle_options(argc, argv);
 
+	osim_init(NULL);
+
 	if (g_output_dir) {
 		int rc;
 		rc = mkdir(g_output_dir, 0750);
@@ -592,34 +642,26 @@
 	if (!chan)
 		exit(3);
 
-	msg = try_select_adf_usim(chan);
-	if (!msg) {
-		exit(4);
-	} else if (msgb_apdu_sw(msg) == 0x6e00) {
+	//verify_pin(chan, 1, "1653");
+
+	rc = osim_uicc_scan_apps(chan);
+	if (rc >= 0) {
+		chan->card->prof = osim_cprof_uicc(chan->card);
+		chan->cwd = chan->card->prof->mf;
+	} else if (rc == -0x6e00) {
 		/* CLA not supported: must be classic SIM, not USIM */
 		g_class = 0xA0;
 		chan->card->prof = osim_cprof_sim(chan->card);
 		chan->cwd = chan->card->prof->mf;
-		msgb_free(msg);
-	} else if (msgb_apdu_sw(msg) == 0x9000) {
-		/* normal file */
-		dump_fcp_template_msg(msg);
-		msgb_free(msg);
-		mkdir_and_chdir("ADF_USIM", 0750);
+	} else if (rc < 0) {
+		exit(4);
 	}
 
-	msg = select_file(chan, 0x6fc5);
-	dump_fcp_template_msg(msg);
-	printf("SW: %s\n", osim_print_sw(chan->card, msgb_apdu_sw(msg)));
-	msgb_free(msg);
-
-	verify_pin(chan, 1, "1653");
-
-	msg = select_file(chan, 0x6f06);
-	dump_fcp_template_msg(msg);
-	msgb_free(msg);
-
+	/* first iterate over normal file system */
 	iterate_fs(chan);
 
+	/* then itereate over all apps and their file system */
+	iterate_apps(chan);
+
 	exit(0);
 }

-- 
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/17555
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: Ic4b4ac433a9976842b30a017fb0fc347d87201cd
Gerrit-Change-Number: 17555
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200321/265802e0/attachment.htm>


More information about the gerrit-log mailing list