All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv3 1/7] sim-auth: prep simauth/dbus headers
@ 2017-10-11 18:57 James Prestwood
  2017-10-11 18:57 ` [PATCHv3 2/7] sim-auth: implementation of core sim-auth atom James Prestwood
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: James Prestwood @ 2017-10-11 18:57 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 2914 bytes --]

Added new dbus interfaces for SimAuth module as well as
function prototype definitions to simauth header.

org.ofono.SimAuthentication:
   Interface to hold the auth object to type mapping property

org.ofono.USimApplication:
   Application with USim functionality (GSM/UMTS auth)

org.ofono.ISimApplication:
   Application with ISim functionality (IMS auth)
---
 include/dbus.h     |  3 +++
 include/sim-auth.h | 20 +++++++++++++++++++-
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/include/dbus.h b/include/dbus.h
index 0a8f2e5..9cc47f7 100644
--- a/include/dbus.h
+++ b/include/dbus.h
@@ -58,6 +58,9 @@ extern "C" {
 #define OFONO_LOCATION_REPORTING_INTERFACE OFONO_SERVICE ".LocationReporting"
 #define OFONO_GNSS_INTERFACE "org.ofono.AssistedSatelliteNavigation"
 #define OFONO_GNSS_POSR_AGENT_INTERFACE "org.ofono.PositioningRequestAgent"
+#define OFONO_USIM_APPLICATION_INTERFACE "org.ofono.USimApplication"
+#define OFONO_ISIM_APPLICATION_INTERFACE "org.ofono.ISimApplication"
+#define OFONO_SIM_AUTHENTICATION_INTERFACE "org.ofono.SimAuthentication"
 #define OFONO_HANDSFREE_INTERFACE OFONO_SERVICE ".Handsfree"
 #define OFONO_SIRI_INTERFACE OFONO_SERVICE ".Siri"
 #define OFONO_NETMON_INTERFACE OFONO_SERVICE ".NetworkMonitor"
diff --git a/include/sim-auth.h b/include/sim-auth.h
index 0a62adc..ccaa7f2 100644
--- a/include/sim-auth.h
+++ b/include/sim-auth.h
@@ -26,6 +26,8 @@
 extern "C" {
 #endif
 
+#include <stdint.h>
+
 #include <ofono/types.h>
 
 struct ofono_sim_auth;
@@ -34,6 +36,15 @@ typedef void (*ofono_sim_list_apps_cb_t)(const struct ofono_error *error,
 					const unsigned char *dataobj,
 					int len, void *data);
 
+typedef void (*ofono_sim_open_channel_cb_t)(const struct ofono_error *error,
+		int session_id, void *data);
+
+typedef void (*ofono_sim_close_channel_cb_t)(const struct ofono_error *error,
+		void *data);
+
+typedef void (*ofono_logical_access_cb_t)(const struct ofono_error *error,
+		const uint8_t *resp, uint16_t len, void *data);
+
 struct ofono_sim_auth_driver {
 	const char *name;
 	int (*probe)(struct ofono_sim_auth *sa, unsigned int vendor,
@@ -41,7 +52,14 @@ struct ofono_sim_auth_driver {
 	void (*remove)(struct ofono_sim_auth *sa);
 
 	void (*list_apps)(struct ofono_sim_auth *sa,
-				ofono_sim_list_apps_cb_t cb, void *data);
+			ofono_sim_list_apps_cb_t cb, void *data);
+	void (*open_channel)(struct ofono_sim_auth *sa, const uint8_t *aid,
+			ofono_sim_open_channel_cb_t cb, void *data);
+	void (*close_channel)(struct ofono_sim_auth *sa, int session_id,
+			ofono_sim_close_channel_cb_t cb, void *data);
+	void (*logical_access)(struct ofono_sim_auth *sa,
+			int session_id, const uint8_t *pdu, uint16_t len,
+			ofono_logical_access_cb_t cb, void *data);
 };
 
 int ofono_sim_auth_driver_register(const struct ofono_sim_auth_driver *d);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCHv3 2/7] sim-auth: implementation of core sim-auth atom
  2017-10-11 18:57 [PATCHv3 1/7] sim-auth: prep simauth/dbus headers James Prestwood
@ 2017-10-11 18:57 ` James Prestwood
  2017-10-11 20:11   ` Denis Kenzior
  2017-10-11 18:57 ` [PATCHv3 3/7] atmodem: implemented sim-auth functionality in atmodem James Prestwood
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 10+ messages in thread
From: James Prestwood @ 2017-10-11 18:57 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 18636 bytes --]

The sim-auth module atom can now be used for SIM application discovery
and authentication. The atom will automatically discover SIM
applications available on the SIM and register a new DBus object under
the modem, whos name is the AID string e.g.

/modem1/A0000000871004FFFFFFFF8906190000

A list of discovered AID object paths and types can be found under the
modems (new) org.ofono.SimAuthentication interface "applications"
property in the format:

"a{o(ss)}" where

o = path (e.g. above)
s = type (Umts, Ims)
s = name (USim, ISim etc.)

The type signifies which interfaces the AID object will have:

Umts = org.ofono.USimApplication
Ims = org.ofono.ISimApplication

These interfaces will contain the supported USIM/ISIM authentication
algorithms. Where:

org.ofono.USimApplication has:
    GsmAuthenticate()
    UmtsAuthenticate()

org.ofono.ISimApplication has:
    ImsAuthenticate()
---
 src/sim-auth.c | 607 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 607 insertions(+)

diff --git a/src/sim-auth.c b/src/sim-auth.c
index 5d2f075..b8a7087 100644
--- a/src/sim-auth.c
+++ b/src/sim-auth.c
@@ -28,19 +28,102 @@
 #include <glib.h>
 #include <errno.h>
 #include <unistd.h>
+#include <gdbus.h>
+#include <string.h>
+#include <stdio.h>
 
 #include "ofono.h"
 
 #include "simutil.h"
+#include "util.h"
+
+#define SIM_AUTH_MAX_RANDS	3
 
 static GSList *g_drivers = NULL;
 
+/*
+ * Temporary handle used for the command authentication sequence.
+ */
+struct auth_request {
+	/* DBus values for GSM authentication */
+	DBusMessage *msg;
+	DBusMessage *reply;
+	DBusMessageIter iter;
+	DBusMessageIter dict;
+	/* ID from open_channel */
+	int session_id;
+	/* list of rands to calculate key (1 if umts == 1) */
+	void *rands[SIM_AUTH_MAX_RANDS];
+	int num_rands;
+	/* number of keys that have been returned */
+	int cb_count;
+	void *autn;
+	uint8_t umts : 1;
+};
+
 struct ofono_sim_auth {
 	const struct ofono_sim_auth_driver *driver;
 	void *driver_data;
 	struct ofono_atom *atom;
+	GSList *aid_list;
+	struct ofono_sim *sim;
+	uint8_t gsm_access : 1;
+	uint8_t gsm_context : 1;
+	struct auth_request *pending;
 };
 
+/*
+ * Find an AID channel by the type of application
+ */
+static struct sim_app_record *find_channel(GSList *aid_list,
+		enum sim_app_type type)
+{
+	GSList *iter = aid_list;
+
+	while (iter) {
+		struct sim_app_record *app = iter->data;
+
+		if (app->type == type)
+			return app;
+
+		iter = g_slist_next(iter);
+	}
+
+	return NULL;
+}
+
+/*
+ * Free all discovered AID's
+ */
+static void free_apps(struct ofono_sim_auth *sa)
+{
+	DBusConnection *conn = ofono_dbus_get_connection();
+	struct ofono_modem *modem = __ofono_atom_get_modem(sa->atom);
+	const char *path = __ofono_atom_get_path(sa->atom);
+	GSList *iter = sa->aid_list;
+
+
+	while (iter) {
+		struct sim_app_record *app = iter->data;
+
+		if (app->type == SIM_APP_TYPE_USIM) {
+			g_dbus_unregister_interface(conn, path,
+					OFONO_USIM_APPLICATION_INTERFACE);
+			ofono_modem_remove_interface(modem,
+					OFONO_USIM_APPLICATION_INTERFACE);
+		} else if (app->type == SIM_APP_TYPE_ISIM) {
+			g_dbus_unregister_interface(conn, path,
+					OFONO_ISIM_APPLICATION_INTERFACE);
+			ofono_modem_remove_interface(modem,
+					OFONO_USIM_APPLICATION_INTERFACE);
+		}
+
+		iter = g_slist_next(iter);
+	}
+
+	g_slist_free(sa->aid_list);
+}
+
 int ofono_sim_auth_driver_register(const struct ofono_sim_auth_driver *d)
 {
 	DBG("driver: %p, name: %s", d, d->name);
@@ -62,6 +145,9 @@ void ofono_sim_auth_driver_unregister(const struct ofono_sim_auth_driver *d)
 
 static void sim_auth_unregister(struct ofono_atom *atom)
 {
+	struct ofono_sim_auth *sa = __ofono_atom_get_data(atom);
+
+	free_apps(sa);
 }
 
 static void sim_auth_remove(struct ofono_atom *atom)
@@ -113,9 +199,530 @@ struct ofono_sim_auth *ofono_sim_auth_create(struct ofono_modem *modem,
 	return sa;
 }
 
+/*
+ * appends {o(ss)} into an existing dict array
+ */
+static void append_dict_application(DBusMessageIter *iter, const char *path,
+		const char *type, const char *name)
+{
+	DBusMessageIter array;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path);
+
+	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "{sv}", &array);
+
+	ofono_dbus_dict_append(&array, "Type", DBUS_TYPE_STRING, &type);
+	ofono_dbus_dict_append(&array, "Name", DBUS_TYPE_STRING, &name);
+
+	dbus_message_iter_close_container(iter, &array);
+}
+
+/*
+ * appends {say} onto an existing dict array
+ */
+static void append_dict_byte_array(DBusMessageIter *iter, const char *key,
+		const void *arr, uint32_t len)
+{
+	DBusMessageIter keyiter;
+	DBusMessageIter valueiter;
+
+	dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, NULL,
+			&keyiter);
+	dbus_message_iter_append_basic(&keyiter, DBUS_TYPE_STRING, &key);
+	dbus_message_iter_open_container(&keyiter, DBUS_TYPE_ARRAY,
+			"y", &valueiter);
+	dbus_message_iter_append_fixed_array(&valueiter, DBUS_TYPE_BYTE, &arr,
+			len);
+	dbus_message_iter_close_container(&keyiter, &valueiter);
+	dbus_message_iter_close_container(iter, &keyiter);
+}
+
+static void handle_umts(struct ofono_sim_auth *sim, const uint8_t *resp,
+		uint16_t len)
+{
+	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;
+
+	if (!sim_parse_umts_authenticate(resp, len, &res, &ck, &ik,
+			&auts, &kc))
+		goto umts_end;
+
+	reply = dbus_message_new_method_return(sim->pending->msg);
+
+	dbus_message_iter_init_append(reply, &iter);
+
+	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+			"{say}", &dict);
+
+	if (auts) {
+		append_dict_byte_array(&dict, "auts", auts, 16);
+	} 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);
+	}
+
+	dbus_message_iter_close_container(&iter, &dict);
+
+umts_end:
+	if (!reply)
+		reply = __ofono_error_not_supported(sim->pending->msg);
+
+	__ofono_dbus_pending_reply(&sim->pending->msg, reply);
+
+	sim->driver->close_channel(sim, sim->pending->session_id, NULL, NULL);
+
+	g_free(sim->pending);
+	sim->pending = NULL;
+}
+
+static void handle_gsm(struct ofono_sim_auth *sim, const uint8_t *resp,
+		uint16_t len)
+{
+	const uint8_t *sres = NULL;
+	const uint8_t *kc = NULL;
+
+	if (!sim_parse_gsm_authenticate(resp, len, &sres, &kc))
+		goto gsm_end;
+
+	/* initial iteration, setup the reply message */
+	if (sim->pending->cb_count == 0) {
+		sim->pending->reply = dbus_message_new_method_return(
+				sim->pending->msg);
+
+		dbus_message_iter_init_append(sim->pending->reply,
+				&sim->pending->iter);
+
+		dbus_message_iter_open_container(&sim->pending->iter,
+				DBUS_TYPE_ARRAY, "{say}", &sim->pending->dict);
+	}
+
+	/* append the Nth sres/kc byte arrays */
+	append_dict_byte_array(&sim->pending->dict, "sres", sres, 4);
+	append_dict_byte_array(&sim->pending->dict, "kc", kc, 8);
+
+	sim->pending->cb_count++;
+
+	/* calculated the number of keys requested, close container */
+	if (sim->pending->cb_count == sim->pending->num_rands) {
+		dbus_message_iter_close_container(&sim->pending->iter,
+				&sim->pending->dict);
+		goto gsm_end;
+	}
+
+	return;
+
+gsm_end:
+	if (!sim->pending->reply)
+		sim->pending->reply = __ofono_error_not_supported(
+				sim->pending->msg);
+
+	__ofono_dbus_pending_reply(&sim->pending->msg, sim->pending->reply);
+
+	sim->driver->close_channel(sim, sim->pending->session_id, NULL, NULL);
+
+	g_free(sim->pending);
+
+	sim->pending = NULL;
+}
+
+static void logical_access_cb(const struct ofono_error *error,
+		const uint8_t *resp, uint16_t len, void *data)
+{
+	struct ofono_sim_auth *sim = data;
+
+	if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+		__ofono_dbus_pending_reply(&sim->pending->msg,
+				__ofono_error_failed(sim->pending->msg));
+		g_free(sim->pending);
+		sim->pending = NULL;
+		return;
+	}
+
+	if (sim->pending->umts)
+		handle_umts(sim, resp, len);
+	else
+		handle_gsm(sim, resp, len);
+}
+
+static void open_channel_cb(const struct ofono_error *error, int session_id,
+		void *data)
+{
+	struct ofono_sim_auth *sim = data;
+	int i;
+
+	if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
+		goto error;
+
+	if (session_id == -1)
+		goto error;
+
+	/* save session ID for close_channel() */
+	sim->pending->session_id = session_id;
+
+	/*
+	 * This will do the logical access num_rand times, providing a new
+	 * RAND seed each time. In the UMTS case, num_rands should be 1.
+	 */
+	for (i = 0; i < sim->pending->num_rands; i++) {
+		uint8_t auth_cmd[40];
+		int len = 0;
+
+		if (sim->pending->umts)
+			len = sim_build_umts_authenticate(auth_cmd, 40,
+					sim->pending->rands[i],
+					sim->pending->autn);
+		else
+			len = sim_build_gsm_authenticate(auth_cmd, 40,
+					sim->pending->rands[i]);
+
+		if (!len)
+			goto error;
+
+		sim->driver->logical_access(sim, session_id, auth_cmd, len,
+				logical_access_cb, sim);
+	}
+
+	return;
+
+error:
+	__ofono_dbus_pending_reply(&sim->pending->msg,
+			__ofono_error_failed(sim->pending->msg));
+	g_free(sim->pending);
+	sim->pending = NULL;
+}
+
+static DBusMessage *usim_gsm_authenticate(DBusConnection *conn,
+		DBusMessage *msg, void *data)
+{
+	struct ofono_sim_auth *sim = data;
+	DBusMessageIter iter;
+	DBusMessageIter array;
+	int i;
+	struct sim_app_record *app;
+
+	if (sim->pending)
+		return __ofono_error_busy(msg);
+
+	dbus_message_iter_init(msg, &iter);
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
+		return __ofono_error_not_supported(msg);
+
+	sim->pending = malloc(sizeof(struct auth_request));
+	sim->pending->msg = dbus_message_ref(msg);
+	sim->pending->umts = 0;
+	sim->pending->cb_count = 0;
+	sim->pending->num_rands = dbus_message_iter_get_element_count(&iter);
+
+	dbus_message_iter_recurse(&iter, &array);
+
+	for (i = 0; i < sim->pending->num_rands; i++) {
+		int nelement;
+		DBusMessageIter in;
+
+		dbus_message_iter_recurse(&array, &in);
+
+		dbus_message_iter_get_fixed_array(&in, &sim->pending->rands[i],
+				&nelement);
+	}
+
+	app = find_channel(sim->aid_list, SIM_APP_TYPE_USIM);
+
+	if (app) {
+		sim->driver->open_channel(sim, app->aid, open_channel_cb, sim);
+	} else {
+		dbus_message_unref(sim->pending->msg);
+		g_free(sim->pending);
+		sim->pending = NULL;
+		return __ofono_error_not_supported(msg);
+	}
+
+	return NULL;
+}
+
+static DBusMessage *umts_common(DBusConnection *conn, DBusMessage *msg,
+					void *data, enum sim_app_type type)
+{
+	uint8_t *rand = NULL;
+	uint8_t *autn = NULL;
+	uint32_t rlen;
+	uint32_t alen;
+	struct ofono_sim_auth *sim = data;
+	struct sim_app_record *app;
+
+	if (sim->pending)
+		return __ofono_error_busy(msg);
+
+	/* get RAND/AUTN and setup handle args */
+	dbus_message_get_args(msg, NULL, DBUS_TYPE_ARRAY,
+			DBUS_TYPE_BYTE, &rand, &rlen, DBUS_TYPE_ARRAY,
+			DBUS_TYPE_BYTE, &autn, &alen,
+			DBUS_TYPE_INVALID);
+
+	sim->pending = malloc(sizeof(struct auth_request));
+	sim->pending->msg = dbus_message_ref(msg);
+	sim->pending->rands[0] = rand;
+	sim->pending->num_rands = 1;
+	sim->pending->autn = autn;
+	sim->pending->umts = 1;
+
+	app = find_channel(sim->aid_list, type);
+
+	if (app) {
+		sim->driver->open_channel(sim, app->aid, open_channel_cb, sim);
+	} else {
+		dbus_message_unref(sim->pending->msg);
+		g_free(sim->pending);
+		sim->pending = NULL;
+		return __ofono_error_not_supported(msg);
+	}
+
+	return NULL;
+}
+
+static DBusMessage *get_applications(DBusConnection *conn,
+		DBusMessage *msg, void *data)
+{
+	struct ofono_sim_auth *sim = data;
+	const char *path = __ofono_atom_get_path(sim->atom);
+	struct sim_app_record *app;
+	int ret;
+	char object[strlen(path) + 33];
+	DBusMessage *reply;
+	DBusMessageIter iter;
+	DBusMessageIter array;
+	DBusMessageIter dict;
+
+
+	if (!sim->aid_list)
+		return __ofono_error_busy(msg);
+
+	reply = dbus_message_new_method_return(msg);
+	if (reply == NULL)
+		return NULL;
+
+	dbus_message_iter_init_append(reply, &iter);
+
+	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{oa{sv}}",
+			&array);
+
+	app = find_channel(sim->aid_list, SIM_APP_TYPE_ISIM);
+
+	if (app) {
+		ret = sprintf(object, "%s/", path);
+		encode_hex_own_buf(app->aid, 16, 0, object + ret);
+
+		dbus_message_iter_open_container(&array, DBUS_TYPE_DICT_ENTRY,
+				NULL, &dict);
+		append_dict_application(&dict, object, "Ims", "ISim");
+		dbus_message_iter_close_container(&array, &dict);
+	}
+
+	app = find_channel(sim->aid_list, SIM_APP_TYPE_USIM);
+
+	if (app) {
+		ret = sprintf(object, "%s/", path);
+		encode_hex_own_buf(app->aid, 16, 0, object + ret);
+
+		dbus_message_iter_open_container(&array, DBUS_TYPE_DICT_ENTRY,
+				NULL, &dict);
+		append_dict_application(&dict, object, "Umts", "USim");
+		dbus_message_iter_close_container(&array, &dict);
+
+	}
+
+	dbus_message_iter_close_container(&iter, &array);
+
+	return reply;
+}
+
+static DBusMessage *send_properties(DBusConnection *conn, DBusMessage *msg,
+		void *data, const char *type, const char *name)
+{
+	DBusMessage *reply;
+	DBusMessageIter iter;
+	DBusMessageIter array;
+
+	reply = dbus_message_new_method_return(msg);
+	if (reply == NULL)
+		return NULL;
+
+	dbus_message_iter_init_append(reply, &iter);
+
+	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}",
+				&array);
+
+	ofono_dbus_dict_append(&array, "Type", DBUS_TYPE_STRING, &type);
+	ofono_dbus_dict_append(&array, "Name", DBUS_TYPE_STRING, &name);
+
+	dbus_message_iter_close_container(&iter, &array);
+
+	return reply;
+}
+
+static DBusMessage *usim_get_properties(DBusConnection *conn,
+		DBusMessage *msg, void *data)
+{
+	return send_properties(conn, msg, data, "Umts", "USim");
+}
+
+static DBusMessage *isim_get_properties(DBusConnection *conn,
+		DBusMessage *msg, void *data)
+{
+	return send_properties(conn, msg, data, "Ims", "ISim");
+}
+
+static DBusMessage *isim_ims_authenticate(DBusConnection *conn,
+		DBusMessage *msg, void *data)
+{
+	return umts_common(conn, msg, data, SIM_APP_TYPE_ISIM);
+}
+
+static DBusMessage *usim_umts_authenticate(DBusConnection *conn,
+		DBusMessage *msg, void *data)
+{
+	return umts_common(conn, msg, data, SIM_APP_TYPE_USIM);
+}
+
+static const GDBusMethodTable sim_authentication[] = {
+	{ GDBUS_METHOD("GetApplications",
+			NULL,
+			GDBUS_ARGS({"applications", "a{oa{sv}}"}),
+			get_applications) },
+	{ }
+};
+
+static const GDBusMethodTable sim_auth_usim_app[] = {
+	{ GDBUS_ASYNC_METHOD("GetProperties",
+			NULL,
+			GDBUS_ARGS({"properties", "a{sv}"}),
+			usim_get_properties) },
+	{ GDBUS_ASYNC_METHOD("GsmAuthenticate",
+			GDBUS_ARGS({"rands", "aay"}),
+			GDBUS_ARGS({"keys", "a{say}"}),
+			usim_gsm_authenticate) },
+	{ GDBUS_ASYNC_METHOD("UmtsAuthenticate",
+			GDBUS_ARGS({"rand", "ay"}, {"autn", "ay"}),
+			GDBUS_ARGS({"return", "a{sv}"}),
+			usim_umts_authenticate) },
+	{ }
+};
+
+static const GDBusMethodTable sim_auth_isim_app[] = {
+	{ GDBUS_ASYNC_METHOD("GetProperties",
+			NULL,
+			GDBUS_ARGS({"properties", "a{sv}"}),
+			isim_get_properties) },
+	{ GDBUS_ASYNC_METHOD("ImsAuthenticate",
+			GDBUS_ARGS({"rand", "ay"}, {"autn", "ay"}),
+			GDBUS_ARGS({"return", "a{sv}"}),
+			isim_ims_authenticate) },
+	{ }
+};
+
+static void discover_apps_cb(const struct ofono_error *error,
+		const unsigned char *dataobj,
+		int len, void *data)
+{
+	DBusConnection *conn = ofono_dbus_get_connection();
+	struct ofono_sim_auth *sim = data;
+	const char *path = __ofono_atom_get_path(sim->atom);
+	GSList *iter;
+	char app_path[strlen(path) + 34];
+	int ret;
+
+	if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
+		goto parse_error;
+
+	sim->aid_list = sim_parse_app_template_entries(dataobj, len);
+
+	if (!sim->aid_list)
+		goto parse_error;
+
+	iter = sim->aid_list;
+
+	ret = sprintf(app_path, "%s/", path);
+
+	while (iter) {
+		struct sim_app_record *app = iter->data;
+
+		switch (app->type) {
+		case SIM_APP_TYPE_USIM:
+			encode_hex_own_buf(app->aid, 16, 0, app_path + ret);
+
+			app_path[ret + 32] = '\0';
+
+			g_dbus_register_interface(conn, app_path,
+					OFONO_USIM_APPLICATION_INTERFACE,
+					sim_auth_usim_app, NULL, NULL,
+					sim, NULL);
+			break;
+		case SIM_APP_TYPE_ISIM:
+			encode_hex_own_buf(app->aid, 16, 0, app_path + ret);
+
+			app_path[ret + 32] = '\0';
+
+			g_dbus_register_interface(conn, app_path,
+					OFONO_ISIM_APPLICATION_INTERFACE,
+					sim_auth_isim_app, NULL, NULL,
+					sim, NULL);
+			break;
+		default:
+			DBG("Unknown SIM application '%04x'", app->type);
+			/*
+			 * If we get here, the SIM application was not ISIM
+			 * or USIM, skip.
+			 */
+		}
+
+		iter = g_slist_next(iter);
+	}
+
+	return;
+
+parse_error:
+	/*
+	 * Something went wrong parsing the AID list, it can't be assumed that
+	 * any previously parsed AID's are valid so free them all.
+	 */
+	DBG("Error parsing app list");
+}
+
 void ofono_sim_auth_register(struct ofono_sim_auth *sa)
 {
+	DBusConnection *conn = ofono_dbus_get_connection();
+	struct ofono_modem *modem = __ofono_atom_get_modem(sa->atom);
+	const char *path = __ofono_atom_get_path(sa->atom);
+
+	ofono_modem_add_interface(modem, OFONO_PHONEBOOK_INTERFACE);
+
 	__ofono_atom_register(sa->atom, sim_auth_unregister);
+
+	/* Do SIM application discovery, the cb will register DBus ifaces */
+	sa->driver->list_apps(sa, discover_apps_cb, sa);
+
+	sa->sim = __ofono_atom_find(OFONO_ATOM_TYPE_SIM, modem);
+
+	sa->gsm_access = __ofono_sim_ust_service_available(sa->sim,
+			SIM_UST_SERVICE_GSM_ACCESS);
+	sa->gsm_context = __ofono_sim_ust_service_available(sa->sim,
+			SIM_UST_SERVICE_GSM_SECURITY_CONTEXT);
+
+	g_dbus_register_interface(conn, path,
+			OFONO_SIM_AUTHENTICATION_INTERFACE,
+			sim_authentication, NULL, NULL,
+			sa, NULL);
+	ofono_modem_add_interface(modem,
+			OFONO_SIM_AUTHENTICATION_INTERFACE);
 }
 
 void ofono_sim_auth_remove(struct ofono_sim_auth *sa)
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCHv3 3/7] atmodem: implemented sim-auth functionality in atmodem
  2017-10-11 18:57 [PATCHv3 1/7] sim-auth: prep simauth/dbus headers James Prestwood
  2017-10-11 18:57 ` [PATCHv3 2/7] sim-auth: implementation of core sim-auth atom James Prestwood
@ 2017-10-11 18:57 ` James Prestwood
  2017-10-11 18:57 ` [PATCHv3 4/7] xmm7xxx: add sim-auth driver to xmm7xxx plugin James Prestwood
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: James Prestwood @ 2017-10-11 18:57 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 5085 bytes --]

Implemented the core API's needed for sim-auth:

list_apps: already implemented
open_channel: Opens a logical channel with +CCHO
close_channel: Closes logical channel with +CCHC
logical_access: Access an opened channel with +CGLA
---
 drivers/atmodem/sim-auth.c | 152 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 152 insertions(+)

diff --git a/drivers/atmodem/sim-auth.c b/drivers/atmodem/sim-auth.c
index 271ceed..d04f561 100644
--- a/drivers/atmodem/sim-auth.c
+++ b/drivers/atmodem/sim-auth.c
@@ -25,6 +25,7 @@
 
 #define _GNU_SOURCE
 #include <string.h>
+#include <stdio.h>
 
 #include <glib.h>
 
@@ -35,6 +36,7 @@
 #include "gatresult.h"
 #include "simutil.h"
 #include "vendor.h"
+#include "util.h"
 
 #include "atmodem.h"
 
@@ -44,6 +46,8 @@ struct sim_auth_data {
 };
 
 static const char *cuad_prefix[] = { "+CUAD:", NULL };
+static const char *ccho_prefix[] = { "+CCHO:", NULL };
+static const char *cgla_prefix[] = { "+CGLA:", NULL };
 
 static void at_discover_apps_cb(gboolean ok, GAtResult *result,
 				gpointer user_data)
@@ -110,6 +114,151 @@ static void at_discover_apps(struct ofono_sim_auth *sa,
 	CALLBACK_WITH_FAILURE(cb, NULL, 0, data);
 }
 
+static void at_open_channel_cb(gboolean ok, GAtResult *result,
+		gpointer user_data)
+{
+	struct cb_data *cbd = user_data;
+	GAtResultIter iter;
+	ofono_sim_open_channel_cb_t cb = cbd->cb;
+	struct ofono_error error;
+	int session_id = -1;
+
+	decode_at_error(&error, g_at_result_final_response(result));
+
+	if (!ok)
+		goto error;
+
+	g_at_result_iter_init(&iter, result);
+
+	if (!g_at_result_iter_next(&iter, "+CCHO:"))
+		goto error;
+
+	if (!g_at_result_iter_next_number(&iter, &session_id))
+		goto error;
+
+	cb(&error, session_id, cbd->data);
+
+	return;
+
+error:
+	cb(&error, -1, cbd->data);
+}
+
+static void at_open_channel(struct ofono_sim_auth *sa, const uint8_t *aid,
+		ofono_sim_open_channel_cb_t cb, void *data)
+{
+	struct sim_auth_data *sad = ofono_sim_auth_get_data(sa);
+	struct cb_data *cbd = cb_data_new(cb, data);
+	char cmd[43];
+	int ret = 0;
+
+	strcpy(cmd, "AT+CCHO=\"");
+	ret += 9;
+
+	encode_hex_own_buf(aid, 16, 0, cmd + ret);
+	ret += 32;
+
+	strcpy(cmd + ret, "\"");
+
+	if (g_at_chat_send(sad->chat, cmd, ccho_prefix, at_open_channel_cb,
+			cbd, g_free) > 0)
+		return;
+
+	g_free(cbd);
+
+	CALLBACK_WITH_FAILURE(cb, -1, data);
+}
+
+static void at_close_channel_cb(gboolean ok, GAtResult *result,
+		gpointer user_data)
+{
+	struct cb_data *cbd = user_data;
+	ofono_sim_close_channel_cb_t cb = cbd->cb;
+	struct ofono_error error;
+
+	decode_at_error(&error, g_at_result_final_response(result));
+
+	if (cb)
+		cb(&error, cbd->data);
+}
+
+static void at_close_channel(struct ofono_sim_auth *sa, int session_id,
+		ofono_sim_close_channel_cb_t cb, void *data)
+{
+	struct sim_auth_data *sad = ofono_sim_auth_get_data(sa);
+	struct cb_data *cbd = cb_data_new(cb, data);
+	char cmd[15];
+
+	sprintf(cmd, "AT+CCHC=%d", session_id);
+
+	g_at_chat_send(sad->chat, cmd, NULL, at_close_channel_cb, cbd, g_free);
+}
+
+static void logical_access_cb(gboolean ok, GAtResult *result,
+		gpointer user_data)
+{
+	struct cb_data *cbd = user_data;
+	ofono_logical_access_cb_t cb = cbd->cb;
+	struct ofono_error error;
+	const char *str_data;
+	uint8_t *raw;
+	gint len = 0;
+	GAtResultIter iter;
+
+	decode_at_error(&error, g_at_result_final_response(result));
+
+	if (!ok)
+		goto error;
+
+	g_at_result_iter_init(&iter, result);
+
+	if (!g_at_result_iter_next(&iter, "+CGLA:"))
+		goto error;
+
+	if (!g_at_result_iter_next_number(&iter, &len))
+		goto error;
+
+	if (!g_at_result_iter_next_string(&iter, &str_data))
+		goto error;
+
+	raw = alloca(len / 2);
+
+	decode_hex_own_buf(str_data, len, NULL, 0, raw);
+
+	cb(&error, raw, len / 2, cbd->data);
+
+	return;
+
+error:
+	cb(&error, NULL, 0, cbd->data);
+}
+
+static void at_logical_access(struct ofono_sim_auth *sa, int session_id,
+		const uint8_t *pdu, uint16_t len, ofono_logical_access_cb_t cb,
+		void *data)
+
+{
+	struct sim_auth_data *sad = ofono_sim_auth_get_data(sa);
+	struct cb_data *cbd = cb_data_new(cb, data);
+	int ret = 0;
+	char cmd[(len * 2) + 19];
+
+	ret = sprintf(cmd, "AT+CGLA=%d,%d,\"", session_id, len * 2);
+
+	encode_hex_own_buf(pdu, len, 0, cmd + ret);
+	ret += len * 2;
+
+	strcpy(cmd + ret, "\"");
+
+	if (g_at_chat_send(sad->chat, cmd, cgla_prefix, logical_access_cb,
+			cbd, g_free) > 0)
+		return;
+
+	g_free(cbd);
+
+	CALLBACK_WITH_FAILURE(cb, NULL, 0, data);
+}
+
 static gboolean at_sim_auth_register(gpointer user)
 {
 	struct ofono_sim_auth *sa = user;
@@ -151,6 +300,9 @@ static struct ofono_sim_auth_driver driver = {
 	.probe		= at_sim_auth_probe,
 	.remove		= at_sim_auth_remove,
 	.list_apps	= at_discover_apps,
+	.open_channel	= at_open_channel,
+	.close_channel	= at_close_channel,
+	.logical_access = at_logical_access
 };
 
 void at_sim_auth_init(void)
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCHv3 4/7] xmm7xxx: add sim-auth driver to xmm7xxx plugin
  2017-10-11 18:57 [PATCHv3 1/7] sim-auth: prep simauth/dbus headers James Prestwood
  2017-10-11 18:57 ` [PATCHv3 2/7] sim-auth: implementation of core sim-auth atom James Prestwood
  2017-10-11 18:57 ` [PATCHv3 3/7] atmodem: implemented sim-auth functionality in atmodem James Prestwood
@ 2017-10-11 18:57 ` James Prestwood
  2017-10-11 18:57 ` [PATCHv3 5/7] phonesim: Added sim-auth to phonesim plugin James Prestwood
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: James Prestwood @ 2017-10-11 18:57 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 1055 bytes --]

---
 plugins/xmm7xxx.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/plugins/xmm7xxx.c b/plugins/xmm7xxx.c
index 5cb843b..ff0cb4c 100644
--- a/plugins/xmm7xxx.c
+++ b/plugins/xmm7xxx.c
@@ -49,6 +49,7 @@
 #include <ofono/stk.h>
 #include <ofono/lte.h>
 #include <ofono/ims.h>
+#include <ofono/sim-auth.h>
 
 #include <drivers/atmodem/atutil.h>
 #include <drivers/atmodem/vendor.h>
@@ -61,6 +62,7 @@ struct xmm7xxx_data {
 	struct ofono_sim *sim;
 	ofono_bool_t have_sim;
 	ofono_bool_t sms_phonebook_added;
+	struct ofono_sim_auth *sim_auth;
 };
 
 static void xmm7xxx_debug(const char *str, void *user_data)
@@ -286,6 +288,7 @@ static void xmm7xxx_pre_sim(struct ofono_modem *modem)
 	ofono_devinfo_create(modem, OFONO_VENDOR_IFX, "atmodem", data->chat);
 	data->sim = ofono_sim_create(modem, OFONO_VENDOR_IFX, "atmodem",
 					data->chat);
+	data->sim_auth = ofono_sim_auth_create(modem, 0, "atmodem", data->chat);
 }
 
 static void set_online_cb(gboolean ok, GAtResult *result, gpointer user_data)
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCHv3 5/7] phonesim: Added sim-auth to phonesim plugin
  2017-10-11 18:57 [PATCHv3 1/7] sim-auth: prep simauth/dbus headers James Prestwood
                   ` (2 preceding siblings ...)
  2017-10-11 18:57 ` [PATCHv3 4/7] xmm7xxx: add sim-auth driver to xmm7xxx plugin James Prestwood
@ 2017-10-11 18:57 ` James Prestwood
  2017-10-11 18:57 ` [PATCHv3 6/7] test: added tests for GSM/UMTS auth algorithms James Prestwood
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: James Prestwood @ 2017-10-11 18:57 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 977 bytes --]

---
 plugins/phonesim.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/plugins/phonesim.c b/plugins/phonesim.c
index 16bccd5..345c41e 100644
--- a/plugins/phonesim.c
+++ b/plugins/phonesim.c
@@ -61,6 +61,7 @@
 #include <ofono/gnss.h>
 #include <ofono/handsfree.h>
 #include <ofono/siri.h>
+#include <ofono/sim-auth.h>
 
 #include <drivers/atmodem/vendor.h>
 #include <drivers/atmodem/atutil.h>
@@ -84,6 +85,7 @@ struct phonesim_data {
 	unsigned int hfp_watch;
 	int batt_level;
 	struct ofono_sim *sim;
+	struct ofono_sim_auth *sim_auth;
 };
 
 struct gprs_context_data {
@@ -839,6 +841,8 @@ static void phonesim_pre_sim(struct ofono_modem *modem)
 		ofono_voicecall_create(modem, 0, "calypsomodem", data->chat);
 	else
 		ofono_voicecall_create(modem, 0, "atmodem", data->chat);
+
+	data->sim_auth = ofono_sim_auth_create(modem, 0, "atmodem", data->chat);
 }
 
 static void phonesim_post_sim(struct ofono_modem *modem)
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCHv3 6/7] test: added tests for GSM/UMTS auth algorithms
  2017-10-11 18:57 [PATCHv3 1/7] sim-auth: prep simauth/dbus headers James Prestwood
                   ` (3 preceding siblings ...)
  2017-10-11 18:57 ` [PATCHv3 5/7] phonesim: Added sim-auth to phonesim plugin James Prestwood
@ 2017-10-11 18:57 ` James Prestwood
  2017-10-11 18:57 ` [PATCHv3 7/7] doc: documentation for SimAuth dbus interfaces James Prestwood
  2017-10-11 19:17 ` [PATCHv3 1/7] sim-auth: prep simauth/dbus headers Denis Kenzior
  6 siblings, 0 replies; 10+ messages in thread
From: James Prestwood @ 2017-10-11 18:57 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 2551 bytes --]

---
 test/run-isim-umts-auth | 38 ++++++++++++++++++++++++++++++++++++++
 test/run-usim-gsm-auth  | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+)
 create mode 100755 test/run-isim-umts-auth
 create mode 100755 test/run-usim-gsm-auth

diff --git a/test/run-isim-umts-auth b/test/run-isim-umts-auth
new file mode 100755
index 0000000..117822b
--- /dev/null
+++ b/test/run-isim-umts-auth
@@ -0,0 +1,38 @@
+#!/usr/bin/python3
+
+import dbus
+import sys
+
+bus = dbus.SystemBus()
+
+if len(sys.argv) == 4:
+	path = sys.argv[1]
+	rand = sys.argv[2]
+	autn = sys.argv[3]
+
+	sim_auth = dbus.Interface(bus.get_object('org.ofono', path),
+							'org.ofono.SimAuthentication')
+	apps = sim_auth.GetApplications()
+	for i in apps:
+		if apps[i]['Type'] == 'Ims':
+			ims_path = i
+
+	if not ims_path:
+		print("No Ims application found")
+		quit()
+
+	isim_auth = dbus.Interface(bus.get_object('org.ofono', ims_path),
+							'org.ofono.ISimApplication')
+	ret = isim_auth.ImsAuthenticate(bytearray.fromhex(rand),
+								bytearray.fromhex(autn))
+
+	if 'auts' in ret:
+		print('Sync Failure')
+		print('AUTS: ' + ''.join('%02x' % x for x in ret['auts']))
+	else:
+		print('Success')
+		print('RES: ' +  ''.join('%02x' % x for x in ret['res']))
+		print('CK: ' + ''.join('%02x' % x for x in ret['ck']))
+		print('IK: ' + ''.join('%02x' % x for x in ret['ik']))
+else:
+	print("./run-isim-umts-auth <modem> <rand> <autn>")
diff --git a/test/run-usim-gsm-auth b/test/run-usim-gsm-auth
new file mode 100755
index 0000000..d0a0c82
--- /dev/null
+++ b/test/run-usim-gsm-auth
@@ -0,0 +1,36 @@
+#!/usr/bin/python3
+
+import dbus
+import sys
+
+bus = dbus.SystemBus()
+
+if len(sys.argv) < 6 and len(sys.argv) > 2:
+	path = sys.argv[1]
+
+	rands = []
+	for i in sys.argv[2:]:
+		rands.append(bytearray.fromhex(i))
+
+	sim_auth = dbus.Interface(bus.get_object('org.ofono', path),
+							'org.ofono.SimAuthentication')
+	apps = sim_auth.GetApplications()
+
+	for i in apps:
+		if apps[i]['Type'] == 'Umts':
+			umts_path = i
+
+	if not umts_path:
+		print("No Umts application found")
+		quit()
+
+	umts = dbus.Interface(bus.get_object('org.ofono', umts_path),
+						'org.ofono.USimApplication')
+	av = umts.GsmAuthenticate(rands)
+
+	for i in av:
+		print('SRES: ' + ''.join('%02x' % x for x in i['sres']))
+		print('KC: ' + ''.join('%02x' % x for x in i['kc']))
+
+else:
+	print("./run-usim-gsm-auth <modem> <rands>...[up to 3]")
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCHv3 7/7] doc: documentation for SimAuth dbus interfaces
  2017-10-11 18:57 [PATCHv3 1/7] sim-auth: prep simauth/dbus headers James Prestwood
                   ` (4 preceding siblings ...)
  2017-10-11 18:57 ` [PATCHv3 6/7] test: added tests for GSM/UMTS auth algorithms James Prestwood
@ 2017-10-11 18:57 ` James Prestwood
  2017-10-11 19:58   ` Denis Kenzior
  2017-10-11 19:17 ` [PATCHv3 1/7] sim-auth: prep simauth/dbus headers Denis Kenzior
  6 siblings, 1 reply; 10+ messages in thread
From: James Prestwood @ 2017-10-11 18:57 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 3582 bytes --]

---
 doc/sim-auth-api.txt | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 101 insertions(+)
 create mode 100644 doc/sim-auth-api.txt

diff --git a/doc/sim-auth-api.txt b/doc/sim-auth-api.txt
new file mode 100644
index 0000000..ce54ea4
--- /dev/null
+++ b/doc/sim-auth-api.txt
@@ -0,0 +1,101 @@
+SimAuthentication heiarchy [experimental]
+===========================================
+
+Service		org.ofono
+Interface	org.ofono.SimAuthentication
+Object path	[variable prefix]/{modem0,modem1,...}
+
+Methods		array{object,dict} GetApplications()
+
+			Get an array of all SIM applications found during
+			discovery. In the format "a{oa{sv}}" where 'o' is
+			the object path for the application e.g.
+
+			o = "/modem1/A0000000871004FFFFFFFF8906190000"
+
+			Each dictionary will contain 'Type' e.g. 'Ims' and
+			'Name' e.g. 'ISim'
+
+			For each application there will be a corresponding
+			object that matches the path (o). The type will
+			signify which interfaces are under that object (below).
+
+			type = Umts --> org.ofono.USimApplication
+			type = Ims  --> org.ofono.ISimApplication
+
+SimAuth USIM application heiarchy [experimental]
+===========================================
+
+Service		org.ofono
+Interface	org.ofono.USimApplication
+Object path	[variable prefix]/{modem0,modem1,...}/{AID name}
+
+Methods		dict GetProperties()
+
+			Returns properties for the USimApplication. See
+			properties section for available properties.
+
+		array{string, dict} GsmAuthenticate(array{array{byte}} rands)
+
+			Run the USIM application GSM AUTHENTICATE algorithm
+			with N random challenges 'rands'. This should be an
+			array of an array of bytes ("aay"). The number of
+			random challenges is limited to a maximum of 3.
+
+			Returns the derived Kc/SRES values as an array of
+			dictionaries. The index of each dictionary matches
+			the index of the rand value in the method call. The
+			keys for each dictionary are "Kc" and "SRES" and both
+			are arrays of bytes.
+
+			Possible Errors:
+				[service].Error.NotSupported
+				[service].Error.Busy
+
+		dict UmtsAuthenticate(array{byte} rand, array{byte} autn)
+
+			Run the UMTS AUTHENTICATE algorithm in the 3G
+			context with 'rand' and 'autn'. A dictionary will be
+			returned containing 'RES', 'CK', 'IK' and possibly
+			'Kc' if service 27 is available. If there was a
+			sync error 'auts' will be returned.
+
+			Possible Errors: [service].Error.NotSupported
+
+Properties	string Type [readonly]
+
+			Type of application: 'Umts'
+
+		string Name [readonly]
+
+			Human readable name: 'USim'
+
+SimAuth ISIM application heiarchy [experimental]
+===========================================
+
+Service		org.ofono
+Interface	org.ofono.ISimApplication
+Object		[variable prefix]/{modem0,modem1,...}/{AID name}
+
+Methods		dict GetProperties()
+
+			Returns properties for the ISimApplication. See
+			the properties section for available properties.
+
+		dict ImsAuthenticate(array{byte} rand, array{byte} autn)
+
+			Run the UMTS AUTHENTICATE algorithm in the IMS
+			context with 'rand' and 'autn'. A dictionary will be
+			returned containing 'RES', 'CK', 'IK' and possibly
+			'Kc' if service 27 is available. If there was a
+			sync error 'auts' will be returned.
+
+			Possible Errors: [service].Error.NotSupported
+
+Properties	string Type [readonly]
+
+			Type of application: 'Ims'
+
+		string Name [readonly]
+
+			Human readable name: 'ISim'
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCHv3 1/7] sim-auth: prep simauth/dbus headers
  2017-10-11 18:57 [PATCHv3 1/7] sim-auth: prep simauth/dbus headers James Prestwood
                   ` (5 preceding siblings ...)
  2017-10-11 18:57 ` [PATCHv3 7/7] doc: documentation for SimAuth dbus interfaces James Prestwood
@ 2017-10-11 19:17 ` Denis Kenzior
  6 siblings, 0 replies; 10+ messages in thread
From: Denis Kenzior @ 2017-10-11 19:17 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 646 bytes --]

Hi James,

On 10/11/2017 01:57 PM, James Prestwood wrote:
> Added new dbus interfaces for SimAuth module as well as
> function prototype definitions to simauth header.
> 
> org.ofono.SimAuthentication:
>     Interface to hold the auth object to type mapping property
> 
> org.ofono.USimApplication:
>     Application with USim functionality (GSM/UMTS auth)
> 
> org.ofono.ISimApplication:
>     Application with ISim functionality (IMS auth)
> ---
>   include/dbus.h     |  3 +++
>   include/sim-auth.h | 20 +++++++++++++++++++-
>   2 files changed, 22 insertions(+), 1 deletion(-)
> 

Applied, thanks.

Regards,
-Denis


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCHv3 7/7] doc: documentation for SimAuth dbus interfaces
  2017-10-11 18:57 ` [PATCHv3 7/7] doc: documentation for SimAuth dbus interfaces James Prestwood
@ 2017-10-11 19:58   ` Denis Kenzior
  0 siblings, 0 replies; 10+ messages in thread
From: Denis Kenzior @ 2017-10-11 19:58 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 4872 bytes --]

Hi James,

On 10/11/2017 01:57 PM, James Prestwood wrote:
> ---
>   doc/sim-auth-api.txt | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 101 insertions(+)
>   create mode 100644 doc/sim-auth-api.txt
> 
> diff --git a/doc/sim-auth-api.txt b/doc/sim-auth-api.txt
> new file mode 100644
> index 0000000..ce54ea4
> --- /dev/null
> +++ b/doc/sim-auth-api.txt
> @@ -0,0 +1,101 @@
> +SimAuthentication heiarchy [experimental]
> +===========================================
> +
> +Service		org.ofono
> +Interface	org.ofono.SimAuthentication
> +Object path	[variable prefix]/{modem0,modem1,...}
> +
> +Methods		array{object,dict} GetApplications()
> +
> +			Get an array of all SIM applications found during
> +			discovery. In the format "a{oa{sv}}" where 'o' is
> +			the object path for the application e.g.
> +
> +			o = "/modem1/A0000000871004FFFFFFFF8906190000"
> +
> +			Each dictionary will contain 'Type' e.g. 'Ims' and
> +			'Name' e.g. 'ISim'
> +
> +			For each application there will be a corresponding
> +			object that matches the path (o). The type will
> +			signify which interfaces are under that object (below).
> +
> +			type = Umts --> org.ofono.USimApplication
> +			type = Ims  --> org.ofono.ISimApplication
> +
> +SimAuth USIM application heiarchy [experimental]
> +===========================================
> +
> +Service		org.ofono
> +Interface	org.ofono.USimApplication
> +Object path	[variable prefix]/{modem0,modem1,...}/{AID name}
> +
> +Methods		dict GetProperties()
> +
> +			Returns properties for the USimApplication. See
> +			properties section for available properties.
> +
> +		array{string, dict} GsmAuthenticate(array{array{byte}} rands)
> +

In our documentation nomenclature dict = a{sv}.  E.g. as used by 
GetProperties.  It doesn't look like this is what is being returned. 
Also, DBus dictionary is generally used as a representation for a 
map/hashmap type data structure.  So the keys are assumed to be unique. 
It looks like your implementation does something like:

[{"sres", ay (16 bytes)}, {"kc", ay (16 bytes) }, {"sres", "ay (16 
bytes)}, {"kc", ay (16 bytes) }]

What you want is likely:
aa{say}

[
[{ "sres", ay }, { "kc", ay }] /* Dictionary for the first rand */
[{ "sres", ay }, { "kc", ay }] /* Dictionary for the second rand */
]

One general problem is that we have never documented non a{sv} type 
dictionaries in our D-Bus API, so we have to invent a new nomenclature. 
How about:

array{dict{string, array{byte}}} -> aa{say}

> +			Run the USIM application GSM AUTHENTICATE algorithm
> +			with N random challenges 'rands'. This should be an
> +			array of an array of bytes ("aay"). The number of
> +			random challenges is limited to a maximum of 3.
> +
> +			Returns the derived Kc/SRES values as an array of
> +			dictionaries. The index of each dictionary matches
> +			the index of the rand value in the method call. The
> +			keys for each dictionary are "Kc" and "SRES" and both
> +			are arrays of bytes.
> +
> +			Possible Errors:
> +				[service].Error.NotSupported
> +				[service].Error.Busy
> +
> +		dict UmtsAuthenticate(array{byte} rand, array{byte} autn)
> +

Similarly here, dict is not the precise data type.  It should be a{say}, 
so maybe dict{string, array{byte}}

> +			Run the UMTS AUTHENTICATE algorithm in the 3G
> +			context with 'rand' and 'autn'. A dictionary will be
> +			returned containing 'RES', 'CK', 'IK' and possibly
> +			'Kc' if service 27 is available. If there was a
> +			sync error 'auts' will be returned.
> +
> +			Possible Errors: [service].Error.NotSupported
> +
> +Properties	string Type [readonly]
> +
> +			Type of application: 'Umts'
> +
> +		string Name [readonly]
> +
> +			Human readable name: 'USim'
> +
> +SimAuth ISIM application heiarchy [experimental]
> +===========================================
> +
> +Service		org.ofono
> +Interface	org.ofono.ISimApplication
> +Object		[variable prefix]/{modem0,modem1,...}/{AID name}
> +
> +Methods		dict GetProperties()
> +
> +			Returns properties for the ISimApplication. See
> +			the properties section for available properties.
> +
> +		dict ImsAuthenticate(array{byte} rand, array{byte} autn)
> +

Same comment about dict applies here...

> +			Run the UMTS AUTHENTICATE algorithm in the IMS
> +			context with 'rand' and 'autn'. A dictionary will be
> +			returned containing 'RES', 'CK', 'IK' and possibly
> +			'Kc' if service 27 is available. If there was a
> +			sync error 'auts' will be returned.
> +
> +			Possible Errors: [service].Error.NotSupported
> +
> +Properties	string Type [readonly]
> +
> +			Type of application: 'Ims'
> +
> +		string Name [readonly]
> +
> +			Human readable name: 'ISim'
> 

Regards,
-Denis

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCHv3 2/7] sim-auth: implementation of core sim-auth atom
  2017-10-11 18:57 ` [PATCHv3 2/7] sim-auth: implementation of core sim-auth atom James Prestwood
@ 2017-10-11 20:11   ` Denis Kenzior
  0 siblings, 0 replies; 10+ messages in thread
From: Denis Kenzior @ 2017-10-11 20:11 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 21887 bytes --]

Hi James,

On 10/11/2017 01:57 PM, James Prestwood wrote:
> The sim-auth module atom can now be used for SIM application discovery
> and authentication. The atom will automatically discover SIM
> applications available on the SIM and register a new DBus object under
> the modem, whos name is the AID string e.g.
> 
> /modem1/A0000000871004FFFFFFFF8906190000
> 
> A list of discovered AID object paths and types can be found under the
> modems (new) org.ofono.SimAuthentication interface "applications"
> property in the format:
> 
> "a{o(ss)}" where

This needs to be updated ...

> 
> o = path (e.g. above)
> s = type (Umts, Ims)
> s = name (USim, ISim etc.)
> 
> The type signifies which interfaces the AID object will have:
> 
> Umts = org.ofono.USimApplication
> Ims = org.ofono.ISimApplication
> 
> These interfaces will contain the supported USIM/ISIM authentication
> algorithms. Where:
> 
> org.ofono.USimApplication has:
>      GsmAuthenticate()
>      UmtsAuthenticate()
> 
> org.ofono.ISimApplication has:
>      ImsAuthenticate()
> ---
>   src/sim-auth.c | 607 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 607 insertions(+)
> 
> diff --git a/src/sim-auth.c b/src/sim-auth.c
> index 5d2f075..b8a7087 100644
> --- a/src/sim-auth.c
> +++ b/src/sim-auth.c
> @@ -28,19 +28,102 @@
>   #include <glib.h>
>   #include <errno.h>
>   #include <unistd.h>
> +#include <gdbus.h>
> +#include <string.h>
> +#include <stdio.h>
>   
>   #include "ofono.h"
>   
>   #include "simutil.h"
> +#include "util.h"
> +
> +#define SIM_AUTH_MAX_RANDS	3
>   
>   static GSList *g_drivers = NULL;
>   
> +/*
> + * Temporary handle used for the command authentication sequence.
> + */
> +struct auth_request {
> +	/* DBus values for GSM authentication */
> +	DBusMessage *msg;
> +	DBusMessage *reply;
> +	DBusMessageIter iter;
> +	DBusMessageIter dict;
> +	/* ID from open_channel */
> +	int session_id;
> +	/* list of rands to calculate key (1 if umts == 1) */
> +	void *rands[SIM_AUTH_MAX_RANDS];
> +	int num_rands;
> +	/* number of keys that have been returned */
> +	int cb_count;
> +	void *autn;
> +	uint8_t umts : 1;
> +};
> +
>   struct ofono_sim_auth {
>   	const struct ofono_sim_auth_driver *driver;
>   	void *driver_data;
>   	struct ofono_atom *atom;
> +	GSList *aid_list;
> +	struct ofono_sim *sim;
> +	uint8_t gsm_access : 1;
> +	uint8_t gsm_context : 1;
> +	struct auth_request *pending;

What cleans up pending ?

>   };
>   
> +/*
> + * Find an AID channel by the type of application
> + */
> +static struct sim_app_record *find_channel(GSList *aid_list,

The naming is a bit strange.  Aren't you finding the application by 
type?  Maybe

find_aid_by_type or
find_application_by_type

would be better

> +		enum sim_app_type type)
> +{
> +	GSList *iter = aid_list;
> +
> +	while (iter) {
> +		struct sim_app_record *app = iter->data;
> +
> +		if (app->type == type)
> +			return app;
> +
> +		iter = g_slist_next(iter);
> +	}
> +
> +	return NULL;
> +}
> +
> +/*
> + * Free all discovered AID's
> + */
> +static void free_apps(struct ofono_sim_auth *sa)
> +{
> +	DBusConnection *conn = ofono_dbus_get_connection();
> +	struct ofono_modem *modem = __ofono_atom_get_modem(sa->atom);
> +	const char *path = __ofono_atom_get_path(sa->atom);
> +	GSList *iter = sa->aid_list;
> +
> +

No double-free lines please

> +	while (iter) {
> +		struct sim_app_record *app = iter->data;
> +
> +		if (app->type == SIM_APP_TYPE_USIM) {
> +			g_dbus_unregister_interface(conn, path,
> +					OFONO_USIM_APPLICATION_INTERFACE);
> +			ofono_modem_remove_interface(modem,
> +					OFONO_USIM_APPLICATION_INTERFACE);
> +		} else if (app->type == SIM_APP_TYPE_ISIM) {
> +			g_dbus_unregister_interface(conn, path,
> +					OFONO_ISIM_APPLICATION_INTERFACE);
> +			ofono_modem_remove_interface(modem,
> +					OFONO_USIM_APPLICATION_INTERFACE);
> +		}
> +
> +		iter = g_slist_next(iter);
> +	}
> +
> +	g_slist_free(sa->aid_list);
> +}
> +
>   int ofono_sim_auth_driver_register(const struct ofono_sim_auth_driver *d)
>   {
>   	DBG("driver: %p, name: %s", d, d->name);
> @@ -62,6 +145,9 @@ void ofono_sim_auth_driver_unregister(const struct ofono_sim_auth_driver *d)
>   
>   static void sim_auth_unregister(struct ofono_atom *atom)
>   {
> +	struct ofono_sim_auth *sa = __ofono_atom_get_data(atom);
> +
> +	free_apps(sa);
>   }
>   
>   static void sim_auth_remove(struct ofono_atom *atom)
> @@ -113,9 +199,530 @@ struct ofono_sim_auth *ofono_sim_auth_create(struct ofono_modem *modem,
>   	return sa;
>   }
>   
> +/*
> + * appends {o(ss)} into an existing dict array

Comment is out of date

> + */
> +static void append_dict_application(DBusMessageIter *iter, const char *path,
> +		const char *type, const char *name)
> +{
> +	DBusMessageIter array;
> +
> +	dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path);
> +
> +	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "{sv}", &array);
> +
> +	ofono_dbus_dict_append(&array, "Type", DBUS_TYPE_STRING, &type);
> +	ofono_dbus_dict_append(&array, "Name", DBUS_TYPE_STRING, &name);
> +
> +	dbus_message_iter_close_container(iter, &array);
> +}
> +
> +/*
> + * appends {say} onto an existing dict array
> + */
> +static void append_dict_byte_array(DBusMessageIter *iter, const char *key,
> +		const void *arr, uint32_t len)
> +{
> +	DBusMessageIter keyiter;
> +	DBusMessageIter valueiter;
> +
> +	dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, NULL,
> +			&keyiter);
> +	dbus_message_iter_append_basic(&keyiter, DBUS_TYPE_STRING, &key);
> +	dbus_message_iter_open_container(&keyiter, DBUS_TYPE_ARRAY,
> +			"y", &valueiter);
> +	dbus_message_iter_append_fixed_array(&valueiter, DBUS_TYPE_BYTE, &arr,
> +			len);
> +	dbus_message_iter_close_container(&keyiter, &valueiter);
> +	dbus_message_iter_close_container(iter, &keyiter);
> +}
> +
> +static void handle_umts(struct ofono_sim_auth *sim, const uint8_t *resp,
> +		uint16_t len)
> +{
> +	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;
> +
> +	if (!sim_parse_umts_authenticate(resp, len, &res, &ck, &ik,
> +			&auts, &kc))
> +		goto umts_end;
> +
> +	reply = dbus_message_new_method_return(sim->pending->msg);
> +
> +	dbus_message_iter_init_append(reply, &iter);
> +
> +	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
> +			"{say}", &dict);
> +
> +	if (auts) {
> +		append_dict_byte_array(&dict, "auts", auts, 16);
> +	} 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);

Do these match the capitalization in the docs?

> +		if (kc)
> +			append_dict_byte_array(&dict, "kc", kc, 8);
> +	}
> +
> +	dbus_message_iter_close_container(&iter, &dict);
> +
> +umts_end:
> +	if (!reply)
> +		reply = __ofono_error_not_supported(sim->pending->msg);
> +
> +	__ofono_dbus_pending_reply(&sim->pending->msg, reply);
> +
> +	sim->driver->close_channel(sim, sim->pending->session_id, NULL, NULL);
> +
> +	g_free(sim->pending);
> +	sim->pending = NULL;
> +}
> +
> +static void handle_gsm(struct ofono_sim_auth *sim, const uint8_t *resp,
> +		uint16_t len)
> +{
> +	const uint8_t *sres = NULL;
> +	const uint8_t *kc = NULL;
> +
> +	if (!sim_parse_gsm_authenticate(resp, len, &sres, &kc))
> +		goto gsm_end;
> +
> +	/* initial iteration, setup the reply message */
> +	if (sim->pending->cb_count == 0) {
> +		sim->pending->reply = dbus_message_new_method_return(
> +				sim->pending->msg);
> +
> +		dbus_message_iter_init_append(sim->pending->reply,
> +				&sim->pending->iter);
> +
> +		dbus_message_iter_open_container(&sim->pending->iter,
> +				DBUS_TYPE_ARRAY, "{say}", &sim->pending->dict);
> +	}
> +
> +	/* append the Nth sres/kc byte arrays */
> +	append_dict_byte_array(&sim->pending->dict, "sres", sres, 4);
> +	append_dict_byte_array(&sim->pending->dict, "kc", kc, 8);
> +
> +	sim->pending->cb_count++;
> +
> +	/* calculated the number of keys requested, close container */
> +	if (sim->pending->cb_count == sim->pending->num_rands) {
> +		dbus_message_iter_close_container(&sim->pending->iter,
> +				&sim->pending->dict);
> +		goto gsm_end;
> +	}
> +
> +	return;
> +
> +gsm_end:
> +	if (!sim->pending->reply)
> +		sim->pending->reply = __ofono_error_not_supported(
> +				sim->pending->msg);
> +
> +	__ofono_dbus_pending_reply(&sim->pending->msg, sim->pending->reply);
> +
> +	sim->driver->close_channel(sim, sim->pending->session_id, NULL, NULL);
> +
> +	g_free(sim->pending);
> +
> +	sim->pending = NULL;
> +}
> +
> +static void logical_access_cb(const struct ofono_error *error,
> +		const uint8_t *resp, uint16_t len, void *data)
> +{
> +	struct ofono_sim_auth *sim = data;
> +
> +	if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
> +		__ofono_dbus_pending_reply(&sim->pending->msg,
> +				__ofono_error_failed(sim->pending->msg));
> +		g_free(sim->pending);
> +		sim->pending = NULL;
> +		return;
> +	}
> +
> +	if (sim->pending->umts)
> +		handle_umts(sim, resp, len);
> +	else
> +		handle_gsm(sim, resp, len);
> +}
> +
> +static void open_channel_cb(const struct ofono_error *error, int session_id,
> +		void *data)
> +{
> +	struct ofono_sim_auth *sim = data;
> +	int i;
> +
> +	if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
> +		goto error;
> +
> +	if (session_id == -1)
> +		goto error;
> +
> +	/* save session ID for close_channel() */
> +	sim->pending->session_id = session_id;
> +
> +	/*
> +	 * This will do the logical access num_rand times, providing a new
> +	 * RAND seed each time. In the UMTS case, num_rands should be 1.
> +	 */
> +	for (i = 0; i < sim->pending->num_rands; i++) {
> +		uint8_t auth_cmd[40];
> +		int len = 0;
> +
> +		if (sim->pending->umts)
> +			len = sim_build_umts_authenticate(auth_cmd, 40,
> +					sim->pending->rands[i],
> +					sim->pending->autn);
> +		else
> +			len = sim_build_gsm_authenticate(auth_cmd, 40,
> +					sim->pending->rands[i]);
> +
> +		if (!len)
> +			goto error;
> +
> +		sim->driver->logical_access(sim, session_id, auth_cmd, len,
> +				logical_access_cb, sim);
> +	}
> +
> +	return;
> +
> +error:
> +	__ofono_dbus_pending_reply(&sim->pending->msg,
> +			__ofono_error_failed(sim->pending->msg));
> +	g_free(sim->pending);
> +	sim->pending = NULL;
> +}
> +
> +static DBusMessage *usim_gsm_authenticate(DBusConnection *conn,
> +		DBusMessage *msg, void *data)
> +{
> +	struct ofono_sim_auth *sim = data;
> +	DBusMessageIter iter;
> +	DBusMessageIter array;
> +	int i;
> +	struct sim_app_record *app;
> +
> +	if (sim->pending)
> +		return __ofono_error_busy(msg);
> +
> +	dbus_message_iter_init(msg, &iter);
> +
> +	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
> +		return __ofono_error_not_supported(msg);
> +
> +	sim->pending = malloc(sizeof(struct auth_request));
> +	sim->pending->msg = dbus_message_ref(msg);
> +	sim->pending->umts = 0;
> +	sim->pending->cb_count = 0;
> +	sim->pending->num_rands = dbus_message_iter_get_element_count(&iter);
> +
> +	dbus_message_iter_recurse(&iter, &array);
> +
> +	for (i = 0; i < sim->pending->num_rands; i++) {
> +		int nelement;
> +		DBusMessageIter in;
> +
> +		dbus_message_iter_recurse(&array, &in);
> +
> +		dbus_message_iter_get_fixed_array(&in, &sim->pending->rands[i],
> +				&nelement);
> +	}
> +
> +	app = find_channel(sim->aid_list, SIM_APP_TYPE_USIM);
> +
> +	if (app) {
> +		sim->driver->open_channel(sim, app->aid, open_channel_cb, sim);
> +	} else {
> +		dbus_message_unref(sim->pending->msg);
> +		g_free(sim->pending);
> +		sim->pending = NULL;
> +		return __ofono_error_not_supported(msg);
> +	}
> +
> +	return NULL;
> +}
> +
> +static DBusMessage *umts_common(DBusConnection *conn, DBusMessage *msg,
> +					void *data, enum sim_app_type type)
> +{
> +	uint8_t *rand = NULL;
> +	uint8_t *autn = NULL;
> +	uint32_t rlen;
> +	uint32_t alen;
> +	struct ofono_sim_auth *sim = data;
> +	struct sim_app_record *app;
> +
> +	if (sim->pending)
> +		return __ofono_error_busy(msg);
> +
> +	/* get RAND/AUTN and setup handle args */
> +	dbus_message_get_args(msg, NULL, DBUS_TYPE_ARRAY,
> +			DBUS_TYPE_BYTE, &rand, &rlen, DBUS_TYPE_ARRAY,
> +			DBUS_TYPE_BYTE, &autn, &alen,
> +			DBUS_TYPE_INVALID);
> +

Checking that rlen / alen are 16?

> +	sim->pending = malloc(sizeof(struct auth_request));

Please use g_new0

> +	sim->pending->msg = dbus_message_ref(msg);
> +	sim->pending->rands[0] = rand;
> +	sim->pending->num_rands = 1;
> +	sim->pending->autn = autn;
> +	sim->pending->umts = 1;
> +
> +	app = find_channel(sim->aid_list, type);
> + > +	if (app) {
> +		sim->driver->open_channel(sim, app->aid, open_channel_cb, sim);
> +	} else {
> +		dbus_message_unref(sim->pending->msg);
> +		g_free(sim->pending);
> +		sim->pending = NULL;
> +		return __ofono_error_not_supported(msg);

This really should not happen.  I'm not sure its worthwhile even 
checking this case.  Messages arrive only for valid objects registered 
on D-Bus.  So if we have a USimApplication at /modem1/AID, then it 
should always be found...

Also, what happens if there are multiple AIDs of the same type?  If the 
user addresses the message to /modem1/AID3 and you find /modem1/AID1 
instead (through find_channel), then you're going to be addressing the 
wrong application...

> +	}
> +
> +	return NULL;
> +}
> +
> +static DBusMessage *get_applications(DBusConnection *conn,
> +		DBusMessage *msg, void *data)
> +{
> +	struct ofono_sim_auth *sim = data;
> +	const char *path = __ofono_atom_get_path(sim->atom);
> +	struct sim_app_record *app;
> +	int ret;
> +	char object[strlen(path) + 33];
> +	DBusMessage *reply;
> +	DBusMessageIter iter;
> +	DBusMessageIter array;
> +	DBusMessageIter dict;
> +
> +

No double empty lines please

> +	if (!sim->aid_list)
> +		return __ofono_error_busy(msg);
> +
> +	reply = dbus_message_new_method_return(msg);
> +	if (reply == NULL)
> +		return NULL;
> +
> +	dbus_message_iter_init_append(reply, &iter);
> +
> +	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{oa{sv}}",
> +			&array);
> +
> +	app = find_channel(sim->aid_list, SIM_APP_TYPE_ISIM);
> +

Why?  You're assuming one application / type.  Yet you register all 
applications found in discover_apps_cb.  Why not simply walk the 
aid_list and append a dictionary for each one?

> +	if (app) {
> +		ret = sprintf(object, "%s/", path);
> +		encode_hex_own_buf(app->aid, 16, 0, object + ret);
> +
> +		dbus_message_iter_open_container(&array, DBUS_TYPE_DICT_ENTRY,
> +				NULL, &dict);
> +		append_dict_application(&dict, object, "Ims", "ISim");
> +		dbus_message_iter_close_container(&array, &dict);
> +	}
> +
> +	app = find_channel(sim->aid_list, SIM_APP_TYPE_USIM);
> +
> +	if (app) {
> +		ret = sprintf(object, "%s/", path);
> +		encode_hex_own_buf(app->aid, 16, 0, object + ret);
> +
> +		dbus_message_iter_open_container(&array, DBUS_TYPE_DICT_ENTRY,
> +				NULL, &dict);
> +		append_dict_application(&dict, object, "Umts", "USim");
> +		dbus_message_iter_close_container(&array, &dict);
> +
> +	}
> +
> +	dbus_message_iter_close_container(&iter, &array);
> +
> +	return reply;
> +}
> +
> +static DBusMessage *send_properties(DBusConnection *conn, DBusMessage *msg,
> +		void *data, const char *type, const char *name)
> +{
> +	DBusMessage *reply;
> +	DBusMessageIter iter;
> +	DBusMessageIter array;
> +
> +	reply = dbus_message_new_method_return(msg);
> +	if (reply == NULL)
> +		return NULL;
> +
> +	dbus_message_iter_init_append(reply, &iter);
> +
> +	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}",
> +				&array);
> +
> +	ofono_dbus_dict_append(&array, "Type", DBUS_TYPE_STRING, &type);
> +	ofono_dbus_dict_append(&array, "Name", DBUS_TYPE_STRING, &name);
> +
> +	dbus_message_iter_close_container(&iter, &array);
> +
> +	return reply;
> +}
> +
> +static DBusMessage *usim_get_properties(DBusConnection *conn,
> +		DBusMessage *msg, void *data)
> +{
> +	return send_properties(conn, msg, data, "Umts", "USim");
> +}
> +
> +static DBusMessage *isim_get_properties(DBusConnection *conn,
> +		DBusMessage *msg, void *data)
> +{
> +	return send_properties(conn, msg, data, "Ims", "ISim");
> +}
> +
> +static DBusMessage *isim_ims_authenticate(DBusConnection *conn,
> +		DBusMessage *msg, void *data)
> +{
> +	return umts_common(conn, msg, data, SIM_APP_TYPE_ISIM);
> +}
> +
> +static DBusMessage *usim_umts_authenticate(DBusConnection *conn,
> +		DBusMessage *msg, void *data)
> +{
> +	return umts_common(conn, msg, data, SIM_APP_TYPE_USIM);

So in theory you know exactly which application is being addressed. 
E.g. by parsing the msg 'path'.  Alternatively you could register an 
application object which contains a back pointer to struct sim_auth.

> +}
> +
> +static const GDBusMethodTable sim_authentication[] = {
> +	{ GDBUS_METHOD("GetApplications",
> +			NULL,
> +			GDBUS_ARGS({"applications", "a{oa{sv}}"}),
> +			get_applications) },
> +	{ }
> +};
> +
> +static const GDBusMethodTable sim_auth_usim_app[] = {
> +	{ GDBUS_ASYNC_METHOD("GetProperties",
> +			NULL,
> +			GDBUS_ARGS({"properties", "a{sv}"}),
> +			usim_get_properties) },
> +	{ GDBUS_ASYNC_METHOD("GsmAuthenticate",
> +			GDBUS_ARGS({"rands", "aay"}),
> +			GDBUS_ARGS({"keys", "a{say}"}),
> +			usim_gsm_authenticate) },
> +	{ GDBUS_ASYNC_METHOD("UmtsAuthenticate",
> +			GDBUS_ARGS({"rand", "ay"}, {"autn", "ay"}),
> +			GDBUS_ARGS({"return", "a{sv}"}),
> +			usim_umts_authenticate) },
> +	{ }
> +};
> +
> +static const GDBusMethodTable sim_auth_isim_app[] = {
> +	{ GDBUS_ASYNC_METHOD("GetProperties",
> +			NULL,
> +			GDBUS_ARGS({"properties", "a{sv}"}),
> +			isim_get_properties) },
> +	{ GDBUS_ASYNC_METHOD("ImsAuthenticate",
> +			GDBUS_ARGS({"rand", "ay"}, {"autn", "ay"}),
> +			GDBUS_ARGS({"return", "a{sv}"}),
> +			isim_ims_authenticate) },
> +	{ }
> +};
> +
> +static void discover_apps_cb(const struct ofono_error *error,
> +		const unsigned char *dataobj,
> +		int len, void *data)
> +{
> +	DBusConnection *conn = ofono_dbus_get_connection();
> +	struct ofono_sim_auth *sim = data;
> +	const char *path = __ofono_atom_get_path(sim->atom);
> +	GSList *iter;
> +	char app_path[strlen(path) + 34];
> +	int ret;
> +

Register the SimAuthentication interface and call 
ofono_modem_add_interface here.  See below for more details.

> +	if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
> +		goto parse_error;
> +
> +	sim->aid_list = sim_parse_app_template_entries(dataobj, len);
> +
> +	if (!sim->aid_list)
> +		goto parse_error;
> +
> +	iter = sim->aid_list;
> +
> +	ret = sprintf(app_path, "%s/", path);
> +
> +	while (iter) {
> +		struct sim_app_record *app = iter->data;
> +
> +		switch (app->type) {
> +		case SIM_APP_TYPE_USIM:
> +			encode_hex_own_buf(app->aid, 16, 0, app_path + ret);
> +
> +			app_path[ret + 32] = '\0';
> +
> +			g_dbus_register_interface(conn, app_path,
> +					OFONO_USIM_APPLICATION_INTERFACE,
> +					sim_auth_usim_app, NULL, NULL,
> +					sim, NULL);
> +			break;
> +		case SIM_APP_TYPE_ISIM:
> +			encode_hex_own_buf(app->aid, 16, 0, app_path + ret);
> +
> +			app_path[ret + 32] = '\0';
> +
> +			g_dbus_register_interface(conn, app_path,
> +					OFONO_ISIM_APPLICATION_INTERFACE,
> +					sim_auth_isim_app, NULL, NULL,
> +					sim, NULL);
> +			break;
> +		default:
> +			DBG("Unknown SIM application '%04x'", app->type);
> +			/*
> +			 * If we get here, the SIM application was not ISIM
> +			 * or USIM, skip.
> +			 */
> +		}
> +
> +		iter = g_slist_next(iter);
> +	}
> +
> +	return;
> +
> +parse_error:
> +	/*
> +	 * Something went wrong parsing the AID list, it can't be assumed that
> +	 * any previously parsed AID's are valid so free them all.
> +	 */
> +	DBG("Error parsing app list");
> +}
> +
>   void ofono_sim_auth_register(struct ofono_sim_auth *sa)
>   {
> +	DBusConnection *conn = ofono_dbus_get_connection();
> +	struct ofono_modem *modem = __ofono_atom_get_modem(sa->atom);
> +	const char *path = __ofono_atom_get_path(sa->atom);
> +
> +	ofono_modem_add_interface(modem, OFONO_PHONEBOOK_INTERFACE);
> +

???

>   	__ofono_atom_register(sa->atom, sim_auth_unregister);
> +
> +	/* Do SIM application discovery, the cb will register DBus ifaces */
> +	sa->driver->list_apps(sa, discover_apps_cb, sa);
> +
> +	sa->sim = __ofono_atom_find(OFONO_ATOM_TYPE_SIM, modem);
> +
> +	sa->gsm_access = __ofono_sim_ust_service_available(sa->sim,
> +			SIM_UST_SERVICE_GSM_ACCESS);
> +	sa->gsm_context = __ofono_sim_ust_service_available(sa->sim,
> +			SIM_UST_SERVICE_GSM_SECURITY_CONTEXT);
> +
> +	g_dbus_register_interface(conn, path,
> +			OFONO_SIM_AUTHENTICATION_INTERFACE,
> +			sim_authentication, NULL, NULL,
> +			sa, NULL);
> +	ofono_modem_add_interface(modem,
> +			OFONO_SIM_AUTHENTICATION_INTERFACE);

I would register the interface after you run the application discovery. 
Otherwise there is potential for a GetApplications() method call to 
arrive before the atom driver calls discover_apps_cb.  An erroneous 
state will be returned and we have no signals to notify the application 
that the applications state has changed.

>   }
>   
>   void ofono_sim_auth_remove(struct ofono_sim_auth *sa)
> 

Regards,
-Denis

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2017-10-11 20:11 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-11 18:57 [PATCHv3 1/7] sim-auth: prep simauth/dbus headers James Prestwood
2017-10-11 18:57 ` [PATCHv3 2/7] sim-auth: implementation of core sim-auth atom James Prestwood
2017-10-11 20:11   ` Denis Kenzior
2017-10-11 18:57 ` [PATCHv3 3/7] atmodem: implemented sim-auth functionality in atmodem James Prestwood
2017-10-11 18:57 ` [PATCHv3 4/7] xmm7xxx: add sim-auth driver to xmm7xxx plugin James Prestwood
2017-10-11 18:57 ` [PATCHv3 5/7] phonesim: Added sim-auth to phonesim plugin James Prestwood
2017-10-11 18:57 ` [PATCHv3 6/7] test: added tests for GSM/UMTS auth algorithms James Prestwood
2017-10-11 18:57 ` [PATCHv3 7/7] doc: documentation for SimAuth dbus interfaces James Prestwood
2017-10-11 19:58   ` Denis Kenzior
2017-10-11 19:17 ` [PATCHv3 1/7] sim-auth: prep simauth/dbus headers Denis Kenzior

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.