diff options
author | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2015-06-08 18:02:10 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2015-07-01 08:16:41 +0200 |
commit | e2ac6b77feecc5b7194a308bbd11e206c4a41fcb (patch) | |
tree | 02088c69891c0c64124c3e3c74c8bad5462b175a /openbsc/src/osmo-bsc | |
parent | 9705671025eba34b70d73e9d4e78813e4f2d31da (diff) |
bsc: Check for the rand and then generate a res
Check if the NAT has sent 16 bytes of RAND and if a key
has been configured in the system and then generate a
result using milenage. The milenage res will be sent and
noth the four byte GSM SRES derivation.
Diffstat (limited to 'openbsc/src/osmo-bsc')
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_msc.c | 58 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_vty.c | 29 |
2 files changed, 83 insertions, 4 deletions
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_msc.c b/openbsc/src/osmo-bsc/osmo_bsc_msc.c index 5127ca849..773ee1432 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_msc.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_msc.c @@ -23,6 +23,7 @@ #include <openbsc/bsc_nat.h> #include <osmocom/ctrl/control_cmd.h> #include <osmocom/ctrl/control_if.h> +#include <osmocom/crypt/auth.h> #include <openbsc/debug.h> #include <openbsc/gsm_data.h> #include <openbsc/ipaccess.h> @@ -44,7 +45,7 @@ static void initialize_if_needed(struct bsc_msc_connection *conn); static void send_lacs(struct gsm_network *net, struct bsc_msc_connection *conn); -static void send_id_get_response(struct osmo_msc_data *data, int fd); +static void send_id_get_response(struct osmo_msc_data *data, int fd, struct msgb *inp); static void send_ping(struct osmo_msc_data *data); static void schedule_ping_pong(struct osmo_msc_data *data); @@ -302,7 +303,7 @@ static int ipaccess_a_fd_cb(struct osmo_fd *bfd) if (msg->l2h[0] == IPAC_MSGT_ID_ACK) initialize_if_needed(data->msc_con); else if (msg->l2h[0] == IPAC_MSGT_ID_GET) { - send_id_get_response(data, bfd->fd); + send_id_get_response(data, bfd->fd, msg); } else if (msg->l2h[0] == IPAC_MSGT_PONG) { osmo_timer_del(&data->pong_timer); } @@ -451,12 +452,61 @@ static void initialize_if_needed(struct bsc_msc_connection *conn) } } -static void send_id_get_response(struct osmo_msc_data *data, int fd) +static int answer_challenge(struct osmo_msc_data *data, struct msgb *inp, struct osmo_auth_vector *vec) +{ + int ret; + struct tlv_parsed tvp; + const uint8_t *mrand; + uint8_t mrand_len; + struct osmo_sub_auth_data auth = { + .type = OSMO_AUTH_TYPE_GSM, + .algo = OSMO_AUTH_ALG_MILENAGE, + }; + + ret = ipa_ccm_idtag_parse_off(&tvp, + inp->l2h + 1, + msgb_l2len(inp) - 1, 1); + if (ret < 0) { + LOGP(DMSC, LOGL_ERROR, "ignoring IPA response " + "message with malformed TLVs: %s\n", osmo_hexdump(inp->l2h + 1, + msgb_l2len(inp) - 1)); + return 0; + } + + mrand = TLVP_VAL(&tvp, 0x23); + mrand_len = TLVP_LEN(&tvp, 0x23); + if (mrand_len != 16) { + LOGP(DMSC, LOGL_ERROR, + "RAND is not 16 bytes. Was %d\n", + mrand_len); + return 0; + } + + /* copy the key */ + memcpy(auth.u.umts.opc, data->bsc_key, 16); + memcpy(auth.u.umts.k, data->bsc_key, 16); + memset(auth.u.umts.amf, 0, 2); + auth.u.umts.sqn = 0; + + /* generate the result */ + memset(vec, 0, sizeof(*vec)); + osmo_auth_gen_vec(vec, &auth, mrand); + return 1; +} + + +static void send_id_get_response(struct osmo_msc_data *data, int fd, struct msgb *inp) { struct msc_signal_data sig; struct msgb *msg; + struct osmo_auth_vector vec; + int valid = 0; + + if (data->bsc_key_present) + valid = answer_challenge(data, inp, &vec); - msg = bsc_msc_id_get_resp(0, data->bsc_token); + msg = bsc_msc_id_get_resp(valid, data->bsc_token, + vec.res, valid ? vec.res_len : 0); if (!msg) return; msc_queue_write(data->msc_con, msg, IPAC_PROTO_IPACCESS); diff --git a/openbsc/src/osmo-bsc/osmo_bsc_vty.c b/openbsc/src/osmo-bsc/osmo_bsc_vty.c index 06ad77d59..9a17cd064 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_vty.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_vty.c @@ -107,6 +107,9 @@ static void write_msc(struct vty *vty, struct osmo_msc_data *msc) vty_out(vty, "msc %d%s", msc->nr, VTY_NEWLINE); if (msc->bsc_token) vty_out(vty, " token %s%s", msc->bsc_token, VTY_NEWLINE); + if (msc->bsc_key_present) + vty_out(vty, " auth-key %s%s", + osmo_hexdump(msc->bsc_key, sizeof(msc->bsc_key)), VTY_NEWLINE); if (msc->core_ncc != -1) vty_out(vty, " core-mobile-network-code %d%s", msc->core_ncc, VTY_NEWLINE); @@ -231,6 +234,30 @@ DEFUN(cfg_net_bsc_token, return CMD_SUCCESS; } +DEFUN(cfg_net_bsc_key, + cfg_net_bsc_key_cmd, + "auth-key KEY", + "Authentication (secret) key configuration\n" + "Security key\n") +{ + struct osmo_msc_data *data = osmo_msc_data(vty); + + osmo_hexparse(argv[0], data->bsc_key, sizeof(data->bsc_key)); + data->bsc_key_present = 1; + return CMD_SUCCESS; +} + +DEFUN(cfg_net_no_bsc_key, cfg_net_bsc_no_key_cmd, + "no auth-key", + NO_STR "Authentication (secret) key configuration\n") +{ + struct osmo_msc_data *data = osmo_msc_data(vty); + + memset(data->bsc_key, 0, sizeof(data->bsc_key)); + data->bsc_key_present = 0; + return CMD_SUCCESS; +} + DEFUN(cfg_net_bsc_ncc, cfg_net_bsc_ncc_cmd, "core-mobile-network-code <1-999>", @@ -871,6 +898,8 @@ int bsc_vty_init_extra(void) install_node(&msc_node, config_write_msc); vty_install_default(MSC_NODE); install_element(MSC_NODE, &cfg_net_bsc_token_cmd); + install_element(MSC_NODE, &cfg_net_bsc_key_cmd); + install_element(MSC_NODE, &cfg_net_bsc_no_key_cmd); install_element(MSC_NODE, &cfg_net_bsc_ncc_cmd); install_element(MSC_NODE, &cfg_net_bsc_mcc_cmd); install_element(MSC_NODE, &cfg_net_bsc_lac_cmd); |