]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Switch EAP-AKA-SIM to using custom flag parsers
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 25 Oct 2024 03:53:11 +0000 (21:53 -0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 25 Oct 2024 03:53:11 +0000 (21:53 -0600)
src/lib/eap_aka_sim/base.c
src/lib/eap_aka_sim/base.h
src/lib/eap_aka_sim/decode.c
src/lib/eap_aka_sim/encode.c

index 6fe251d1f7dc3021231c4b6f5cbe5319e252d1b9..3b17e4b186559020834ca3310fe94e954fad6704 100644 (file)
@@ -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)
+       }
 };
index 55c9e3c4af2bc24845620a17253c7aa658ddd2c6..580ba78df839b1f446bb8671e18bc34a259696b1 100644 (file)
@@ -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
  */
index 19d84ce007b785dfb83e8f717a5e7145eb9f6530..48d0692b0f941a287096984e6a0e95c2d82474ba 100644 (file)
@@ -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;
index 7b3ef36a57f8b408e1a75d902f6137ed2db9cd8a..9bc8c82b8a7d178e54b5c7def44b0cf83f50591b 100644 (file)
@@ -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;
        }