* 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},
[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.
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)
+ }
};
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
*/
* 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,
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;
* 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),
* 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;
}