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.
This commit is contained in:
parent
9705671025
commit
e2ac6b77fe
|
@ -60,6 +60,6 @@ void bsc_msc_schedule_connect(struct bsc_msc_connection *);
|
|||
|
||||
void bsc_msc_lost(struct bsc_msc_connection *);
|
||||
|
||||
struct msgb *bsc_msc_id_get_resp(int fixed, const char *token);
|
||||
struct msgb *bsc_msc_id_get_resp(int fixed, const char *token, const uint8_t *res, int len);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -59,6 +59,9 @@ struct osmo_msc_data {
|
|||
|
||||
/* Connection data */
|
||||
char *bsc_token;
|
||||
uint8_t bsc_key[16];
|
||||
uint8_t bsc_key_present;
|
||||
|
||||
int ping_timeout;
|
||||
int pong_timeout;
|
||||
struct osmo_timer_list ping_timer;
|
||||
|
|
|
@ -276,7 +276,7 @@ void bsc_msc_schedule_connect(struct bsc_msc_connection *con)
|
|||
osmo_timer_schedule(&con->reconnect_timer, 5, 0);
|
||||
}
|
||||
|
||||
struct msgb *bsc_msc_id_get_resp(int fixed, const char *token)
|
||||
struct msgb *bsc_msc_id_get_resp(int fixed, const char *token, const uint8_t *res, int len)
|
||||
{
|
||||
struct msgb *msg;
|
||||
|
||||
|
@ -302,6 +302,11 @@ struct msgb *bsc_msc_id_get_resp(int fixed, const char *token)
|
|||
msgb_put_u8(msg, 0);
|
||||
msgb_put_u8(msg, strlen(token) + 2);
|
||||
msgb_tv_fixed_put(msg, IPAC_IDTAG_UNITNAME, strlen(token) + 1, (uint8_t *) token);
|
||||
if (len > 0) {
|
||||
msgb_put_u8(msg, 0);
|
||||
msgb_put_u8(msg, len + 1);
|
||||
msgb_tv_fixed_put(msg, 0x24, len, res);
|
||||
}
|
||||
} else {
|
||||
msgb_l16tv_put(msg, strlen(token) + 1,
|
||||
IPAC_IDTAG_UNITNAME, (uint8_t *) token);
|
||||
|
|
|
@ -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;
|
||||
|
||||
msg = bsc_msc_id_get_resp(0, data->bsc_token);
|
||||
if (data->bsc_key_present)
|
||||
valid = answer_challenge(data, inp, &vec);
|
||||
|
||||
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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -394,7 +394,7 @@ static void initialize_msc_if_needed(struct bsc_msc_connection *msc_con)
|
|||
|
||||
static void send_id_get_response(struct bsc_msc_connection *msc_con)
|
||||
{
|
||||
struct msgb *msg = bsc_msc_id_get_resp(0, nat->token);
|
||||
struct msgb *msg = bsc_msc_id_get_resp(0, nat->token, NULL, 0);
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
|
|
Loading…
Reference in New Issue