aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2009-12-05 15:13:22 +0530
committerHarald Welte <laforge@gnumonks.org>2009-12-24 09:37:34 +0100
commit3606cc576502b95d4973fac2af76d1b9bdc4705b (patch)
treeeb1bc60f0c1109a066609dd73398954847b8160a /openbsc
parent61cc306a55bdcbf543ce5c3e74a4d30cdbba5984 (diff)
[authentication] Code for retrieving authentication data from SQL DB
This is the first step towards supporting actual A3/A8 authentication.
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/openbsc/gsm_data.h19
-rw-r--r--openbsc/src/db.c92
2 files changed, 111 insertions, 0 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index c2eec4156..ff01d7287 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -589,6 +589,25 @@ struct gsm_sms {
char text[SMS_TEXT_SIZE];
};
+enum gsm_auth_algo {
+ AUTH_ALGO_NONE,
+ AUTH_ALGO_XOR,
+ AUTH_ALGO_COMP128v1,
+};
+
+/* Real authentication information containing Ki */
+struct gsm_auth_info {
+ enum gsm_auth_algo auth_algo;
+ unsigned int a3a8_ki_len;
+ u_int8_t a3a8_ki[16];
+};
+
+struct gsm_auth_tuple {
+ u_int8_t rand[16];
+ u_int8_t sres[8];
+ u_int8_t kc[8];
+};
+
struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_code,
int (*mncc_recv)(struct gsm_network *, int, void *));
struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, enum gsm_bts_type type,
diff --git a/openbsc/src/db.c b/openbsc/src/db.c
index 7b864fb43..cf9df11ad 100644
--- a/openbsc/src/db.c
+++ b/openbsc/src/db.c
@@ -123,6 +123,18 @@ static char *create_stmts[] = {
"timestamp TIMESTAMP NOT NULL, "
"value INTEGER NOT NULL, "
"name TEXT NOT NULL "
+ "CREATE TABLE IF NOT EXISTS AuthKeys ("
+ "id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ "subscriber_id NUMERIC UNIQUE NOT NULL, "
+ "algorithm_id NUMERIC NOT NULL, "
+ "a3a8_ki BLOB "
+ ")",
+ "CREATE TABLE IF NOT EXISTS AuthTuples ("
+ "id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ "subscriber_id NUMERIC UNIQUE NOT NULL, "
+ "rand BLOB"
+ "sres BLOB"
+ "kc BLOB"
")",
};
@@ -314,6 +326,86 @@ static int get_equipment_by_subscr(struct gsm_subscriber *subscr)
return 0;
}
+
+int get_authinfo_by_subscr(struct gsm_auth_info *ainfo,
+ struct gsm_subscriber *subscr)
+{
+ dbi_result result;
+ const unsigned char *a3a8_ki;
+
+ result = dbi_conn_queryf(conn,
+ "SELECT * FROM AuthKeys WHERE subscriber_id=%u",
+ subscr->id);
+ if (!result)
+ return -EIO;
+
+ if (!dbi_result_next_row(result)) {
+ dbi_result_free(result);
+ return -ENOENT;
+ }
+
+ ainfo->auth_algo = dbi_result_get_ulonglong(result, "algorithm_id");
+ ainfo->a3a8_ki_len = dbi_result_get_field_length(result, "a3a8_ki");
+ a3a8_ki = dbi_result_get_binary(result, "a3a8_ki");
+ if (ainfo->a3a8_ki_len > sizeof(ainfo->a3a8_ki_len))
+ ainfo->a3a8_ki_len = sizeof(ainfo->a3a8_ki_len);
+ memcpy(ainfo->a3a8_ki, a3a8_ki, ainfo->a3a8_ki_len);
+
+ dbi_result_free(result);
+
+ return 0;
+}
+
+int get_authtuple_by_subscr(struct gsm_auth_tuple *atuple,
+ struct gsm_subscriber *subscr)
+{
+ dbi_result result;
+ int len;
+ const unsigned char *blob;
+
+ result = dbi_conn_queryf(conn,
+ "SELECT * FROM AuthTuples WHERE subscriber_id=%u",
+ subscr->id);
+ if (!result)
+ return -EIO;
+
+ if (!dbi_result_next_row(result)) {
+ dbi_result_free(result);
+ return -ENOENT;
+ }
+
+ memset(atuple, 0, sizeof(atuple));
+
+ len = dbi_result_get_field_length(result, "rand");
+ if (len != sizeof(atuple->rand))
+ goto err_size;
+
+ blob = dbi_result_get_binary(result, "rand");
+ memcpy(atuple->rand, blob, len);
+
+ len = dbi_result_get_field_length(result, "sres");
+ if (len != sizeof(atuple->sres))
+ goto err_size;
+
+ blob = dbi_result_get_binary(result, "sres");
+ memcpy(atuple->sres, blob, len);
+
+ len = dbi_result_get_field_length(result, "kc");
+ if (len != sizeof(atuple->kc))
+ goto err_size;
+
+ blob = dbi_result_get_binary(result, "kc");
+ memcpy(atuple->kc, blob, len);
+
+ dbi_result_free(result);
+
+ return 0;
+
+err_size:
+ dbi_result_free(result);
+ return -EIO;
+}
+
#define BASE_QUERY "SELECT * FROM Subscriber "
struct gsm_subscriber *db_get_subscriber(struct gsm_network *net,
enum gsm_subscriber_field field,