add actual MAP component decoding and encoding (auc_map.c)
The code has not been properly integrated yet. This patch simply adds the required functionality but doesn't use it in any way yet. We now depend on libosmo-asn1-map and libans1c.
This commit is contained in:
parent
fe0cb4bc58
commit
a4656d703d
|
@ -1,7 +1,7 @@
|
|||
LDFLAGS=`pkg-config --libs libosmocore libosmogsm`
|
||||
CFLAGS=`pkg-config --cflags libosmocore libosmogsm`
|
||||
CFLAGS = `pkg-config --cflags libosmocore libosmogsm libosmo-asn1-map libasn1c`
|
||||
LDFLAGS = `pkg-config --libs libosmocore libosmogsm libosmo-asn1-map libasn1c`
|
||||
|
||||
auc: auc_main.o auc_core.o auc_rec_csv.o auc_rand.o
|
||||
auc: auc_main.o auc_core.o auc_rec_csv.o auc_rand.o auc_map.o
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
%.o: %.c
|
||||
|
|
|
@ -0,0 +1,255 @@
|
|||
/* (C) 2012 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/crypt/auth.h>
|
||||
|
||||
#include <asn1c/OCTET_STRING.h>
|
||||
#include <asn1c/der_encoder.h>
|
||||
|
||||
#include <osmocom/map/IMSI.h>
|
||||
#include <osmocom/map/TBCD-STRING.h>
|
||||
#include <osmocom/map/SendAuthenticationInfoArg.h>
|
||||
#include <osmocom/map/SendAuthenticationInfoRes.h>
|
||||
#include <osmocom/map/SendAuthenticationInfoResOld.h>
|
||||
|
||||
/* move this to generic osmocom asn1c helper */
|
||||
asn_enc_rval_t
|
||||
der_encode_to_msgb(asn_TYPE_descriptor_t *type_descriptor, void *struct_ptr,
|
||||
struct msgb *msg)
|
||||
{
|
||||
asn_enc_rval_t ar;
|
||||
|
||||
ar = der_encode_to_buffer(type_descriptor, struct_ptr,
|
||||
msg->data, msgb_tailroom(msg));
|
||||
if (ar.encoded > 0)
|
||||
msgb_put(msg, ar.encoded);
|
||||
|
||||
return ar;
|
||||
}
|
||||
|
||||
/* move this to generic osmocom asn1c helper */
|
||||
int tbcd2char(char *out, unsigned int out_len, const TBCD_STRING_t *oct)
|
||||
{
|
||||
char *cur = out;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < oct->size; i++) {
|
||||
uint8_t inbyte = oct->buf[i];
|
||||
uint8_t nibble;
|
||||
|
||||
nibble = inbyte >> 4;
|
||||
/* padding should never occur on the first nibble of an octet */
|
||||
if (nibble == 0xF)
|
||||
return -EINVAL;
|
||||
*cur++ = osmo_bcd2char(oct->buf[i] >> 4);
|
||||
if (cur - out >= out_len)
|
||||
goto ret;
|
||||
|
||||
nibble = inbyte & 0xF;
|
||||
if (nibble == 0xF)
|
||||
break;
|
||||
*cur++ = osmo_bcd2char(oct->buf[i] >> 4);
|
||||
if (cur - out >= out_len)
|
||||
goto ret;
|
||||
}
|
||||
|
||||
ret:
|
||||
out[out_len-1] = '\0';
|
||||
|
||||
return cur - out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The nesting is as follows:
|
||||
* SendAuthenticationInfoRes
|
||||
* AuthenticationSetList
|
||||
* QuintupletList_t
|
||||
* AuthenticationQuintuplet
|
||||
* TripletList_t
|
||||
* AuthenticationTriplet
|
||||
*/
|
||||
|
||||
|
||||
static SendAuthenticationInfoRes_t *
|
||||
make_authinfo_res(void *ctx, const struct osmo_auth_vector *vecs, int num_vecs, int umts)
|
||||
{
|
||||
SendAuthenticationInfoRes_t *ai_res;
|
||||
int i;
|
||||
|
||||
ai_res = talloc_zero(ctx, SendAuthenticationInfoRes_t);
|
||||
|
||||
ai_res->authenticationSetList = talloc_zero(ai_res, AuthenticationSetList_t);
|
||||
|
||||
if (umts) {
|
||||
ai_res->authenticationSetList->present = AuthenticationSetList_PR_quintupletList;
|
||||
|
||||
for (i = 0; i < num_vecs; i++) {
|
||||
const struct osmo_auth_vector *vec = &vecs[i];
|
||||
AuthenticationQuintuplet_t *qt;
|
||||
|
||||
qt = talloc_zero(ai_res, AuthenticationQuintuplet_t);
|
||||
OCTET_STRING_fromBuf(&qt->rand, vec->rand, sizeof(vec->rand));
|
||||
OCTET_STRING_fromBuf(&qt->xres, vec->res, vec->res_len);
|
||||
OCTET_STRING_fromBuf(&qt->ck, vec->ck, sizeof(vec->ck));
|
||||
OCTET_STRING_fromBuf(&qt->ik, vec->ik, sizeof(vec->ik));
|
||||
OCTET_STRING_fromBuf(&qt->autn, vec->autn, sizeof(vec->autn));
|
||||
|
||||
asn_sequence_add(&ai_res->authenticationSetList->choice.quintupletList.list, qt);
|
||||
}
|
||||
} else {
|
||||
ai_res->authenticationSetList->present = AuthenticationSetList_PR_tripletList;
|
||||
|
||||
for (i = 0; i < num_vecs; i++) {
|
||||
const struct osmo_auth_vector *vec = &vecs[i];
|
||||
AuthenticationTriplet_t *t;
|
||||
|
||||
t = talloc_zero(ai_res, AuthenticationTriplet_t);
|
||||
OCTET_STRING_fromBuf(&t->rand, vec->rand, sizeof(vec->rand));
|
||||
OCTET_STRING_fromBuf(&t->sres, vec->sres, sizeof(vec->sres));
|
||||
OCTET_STRING_fromBuf(&t->kc, vec->rand, sizeof(vec->kc));
|
||||
|
||||
asn_sequence_add(&ai_res->authenticationSetList->choice.tripletList.list, t);
|
||||
}
|
||||
}
|
||||
|
||||
return ai_res;
|
||||
}
|
||||
|
||||
static SendAuthenticationInfoResOld_t *
|
||||
make_authinfo_res_old(void *ctx, const struct osmo_auth_vector *vecs, int num_vecs)
|
||||
{
|
||||
SendAuthenticationInfoResOld_t *ai_res;
|
||||
int i;
|
||||
|
||||
ai_res = talloc_zero(ctx, SendAuthenticationInfoResOld_t);
|
||||
|
||||
for (i = 0; i < num_vecs; i++) {
|
||||
const struct osmo_auth_vector *vec = &vecs[i];
|
||||
struct Member *t;
|
||||
|
||||
t = talloc_zero(ai_res, struct Member);
|
||||
OCTET_STRING_fromBuf(&t->rand, vec->rand, sizeof(vec->rand));
|
||||
OCTET_STRING_fromBuf(&t->sres, vec->sres, sizeof(vec->sres));
|
||||
OCTET_STRING_fromBuf(&t->kc, vec->rand, sizeof(vec->kc));
|
||||
|
||||
asn_sequence_add(&ai_res->list, t);
|
||||
}
|
||||
|
||||
return ai_res;
|
||||
}
|
||||
|
||||
struct msgb *
|
||||
handle_authinfo_req(void *ctx, const SendAuthenticationInfoArg_t *ai_arg,
|
||||
int is_v2)
|
||||
{
|
||||
struct msgb *msg;
|
||||
struct osmo_auth_vector vecs[3];
|
||||
char imsi[15+1];
|
||||
unsigned int num_vec;
|
||||
asn_enc_rval_t ar;
|
||||
int rc;
|
||||
|
||||
|
||||
/* FIXME: decode IMSI */
|
||||
rc = tbcd2char(imsi, sizeof(imsi), &ai_arg->imsi);
|
||||
if (rc < 0)
|
||||
return NULL;
|
||||
|
||||
/* don't send more thnan three (our policy) */
|
||||
num_vec = OSMO_MAX(ai_arg->numberOfRequestedVectors, ARRAY_SIZE(vecs));
|
||||
|
||||
/* generate the triplets/quintuplets */
|
||||
if (ai_arg->re_synchronisationInfo) {
|
||||
Re_synchronisationInfo_t *res = ai_arg->re_synchronisationInfo;
|
||||
if (res->rand.size < 16 || res->auts.size < 16)
|
||||
return NULL;
|
||||
/* always only one */
|
||||
num_vec = 1;
|
||||
rc = auc_gen_vec_auts(vecs, imsi, res->rand.buf, res->auts.buf);
|
||||
} else
|
||||
rc = auc_gen_vecs(vecs, imsi, num_vec);
|
||||
|
||||
if (rc < 0)
|
||||
return NULL;
|
||||
|
||||
msg = msgb_alloc(1024, "authinfo_res");
|
||||
if (!msg)
|
||||
return NULL;
|
||||
|
||||
/* actaully encode the response MAP component */
|
||||
if (!ai_arg->re_synchronisationInfo && is_v2) {
|
||||
SendAuthenticationInfoResOld_t *ai_res_old;
|
||||
ai_res_old = make_authinfo_res_old(ctx, vecs, num_vec);
|
||||
ar = der_encode_to_msgb(&asn_DEF_SendAuthenticationInfoResOld,
|
||||
ai_res_old, msg);
|
||||
talloc_free(ai_res_old);
|
||||
} else {
|
||||
SendAuthenticationInfoRes_t *ai_res;
|
||||
int is_umts = 0;
|
||||
if (vecs[0].auth_types & OSMO_AUTH_TYPE_UMTS)
|
||||
is_umts = 1;
|
||||
ai_res = make_authinfo_res(ctx, vecs, num_vec, is_umts);
|
||||
ar = der_encode_to_msgb(&asn_DEF_SendAuthenticationInfoRes,
|
||||
ai_res, msg);
|
||||
talloc_free(ai_res);
|
||||
}
|
||||
|
||||
if (ar.encoded < 0) {
|
||||
msgb_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct osmo_auth_vector vecs[3];
|
||||
SendAuthenticationInfoRes_t *res;
|
||||
asn_enc_rval_t ar;
|
||||
uint8_t buf[1024];
|
||||
uint32_t buf_len = sizeof(buf);
|
||||
|
||||
memset(vecs, 0, sizeof(vecs));
|
||||
|
||||
res = make_authinfo_res(NULL, vecs, ARRAY_SIZE(vecs), 1);
|
||||
if (!res)
|
||||
exit(1);
|
||||
|
||||
ar = der_encode_to_buffer(&asn_DEF_SendAuthenticationInfoRes, res, buf, buf_len);
|
||||
if (ar.encoded < 0)
|
||||
exit(2);
|
||||
|
||||
buf_len = ar.encoded;
|
||||
|
||||
printf("Output: %s\n", osmo_hexdump(buf, buf_len));
|
||||
//write(1, buf, buf_len);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
Reference in New Issue