Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[sim-auth] Support short AIDs. JB#54048
They can be shorter than 16 bytes.
  • Loading branch information
monich committed May 31, 2021
1 parent 97b5fcb commit dffc04d
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 52 deletions.
5 changes: 5 additions & 0 deletions ofono/include/sim.h
Expand Up @@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2015-2021 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
Expand Down Expand Up @@ -210,6 +211,10 @@ struct ofono_sim_driver {
void (*logical_access)(struct ofono_sim *sim, int session_id,
const unsigned char *pdu, unsigned int len,
ofono_sim_logical_access_cb_t cb, void *data);
/* Since mer/1.23+git28 */
void (*open_channel2)(struct ofono_sim *sim, const unsigned char *aid,
unsigned int len, ofono_sim_open_channel_cb_t cb,
void *data);
};

int ofono_sim_driver_register(const struct ofono_sim_driver *d);
Expand Down
7 changes: 4 additions & 3 deletions ofono/src/ofono.h
Expand Up @@ -3,7 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2015-2019 Jolla Ltd.
* Copyright (C) 2015-2021 Jolla Ltd.
* Copyright (C) 2019 Open Mobile Platform LLC.
*
* This program is free software; you can redistribute it and/or modify
Expand Down Expand Up @@ -388,6 +388,7 @@ unsigned short __ofono_sms_get_next_ref(struct ofono_sms *sms);

#include <ofono/sim.h>

struct sim_aid;
struct ofono_sim_aid_session;
enum sim_app_type;

Expand Down Expand Up @@ -426,7 +427,7 @@ void __ofono_sim_remove_session_watch(struct ofono_sim_aid_session *session,
unsigned int id);

struct ofono_sim_aid_session *__ofono_sim_get_session_by_aid(
struct ofono_sim *sim, unsigned char *aid);
struct ofono_sim *sim, const struct sim_aid *aid);

struct ofono_sim_aid_session *__ofono_sim_get_session_by_type(
struct ofono_sim *sim, enum sim_app_type type);
Expand All @@ -436,7 +437,7 @@ int __ofono_sim_session_get_id(struct ofono_sim_aid_session *session);
enum sim_app_type __ofono_sim_session_get_type(
struct ofono_sim_aid_session *session);

unsigned char *__ofono_sim_session_get_aid(
const struct sim_aid *__ofono_sim_session_get_aid(
struct ofono_sim_aid_session *session);

const char *__ofono_sim_get_impi(struct ofono_sim *sim);
Expand Down
46 changes: 31 additions & 15 deletions ofono/src/sim-auth.c
Expand Up @@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2015-2021 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
Expand Down Expand Up @@ -62,7 +63,7 @@ struct auth_request {
};

struct aid_object {
uint8_t aid[16];
struct sim_aid aid;
char *path;
enum sim_app_type type;
};
Expand All @@ -82,7 +83,7 @@ struct ofono_sim_auth {
/*
* Find an application by path. 'path' should be a DBusMessage object path.
*/
static uint8_t *find_aid_by_path(GSList *aid_objects,
static const struct aid_object *find_aid_by_path(GSList *aid_objects,
const char *path)
{
GSList *iter = aid_objects;
Expand All @@ -91,7 +92,7 @@ static uint8_t *find_aid_by_path(GSList *aid_objects,
struct aid_object *obj = iter->data;

if (!strcmp(path, obj->path))
return obj->aid;
return obj;

iter = g_slist_next(iter);
}
Expand Down Expand Up @@ -384,7 +385,7 @@ static DBusMessage *usim_gsm_authenticate(DBusConnection *conn,
struct ofono_sim_auth *sa = data;
DBusMessageIter iter;
DBusMessageIter array;
uint8_t *aid;
const struct aid_object *obj;

if (sa->pending)
return __ofono_error_busy(msg);
Expand Down Expand Up @@ -424,13 +425,20 @@ static DBusMessage *usim_gsm_authenticate(DBusConnection *conn,
/*
* retrieve session from SIM
*/
aid = find_aid_by_path(sa->aid_objects, dbus_message_get_path(msg));
sa->pending->session = __ofono_sim_get_session_by_aid(sa->sim, aid);
obj = find_aid_by_path(sa->aid_objects, dbus_message_get_path(msg));
sa->pending->session = __ofono_sim_get_session_by_aid(sa->sim,
&obj->aid);
sa->pending->msg = dbus_message_ref(msg);
sa->pending->watch_id = __ofono_sim_add_session_watch(
sa->pending->session, get_session_cb, sa, NULL);

return NULL;
if (!sa->pending->watch_id) {
g_free(sa->pending);
sa->pending = NULL;
return __ofono_error_not_supported(msg);
}

return NULL;

format_error:
g_free(sa->pending);
Expand All @@ -446,7 +454,7 @@ static DBusMessage *umts_common(DBusConnection *conn, DBusMessage *msg,
uint32_t rlen;
uint32_t alen;
struct ofono_sim_auth *sa = data;
uint8_t *aid;
const struct aid_object *obj;

if (sa->pending)
return __ofono_error_busy(msg);
Expand All @@ -471,12 +479,18 @@ static DBusMessage *umts_common(DBusConnection *conn, DBusMessage *msg,
/*
* retrieve session from SIM
*/
aid = find_aid_by_path(sa->aid_objects, dbus_message_get_path(msg));
sa->pending->session = __ofono_sim_get_session_by_aid(sa->sim, aid);

obj = find_aid_by_path(sa->aid_objects, dbus_message_get_path(msg));
sa->pending->session = __ofono_sim_get_session_by_aid(sa->sim,
&obj->aid);
sa->pending->watch_id = __ofono_sim_add_session_watch(
sa->pending->session, get_session_cb, sa, NULL);

if (!sa->pending->watch_id) {
g_free(sa->pending);
sa->pending = NULL;
return __ofono_error_not_supported(msg);
}

return NULL;
}

Expand Down Expand Up @@ -706,29 +720,31 @@ static void sim_auth_register(struct ofono_sim_auth *sa)

ret = sprintf(new->path, "%s/", path);

encode_hex_own_buf(r->aid, 16, 0, new->path + ret);
encode_hex_own_buf(r->aid.aid, r->aid.len, 0,
new->path + ret);

g_dbus_register_interface(conn, new->path,
OFONO_USIM_APPLICATION_INTERFACE,
sim_auth_usim_app, NULL, NULL,
sa, NULL);

memcpy(new->aid, r->aid, 16);
new->aid = r->aid;

break;
case SIM_APP_TYPE_ISIM:
new->path = g_new0(char, strlen(path) + 34);

ret = sprintf(new->path, "%s/", path);

encode_hex_own_buf(r->aid, 16, 0, new->path + ret);
encode_hex_own_buf(r->aid.aid, r->aid.len, 0,
new->path + ret);

g_dbus_register_interface(conn, new->path,
OFONO_ISIM_APPLICATION_INTERFACE,
sim_auth_isim_app, NULL, NULL,
sa, NULL);

memcpy(new->aid, r->aid, 16);
new->aid = r->aid;

break;
default:
Expand Down
48 changes: 35 additions & 13 deletions ofono/src/sim.c
Expand Up @@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2015-2021 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
Expand Down Expand Up @@ -2441,7 +2442,7 @@ struct ofono_sim_context *ofono_sim_context_create_isim(

if (session->record->type == SIM_APP_TYPE_ISIM) {
return sim_fs_context_new_with_aid(sim->simfs_isim,
session->record->aid);
&session->record->aid);
}

iter = g_slist_next(iter);
Expand Down Expand Up @@ -3667,6 +3668,26 @@ const char *__ofono_sim_get_impi(struct ofono_sim *sim)
static void open_channel_cb(const struct ofono_error *error, int session_id,
void *data);

static gboolean open_channel(struct ofono_sim_aid_session *session)
{
struct ofono_sim *sim = session->sim;
const struct ofono_sim_driver *driver = sim->driver;
const struct sim_aid *aid = &session->record->aid;

if (driver->open_channel2) {
driver->open_channel2(sim, aid->aid, aid->len, open_channel_cb,
session);
return TRUE;
}

if (driver->open_channel && aid->len == 16) {
driver->open_channel(sim, aid->aid, open_channel_cb, session);
return TRUE;
}

return FALSE;
}

static void close_channel_cb(const struct ofono_error *error, void *data)
{
struct ofono_sim_aid_session *session = data;
Expand All @@ -3680,10 +3701,8 @@ static void close_channel_cb(const struct ofono_error *error, void *data)
* An atom requested to open during a close, we can re-open
* here.
*/
session->sim->driver->open_channel(session->sim,
session->record->aid, open_channel_cb,
session);
return;
if (open_channel(session))
return;
}

session->state = SESSION_STATE_INACTIVE;
Expand Down Expand Up @@ -3758,10 +3777,12 @@ unsigned int __ofono_sim_add_session_watch(
* If the session is inactive and there are no watchers, open
* a new session.
*/
session->state = SESSION_STATE_OPENING;
session->sim->driver->open_channel(session->sim,
session->record->aid, open_channel_cb,
session);
if (open_channel(session)) {
session->state = SESSION_STATE_OPENING;
} else {
g_free(item);
return 0;
}
} else if (session->state == SESSION_STATE_OPEN) {
/*
* Session is already open and available, just call the
Expand Down Expand Up @@ -3794,14 +3815,15 @@ void __ofono_sim_remove_session_watch(struct ofono_sim_aid_session *session,
}

struct ofono_sim_aid_session *__ofono_sim_get_session_by_aid(
struct ofono_sim *sim, unsigned char *aid)
struct ofono_sim *sim, const struct sim_aid *aid)
{
GSList *iter = sim->aid_sessions;

while (iter) {
struct ofono_sim_aid_session *session = iter->data;

if (!memcmp(session->record->aid, aid, 16))
if (session->record->aid.len == aid->len &&
!memcmp(session->record->aid.aid, aid, aid->len))
return session;

iter = g_slist_next(iter);
Expand Down Expand Up @@ -3838,10 +3860,10 @@ enum sim_app_type __ofono_sim_session_get_type(
return session->record->type;
}

unsigned char *__ofono_sim_session_get_aid(
const struct sim_aid *__ofono_sim_session_get_aid(
struct ofono_sim_aid_session *session)
{
return session->record->aid;
return &session->record->aid;
}

GSList *__ofono_sim_get_aid_list(struct ofono_sim *sim)
Expand Down
3 changes: 2 additions & 1 deletion ofono/src/simfs.c
Expand Up @@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2015-2021 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
Expand Down Expand Up @@ -164,7 +165,7 @@ struct ofono_sim_context *sim_fs_context_new(struct sim_fs *fs)
}

struct ofono_sim_context *sim_fs_context_new_with_aid(struct sim_fs *fs,
unsigned char *aid)
const struct sim_aid *aid)
{
struct ofono_sim_context *context = sim_fs_context_new(fs);

Expand Down
4 changes: 3 additions & 1 deletion ofono/src/simfs.h
Expand Up @@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2015-2021 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
Expand All @@ -20,6 +21,7 @@
*/

struct sim_fs;
struct sim_aid;

typedef void (*sim_fs_read_info_cb_t)(int ok, unsigned char file_status,
int total_length, int record_length,
Expand All @@ -30,7 +32,7 @@ struct sim_fs *sim_fs_new(struct ofono_sim *sim,
struct ofono_sim_context *sim_fs_context_new(struct sim_fs *fs);

struct ofono_sim_context *sim_fs_context_new_with_aid(struct sim_fs *fs,
unsigned char *aid);
const struct sim_aid *aid);

unsigned int sim_fs_file_watch_add(struct ofono_sim_context *context,
int id, ofono_sim_file_changed_cb_t cb,
Expand Down
30 changes: 17 additions & 13 deletions ofono/src/simutil.c
Expand Up @@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2015-2021 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
Expand Down Expand Up @@ -1572,21 +1573,17 @@ GSList *sim_parse_app_template_entries(const unsigned char *buffer, int len)
/* Find all the application entries */
while ((dataobj = ber_tlv_find_by_tag(buffer, 0x61, len,
&dataobj_len)) != NULL) {
struct sim_app_record app;
struct sim_app_record *app;
const unsigned char *aid, *label;
int label_len;
int label_len, aid_len;
char *app_label;

/* Find the aid (mandatory) */
aid = ber_tlv_find_by_tag(dataobj, 0x4f, dataobj_len,
&app.aid_len);
if (!aid || app.aid_len < 0x01 || app.aid_len > 0x10)
&aid_len);
if (!aid || aid_len < 0x01 || aid_len > 0x10)
goto error;

memcpy(app.aid, aid, app.aid_len);
memset(app.aid + app.aid_len, 0xff, 16 - app.aid_len);

app.type = (app.aid[5] << 8) | app.aid[6];

/* Find the label (optional) */
label = ber_tlv_find_by_tag(dataobj, 0x50, dataobj_len,
&label_len);
Expand All @@ -1595,14 +1592,21 @@ GSList *sim_parse_app_template_entries(const unsigned char *buffer, int len)
* Label field uses the extra complicated
* encoding in 102.221 Annex A
*/
app.label = sim_string_to_utf8(label, label_len);
app_label = sim_string_to_utf8(label, label_len);

if (app.label == NULL)
if (app_label == NULL)
goto error;
} else
app.label = NULL;
app_label = NULL;

app = g_new0(struct sim_app_record, 1);

memcpy(app->aid.aid, aid, aid_len);
app->aid.len = aid_len;
app->label = app_label;
app->type = (aid[5] << 8) | aid[6];

ret = g_slist_prepend(ret, g_memdup(&app, sizeof(app)));
ret = g_slist_prepend(ret, app);

len -= (dataobj - buffer) + dataobj_len;
buffer = dataobj + dataobj_len;
Expand Down

0 comments on commit dffc04d

Please sign in to comment.