27 #include <freeradius-devel/server/base.h>
28 #include <freeradius-devel/unlang/xlat_func.h>
52 fr_value_box_list_t *
in)
60 if (
fr_aka_sim_id_type(&type_hint, &method_hint, id->vb_strvalue, id->vb_length) < 0) {
61 RPEDEBUG2(
"AKA/SIM Id \"%pV\" has unrecognised format",
id);
65 switch (method_hint) {
116 if (
fr_aka_sim_id_type(&type_hint, &method_hint, id->vb_strvalue, id->vb_length) < 0) {
117 RPEDEBUG2(
"AKA/AKA/SIM Id \"%pV\" has unrecognised format",
id);
170 REDEBUG2(
"3gpp pseudonym incorrect length, expected %i bytes, got %zu bytes",
184 .func = NULL, .uctx = NULL },
185 { .required =
true, .concat =
true, .single =
false, .type =
FR_TYPE_OCTETS,
186 .func = NULL, .uctx = NULL },
187 { .required =
false, .concat =
false, .single =
true, .type =
FR_TYPE_BOOL,
188 .func = NULL, .uctx = NULL },
231 char out_tag =
'\0', *
buff;
236 char const *
id = id_vb->vb_strvalue;
237 size_t id_len = id_vb->vb_length;
241 uint8_t const *key = key_vb->vb_octets;
242 size_t key_len = key_vb->vb_length;
245 bool include_tag =
true;
250 if (tag_vb) include_tag = tag_vb->vb_bool;
253 REDEBUG2(
"3gpp pseudonym incorrect length, expected %i bytes, got %zu bytes",
260 REDEBUG2(
"Decryption key incorrect length, expected %i bytes, got %zu bytes", 16, key_len);
277 goto use_existing_tag;
307 RPEDEBUG2(
"Failed decrypting AKA/SIM Id");
329 { .required =
true, .concat =
true, .single =
false, .type =
FR_TYPE_OCTETS },
330 { .required =
true, .concat =
false, .single =
true, .type =
FR_TYPE_UINT8 },
331 { .required =
false, .concat =
false, .single =
true, .type =
FR_TYPE_STRING },
350 char const *id_p, *id_end;
355 char const *
id = id_vb->vb_strvalue;
356 size_t id_len = id_vb->vb_length;
360 uint8_t const *key = key_vb->vb_octets;
361 size_t key_len = key_vb->vb_length;
364 uint8_t key_index = index_vb->vb_uint8;
368 bool fastauth =
false;
375 if (key_index > 15) {
376 REDEBUG2(
"Key index must be between 0-15");
382 REDEBUG2(
"Encryption key incorrect length, expected %i bytes, got %zu bytes", 16, key_len);
393 type_vb->vb_strvalue, type_vb->vb_length);
396 REDEBUG2(
"Bad type %pV, must be one of 'fastauth' or 'pseudonym'", type_vb);
400 switch (type_enum->
value->vb_uint32) {
401 case FR_IDENTITY_TYPE_VALUE_PSEUDONYM:
404 case FR_IDENTITY_TYPE_VALUE_FASTAUTH:
427 switch (method_hint) {
447 id_end = (id_p + id_len) - 1;
456 REDEBUG(
"ID does not contain method hint, and no &request.EAP-Type found. "
457 "Don't know what tag to prepend to encrypted identity");
468 REDEBUG(
"&request.EAP-Type does not match a SIM based EAP-Type (SIM, AKA, AKA-Prime)");
472 id_end = id_p + id_len;
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
fr_value_box_t const * value
Enum value (what name maps to).
fr_dict_enum_value_t * fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len)
char const * fr_dict_enum_name_by_value(fr_dict_attr_t const *da, fr_value_box_t const *value)
Lookup the name of an enum value in a fr_dict_attr_t.
Value of an enumerated attribute.
static xlat_arg_parser_t aka_sim_3gpp_temporary_id_encrypt_xlat_args[]
static xlat_arg_parser_t const aka_sim_id_3gpp_temporary_id_key_index_xlat_args[]
static xlat_arg_parser_t const aka_sim_xlat_id_method_xlat_args[]
int fr_aka_sim_xlat_func_register(void)
static xlat_arg_parser_t aka_sim_3gpp_temporary_id_decrypt_xlat_args[]
static xlat_arg_parser_t const aka_sim_xlat_id_type_xlat_args[]
static int aka_sim_xlat_refs
void fr_aka_sim_xlat_func_unregister(void)
static xlat_action_t aka_sim_id_3gpp_temporary_id_key_index_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Returns the key index from a 3gpp temporary id.
static xlat_action_t aka_sim_xlat_id_method_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Returns the SIM method EAP-SIM or EAP-AKA hinted at by the user identifier.
static xlat_action_t aka_sim_xlat_id_type_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Returns the type of identity used.
static xlat_action_t aka_sim_3gpp_temporary_id_encrypt_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Encrypts a 3gpp pseudonym.
static xlat_action_t aka_sim_3gpp_temporary_id_decrypt_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Decrypt a 3gpp temporary id.
HIDDEN fr_dict_attr_t const * attr_eap_type
fr_value_box_t const * enum_eap_type_aka
fr_value_box_t const * enum_eap_type_sim
fr_value_box_t const * enum_eap_type_aka_prime
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_method_hint
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_identity_type
int fr_aka_sim_id_3gpp_pseudonym_decrypt(char out[AKA_SIM_IMSI_MAX_LEN+1], char const encr_id[AKA_SIM_3GPP_PSEUDONYM_LEN], uint8_t const key[16])
Decrypt the 3GPP pseudonym.
uint8_t fr_aka_sim_id_3gpp_pseudonym_tag(char const encr_id[AKA_SIM_3GPP_PSEUDONYM_LEN])
Return the tag from a 3gpp pseudonym.
int fr_aka_sim_id_3gpp_pseudonym_encrypt(char out[AKA_SIM_3GPP_PSEUDONYM_LEN+1], char const *imsi, size_t imsi_len, uint8_t tag, uint8_t key_ind, uint8_t const key[16])
Create a 3gpp pseudonym from a permanent ID.
int fr_aka_sim_id_type(fr_aka_sim_id_type_t *type, fr_aka_sim_method_hint_t *hint, char const *id, size_t id_len)
Determine what type of ID was provided in the initial identity response.
#define ID_TAG_SIM_PSEUDONYM_B64
#define ID_TAG_AKA_PSEUDONYM_B64
#define AKA_SIM_IMSI_MAX_LEN
Length of an IMSI number in ASCII.
#define ID_TAG_AKA_FASTAUTH_B64
#define ID_TAG_SIM_FASTAUTH_B64
#define ID_TAG_AKA_PRIME_PSEUDONYM_B64
@ ID_TAG_AKA_PERMANENT
IMSI, and hint that client wants to do EAP-AKA.
@ ID_TAG_SIM_PERMANENT
IMSI, and hint that client wants to do EAP-SIM.
@ ID_TAG_AKA_PRIME_PERMANENT
IMSI, and hint that client wants to do EAP-AKA-Prime.
fr_aka_sim_method_hint_t
SIM/AKA method hints.
@ AKA_SIM_METHOD_HINT_AKA
The identity hints the supplicant wants to use EAP-AKA.
@ AKA_SIM_METHOD_HINT_SIM
The identity hints the supplicant wants to use EAP-SIM.
@ AKA_SIM_METHOD_HINT_AKA_PRIME
@ AKA_SIM_METHOD_HINT_MAX
@ AKA_SIM_METHOD_HINT_UNKNOWN
We don't know what method the identity hints at.
#define AKA_SIM_IMSI_MIN_LEN
Minimum length of an IMSI number in ASCII.
#define AKA_SIM_3GPP_PSEUDONYM_LEN
Length of a base64 encoded 3gpp pseudonym.
fr_aka_sim_id_type_t
SIM/AKA identity type hints.
@ AKA_SIM_ID_TYPE_UNKNOWN
We don't know what type of identity this is.
@ AKA_SIM_ID_TYPE_PSEUDONYM
This is a custom pseudonym.
@ AKA_SIM_ID_TYPE_PERMANENT
This is a permanent identity (the IMSI of the SIM).
@ AKA_SIM_ID_TYPE_FASTAUTH
This is a fastauth (session-resumption) id.
#define ID_TAG_AKA_PRIME_FASTAUTH_B64
#define RPEDEBUG2(fmt,...)
#define REDEBUG2(fmt,...)
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_OCTETS
Raw octets.
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
static char buff[sizeof("18446744073709551615")+3]
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
fr_aka_sim_id_type_t type
Stores an attribute, a value and various bits of other data.
bool required
Argument must be present, and non-empty.
#define XLAT_ARG_PARSER_TERMINATOR
@ XLAT_ACTION_FAIL
An xlat function failed.
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition for a single argument consumend by an xlat function.
Master include file to access all functions and structures in the library.
int fr_value_box_bstr_alloc(TALLOC_CTX *ctx, char **out, fr_value_box_t *dst, fr_dict_attr_t const *enumv, size_t len, bool tainted)
Alloc and assign an empty \0 terminated string to a fr_value_box_t.
int fr_value_box_bstrndup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, size_t len, bool tainted)
Copy a string to to a fr_value_box_t.
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
#define fr_box_strvalue_len(_val, _len)
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
#define fr_box_uint32(_val)
static size_t char ** out
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
xlat_t * xlat_func_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, fr_type_t return_type)
Register an xlat function.
void xlat_func_unregister(char const *name)
Unregister an xlat function.