From: Alan T. DeKok Date: Tue, 12 Sep 2023 20:57:48 +0000 (-0400) Subject: allow EAP-AKA-SIM to encode nested pairs. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d987d835b7b3958e71109b451e67edbd2b165c28;p=thirdparty%2Ffreeradius-server.git allow EAP-AKA-SIM to encode nested pairs. The decoder is still not done. That's next. --- diff --git a/src/lib/eap_aka_sim/encode.c b/src/lib/eap_aka_sim/encode.c index ab495b03884..084ef1dbab8 100644 --- a/src/lib/eap_aka_sim/encode.c +++ b/src/lib/eap_aka_sim/encode.c @@ -57,9 +57,9 @@ RCSID("$Id$") * of 32 bits, and includes the Type/Length fields. */ -static ssize_t encode_tlv_hdr(fr_dbuff_t *dbuff, - fr_da_stack_t *da_stack, unsigned int depth, - fr_dcursor_t *cursor, void *encode_ctx); +static ssize_t encode_tlv(fr_dbuff_t *dbuff, + fr_da_stack_t *da_stack, unsigned int depth, + fr_dcursor_t *cursor, void *encode_ctx); /** Evaluation function for EAP-AKA-encodability * @@ -584,7 +584,7 @@ static ssize_t encode_array(fr_dbuff_t *dbuff, * If it's a standard attribute, then vp->da->attr == attribute. * Otherwise, attribute may be something else. */ -static ssize_t encode_rfc_hdr(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, unsigned int depth, +static ssize_t encode_rfc(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, unsigned int depth, fr_dcursor_t *cursor, void *encode_ctx) { size_t pad_len; @@ -677,9 +677,9 @@ static inline ssize_t encode_tlv_internal(fr_dbuff_t *dbuff, * Determine the nested type and call the appropriate encoder */ if (da_stack->da[depth + 1]->type == FR_TYPE_TLV) { - slen = encode_tlv_hdr(&work_dbuff, da_stack, depth + 1, cursor, encode_ctx); + slen = encode_tlv(&work_dbuff, da_stack, depth + 1, cursor, encode_ctx); } else { - slen = encode_rfc_hdr(&work_dbuff, da_stack, depth + 1, cursor, encode_ctx); + slen = encode_rfc(&work_dbuff, da_stack, depth + 1, cursor, encode_ctx); } if (slen <= 0) { @@ -724,7 +724,7 @@ static inline ssize_t encode_tlv_internal(fr_dbuff_t *dbuff, return fr_dbuff_set(dbuff, &work_dbuff); } -static ssize_t encode_tlv_hdr(fr_dbuff_t *dbuff, +static ssize_t encode_tlv(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, unsigned int depth, fr_dcursor_t *cursor, void *encode_ctx) { @@ -733,6 +733,8 @@ static ssize_t encode_tlv_hdr(fr_dbuff_t *dbuff, fr_dict_attr_t const *da; fr_dbuff_t tl_dbuff; fr_dbuff_t work_dbuff = FR_DBUFF(dbuff); + fr_dcursor_t *my_cursor = cursor; + fr_dcursor_t child_cursor; PAIR_VERIFY(fr_dcursor_current(cursor)); FR_PROTO_STACK_PRINT(da_stack, depth); @@ -744,8 +746,20 @@ static ssize_t encode_tlv_hdr(fr_dbuff_t *dbuff, } if (!da_stack->da[depth + 1]) { - fr_strerror_printf("%s: Can't encode empty TLV", __FUNCTION__); - return PAIR_ENCODE_FATAL_ERROR; + fr_pair_t *vp; + + vp = fr_dcursor_current(cursor); + if ((vp->vp_type != FR_TYPE_TLV) || (fr_pair_list_num_elements(&vp->vp_group) == 0)) { + fr_strerror_printf("%s: Can't encode empty TLV", __FUNCTION__); + return PAIR_ENCODE_FATAL_ERROR; + } + + fr_assert(vp->da == da_stack->da[depth]); + + vp = fr_pair_dcursor_child_iter_init(&child_cursor, &vp->vp_group, cursor); + my_cursor = &child_cursor; + + fr_proto_da_stack_build(da_stack, vp->da); } /* @@ -764,9 +778,11 @@ static ssize_t encode_tlv_hdr(fr_dbuff_t *dbuff, da = da_stack->da[depth]; len = encode_tlv_internal(&FR_DBUFF_MAX_BIND_CURRENT(&work_dbuff, SIM_MAX_ATTRIBUTE_VALUE_LEN - 2), - da_stack, depth, cursor, encode_ctx); + da_stack, depth, my_cursor, encode_ctx); if (len <= 0) return len; + if (my_cursor != cursor) fr_dcursor_next(cursor); + /* * Round attr + len + data length out to a multiple * of four, and setup the attribute header and @@ -788,7 +804,6 @@ ssize_t fr_aka_sim_encode_pair(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *en ssize_t slen; fr_da_stack_t da_stack; - fr_dict_attr_t const *da = NULL; fr_dbuff_marker(&m, &work_dbuff); if (!cursor) return PAIR_ENCODE_FATAL_ERROR; @@ -814,42 +829,20 @@ ssize_t fr_aka_sim_encode_pair(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *en * only use 4 * 255 bytes of buffer space at a time. */ - /* - * Fast path for the common case. - */ - if ((vp->da->parent == fr_dict_root(dict_eap_aka_sim)) && (vp->vp_type != FR_TYPE_TLV)) { - da_stack.da[0] = vp->da; - da_stack.da[1] = NULL; - da_stack.depth = 1; - FR_PROTO_STACK_PRINT(&da_stack, 0); - return encode_rfc_hdr(&FR_DBUFF_MAX_BIND_CURRENT(dbuff, SIM_MAX_ATTRIBUTE_VALUE_LEN + 2), - &da_stack, 0, cursor, encode_ctx); - } - /* * Do more work to set up the stack for the complex case. */ fr_proto_da_stack_build(&da_stack, vp->da); FR_PROTO_STACK_PRINT(&da_stack, 0); - da = da_stack.da[0]; - - switch (da->type) { - /* - * Supported types - */ - default: - slen = encode_rfc_hdr(&FR_DBUFF_MAX_BIND_CURRENT(&work_dbuff, SIM_MAX_ATTRIBUTE_VALUE_LEN + 2), - &da_stack, 0, cursor, encode_ctx); - if (slen < 0) return slen; - break; - - case FR_TYPE_TLV: - slen = encode_tlv_hdr(&FR_DBUFF_MAX_BIND_CURRENT(&work_dbuff, SIM_MAX_ATTRIBUTE_VALUE_LEN + 2), - &da_stack, 0, cursor, encode_ctx); - if (slen < 0) return slen; - break; + if (da_stack.da[0]->type == FR_TYPE_TLV) { + slen = encode_tlv(&FR_DBUFF_MAX_BIND_CURRENT(&work_dbuff, SIM_MAX_ATTRIBUTE_VALUE_LEN + 2), + &da_stack, 0, cursor, encode_ctx); + } else { + slen = encode_rfc(&FR_DBUFF_MAX_BIND_CURRENT(&work_dbuff, SIM_MAX_ATTRIBUTE_VALUE_LEN + 2), + &da_stack, 0, cursor, encode_ctx); } + if (slen < 0) return slen; /* * We couldn't do it, so we didn't do anything. diff --git a/src/tests/unit/protocols/eap/sim/encode.txt b/src/tests/unit/protocols/eap/sim/encode.txt index 18bf19a5dc5..45e1534391a 100644 --- a/src/tests/unit/protocols/eap/sim/encode.txt +++ b/src/tests/unit/protocols/eap/sim/encode.txt @@ -8,8 +8,6 @@ need-feature tls proto eap-aka-sim proto-dictionary eap-aka-sim eap/aka-sim -migrate pair_legacy_nested = false - # Boolean attribute encode-pair.sim_tp_encode Any-ID-Req = yes match 0d 01 00 00 @@ -86,12 +84,20 @@ match 82 09 00 00 3f b8 34 1f f8 26 e0 4d 4a f3 f9 61 3c a9 84 26 0f 4a 53 ce 33 decode-pair.sim_tp_decode - match Encr-Data.Next-Pseudonym = "testing123", Encr-Data.Counter-Too-Small = yes +pair Encr-Data.Next-Pseudonym = "testing123", Any-ID-Req = yes, Encr-Data.Counter-Too-Small = yes +match Encr-Data = { Next-Pseudonym = "testing123", Counter-Too-Small = yes }, Any-ID-Req = yes + # Plaintext and encrypted attributes interleaved (this shouldn't happen usually, due to sorting) encode-pair.sim_tp_encode Encr-Data.Next-Pseudonym = "testing123", Any-ID-Req = yes, Encr-Data.Counter-Too-Small = yes -match 82 05 00 00 3f b8 34 1f f8 26 e0 4d 4a f3 f9 61 3c a9 84 26 0d 01 00 00 82 05 00 00 5a f8 99 3c 02 f5 6c 04 b8 6e bb 54 3a af 74 32 +match 82 09 00 00 3f b8 34 1f f8 26 e0 4d 4a f3 f9 61 3c a9 84 26 0f 4a 53 ce 33 99 9e 4f 29 df a4 79 18 a9 57 dd 0d 01 00 00 + +# +# Old style: NOT nested. So we put the children of the TLV 82 into different top-level TLVs. +# +#match 82 05 00 00 3f b8 34 1f f8 26 e0 4d 4a f3 f9 61 3c a9 84 26 0d 01 00 00 82 05 00 00 5a f8 99 3c 02 f5 6c 04 b8 6e bb 54 3a af 74 32 decode-pair.sim_tp_decode - -match Encr-Data.Next-Pseudonym = "testing123", Any-ID-Req = yes, Encr-Data.Counter-Too-Small = yes +match Encr-Data.Next-Pseudonym = "testing123", Encr-Data.Counter-Too-Small = yes, Any-ID-Req = yes # Array (one element) encode-pair.sim_tp_encode Version-List = 1 @@ -126,4 +132,4 @@ encode-pair.sim_tp_encode_rfc4186 IV = 0xcdf7ffa65de04c026b56c86b76b102ea, Encr- match 81 05 00 00 cd f7 ff a6 5d e0 4c 02 6b 56 c8 6b 76 b1 02 ea 82 05 00 00 b6 ed d3 82 79 e2 a1 42 3c 1a fc 5c 45 5c 7d 56 count -match 63 +match 64 diff --git a/src/tests/unit/protocols/eap/sim/encrypted.txt b/src/tests/unit/protocols/eap/sim/encrypted.txt index 63dc0fe7f6e..350ccf2a261 100644 --- a/src/tests/unit/protocols/eap/sim/encrypted.txt +++ b/src/tests/unit/protocols/eap/sim/encrypted.txt @@ -9,8 +9,6 @@ need-feature tls proto eap-aka-sim proto-dictionary eap-aka-sim eap/aka-sim -migrate pair_legacy_nested = false - # Encr-Data attributes should not be split between multiple outer TLVs (regression test) encode-pair.sim_tp_encode_rfc4186 IV = 0xd585ac7786b90336657c77b46575b9c4, Encr-Data.Next-Reauth-ID = "8osafwilQBCdof4", Encr-Data.Next-Pseudonym = "7QSzGAfgFKU8De9", Encr-Data.Nonce-S = 0xd61d1c6124106953f6f7283ae680a5ed, Encr-Data.Counter = 1 match 81 05 00 00 d5 85 ac 77 86 b9 03 36 65 7c 77 b4 65 75 b9 c4 82 11 00 00 6e a1 2b 5c d1 57 fa fc be a9 c9 7c ad 30 07 ff 72 dc cb c8 a9 96 b3 33 1f 71 aa 06 bb f0 1d 04 6b 51 9e fa 83 31 11 67 c6 93 1e 9c 06 5c 1f 2c 62 0d 1d 6d b0 b1 59 2f 91 f1 56 98 a9 e2 dc 3c