summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSlava Monich <slava.monich@jolla.com>2021-05-03 17:04:35 +0300
committerDenis Kenzior <denkenz@gmail.com>2021-06-01 10:52:48 -0500
commit37745c22019e382b1c1d8e511183c43c38b050ce (patch)
tree1eb6af7d068aa687ebb58c0c19105b2a133c4d91 /src
parent8b4e79b443ee20d287bb68ae3a02c1819fd1b2d5 (diff)
downloadofono-37745c22019e382b1c1d8e511183c43c38b050ce.tar.gz
sim-auth: Parse auth response according to TS 31.102
Diffstat (limited to 'src')
-rw-r--r--src/sim-auth.c34
-rw-r--r--src/simutil.c146
-rw-r--r--src/simutil.h13
3 files changed, 137 insertions, 56 deletions
diff --git a/src/sim-auth.c b/src/sim-auth.c
index 3c3f35e7..6dab52ee 100644
--- a/src/sim-auth.c
+++ b/src/sim-auth.c
@@ -207,14 +207,10 @@ static void handle_umts(struct ofono_sim_auth *sa, const uint8_t *resp,
DBusMessage *reply = NULL;
DBusMessageIter iter;
DBusMessageIter dict;
- const uint8_t *res = NULL;
- const uint8_t *ck = NULL;
- const uint8_t *ik = NULL;
- const uint8_t *auts = NULL;
- const uint8_t *kc = NULL;
+ struct data_block res, ck, ik, auts, sres, kc;
if (!sim_parse_umts_authenticate(resp, len, &res, &ck, &ik,
- &auts, &kc))
+ &auts, &sres, &kc))
goto umts_end;
reply = dbus_message_new_method_return(sa->pending->msg);
@@ -224,15 +220,23 @@ static void handle_umts(struct ofono_sim_auth *sa, const uint8_t *resp,
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
"{say}", &dict);
- if (auts) {
- append_dict_byte_array(&dict, "AUTS", auts, 14);
- } else {
- append_dict_byte_array(&dict, "RES", res, 8);
- append_dict_byte_array(&dict, "CK", ck, 16);
- append_dict_byte_array(&dict, "IK", ik, 16);
- if (kc)
- append_dict_byte_array(&dict, "Kc", kc, 8);
- }
+ if (auts.data)
+ append_dict_byte_array(&dict, "AUTS", auts.data, auts.len);
+
+ if (sres.data)
+ append_dict_byte_array(&dict, "SRES", sres.data, sres.len);
+
+ if (res.data)
+ append_dict_byte_array(&dict, "RES", res.data, res.len);
+
+ if (ck.data)
+ append_dict_byte_array(&dict, "CK", ck.data, ck.len);
+
+ if (ik.data)
+ append_dict_byte_array(&dict, "IK", ik.data, ik.len);
+
+ if (kc.data)
+ append_dict_byte_array(&dict, "Kc", kc.data, kc.len);
dbus_message_iter_close_container(&iter, &dict);
diff --git a/src/simutil.c b/src/simutil.c
index edd7de88..59d8d5dd 100644
--- a/src/simutil.c
+++ b/src/simutil.c
@@ -1674,63 +1674,135 @@ int sim_build_gsm_authenticate(unsigned char *buffer, int len,
return build_authenticate(buffer, rand, NULL);
}
-gboolean sim_parse_umts_authenticate(const unsigned char *buffer,
- int len, const unsigned char **res, const unsigned char **ck,
- const unsigned char **ik, const unsigned char **auts,
- const unsigned char **kc)
+gboolean sim_parse_umts_authenticate(const unsigned char *buffer, int len,
+ struct data_block *res, struct data_block *ck,
+ struct data_block *ik, struct data_block *auts,
+ struct data_block *sres, struct data_block *kc)
{
- if (len < 16 || !buffer)
+ const unsigned char *ptr = buffer;
+ const unsigned char *end = ptr + len;
+ unsigned int l;
+
+ if (!buffer || len < 2)
return FALSE;
- switch (buffer[0]) {
+ memset(res, 0, sizeof(*res));
+ memset(ck, 0, sizeof(*ck));
+ memset(ik, 0, sizeof(*ik));
+ memset(kc, 0, sizeof(*kc));
+ memset(auts, 0, sizeof(*auts));
+ memset(sres, 0, sizeof(*sres));
+
+ /*
+ * TS 31.102
+ * 7.1.2.1 GSM/3G security context
+ */
+ switch (*ptr++) {
case 0xdb:
- /* 'DB' + '08' + RES(16) + '10' + CK(32) + '10' + IK(32) = 43 */
- if (len < 43)
- goto umts_end;
+ /*
+ * Response parameters/data, case 1, 3G security context,
+ * command successful:
+ *
+ * "Successful 3G authentication" tag = 'DB'
+ * 'DB' + L3 + RES(L3) + L4 + CK(L4) + L5 + IK(L5) + 8 + Kc(8)
+ */
+ l = *ptr++; /* L3 */
+ if ((ptr + l) > end)
+ return FALSE;
- /* success */
- if (buffer[1] != 0x08)
- goto umts_end;
+ res->data = ptr;
+ res->len = l;
+ ptr += l;
- *res = buffer + 2;
+ if (ptr == end)
+ return FALSE;
- if (buffer[10] != 0x10)
- goto umts_end;
+ l = *ptr++; /* L4 */
+ if ((ptr + l) > end)
+ return FALSE;
- *ck = buffer + 11;
+ ck->data = ptr;
+ ck->len = l;
+ ptr += l;
- if (buffer[27] != 0x10)
- goto umts_end;
+ if (ptr == end)
+ return FALSE;
- *ik = buffer + 28;
+ l = *ptr++; /* L5 */
+ if ((ptr + l) > end)
+ return FALSE;
- if (len >= 53 && kc) {
- if (buffer[44] != 0x08)
- goto umts_end;
+ ik->data = ptr;
+ ik->len = l;
+ ptr += l;
- *kc = buffer + 45;
- } else {
- *kc = NULL;
+ if (ptr < end) {
+ l = *ptr++;
+ if (l != 8 || (ptr + l) != end)
+ return FALSE;
+
+ kc->data = ptr;
+ kc->len = l;
+ ptr += l;
}
- *auts = NULL;
+ return TRUE;
- break;
case 0xdc:
- /* sync error */
- if (buffer[1] != 0x0e)
- goto umts_end;
+ /*
+ * Response parameters/data, case 2, 3G security context,
+ * synchronisation failure:
+ *
+ * "Synchronisation failure" tag = 'DC'
+ * 'DC' + L1 + AUTS(L1)
+ */
+ l = *ptr++; /* L1 */
+ if ((ptr + l) > end)
+ return FALSE;
- *auts = buffer + 2;
+ auts->data = ptr;
+ auts->len = l;
+ ptr += l;
- break;
- default:
- goto umts_end;
- }
+ if (ptr != end)
+ return FALSE;
- return TRUE;
+ return TRUE;
+
+ case 0x04:
+ /*
+ * Response parameters/data, case 3, GSM security context,
+ * command successful:
+ *
+ * 4 + SRES(4) + 8 + Kc(8)
+ */
+ l = 4; /* Already skipped this one */
+ if ((ptr + l) > end)
+ return FALSE;
+
+ sres->data = ptr;
+ sres->len = l;
+ ptr += l;
+
+ if (ptr == end)
+ return FALSE;
+
+ l = *ptr++; /* 8 */
+ if (l != 8 || (ptr + l) > end)
+ return FALSE;
-umts_end:
+ kc->data = ptr;
+ kc->len = l;
+ ptr += l;
+
+ if (ptr != end)
+ return FALSE;
+
+ return TRUE;
+
+ default:
+ break;
+ }
return FALSE;
}
diff --git a/src/simutil.h b/src/simutil.h
index 33b775a7..f908bbb4 100644
--- a/src/simutil.h
+++ b/src/simutil.h
@@ -371,6 +371,11 @@ struct comprehension_tlv_builder {
struct ber_tlv_builder *parent;
};
+struct data_block {
+ const unsigned char *data;
+ unsigned int len;
+};
+
void simple_tlv_iter_init(struct simple_tlv_iter *iter,
const unsigned char *pdu, unsigned int len);
gboolean simple_tlv_iter_next(struct simple_tlv_iter *iter);
@@ -527,10 +532,10 @@ int sim_build_umts_authenticate(unsigned char *buffer, int len,
int sim_build_gsm_authenticate(unsigned char *buffer, int len,
const unsigned char *rand);
-gboolean sim_parse_umts_authenticate(const unsigned char *buffer,
- int len, const unsigned char **res, const unsigned char **ck,
- const unsigned char **ik, const unsigned char **auts,
- const unsigned char **kc);
+gboolean sim_parse_umts_authenticate(const unsigned char *buffer, int len,
+ struct data_block *res, struct data_block *ck,
+ struct data_block *ik, struct data_block *auts,
+ struct data_block *sres, struct data_block *kc);
gboolean sim_parse_gsm_authenticate(const unsigned char *buffer, int len,
const unsigned char **sres, const unsigned char **kc);