From: Arran Cudbard-Bell Date: Fri, 25 Oct 2024 03:53:11 +0000 (-0600) Subject: Switch EAP-AKA-SIM to using custom flag parsers X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=46f065ee9a8c40b7afea43dcc54ce0cb1ed5e804;p=thirdparty%2Ffreeradius-server.git Switch EAP-AKA-SIM to using custom flag parsers --- diff --git a/src/lib/eap_aka_sim/base.c b/src/lib/eap_aka_sim/base.c index 6fe251d1f7d..3b17e4b1865 100644 --- a/src/lib/eap_aka_sim/base.c +++ b/src/lib/eap_aka_sim/base.c @@ -208,7 +208,7 @@ fr_dict_enum_autoload_t libfreeradius_aka_sim_dict_enum[] = { * formats and generic NETWORK formats. */ size_t const fr_aka_sim_attr_sizes[FR_TYPE_MAX + 1][2] = { - [FR_TYPE_NULL] = {~0, 0}, + [FR_TYPE_NULL] = {~0, 0}, [FR_TYPE_STRING] = {0, ~0}, [FR_TYPE_OCTETS] = {0, ~0}, @@ -224,6 +224,31 @@ size_t const fr_aka_sim_attr_sizes[FR_TYPE_MAX + 1][2] = { [FR_TYPE_MAX] = {~0, 0} //!< Ensure array covers all types. }; +static int dict_flag_encrypt(fr_dict_attr_t **da_p, char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules) +{ + static fr_table_num_sorted_t const encrypted[] = { + { L("aes-cbc"), AKA_SIM_FLAG_ENCRYPT_AES_CBC } + }; + static size_t encrypted_len = NUM_ELEMENTS(encrypted); + + fr_aka_sim_attr_flags_encrypt_t encrypt; + fr_aka_sim_attr_flags_t *flags = fr_dict_attr_ext(*da_p, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC); + + encrypt = fr_table_value_by_str(encrypted, value, AKA_SIM_FLAG_ENCRYPT_INVALID); + if (encrypt == AKA_SIM_FLAG_ENCRYPT_INVALID) { + fr_strerror_printf("Unknown encryption type '%s'", value); + return -1; + } + + flags->encrypt = encrypt; + + return 0; +} + +static fr_dict_flag_parser_t const eap_aka_sim_flags[] = { + { L("encrypt"), { .func = dict_flag_encrypt, .needs_value = true} } +}; + /** Return the on-the-wire length of an attribute value * * @param[in] vp to return the length of. @@ -298,15 +323,14 @@ void fr_aka_sim_free(void) fr_openssl_free(); } -static fr_table_num_ordered_t const subtype_table[] = { - { L("encrypt=aes-cbc"), 1 }, /* any non-zero value will do */ -}; - extern fr_dict_protocol_t libfreeradius_eap_aka_sim_dict_protocol; fr_dict_protocol_t libfreeradius_eap_aka_sim_dict_protocol = { .name = "eap_aka_sim", .default_type_size = 1, .default_type_length = 1, - .subtype_table = subtype_table, - .subtype_table_len = NUM_ELEMENTS(subtype_table), + .attr = { + .flags_table = eap_aka_sim_flags, + .flags_table_len = NUM_ELEMENTS(eap_aka_sim_flags), + .flags_len = sizeof(fr_aka_sim_attr_flags_t) + } }; diff --git a/src/lib/eap_aka_sim/base.h b/src/lib/eap_aka_sim/base.h index 55c9e3c4af2..580ba78df83 100644 --- a/src/lib/eap_aka_sim/base.h +++ b/src/lib/eap_aka_sim/base.h @@ -252,6 +252,23 @@ typedef struct { extern size_t const fr_aka_sim_attr_sizes[FR_TYPE_MAX + 1][2]; +typedef enum { + AKA_SIM_FLAG_ENCRYPT_INVALID = -1, //!< Invalid encryption flag. + AKA_SIM_FLAG_ENCRYPT_NONE = 0, //!< No encryption. + AKA_SIM_FLAG_ENCRYPT_AES_CBC = 1, //!< Encrypt attribute RFC 2865 style. +} fr_aka_sim_attr_flags_encrypt_t; + +typedef struct { + fr_aka_sim_attr_flags_encrypt_t encrypt; //!< Attribute has a tag and is encrypted +} fr_aka_sim_attr_flags_t; + +static inline fr_aka_sim_attr_flags_t const * fr_aka_sim_attr_flags(fr_dict_attr_t const *da) +{ + return fr_dict_attr_ext(da, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC); +} + +#define fr_aka_sim_flag_encrypted(_da) fr_aka_sim_attr_flags(_da)->encrypt + /* * decode.c */ diff --git a/src/lib/eap_aka_sim/decode.c b/src/lib/eap_aka_sim/decode.c index 19d84ce007b..48d0692b0f9 100644 --- a/src/lib/eap_aka_sim/decode.c +++ b/src/lib/eap_aka_sim/decode.c @@ -393,7 +393,7 @@ static ssize_t sim_decode_tlv(TALLOC_CTX *ctx, fr_pair_list_t *out, * unfortunately the ordering of these two attributes * aren't specified, so we may have to hunt for the IV. */ - if (!parent->flags.extra && parent->flags.subtype) { + if (fr_aka_sim_flag_encrypted(parent)) { FR_PROTO_TRACE("found encrypted attribute '%s'", parent->name); decr_len = sim_value_decrypt(ctx, &decr, p + 2, @@ -442,7 +442,7 @@ static ssize_t sim_decode_tlv(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t zero = 0; uint8_t i; - if (!parent->flags.subtype) { + if (!fr_aka_sim_flag_encrypted(parent)) { fr_strerror_printf("%s: Found padding attribute outside of an encrypted TLV", __FUNCTION__); goto error; diff --git a/src/lib/eap_aka_sim/encode.c b/src/lib/eap_aka_sim/encode.c index 7b3ef36a57f..9bc8c82b8a7 100644 --- a/src/lib/eap_aka_sim/encode.c +++ b/src/lib/eap_aka_sim/encode.c @@ -708,7 +708,7 @@ static inline ssize_t encode_tlv_internal(fr_dbuff_t *dbuff, * encrypt the contents of the TLV using AES-CBC-128 * or another encryption algorithm. */ - if (!da->flags.extra && da->flags.subtype) { + if (fr_aka_sim_flag_encrypted(da)) { ssize_t value_len = fr_dbuff_used(&work_dbuff) - 2; slen = encode_encrypted_value(&value_dbuff, fr_dbuff_current(&value_start), @@ -776,7 +776,7 @@ static ssize_t encode_tlv(fr_dbuff_t *dbuff, * The ASCII art in the RFCs the attributes in * this order. */ - if (!da_stack->da[depth]->flags.extra && da_stack->da[depth]->flags.subtype) { + if (fr_aka_sim_flag_encrypted(da_stack->da[depth])) { len = encode_iv(&work_dbuff, encode_ctx); if (len < 0) return len; }