<p>laforge has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/17154">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">osmo-sim-test: Fall-back to classic SIM<br><br>If selection of ADF_USIM fails, let's fall-back to reading/dumping<br>a classic TS 11.11 (51.011) SIM card.<br><br>Change-Id: I5a986fc65de76c24c5af52ce7e8c699cf302fda9<br>---<br>M include/osmocom/sim/sim.h<br>M utils/osmo-sim-test.c<br>2 files changed, 101 insertions(+), 22 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/54/17154/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/sim/sim.h b/include/osmocom/sim/sim.h</span><br><span>index 2bc4715..8eb3f11 100644</span><br><span>--- a/include/osmocom/sim/sim.h</span><br><span>+++ b/include/osmocom/sim/sim.h</span><br><span>@@ -135,6 +135,7 @@</span><br><span>     TYPE_ADF,       /*!< Application Dedicated File */</span><br><span>        TYPE_EF,        /*!< Entry File */</span><br><span>        TYPE_EF_INT,    /*!< Internal Entry File */</span><br><span style="color: hsl(120, 100%, 40%);">+        TYPE_MF,        /*!< Master File */</span><br><span> };</span><br><span> </span><br><span> enum osim_ef_type {</span><br><span>diff --git a/utils/osmo-sim-test.c b/utils/osmo-sim-test.c</span><br><span>index ea3ce2a..3cb1c59 100644</span><br><span>--- a/utils/osmo-sim-test.c</span><br><span>+++ b/utils/osmo-sim-test.c</span><br><span>@@ -33,6 +33,8 @@</span><br><span> </span><br><span> /* FIXME: this needs to be moved to card_fs_uicc.c */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static uint8_t g_class = 0x00; /* UICC/USIM */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* 11.1.1 */</span><br><span> static struct msgb *_select_file(struct osim_chan_hdl *st, uint8_t p1, uint8_t p2,</span><br><span>                        const uint8_t *data, uint8_t data_len)</span><br><span>@@ -40,7 +42,7 @@</span><br><span>   struct msgb *msg;</span><br><span>    uint8_t *dst;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       msg = osim_new_apdumsg(0x00, 0xA4, p1, p2, data_len, 256);</span><br><span style="color: hsl(120, 100%, 40%);">+    msg = osim_new_apdumsg(g_class, 0xA4, p1, p2, data_len, 256);</span><br><span>        dst = msgb_put(msg, data_len);</span><br><span>       memcpy(dst, data, data_len);</span><br><span> </span><br><span>@@ -60,7 +62,7 @@</span><br><span> {</span><br><span>    uint16_t cfid = htons(fid);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- return _select_file(st, 0x00, 0x04, (uint8_t *)&cfid, 2);</span><br><span style="color: hsl(120, 100%, 40%);">+ return _select_file(st, 0x00, 0x00, (uint8_t *)&cfid, 2);</span><br><span> }</span><br><span> </span><br><span> /* 11.1.9 */</span><br><span>@@ -72,7 +74,7 @@</span><br><span>   if (strlen(pin) > 8)</span><br><span>              return -EINVAL;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     msg = osim_new_apdumsg(0x00, 0x20, 0x00, pin_nr, 8, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+       msg = osim_new_apdumsg(g_class, 0x20, 0x00, pin_nr, 8, 0);</span><br><span>   pindst = (char *) msgb_put(msg, 8);</span><br><span>  memset(pindst, 0xFF, 8);</span><br><span>     /* Do not copy the terminating \0 */</span><br><span>@@ -86,7 +88,7 @@</span><br><span> {</span><br><span>        struct msgb *msg;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   msg = osim_new_apdumsg(0x00, 0xB2, rec_nr, 0x04, 0, rec_size);</span><br><span style="color: hsl(120, 100%, 40%);">+        msg = osim_new_apdumsg(g_class, 0xB2, rec_nr, 0x04, 0, rec_size);</span><br><span> </span><br><span>        osim_transceive_apdu(st, msg);</span><br><span> </span><br><span>@@ -101,7 +103,7 @@</span><br><span>     if (offset > 0x7fff || len > 256)</span><br><span>              return NULL;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        msg = osim_new_apdumsg(0x00, 0xB0, offset >> 8, offset & 0xff, 0, len & 0xff);</span><br><span style="color: hsl(120, 100%, 40%);">+  msg = osim_new_apdumsg(g_class, 0xB0, offset >> 8, offset & 0xff, 0, len & 0xff);</span><br><span> </span><br><span>  osim_transceive_apdu(st, msg);</span><br><span> </span><br><span>@@ -175,7 +177,61 @@</span><br><span>    return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* TS 51.011 Section 9.3 Type of File */</span><br><span style="color: hsl(120, 100%, 40%);">+static const enum osim_file_type sim2ftype[8] = {</span><br><span style="color: hsl(120, 100%, 40%);">+       [1] = TYPE_MF,</span><br><span style="color: hsl(120, 100%, 40%);">+        [2] = TYPE_DF,</span><br><span style="color: hsl(120, 100%, 40%);">+        [4] = TYPE_EF,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* TS 51.011 Section 9.3 Structure of File */</span><br><span style="color: hsl(120, 100%, 40%);">+static const enum osim_ef_type sim2eftype[8] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ [0] = EF_TYPE_TRANSP,</span><br><span style="color: hsl(120, 100%, 40%);">+ [1] = EF_TYPE_RECORD_FIXED,</span><br><span style="color: hsl(120, 100%, 40%);">+   [3] = EF_TYPE_RECORD_CYCLIC,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* TS 51.011 Section 9.2.1 */</span><br><span style="color: hsl(120, 100%, 40%);">+static int osim_fcp_fd_decode_sim(struct osim_fcp_fd_decoded *ofd, const uint8_t *fcp, int fcp_len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     memset(ofd, 0, sizeof(*ofd));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (fcp_len < 14)</span><br><span style="color: hsl(120, 100%, 40%);">+          return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     ofd->type = sim2ftype[fcp[6] & 7];</span><br><span style="color: hsl(120, 100%, 40%);">+     switch (ofd->type) {</span><br><span style="color: hsl(120, 100%, 40%);">+       case TYPE_EF:</span><br><span style="color: hsl(120, 100%, 40%);">+         ofd->ef_type = sim2eftype[fcp[13] & 7];</span><br><span style="color: hsl(120, 100%, 40%);">+                if (fcp_len < 13 + fcp[12])</span><br><span style="color: hsl(120, 100%, 40%);">+                        return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               switch (ofd->ef_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+            case EF_TYPE_RECORD_FIXED:</span><br><span style="color: hsl(120, 100%, 40%);">+            case EF_TYPE_RECORD_CYCLIC:</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (fcp_len < 15)</span><br><span style="color: hsl(120, 100%, 40%);">+                          return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+                       ofd->rec_len = fcp[14];</span><br><span style="color: hsl(120, 100%, 40%);">+                    ofd->num_rec = ntohs(*(uint16_t *)(fcp+2)) / ofd->rec_len;</span><br><span style="color: hsl(120, 100%, 40%);">+                      break;</span><br><span style="color: hsl(120, 100%, 40%);">+                default:</span><br><span style="color: hsl(120, 100%, 40%);">+                      break;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case TYPE_MF:</span><br><span style="color: hsl(120, 100%, 40%);">+ case TYPE_DF:</span><br><span style="color: hsl(120, 100%, 40%);">+         if (fcp_len < 22)</span><br><span style="color: hsl(120, 100%, 40%);">+                  return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+extern struct osim_card_profile *osim_cprof_sim(void *ctx);</span><br><span> extern struct osim_card_profile *osim_cprof_usim(void *ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+extern struct osim_card_profile *osim_cprof_isim(void *ctx);</span><br><span> </span><br><span> static struct msgb *try_select_adf_usim(struct osim_chan_hdl *st)</span><br><span> {</span><br><span>@@ -186,9 +242,17 @@</span><br><span>       int rc, i;</span><br><span> </span><br><span>       msg = select_file(st, 0x2f00);</span><br><span style="color: hsl(0, 100%, 40%);">-  rc = tlv_parse(&tp, &ts102221_fcp_tlv_def, msgb_apdu_de(msg)+2, msgb_apdu_le(msg)-2, 0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-     if (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!msg)</span><br><span>            return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  /* return status word in case of error */</span><br><span style="color: hsl(120, 100%, 40%);">+     if (msgb_apdu_sw(msg) != 0x9000)</span><br><span style="color: hsl(120, 100%, 40%);">+              return msg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = tlv_parse(&tp, &ts102221_fcp_tlv_def, msgb_apdu_de(msg)+2, msgb_apdu_le(msg)-2, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+               return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span> </span><br><span>        dump_fcp_template(&tp);</span><br><span> </span><br><span>@@ -266,20 +330,25 @@</span><br><span>              goto out;</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   rc = tlv_parse(&tp, &ts102221_fcp_tlv_def, msgb_apdu_de(msg)+2, msgb_apdu_le(msg)-2, 0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-     if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                printf("Unable to parse FCP\n");</span><br><span style="color: hsl(0, 100%, 40%);">-              goto out;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (g_class != 0xA0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                rc = tlv_parse(&tp, &ts102221_fcp_tlv_def, msgb_apdu_de(msg)+2, msgb_apdu_le(msg)-2, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+           if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      printf("Unable to parse FCP: %s\n", msgb_hexdump(msg));</span><br><span style="color: hsl(120, 100%, 40%);">+                     goto out;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if (!TLVP_PRESENT(&tp, UICC_FCP_T_FILE_DESC) ||</span><br><span style="color: hsl(120, 100%, 40%);">+               TLVP_LEN(&tp, UICC_FCP_T_FILE_DESC) < 2) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 printf("No file descriptor present ?!?\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                 goto out;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           rc = osim_fcp_fd_decode(&ffdd, TLVP_VAL(&tp, UICC_FCP_T_FILE_DESC),</span><br><span style="color: hsl(120, 100%, 40%);">+                                   TLVP_LEN(&tp, UICC_FCP_T_FILE_DESC));</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              rc = osim_fcp_fd_decode_sim(&ffdd, msgb_apdu_de(msg), msgb_apdu_le(msg));</span><br><span>        }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (!TLVP_PRESENT(&tp, UICC_FCP_T_FILE_DESC) ||</span><br><span style="color: hsl(0, 100%, 40%);">-         TLVP_LEN(&tp, UICC_FCP_T_FILE_DESC) < 2) {</span><br><span style="color: hsl(0, 100%, 40%);">-           printf("No file descriptor present ?!?\n");</span><br><span style="color: hsl(0, 100%, 40%);">-           goto out;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       rc = osim_fcp_fd_decode(&ffdd, TLVP_VAL(&tp, UICC_FCP_T_FILE_DESC),</span><br><span style="color: hsl(0, 100%, 40%);">-                             TLVP_LEN(&tp, UICC_FCP_T_FILE_DESC));</span><br><span>    if (rc < 0) {</span><br><span>             printf("Unable to decode File Descriptor\n");</span><br><span>              goto out;</span><br><span>@@ -432,10 +501,19 @@</span><br><span>            exit(3);</span><br><span> </span><br><span>         msg = try_select_adf_usim(chan);</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!msg || msgb_apdu_sw(msg) != 0x9000)</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!msg) {</span><br><span>          exit(4);</span><br><span style="color: hsl(0, 100%, 40%);">-        dump_fcp_template_msg(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-     msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+       } else if (msgb_apdu_sw(msg) == 0x6e00) {</span><br><span style="color: hsl(120, 100%, 40%);">+             /* CLA not supported: must be classic SIM, not USIM */</span><br><span style="color: hsl(120, 100%, 40%);">+                g_class = 0xA0;</span><br><span style="color: hsl(120, 100%, 40%);">+               chan->card->prof = osim_cprof_sim(chan->card);</span><br><span style="color: hsl(120, 100%, 40%);">+               chan->cwd = chan->card->prof->mf;</span><br><span style="color: hsl(120, 100%, 40%);">+         msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+       } else if (msgb_apdu_sw(msg) == 0x9000) {</span><br><span style="color: hsl(120, 100%, 40%);">+             /* normal file */</span><br><span style="color: hsl(120, 100%, 40%);">+             dump_fcp_template_msg(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+           msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span> </span><br><span>        msg = select_file(chan, 0x6fc5);</span><br><span>     dump_fcp_template_msg(msg);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/17154">change 17154</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/libosmocore/+/17154"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I5a986fc65de76c24c5af52ce7e8c699cf302fda9 </div>
<div style="display:none"> Gerrit-Change-Number: 17154 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>