/src/freeradius-server/src/protocols/cbor/base.c
Line | Count | Source |
1 | | #include <freeradius-devel/util/cbor.h> |
2 | | #include <freeradius-devel/io/test_point.h> |
3 | | |
4 | | static ssize_t decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, |
5 | | uint8_t const *data, size_t data_len, UNUSED void *decode_ctx) |
6 | 4.53k | { |
7 | 4.53k | fr_dbuff_t dbuff; |
8 | 4.53k | uint8_t field = 0; |
9 | 4.53k | ssize_t slen; |
10 | | |
11 | 4.53k | fr_dbuff_init(&dbuff, data, data_len); |
12 | | |
13 | 4.53k | FR_DBUFF_OUT_RETURN(&field, &dbuff); |
14 | 4.53k | if (field != 0x9f) { |
15 | 13 | fr_strerror_printf("Invalid cbor header - expected indefinite array 9f, got %02x", |
16 | 13 | field); |
17 | 13 | return -1; |
18 | 13 | } |
19 | | |
20 | 58.4k | do { |
21 | 58.4k | if (fr_dbuff_extend_lowat(NULL, &dbuff, 1) == 0) { |
22 | 677 | fr_strerror_printf("Invalid cbor header - unexpected end of data"); |
23 | 677 | return -fr_dbuff_used(&dbuff); |
24 | 677 | } |
25 | | |
26 | 57.7k | field = *fr_dbuff_current(&dbuff); |
27 | 57.7k | if (field == 0xff) { |
28 | 110 | fr_dbuff_advance(&dbuff, 1); |
29 | 110 | break; |
30 | 110 | } |
31 | | |
32 | 57.6k | slen = fr_cbor_decode_pair(ctx, out, &dbuff, parent, false); |
33 | 57.6k | if (slen <= 0) return FR_DBUFF_ERROR_OFFSET(slen, fr_dbuff_used(&dbuff)); |
34 | 57.6k | } while (true); |
35 | | |
36 | 110 | return fr_dbuff_used(&dbuff); |
37 | 4.51k | } |
38 | | |
39 | | static ssize_t encode_pair(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, UNUSED void *encode_ctx) |
40 | 0 | { |
41 | 0 | fr_dbuff_t work_dbuff = FR_DBUFF(dbuff); |
42 | 0 | fr_pair_t *vp; |
43 | |
|
44 | 0 | FR_DBUFF_IN_BYTES_RETURN(&work_dbuff, (uint8_t) 0x9f); /* indefinite array */ |
45 | | |
46 | 0 | for (vp = fr_dcursor_current(cursor); |
47 | 0 | vp != NULL; |
48 | 0 | vp = fr_dcursor_next(cursor)) { |
49 | 0 | ssize_t slen; |
50 | |
|
51 | 0 | slen = fr_cbor_encode_pair(&work_dbuff, vp); |
52 | 0 | if (slen <= 0) return FR_DBUFF_ERROR_OFFSET(slen, fr_dbuff_used(&work_dbuff)); |
53 | 0 | } |
54 | | |
55 | 0 | FR_DBUFF_IN_BYTES_RETURN(&work_dbuff, (uint8_t) 0xff); /* end of indefinite array */ |
56 | | |
57 | 0 | return fr_dbuff_set(dbuff, &work_dbuff); |
58 | 0 | } |
59 | | |
60 | | /* |
61 | | * Test points |
62 | | */ |
63 | | extern fr_test_point_pair_encode_t cbor_tp_encode_pair; |
64 | | fr_test_point_pair_encode_t cbor_tp_encode_pair = { |
65 | | .func = encode_pair, |
66 | | }; |
67 | | |
68 | | extern fr_test_point_pair_decode_t cbor_tp_decode_pair; |
69 | | fr_test_point_pair_decode_t cbor_tp_decode_pair = { |
70 | | .func = decode_pair |
71 | | }; |
72 | | |
73 | | static int decode_test_ctx(void **out, UNUSED TALLOC_CTX *ctx, fr_dict_t const *dict, |
74 | | UNUSED fr_dict_attr_t const *root_da) |
75 | 4.53k | { |
76 | 4.53k | *out = UNCONST(fr_dict_t *, dict); |
77 | | |
78 | 4.53k | return 0; |
79 | 4.53k | } |
80 | | |
81 | | static ssize_t encode_proto(UNUSED TALLOC_CTX *ctx, fr_pair_list_t *vps, uint8_t *data, size_t data_len, UNUSED void *proto_ctx) |
82 | 0 | { |
83 | 0 | fr_dbuff_t dbuff; |
84 | 0 | fr_dcursor_t cursor; |
85 | |
|
86 | 0 | FR_DBUFF_INIT(&dbuff, data, data_len); |
87 | |
|
88 | 0 | fr_pair_dcursor_init(&cursor, vps); |
89 | 0 | return encode_pair(&dbuff, &cursor, NULL); |
90 | 0 | } |
91 | | |
92 | | static ssize_t decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, void *proto_ctx) |
93 | 4.53k | { |
94 | 4.53k | fr_dict_t *dict = proto_ctx; |
95 | | |
96 | 4.53k | return decode_pair(ctx, out, fr_dict_root(dict), data, data_len, proto_ctx); |
97 | 4.53k | } |
98 | | |
99 | | extern fr_test_point_proto_encode_t cbor_tp_encode_proto; |
100 | | fr_test_point_proto_encode_t cbor_tp_encode_proto = { |
101 | | .func = encode_proto |
102 | | }; |
103 | | |
104 | | extern fr_test_point_proto_decode_t cbor_tp_decode_proto; |
105 | | fr_test_point_proto_decode_t cbor_tp_decode_proto = { |
106 | | .test_ctx = decode_test_ctx, |
107 | | .func = decode_proto |
108 | | }; |