The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
decode.c
Go to the documentation of this file.
1/*
2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2.1 of the License, or (at your option) any later version.
6 *
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: f83a9d18c0e27fadd31570a6d9046d053cc799fe $
19 *
20 * @file protocols/der/decode.c
21 * @brief Functions to decode DER encoded data.
22 *
23 * @author Arran Cudbard-Bell (a.cudbardb@freeradius.org)
24 * @author Ethan Thompson (ethan.thompson@inkbridge.io)
25 *
26 * @copyright 2025 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
27 * @copyright 2025 Network RADIUS SAS (legal@networkradius.com)
28 */
29
30#include <freeradius-devel/io/test_point.h>
31#include <freeradius-devel/util/dbuff.h>
32#include <freeradius-devel/util/decode.h>
33#include <freeradius-devel/util/dict.h>
34#include <freeradius-devel/util/pair.h>
35#include <freeradius-devel/util/proto.h>
36#include <freeradius-devel/util/sbuff.h>
37#include <freeradius-devel/util/struct.h>
38#include <freeradius-devel/util/time.h>
39#include <freeradius-devel/util/dict_ext.h>
40
41#include "attrs.h"
42#include "der.h"
43
44#define IS_DER_TAG_CONTINUATION(_tag) (((_tag) & DER_TAG_CONTINUATION) == DER_TAG_CONTINUATION)
45#define IS_DER_TAG_CONSTRUCTED(_tag) (((_tag) & 0x20) == 0x20)
46#define IS_DER_LEN_MULTI_BYTE(_len) (((_len) & DER_LEN_MULTI_BYTE) == DER_LEN_MULTI_BYTE)
47
48typedef ssize_t (*fr_der_decode_oid_t)(uint64_t subidentifier, void *uctx, bool is_last);
49
50static ssize_t fr_der_decode_oid(fr_dbuff_t *in, fr_der_decode_oid_t func, void *uctx) CC_HINT(nonnull);
51
52static ssize_t fr_der_decode_hdr(fr_dict_attr_t const *parent, fr_dbuff_t *in, uint8_t *tag, size_t *len,
53 fr_der_tag_t expected) CC_HINT(nonnull(2,3,4));
54
56 fr_der_decode_ctx_t *decode_ctx);
57
62
63/** Function signature for DER decode functions
64 *
65 * @param[in] ctx Allocation context
66 * @param[in] out Where to store the decoded pairs.
67 * @param[in] parent Parent attribute. This should be the root of the dictionary
68 * we're using to decode DER data initially, and then nested children.
69 * @param[in] in The DER encoded data.
70 * @param[in] allowed_chars Optional array indicating which ASCII characters are allowed.
71 * @param[in] decode_ctx Any decode specific data.
72 * @return
73 * - > 0 on success. How many bytes were decoded.
74 * - 0 no bytes decoded.
75 * - < 0 on error. May be the offset (as a negative value) where the error occurred.
76 */
78 bool const allowed_chars[], fr_der_decode_ctx_t *decode_ctx) CC_HINT(nonnull(1,2,3,4,6));
79
81 UNUSED fr_der_decode_ctx_t *decode_ctx)
82{
84 fr_dbuff_t our_in = FR_DBUFF(in);
85 uint8_t value = 0;
86
87 size_t len = fr_dbuff_remaining(&our_in);
88
90
91 /*
92 * ISO/IEC 8825-1:2021
93 * 8.2 Encoding of a boolean value
94 * 8.2.1 The encoding of a boolean value shall be primitive.
95 * The contents octets shall consist of a single octet.
96 * 8.2.2 If the boolean value is:
97 * FALSE the octet shall be zero [0x00].
98 * If the boolean value is TRUE the octet shall have any non-zero value, as a sender's option.
99 *
100 * 11.1 Boolean values
101 * If the encoding represents the boolean value TRUE, its single contents octet shall have all
102 * eight bits set to one [0xff]. (Contrast with 8.2.2.)
103 */
104 if (len != 1) {
105 fr_strerror_printf_push("Boolean has incorrect length (%zu). Must be 1.", len);
106 return -1;
107 }
108
109 FR_DBUFF_OUT_RETURN(&value, &our_in);
110
112 fr_strerror_printf_push("Boolean is not correctly DER encoded (0x%02" PRIx32 " or 0x%02" PRIx32 ").", DER_BOOLEAN_FALSE,
114 return -1;
115 }
116
117 vp = fr_pair_afrom_da(ctx, parent);
118 if (unlikely(vp == NULL)) {
119 fr_strerror_const_push("Out of memory");
120 return -1;
121 }
122
123 vp->vp_bool = value > 0;
124
126
127 return fr_dbuff_set(in, &our_in);
128}
129
131 UNUSED fr_der_decode_ctx_t *decode_ctx)
132{
133 fr_pair_t *vp;
134 fr_dbuff_t our_in = FR_DBUFF(in);
135 uint64_t value = 0;
136 uint8_t sign = 0;
137 size_t i;
138
139 size_t len = fr_dbuff_remaining(&our_in);
140
141 if (parent->type != FR_TYPE_INT64) {
142 fr_strerror_printf_push("Expected parent type 'int64', got attribute %s of type %s", parent->name,
143 fr_type_to_str(parent->type));
144 return -1;
145 }
146
147 if (len > sizeof(value)) {
148 fr_strerror_printf_push("Integer too large (%zu)", len);
149 return -1;
150 }
151
152 /*
153 * ISO/IEC 8825-1:2021
154 * 8.3 Encoding of an integer value
155 * 8.3.1 The encoding of an integer value shall be primitive.
156 * The contents octets shall consist of one or more octets.
157 * 8.3.2 If the contents octets of an integer value encoding consist of more than one octet,
158 * then the bits of the first octet and bit 8 of the second octet:
159 * a) shall not all be ones; and
160 * b) shall not all be zero.
161 * NOTE - These rules ensure that an integer value is always encoded in the smallest possible number
162 * of octets. 8.3.3 The contents octets shall be a two's complement binary number equal to the
163 * integer value, and consisting of bits 8 to 1 of the first octet, followed by bits 8 to 1 of the
164 * second octet, followed by bits 8 to 1 of each octet in turn up to and including the last octet of
165 * the contents octets.
166 */
167 FR_DBUFF_OUT_RETURN(&sign, &our_in);
168
169 if (sign & 0x80) {
170 /*
171 * If the sign bit is set, this fill the upper bits with all zeros,
172 * and set the lower bits to "sign".
173 * This is important for the case where the length of the integer is less than the length of the
174 * integer type.
175 */
176 value = ~(uint64_t) 0xff;
177 }
178
179 value |= sign;
180
181 if (len > 1) {
182 /*
183 * If the length of the integer is greater than 1, we need to check that the first 9 bits:
184 * 1. are not all 0s; and
185 * 2. are not all 1s
186 * These two conditions are necessary to ensure that the integer conforms to DER.
187 */
188 uint8_t byte;
189
190 FR_DBUFF_OUT_RETURN(&byte, &our_in);
191
192 if ((((value & 0xff) == 0xff) && (byte & 0x80)) || (((~value & 0xff) == 0xff) && !(byte & 0x80))) {
193 fr_strerror_const_push("Integer is not correctly DER encoded. First two bytes are all 0s or all 1s.");
194 return -1;
195 }
196
197 value = (value << 8) | byte;
198 }
199
200 for (i = 2; i < len; i++) {
201 uint8_t byte;
202
203 FR_DBUFF_OUT_RETURN(&byte, &our_in);
204 value = (value << 8) | byte;
205 }
206
207 vp = fr_pair_afrom_da(ctx, parent);
208 if (unlikely(vp == NULL)) {
209 fr_strerror_const_push("Out of memory");
210 return -1;
211 }
212
213 vp->vp_int64 = value;
214
216
217 return fr_dbuff_set(in, &our_in);
218}
219
221 fr_dbuff_t *in, fr_der_decode_ctx_t *decode_ctx)
222{
223 fr_pair_t *vp;
224 fr_dbuff_t our_in = FR_DBUFF(in);
225 uint8_t unused_bits = 0;
226 uint8_t *data;
227
228 ssize_t data_len = 0, index = 0;
229 size_t len = fr_dbuff_remaining(&our_in);
230
232
233 /*
234 * Now we know that the parent is an octets attribute, we can decode the bitstring
235 */
236
237 /*
238 * ISO/IEC 8825-1:2021
239 * 8.6 Encoding of a bitstring value
240 * 8.6.1 The encoding of a bitstring value shall be either primitive or constructed at the option
241 * of the sender.
242 * NOTE - Where it is necessary to transfer part of a bit string before the entire
243 * bitstring is available, the constructed encoding is used.
244 * 8.6.2 The contents octets for the primitive encoding shall contain an initial octet followed
245 * by zero, one or more subsequent octets.
246 * 8.6.2.1 The bits in the bitstring value, commencing with the leading bit and proceeding
247 * to the trailing bit, shall be placed in bits 8 to 1 of the first subsequent
248 * octet, followed by bits 8 to 1 of the second subsequent octet, followed by bits
249 * 8 to 1 of each octet in turn, followed by as many bits as are needed of the
250 * final subsequent octet, commencing with bit 8.
251 * NOTE - The terms "leading bit" and "trailing bit" are defined in
252 * Rec. ITU-T X.680 | ISO/IEC 8824-1, 22.2.
253 * 8.6.2.2 The initial octet shall encode, as an unsigned binary integer with bit 1 as the
254 * least significant bit, the number of unused bits in the final subsequent octet.
255 * The number shall be in the range zero to seven.
256 * 8.6.2.3 If the bitstring is empty, there shall be no subsequent octets, and the initial
257 * octet shall be zero.
258 *
259 * 10.2 String encoding forms
260 * For bitstring, octetstring and restricted character string types, the constructed form of
261 * encoding shall not be used. (Contrast with 8.23.6.)
262 *
263 * 11.2 Unused bits 11.2.1 Each unused bit in the final octet of the encoding of a bit string value shall
264 * be set to zero.
265 */
266
267 FR_DBUFF_OUT_RETURN(&unused_bits, &our_in);
268
269 if (unlikely(unused_bits > 7)) {
270 /*
271 * This means an entire byte is unused bits. Which is not allowed.
272 */
273 fr_strerror_const_push("Invalid number of unused bits in 'bitstring'");
274 return -1;
275 }
276
277 if ((len == 1) && unused_bits) {
278 fr_strerror_const_push("Insufficient data for 'bitstring'. Missing data bytes");
279 return -1;
280 }
281
282 if (fr_type_is_struct(parent->type)) {
283 if (!len) {
284 fr_strerror_const_push("Insufficient data for 'struct'. Missing data bytes");
285 return -1;
286 }
287
288 /*
289 * If the parent is a struct attribute, we will not be adding the unused bits count to the first
290 * byte
291 */
292 data_len = len - 1;
293 } else {
294 data_len = len;
295 }
296
297 data = talloc_array(decode_ctx->tmp_ctx, uint8_t, data_len);
298 if (unlikely(!data)) {
299 fr_strerror_const_push("Out of memory");
300 return -1;
301 }
302
303 if (fr_type_is_octets(parent->type)) {
304 /*
305 * If the parent is an octets attribute, we need to add the unused bits count to the first byte
306 */
307 index = 1;
308 data[0] = unused_bits;
309 }
310
311 for (; index < data_len; index++) {
312 uint8_t byte;
313
314 FR_DBUFF_OUT_RETURN(&byte, &our_in);
315
316 data[index] = byte;
317 }
318
319 /*
320 * Remove the unused bits from the last byte
321 */
322 if (unused_bits) {
323 uint8_t mask = 0xff << unused_bits;
324
325 data[data_len - 1] &= mask;
326 }
327
328 if (fr_type_is_struct(parent->type)) {
329 ssize_t slen;
330
331 slen = fr_struct_from_network(ctx, out, parent, data, data_len, decode_ctx, NULL, NULL);
332
333 /*
334 * If the structure decoder didn't consume all the data, we need to free the data and bail out
335 */
336 if (unlikely(slen < data_len - 1)) {
337 fr_strerror_printf_push("Bitstring structure decoder didn't consume all data. Consumed %zd of %zu bytes",
338 slen, data_len);
339 error:
341 return -1;
342 }
343
345 return fr_dbuff_set(in, &our_in);
346 }
347
348 vp = fr_pair_afrom_da(ctx, parent);
349 if (unlikely(!vp)) {
350 fr_strerror_const_push("Out of memory");
351 goto error;
352 }
353
354 /*
355 * Add the bitstring to the pair value as octets
356 */
357 fr_pair_value_memdup(vp, data, len, false);
358
360
361 return fr_dbuff_set(in, &our_in);
362}
363
366{
367 fr_pair_t *vp;
368 fr_dbuff_t our_in = FR_DBUFF(in);
369 uint8_t *data = NULL;
370
371 size_t len = fr_dbuff_remaining(&our_in);
372
374
375 /*
376 * ISO/IEC 8825-1:2021
377 * 8.7 Encoding of an octetstring value
378 * 8.7.1 The encoding of an octetstring value shall be either primitive or constructed at the
379 * option of the sender.
380 * NOTE - Where it is necessary to transfer part of an octet string before the entire
381 * octetstring is available, the constructed encoding is used.
382 * 8.7.2 The primitive encoding contains zero, one or more contents octets equal in value to the
383 * octets in the data value, in the order they appear in the data value, and with the most
384 * significant bit of an octet of the data value aligned with the most significant bit of an
385 * octet of the contents octets.
386 * 8.7.3 The contents octets for the constructed encoding shall consist of zero, one, or more
387 * encodings.
388 * NOTE - Each such encoding includes identifier, length, and contents octets, and may
389 * include end-of-contents octets if it is constructed.
390 * 8.7.3.1 To encode an octetstring value in this way, it is segmented. Each segment shall
391 * consist of a series of consecutive octets of the value. There shall be no
392 * significance placed on the segment boundaries.
393 * NOTE - A segment may be of size zero, i.e. contain no octets.
394 *
395 * 10.2 String encoding forms
396 * For bitstring, octetstring and restricted character string types, the constructed form of
397 * encoding shall not be used. (Contrast with 8.23.6.)
398 */
399
400 vp = fr_pair_afrom_da(ctx, parent);
401 if (unlikely(!vp)) {
402 oom:
403 fr_strerror_const_push("Out of memory");
404 return -1;
405 }
406
407 if (unlikely(fr_pair_value_mem_alloc(vp, &data, len, false) < 0)) {
409 goto oom;
410 }
411
412 (void) fr_dbuff_out_memcpy(data, &our_in, len); /* this can never fail */
413
415
416 return fr_dbuff_set(in, &our_in);
417}
418
420 UNUSED fr_der_decode_ctx_t *decode_ctx)
421{
422 fr_pair_t *vp;
423 fr_dbuff_t our_in = FR_DBUFF(in);
424
425 if (fr_dbuff_remaining(&our_in) != 0) {
426 fr_strerror_const_push("Null has non-zero length");
427 return -1;
428 }
429
430 /*
431 * ISO/IEC 8825-1:2021
432 * 8.8 Encoding of a null value 8.8.1 The encoding of a null value shall be primitive. 8.8.2 The contents
433 * octets shall not contain any octets. NOTE - The length octet is zero.
434 */
435
436 vp = fr_pair_afrom_da(ctx, parent);
437 if (unlikely(!vp)) {
438 fr_strerror_const_push("Out of memory");
439 return -1;
440 }
441
443
444 return fr_dbuff_set(in, &our_in);
445}
446
447typedef struct {
448 int depth;
449 unsigned int oid[FR_DICT_MAX_TLV_STACK];
450} fr_der_decode_oid_to_stack_ctx_t; //!< Context for decoding an OID to a DA
451
452/** Decode an OID to an exploded list
453 *
454 * @param[in] subidentifier The subidentifier to decode
455 * @param[in] uctx User context
456 * @param[in] is_last Is this the last subidentifier in the OID
457 * @return
458 * - 1 on success
459 * - < 0 on error
460 */
461static ssize_t fr_der_decode_oid_to_stack(uint64_t subidentifier, void *uctx, UNUSED bool is_last)
462{
463 fr_der_decode_oid_to_stack_ctx_t *decode_ctx = uctx;
464
465 if (decode_ctx->depth > 20) {
466 fr_strerror_printf("OID has too many elements (%d > 20)", decode_ctx->depth);
467 return -1;
468 }
469
470
471 decode_ctx->oid[decode_ctx->depth++] = subidentifier;
472
473 return 1;
474}
475
476typedef struct {
477 TALLOC_CTX *ctx; //!< Allocation context
478 fr_dict_attr_t const *parent_da; //!< Parent dictionary attribute
479 fr_pair_list_t *parent_list; //!< Parent pair list
480} fr_der_decode_oid_to_da_ctx_t; //!< Context for decoding an OID to a dictionary attribute
481
482/** Decode an OID to a dictionary attribute
483 *
484 * @param[in] subidentifier The subidentifier to decode
485 * @param[in] uctx User context
486 * @param[in] is_last Is this the last subidentifier in the OID
487 * @return
488 * - 1 on success
489 * - < 0 on error
490 */
491static ssize_t fr_der_decode_oid_to_da(uint64_t subidentifier, void *uctx, bool is_last)
492{
493 fr_der_decode_oid_to_da_ctx_t *decode_ctx = uctx;
494 fr_pair_t *vp;
495 fr_dict_attr_t const *da;
496
497 fr_dict_attr_t const *parent_da = fr_type_is_group(decode_ctx->parent_da->type) ?
498 fr_dict_attr_ref(decode_ctx->parent_da) :
499 decode_ctx->parent_da;
500
501 FR_PROTO_TRACE("Decoding OID to dictionary attribute");
502 FR_PROTO_TRACE("decode context - Parent Name: %s Sub-Identifier %" PRIu64, parent_da->name, subidentifier);
503 FR_PROTO_TRACE("decode context - Parent Address: %p", parent_da);
504
505 da = fr_dict_attr_child_by_num(parent_da, subidentifier);
506
507 if (is_last) {
508 if (unlikely(da == NULL)) {
509 decode_ctx->parent_da = fr_dict_attr_unknown_typed_afrom_num(decode_ctx->ctx, parent_da,
510 subidentifier, FR_TYPE_OCTETS);
511
512 if (unlikely(decode_ctx->parent_da == NULL)) {
513 return -1;
514 }
515
516 FR_PROTO_TRACE("Created DA: %s", decode_ctx->parent_da->name);
517 return 1;
518 }
519
520 decode_ctx->parent_da = da;
521
522 FR_PROTO_TRACE("Created DA: %s", decode_ctx->parent_da->name);
523 return 1;
524 }
525
526 if (unlikely(da == NULL)) {
527 /*
528 * We need to create an unknown attribute for this subidentifier so we can store the raw data
529 */
530 fr_dict_attr_t *unknown_da =
531 fr_dict_attr_unknown_typed_afrom_num(decode_ctx->ctx, parent_da, subidentifier, FR_TYPE_TLV);
532
533 if (unlikely(unknown_da == NULL)) {
534 oom:
535 fr_strerror_const_push("Out of memory");
536 return -1;
537 }
538
539 vp = fr_pair_afrom_da(decode_ctx->ctx, unknown_da);
540
541 talloc_free(unknown_da);
542 } else {
543 vp = fr_pair_afrom_da(decode_ctx->ctx, da);
544 }
545
546 if (unlikely(!vp)) goto oom;
547
548 fr_pair_append(decode_ctx->parent_list, vp);
549
550 decode_ctx->ctx = vp;
551 decode_ctx->parent_da = vp->da;
552 decode_ctx->parent_list = &vp->vp_group;
553
554 FR_PROTO_TRACE("Created DA: %s", decode_ctx->parent_da->name);
555 return 1;
556}
557
558/** Decode an OID from a DER encoded buffer using a callback
559 *
560 * @param[in] in The DER encoded data.
561 * @param[in] func The callback function to call for each subidentifier.
562 * @param[in] uctx User context for the callback function.
563 * @return
564 * - 0 on success
565 * - < 0 on error
566 */
568{
569 fr_dbuff_t our_in = FR_DBUFF(in);
570 bool first;
571 uint64_t oid;
572 int magnitude, depth;
573 size_t len = fr_dbuff_remaining(&our_in); /* we decode the entire dbuff */
574
575 /*
576 * ISO/IEC 8825-1:2021
577 * 8.19 Encoding of an object identifier value
578 * 8.19.1 The encoding of an object identifier value shall be primitive.
579 * 8.19.2 The contents octets shall be an (ordered) list of encodings of subidentifiers (see 8.19.3
580 * and 8.19.4) concatenated together. Each subidentifier is represented as a series of
581 * (one or more) octets. Bit 8 of each octet indicates whether it is the last in the series: bit 8
582 * of the last octet is zero; bit 8 of each preceding octet is one. Bits 7 to 1 of the octets in
583 * the series collectively encode the subidentifier. Conceptually, these groups of bits are
584 * concatenated to form an unsigned binary number whose most significant bit is bit 7 of the first
585 * octet and whose least significant bit is bit 1 of the last octet. The subidentifier shall be
586 * encoded in the fewest possible octets, that is, the leading octet of the subidentifier shall not
587 * have the value 8016.
588 * 8.19.3 The number of subidentifiers (N) shall be one less than the number of object identifier
589 * components in the object identifier value being encoded. 8.19.4 The numerical value of the
590 * first subidentifier is derived from the values of the first two object identifier components in
591 * the object identifier value being encoded, using the formula: (X*40) + Y where X is the value
592 * of the first object identifier component and Y is the value of the second object identifier
593 * component. NOTE - This packing of the first two object identifier components recognizes that
594 * only three values are allocated from the root node, and at most 39 subsequent values from nodes
595 * reached by X = 0 and X = 1. 8.19.5 The numerical value of the ith subidentifier, (2 <= i <= N) is
596 * that of the (i + 1)th object identifier component.
597 */
598
599 /*
600 * RFC 5280 says:
601 *
602 * ...
603 * This specification mandates support for OIDs that have arc elements
604 * with values that are less than 2^28, that is, they MUST be between 0
605 * and 268,435,455, inclusive. This allows each arc element to be
606 * represented within a single 32-bit word. Implementations MUST also
607 * support OIDs where the length of the dotted decimal (see Section 1.4
608 * of [RFC4512]) string representation can be up to 100 bytes
609 * (inclusive). Implementations MUST be able to handle OIDs with up to
610 * 20 elements (inclusive).
611 * ...
612 *
613 * We support up to 2^32 for attribute numbers (unsigned int), and 24 for
614 * nesting (FR_DICT_TLV_NEST_MAX), so we're OK here.
615 *
616 */
617 FR_PROTO_TRACE("Decoding OID");
618 FR_PROTO_HEX_DUMP(fr_dbuff_current(&our_in), len, "buff in OID");
619
620 first = true;
621 oid = 0;
622 magnitude = 0;
623 depth = 0;
624
625 /*
626 * Loop until done.
627 */
628 while (len) {
629 uint8_t byte;
630
631 FR_DBUFF_OUT_RETURN(&byte, &our_in);
632
633 magnitude++;
634 if (magnitude > 4) {
635 fr_strerror_const_push("OID subidentifier too large (>32 bits)");
636 return -1;
637 }
638
639 /*
640 * Shift in the new data.
641 */
642 oid <<= 7;
643 oid |= byte & 0x7f;
644 len--;
645
646 /*
647 * There's more? The MUST be more if the high bit is set.
648 */
649 if ((byte & 0x80) != 0) {
650 if (len == 0) {
651 fr_strerror_const_push("OID subidentifier is truncated");
652 return -1;
653 }
654 continue;
655 }
656
657 depth++;
659 fr_strerror_printf_push("OID has too many elements (%d >= %d)",
661 return -1;
662 }
663
664 /*
665 * The initial packed field has the first two compenents included, as (x * 40) + y.
666 */
667 if (first) {
668 uint64_t first_component;
669
670 if (oid < 40) {
671 first_component = 0;
672
673 } else if (oid < 80) {
674 first_component = 1;
675 oid -= 40;
676
677 } else {
678 first_component = 2;
679 oid -= 80;
680 }
681 first = false;
682 depth++; /* 2 OIDs packed into the first byte */
683
684 /*
685 * Note that we allow OID=1 here. It doesn't make sense, but whatever.
686 */
687 FR_PROTO_TRACE("decode context - first OID: %" PRIu64, first_component);
688 if (unlikely(func(first_component, uctx, (len == 0)) <= 0)) return -1;
689 }
690
691 /*
692 * 32 bits is still larger than 28, so we do another check here.
693 */
694 if (oid >= ((uint64_t) 1 << 28)) {
695 fr_strerror_printf("OID subidentifier '%" PRIu64 " is invalid - it must be no more than 28 bits in side",
696 oid);
697 return -1;
698 }
699
700 FR_PROTO_TRACE("decode context - OID: %" PRIu64, oid);
701 if (unlikely(func(oid, uctx, (len == 0)) <= 0)) return -1;
702
703 /*
704 * Reset fields.
705 */
706 oid = 0;
707 magnitude = 0;
708 }
709
710 return fr_dbuff_set(in, &our_in);
711}
712
713
715 fr_dbuff_t *in, fr_der_decode_ctx_t *decode_ctx)
716{
717 /*
718 * @todo - check for valid UTF8 string.
719 */
720
721 return fr_der_decode_string(ctx, out, parent, in, NULL, decode_ctx);
722}
723
725 fr_dbuff_t *in, fr_der_decode_ctx_t *decode_ctx)
726{
727 fr_pair_t *vp;
728 fr_dict_attr_t const *child = NULL;
729 fr_dbuff_t our_in = FR_DBUFF(in);
731
733
734 /*
735 * ISO/IEC 8825-1:2021
736 * 8.9 Encoding of a sequence value
737 * 8.9.1 The encoding of a sequence value shall be constructed.
738 * 8.9.2 The contents octets shall consist of the complete encoding of one data value from each of
739 * the types listed in the ASN.1 definition of the sequence type, in the order of their
740 * appearance in the definition, unless the type was referenced with the keyword OPTIONAL
741 * or the keyword DEFAULT.
742 * 8.9.3 The encoding of a data value may, but need not, be present for a type referenced with the
743 * keyword OPTIONAL or the keyword DEFAULT. If present, it shall appear in the order of
744 * appearance of the corresponding type in the ASN.1 definition.
745 *
746 * 11.5 Set and sequence components with default value
747 * The encoding of a set value or sequence value shall not include an encoding for any component
748 * value which is equal to its default value.
749 */
750
751 if (flags->min && !fr_dbuff_remaining(&our_in)) {
752 fr_strerror_printf_push("Expected at last %d elements in %s, got 0", flags->min, parent->name);
753 return -1;
754 }
755
756 vp = fr_pair_afrom_da(ctx, parent);
757 if (unlikely(!vp)) {
758 fr_strerror_const_push("Out of memory");
759 return -1;
760 }
761
762 /*
763 * This is a sequence-of, which means it either has only one child, or it's a sequence_of=choice,
764 * and all of the children are numbered options.
765 */
766 if (unlikely(flags->is_sequence_of)) {
767 if (flags->sequence_of != FR_DER_TAG_CHOICE) {
768 child = fr_dict_attr_iterate_children(parent, &child);
769 if (!child) {
770 fr_strerror_printf_push("Sequence %s has no children", parent->name);
771 error:
773 return -1;
774 }
775 }
776
777 /*
778 * Decode all of the data.
779 */
780 while (fr_dbuff_remaining(&our_in) > 0) {
781 ssize_t slen;
782 uint8_t current_tag;
783 uint8_t tag_byte;
784 uint8_t *current_marker = fr_dbuff_current(&our_in);
785
786 FR_DBUFF_OUT_RETURN(&tag_byte, &our_in);
787
788 current_tag = (tag_byte & DER_TAG_CONTINUATION); /* always <= FR_DER_TAG_MAX */
789
790 /*
791 * If we have a choice, the children must be numbered. The class can be CONTEXT,
792 * PRIVATE, or ENTERPRISE.
793 *
794 * Otherwise the children are standard DER tags. The class must be UNIVERSAL.
795 */
796 if (unlikely(flags->sequence_of == FR_DER_TAG_CHOICE)) {
797 if ((tag_byte & DER_TAG_CLASS_MASK) == FR_DER_CLASS_UNIVERSAL) {
798 unexpected_class:
799 fr_strerror_printf_push("Tag has unexpected class %20x", tag_byte & DER_TAG_CLASS_MASK);
800 goto error;
801 }
802
803 child = fr_dict_attr_child_by_num(parent, current_tag);
804 if (!child) {
805 fr_der_attr_flags_t *child_flags;
806
807 child = fr_dict_attr_unknown_raw_afrom_num(decode_ctx->tmp_ctx, parent, current_tag);
808 if (!child) goto error;
809
810 /*
811 * Save the option and class, so that we can encode it later.
812 */
814 child_flags->is_option = true;
815 child_flags->option = current_tag;
816 child_flags->class = tag_byte & DER_TAG_CLASS_MASK;
817 }
818
819 } else if (unlikely(current_tag != flags->sequence_of)) {
820 if ((tag_byte & DER_TAG_CLASS_MASK) != FR_DER_CLASS_UNIVERSAL) {
821 goto unexpected_class;
822 }
823
824 fr_strerror_printf_push("Attribute %s is a sequence_of=%s which does not allow DER type '%s'",
825 parent->name,
826 fr_der_tag_to_str(flags->sequence_of),
827 fr_der_tag_to_str(current_tag));
828 goto error;
829 }
830
831 FR_PROTO_TRACE("decode context %s -> %s", parent->name, child->name);
832
833 fr_dbuff_set(&our_in, current_marker);
834
835 /*
836 * A child could have been encoded with zero bytes if it has a default value.
837 */
838 slen = fr_der_decode_pair_dbuff(vp, &vp->vp_group, child, &our_in, decode_ctx);
839 if (unlikely(slen < 0)) {
840 fr_strerror_printf_push("Failed decoding %s", vp->da->name);
841 goto error;
842 }
843 }
844
846
847 return fr_dbuff_set(in, &our_in);
848 }
849
850 /*
851 * Decode the children. Since it's not a sequence_of=..., we must have a random bunch of
852 * children. The children are packed in order. Some may be optional.
853 *
854 * We loop over all of the children, because some might have default values.
855 */
856 while ((child = fr_dict_attr_iterate_children(parent, &child))) {
857 ssize_t ret;
858
859 FR_PROTO_TRACE("decode context %s -> %s", parent->name, child->name);
860
861 ret = fr_der_decode_pair_dbuff(vp, &vp->vp_group, child, &our_in, decode_ctx);
862 if (unlikely(ret < 0)) {
863 fr_strerror_printf_push("Failed decoding %s", vp->da->name);
865 return ret;
866 }
867 }
868
869 /*
870 * Ensure that we grab all of the data.
871 *
872 * @todo - if there is data left over, decode it as raw octets. We then also have to keep track
873 * of the maximum child number, and create unknown attributes starting from the last one.
874 */
875 if (fr_dbuff_remaining(&our_in)) {
876 FR_PROTO_TRACE("Ignoring extra data in sequence");
878
879 (void) fr_dbuff_advance(&our_in, fr_dbuff_remaining(&our_in));
880 }
881
883
884 return fr_dbuff_set(in, &our_in);
885}
886
888 fr_der_decode_ctx_t *decode_ctx)
889{
890 fr_pair_t *vp;
891 fr_dict_attr_t const *child = NULL;
892 fr_dbuff_t our_in = FR_DBUFF(in);
893 fr_dbuff_marker_t previous_marker;
894 uint8_t previous_tag = 0x00;
895 size_t previous_len = 0;
897
899
900 /*
901 * ISO/IEC 8825-1:2021
902 * 8.11 Encoding of a set value
903 * 8.11.1 The encoding of a set value shall be constructed.
904 * 8.11.2 The contents octets shall consist of the complete encoding of one data value from each
905 * of the types listed in the ASN.1 definition of the set type, in an order chosen by the
906 * sender, unless the type was referenced with the keyword OPTIONAL or the keyword DEFAULT.
907 * 8.11.3 The encoding of a data value may, but need not, be present for a type referenced with the
908 * keyword OPTIONAL or the keyword DEFAULT.
909 *
910 * 11.5 Set and sequence components with default value
911 * The encoding of a set value or sequence value shall not include an encoding for any component
912 * value which is equal to its default value.
913 */
914
915 if (flags->min && !fr_dbuff_remaining(&our_in)) {
916 fr_strerror_printf_push("Expected at last %d elements in %s, got 0", flags->min, parent->name);
917 return -1;
918 }
919
920 vp = fr_pair_afrom_da(ctx, parent);
921 if (unlikely(!vp)) {
922 fr_strerror_const_push("Out of memory");
923 return -1;
924 }
925
926 if (flags->is_set_of) {
927 /*
928 * There should only be one child in a "set_of". We can't check this when we load
929 * the dictionaries, because there is no "finalize" callback.
930 *
931 * @todo - we would need to walk through all of the dictionary attributes, and
932 * call a new function which would check whether or not the parent had any
933 * children. And if not, return a load-time error.
934 */
935 child = NULL;
936 child = fr_dict_attr_iterate_children(parent, &child);
937 if (!child) {
938 fr_strerror_printf_push("Missing child for %s", parent->name);
939 return -1;
940 }
941
942 while (fr_dbuff_remaining(&our_in) > 0) {
943 fr_dbuff_marker_t current_value_marker;
944 ssize_t ret;
945 uint8_t current_tag;
946 uint8_t *current_marker = fr_dbuff_current(&our_in);
947 size_t len;
948
949 FR_PROTO_TRACE("decode context %s -> %s", parent->name, child->name);
950
951 if (unlikely(fr_der_decode_hdr(NULL, &our_in, &current_tag, &len, flags->set_of) <= 0)) {
952 ret = -1;
953 error:
955 fr_strerror_printf_push("Failed decoding %s", parent->name);
956 return ret;
957 }
958
959 fr_dbuff_marker(&current_value_marker, &our_in);
960
961 /*
962 * Ensure that the contents of the tags are sorted.
963 */
964 if (previous_tag) {
965 uint8_t prev_byte = 0, curr_byte = 0;
966 fr_dbuff_t previous_item = FR_DBUFF(&previous_marker);
967
968 fr_dbuff_set_end(&previous_item, fr_dbuff_current(&previous_marker) + previous_len);
969
970 do {
971 FR_DBUFF_OUT_RETURN(&prev_byte, &previous_item);
972 FR_DBUFF_OUT_RETURN(&curr_byte, &our_in);
973
974 if (prev_byte > curr_byte) {
975 fr_strerror_const_push("Set tags are not in ascending order");
976 ret = -1;
977 goto error;
978 }
979
980 if (prev_byte < curr_byte) {
981 break;
982 }
983
984 } while (fr_dbuff_remaining(&our_in) > 0 && fr_dbuff_remaining(&previous_item) > 0);
985
986 if (prev_byte > curr_byte && fr_dbuff_remaining(&previous_item) > 0) {
988 "Set tags are not in ascending order. Previous item has more data");
989 ret = -1;
990 goto error;
991 }
992 }
993
994 previous_tag = current_tag;
995 previous_len = len;
996
997 previous_marker = current_value_marker;
998
999 fr_dbuff_set(&our_in, current_marker);
1000
1001 ret = fr_der_decode_pair_dbuff(vp, &vp->vp_group, child, &our_in, decode_ctx);
1002 if (unlikely(ret <= 0)) {
1003 fr_strerror_printf_push("Failed decoding %s", vp->da->name);
1004 goto error;
1005 }
1006 }
1007
1009
1010 return fr_dbuff_set(in, &our_in);
1011 }
1012
1013 /*
1014 * Decode the children. Since it's not a sequence_of=..., we must have a set of children. The
1015 * children are packed in order. Some may be optional.
1016 */
1017 while ((child = fr_dict_attr_iterate_children(parent, &child))) {
1018 ssize_t ret;
1019 uint8_t current_tag;
1020
1021 FR_PROTO_TRACE("decode context %s -> %s", parent->name, child->name);
1022
1023 if (fr_dbuff_remaining(&our_in)) {
1024 uint8_t *current_ptr = fr_dbuff_current(&our_in);
1025
1026 /*
1027 * Check that the tag is in ascending order
1028 */
1029 FR_DBUFF_OUT_RETURN(&current_tag, &our_in);
1030
1031 if (unlikely(current_tag < previous_tag)) {
1032 fr_strerror_const_push("Set tags are not in ascending order");
1033 talloc_free(vp);
1034 return -1;
1035 }
1036
1037 previous_tag = current_tag;
1038
1039 /*
1040 * Reset the buffer to the start of the tag
1041 */
1042 fr_dbuff_set(&our_in, current_ptr);
1043 }
1044
1045 /*
1046 * A child could have been encoded with zero bytes if it has a default value.
1047 */
1048 ret = fr_der_decode_pair_dbuff(vp, &vp->vp_group, child, &our_in, decode_ctx);
1049 if (unlikely(ret < 0)) {
1050 fr_strerror_printf_push("Failed decoding %s", vp->da->name);
1051 talloc_free(vp);
1052 return ret;
1053 }
1054 }
1055
1056 /*
1057 * Ensure that we grab all of the data.
1058 *
1059 * @todo - if there is data left over, decode it as raw octets. We then also have to keep track
1060 * of the maximum child number, and create unknown attributes starting from the last one.
1061 */
1062 if (fr_dbuff_remaining(&our_in)) {
1063 FR_PROTO_TRACE("Ignoring extra data in set");
1064 FR_PROTO_HEX_DUMP(fr_dbuff_current(&our_in), fr_dbuff_remaining(&our_in), " ");
1065
1066 (void) fr_dbuff_advance(&our_in, fr_dbuff_remaining(&our_in));
1067 }
1068
1070
1071 return fr_dbuff_set(in, &our_in);
1072}
1073
1076{
1077 static bool const allowed_chars[UINT8_MAX + 1] = {
1078 [' '] = true, ['\''] = true, ['('] = true, [')'] = true,
1079 ['+'] = true, [','] = true, ['-'] = true, ['.'] = true,
1080 ['/'] = true, [':'] = true, ['='] = true, ['?'] = true,
1081 ['A' ... 'Z'] = true, ['a' ... 'z'] = true,
1082 ['0' ... '9'] = true,
1083 };
1084
1085 return fr_der_decode_string(ctx, out, parent, in, allowed_chars, decode_ctx);
1086}
1087
1090{
1091 static bool const allowed_chars[UINT8_MAX + 1] = {
1092 [0x08] = true, [0x0A] = true, [0x0C] = true, [0x0D] = true,
1093 [0x0E] = true, [0x0F] = true, [0x19] = true, [0x1A] = true,
1094 [0x1B] = true, [0x1D] = true, [' '] = true, ['!'] = true,
1095 ['"'] = true, ['%'] = true, ['&'] = true, ['\''] = true,
1096 ['('] = true, [')'] = true, ['*'] = true, ['+'] = true,
1097 [','] = true, ['-'] = true, ['.'] = true, ['/'] = true,
1098 [':'] = true, [';'] = true, ['<'] = true, ['='] = true,
1099 ['>'] = true, ['?'] = true, ['@'] = true, ['['] = true,
1100 [']'] = true, ['_'] = true, ['|'] = true, [0x7F] = true,
1101 [0x8B] = true, [0x8C] = true, [0x9B] = true, [0xA0] = true,
1102 [0xA1] = true, [0xA2] = true, [0xA3] = true, [0xA4] = true,
1103 [0xA5] = true, [0xA6] = true, [0xA7] = true, [0xA8] = true,
1104 [0xAB] = true, [0xB0] = true, [0xB1] = true, [0xB2] = true,
1105 [0xB3] = true, [0xB4] = true, [0xB5] = true, [0xB6] = true,
1106 [0xB7] = true, [0xB8] = true, [0xBB] = true, [0xBC] = true,
1107 [0xBD] = true, [0xBE] = true, [0xBF] = true, [0xC1] = true,
1108 [0xC2] = true, [0xC3] = true, [0xC4] = true, [0xC5] = true,
1109 [0xC6] = true, [0xC7] = true, [0xC8] = true, [0xC9] = true,
1110 [0xCA] = true, [0xCB] = true, [0xCC] = true, [0xCD] = true,
1111 [0xCE] = true, [0xCF] = true, [0xE0] = true, [0xE1] = true,
1112 [0xE2] = true, [0xE3] = true, [0xE4] = true, [0xE5] = true,
1113 [0xE7] = true, [0xE8] = true, [0xE9] = true, [0xEA] = true,
1114 [0xEB] = true, [0xEC] = true, [0xED] = true, [0xEE] = true,
1115 [0xEF] = true, [0xF0] = true, [0xF1] = true, [0xF2] = true,
1116 [0xF3] = true, [0xF4] = true, [0xF5] = true, [0xF6] = true,
1117 [0xF7] = true, [0xF8] = true, [0xF9] = true, [0xFA] = true,
1118 [0xFB] = true, [0xFC] = true, [0xFD] = true, [0xFE] = true,
1119 ['A' ... 'Z'] = true, ['a' ... 'z'] = true,
1120 ['0' ... '9'] = true,
1121 };
1122
1123 return fr_der_decode_string(ctx, out, parent, in, allowed_chars, decode_ctx);
1124}
1125
1126/*
1127 * 128 characters exactly. Identical to the first 128 characters of the ASCII alphabet.
1128 */
1131{
1132#if 0
1133 static bool const allowed_chars[UINT8_MAX + 1] = {
1134 [0x00 ... 0x7f] = true,
1135 };
1136#endif
1137
1138 return fr_der_decode_string(ctx, out, parent, in, NULL, decode_ctx);
1139}
1140
1143{
1144 fr_pair_t *vp;
1145 fr_dbuff_t our_in = FR_DBUFF(in);
1146 char timestr[DER_UTC_TIME_LEN + 1] = {};
1147 char *p;
1148 struct tm tm = {};
1149
1151
1152 /*
1153 * ISO/IEC 8825-1:2021
1154 * 8.25 Encoding for values of the useful types
1155 * The following "useful types" shall be encoded as if they had been replaced by their definitions
1156 * given in clauses 46-48 of Rec. ITU-T X.680 | ISO/IEC 8824-1:
1157 * - generalized time;
1158 * - universal time;
1159 * - object descriptor.
1160 *
1161 * 8.26 Encoding for values of the TIME type and the useful time types
1162 * 8.26 Encoding for values of the TIME type and the useful time types 8.26.1 Encoding for values
1163 * of the TIME type NOTE - The defined time types are subtypes of the TIME type, with the same
1164 * tag, and have the same encoding as the TIME type. 8.26.1.1 The encoding of the TIME type shall
1165 * be primitive. 8.26.1.2 The contents octets shall be the UTF-8 encoding of the value notation,
1166 * after the removal of initial and final QUOTATION MARK (34) characters.
1167 *
1168 * 11.8 UTCTime
1169 * 11.8.1 The encoding shall terminate with "Z", as described in the ITU-T X.680 | ISO/IEC 8824-1
1170 * clause on UTCTime.
1171 * 11.8.2 The seconds element shall always be present.
1172 * 11.8.3 Midnight (GMT) shall be represented as "YYMMDD000000Z", where "YYMMDD" represents the
1173 * day following the midnight in question.
1174 */
1175
1176 /*
1177 * The format of a UTC time is "YYMMDDhhmmssZ"
1178 * Where:
1179 * 1. YY is the year
1180 * 2. MM is the month
1181 * 3. DD is the day
1182 * 4. hh is the hour
1183 * 5. mm is the minute
1184 * 6. ss is the second (not optional in DER)
1185 * 7. Z is the timezone (UTC)
1186 */
1187
1189
1190 if (memchr(timestr, '\0', DER_UTC_TIME_LEN) != NULL) {
1191 fr_strerror_const_push("UTC time contains null byte");
1192 return -1;
1193 }
1194
1195 timestr[DER_UTC_TIME_LEN] = '\0';
1196
1197 p = strptime(timestr, "%y%m%d%H%M%SZ", &tm);
1198
1199 if (unlikely(p == NULL) || *p != '\0') {
1200 fr_strerror_const_push("Invalid UTC time format");
1201 return -1;
1202 }
1203
1204 vp = fr_pair_afrom_da(ctx, parent);
1205 if (unlikely(!vp)) {
1206 fr_strerror_const_push("Out of memory");
1207 return -1;
1208 }
1209
1210 vp->vp_date = fr_unix_time_from_tm(&tm);
1211
1213
1214 return fr_dbuff_set(in, &our_in);
1215}
1216
1219{
1220 fr_pair_t *vp;
1221 fr_dbuff_t our_in = FR_DBUFF(in);
1223 char *p;
1224 unsigned long subseconds = 0;
1225 struct tm tm = {};
1226
1227 size_t len = fr_dbuff_remaining(&our_in);
1228
1230
1231 if (len < DER_GENERALIZED_TIME_LEN_MIN) {
1232 fr_strerror_const_push("Insufficient data for generalized time or incorrect length");
1233 return -1;
1234 }
1235
1236 /*
1237 * ISO/IEC 8825-1:2021
1238 * 8.25 Encoding for values of the useful types
1239 * The following "useful types" shall be encoded as if they had been replaced by their definitions
1240 * given in clauses 46-48 of Rec. ITU-T X.680 | ISO/IEC 8824-1:
1241 * - generalized time;
1242 * - universal time;
1243 * - object descriptor.
1244 *
1245 * 8.26 Encoding for values of the TIME type and the useful time types
1246 * 8.26 Encoding for values of the TIME type and the useful time types 8.26.1 Encoding for values
1247 * of the TIME type NOTE - The defined time types are subtypes of the TIME type, with the same
1248 * tag, and have the same encoding as the TIME type. 8.26.1.1 The encoding of the TIME type shall
1249 * be primitive. 8.26.1.2 The contents octets shall be the UTF-8 encoding of the value notation,
1250 * after the removal of initial and final QUOTATION MARK (34) characters.
1251 *
1252 * 11.7 GeneralizedTime
1253 * 11.7.1 The encoding shall terminate with a "Z", as described in the Rec. ITU-T X.680 | ISO/IEC
1254 * 8824-1 clause on GeneralizedTime.
1255 * 11.7.2 The seconds element shall always be present.
1256 * 11.7.3 The fractional-seconds elements, if present, shall omit all trailing zeros; if the
1257 * elements correspond to 0, they shall be wholly omitted, and the decimal point element
1258 * also shall be omitted.
1259 */
1260
1261 /*
1262 * The format of a generalized time is "YYYYMMDDHHMMSS[.fff]Z"
1263 * Where:
1264 * 1. YYYY is the year
1265 * 2. MM is the month
1266 * 3. DD is the day
1267 * 4. HH is the hour
1268 * 5. MM is the minute
1269 * 6. SS is the second
1270 * 7. fff is the fraction of a second (optional)
1271 * 8. Z is the timezone (UTC)
1272 */
1273
1275
1276 if (memchr(timestr, '\0', DER_GENERALIZED_TIME_LEN_MIN) != NULL) {
1277 fr_strerror_const_push("Generalized time contains null byte");
1278 return -1;
1279 }
1280
1282 fr_strerror_const_push("Incorrect format for generalized time. Missing timezone");
1283 return -1;
1284 }
1285
1286 /*
1287 * Check if the fractional seconds are present
1288 */
1289 if (timestr[DER_GENERALIZED_TIME_LEN_MIN - 1] == '.') {
1290 /*
1291 * We only support subseconds up to 4 decimal places
1292 */
1293 char subsecstring[DER_GENERALIZED_TIME_PRECISION_MAX + 1];
1294
1296
1298 precision = fr_dbuff_remaining(&our_in) - 1;
1299 }
1300
1301 if (unlikely(precision == 0)) {
1302 fr_strerror_const_push("Insufficient data for subseconds");
1303 return -1;
1304 }
1305
1306 FR_DBUFF_OUT_MEMCPY_RETURN((uint8_t *)subsecstring, &our_in, precision);
1307
1308 if (memchr(subsecstring, '\0', precision) != NULL) {
1309 fr_strerror_const_push("Generalized time contains null byte in subseconds");
1310 return -1;
1311 }
1312
1313 subsecstring[DER_GENERALIZED_TIME_PRECISION_MAX] = '\0';
1314
1315 /*
1316 * Convert the subseconds to an unsigned long
1317 */
1318 subseconds = strtoul(subsecstring, NULL, 10);
1319
1320 /*
1321 * Scale to nanoseconds
1322 */
1323 subseconds *= 1000000;
1324 }
1325
1326 /*
1327 * Make sure the timezone is UTC (Z)
1328 */
1330
1332
1333 p = strptime(timestr, "%Y%m%d%H%M%SZ", &tm);
1334
1335 if (unlikely(p == NULL)) {
1336 fr_strerror_const_push("Invalid generalized time format (strptime)");
1337 return -1;
1338 }
1339
1340 vp = fr_pair_afrom_da(ctx, parent);
1341 if (unlikely(!vp)) {
1342 fr_strerror_const_push("Out of memory");
1343 return -1;
1344 }
1345
1346 vp->vp_date = fr_unix_time_add(fr_unix_time_from_tm(&tm), fr_time_delta_wrap(subseconds));
1347
1349
1350 /*
1351 * Move to the end of the buffer
1352 * This is necessary because the fractional seconds are being ignored
1353 */
1354 fr_dbuff_advance(&our_in, fr_dbuff_remaining(&our_in));
1355
1356 return fr_dbuff_set(in, &our_in);
1357}
1358
1361{
1362 static bool const allowed_chars[UINT8_MAX + 1] = {
1363 [' '] = true, ['!'] = true, ['"'] = true, ['#'] = true,
1364 ['$'] = true, ['%'] = true, ['&'] = true, ['\''] = true,
1365 ['('] = true, [')'] = true, ['*'] = true, ['+'] = true,
1366 [','] = true, ['-'] = true, ['.'] = true, ['/'] = true,
1367 [':'] = true, [';'] = true, ['<'] = true, ['='] = true,
1368 ['>'] = true, ['?'] = true, ['@'] = true, ['['] = true,
1369 ['\\'] = true, [']'] = true, ['^'] = true, ['_'] = true,
1370 ['`'] = true, ['{'] = true, ['|'] = true, ['}'] = true,
1371 ['A' ... 'Z'] = true, ['a' ... 'z'] = true,
1372 ['0' ... '9'] = true,
1373 };
1374
1375 return fr_der_decode_string(ctx, out, parent, in, allowed_chars, decode_ctx);
1376}
1377
1378/*
1379 * We have per-type function names to make it clear that different types have different decoders.
1380 * However, the methods to decode them are the same. So rather than having trampoline functions, we just
1381 * use defines.
1382 */
1383#define fr_der_decode_enumerated fr_der_decode_integer
1384
1387{
1388 return fr_der_decode_string(ctx, out, parent, in, NULL, decode_ctx);
1389}
1390
1393{
1394 return fr_der_decode_string(ctx, out, parent, in, NULL, decode_ctx);
1395}
1396
1399{
1400 uint8_t byte;
1401 fr_pair_t *vp;
1402 fr_dbuff_t our_in = FR_DBUFF(in);
1403
1404 /*
1405 * RFC3779 Section 2.1.1.
1406 *
1407 * An IP address or prefix is encoded in the IP address delegation
1408 * extension as a DER-encoded ASN.1 BIT STRING containing the constant
1409 * most-significant bits. Recall [X.690] that the DER encoding of a BIT
1410 * STRING consists of the BIT STRING type (0x03), followed by (an
1411 * encoding of) the number of value octets, followed by the value. The
1412 * value consists of an "initial octet" that specifies the number of
1413 * unused bits in the last value octet, followed by the "subsequent
1414 * octets" that contain the octets of the bit string. (For IP
1415 * addresses, the encoding of the length will be just the length.)
1416 */
1417
1418 if (fr_dbuff_remaining(&our_in) != 1 + sizeof(vp->vp_ipv4addr)) {
1419 fr_strerror_printf_push("Invalid ipv4addr size. Expected %zu, got %zu",
1420 1 + sizeof(vp->vp_ipv4addr), fr_dbuff_remaining(&our_in));
1421 return -1;
1422 }
1423
1424 FR_DBUFF_OUT_RETURN(&byte, &our_in);
1425 if (byte != 0) {
1426 fr_strerror_printf_push("Invalid ipv4addr prefix is non-zero (%02x)", byte);
1427 return -1;
1428 }
1429
1430 vp = fr_pair_afrom_da(ctx, parent);
1431 if (unlikely(!vp)) {
1432 fr_strerror_const_push("Out of memory");
1433 return -1;
1434 }
1435
1436 vp->vp_ip.af = AF_INET;
1437 vp->vp_ip.prefix = 32;
1438 FR_DBUFF_OUT_MEMCPY_RETURN((uint8_t *) &vp->vp_ipv4addr, &our_in, sizeof(vp->vp_ipv4addr));
1439
1441
1442 return fr_dbuff_set(in, &our_in);
1443}
1444
1447{
1448 uint8_t byte;
1449 fr_pair_t *vp;
1450 fr_dbuff_t our_in = FR_DBUFF(in);
1451 size_t len = fr_dbuff_remaining(&our_in);
1452
1453 /*
1454 * RFC3779 Section 2.1.1.
1455 *
1456 * An IP address or prefix is encoded in the IP address delegation
1457 * extension as a DER-encoded ASN.1 BIT STRING containing the constant
1458 * most-significant bits. Recall [X.690] that the DER encoding of a BIT
1459 * STRING consists of the BIT STRING type (0x03), followed by (an
1460 * encoding of) the number of value octets, followed by the value. The
1461 * value consists of an "initial octet" that specifies the number of
1462 * unused bits in the last value octet, followed by the "subsequent
1463 * octets" that contain the octets of the bit string. (For IP
1464 * addresses, the encoding of the length will be just the length.)
1465 */
1466
1467 if (!len || (len > 1 + sizeof(vp->vp_ipv4addr))) {
1468 fr_strerror_printf_push("Invalid ipv4prefix size. Expected 1..%zu, got %zu",
1469 1 + sizeof(vp->vp_ipv4addr), len);
1470 return -1;
1471 }
1472 len--;
1473
1474 FR_DBUFF_OUT_RETURN(&byte, &our_in);
1475 if (byte > 7) {
1476 fr_strerror_printf_push("Invalid ipv4prefix is too large (%02x)", byte);
1477 return -1;
1478 }
1479
1480 vp = fr_pair_afrom_da(ctx, parent);
1481 if (unlikely(!vp)) {
1482 fr_strerror_const_push("Out of memory");
1483 return -1;
1484 }
1485
1486 vp->vp_ip.af = AF_INET;
1487 vp->vp_ip.prefix = len * 8 - byte;
1488
1489 if (len) FR_DBUFF_OUT_MEMCPY_RETURN((uint8_t *) &vp->vp_ipv4addr, &our_in, len);
1490
1492
1493 return fr_dbuff_set(in, &our_in);
1494}
1495
1498{
1499 uint8_t byte;
1500 fr_pair_t *vp;
1501 fr_dbuff_t our_in = FR_DBUFF(in);
1502
1503 /*
1504 * RFC3779 Section 2.1.1.
1505 *
1506 * An IP address or prefix is encoded in the IP address delegation
1507 * extension as a DER-encoded ASN.1 BIT STRING containing the constant
1508 * most-significant bits. Recall [X.690] that the DER encoding of a BIT
1509 * STRING consists of the BIT STRING type (0x03), followed by (an
1510 * encoding of) the number of value octets, followed by the value. The
1511 * value consists of an "initial octet" that specifies the number of
1512 * unused bits in the last value octet, followed by the "subsequent
1513 * octets" that contain the octets of the bit string. (For IP
1514 * addresses, the encoding of the length will be just the length.)
1515 */
1516
1517 if (fr_dbuff_remaining(&our_in) != 1 + sizeof(vp->vp_ipv6addr)) {
1518 fr_strerror_printf_push("Invalid ipv6addr size. Expected %zu, got %zu",
1519 1 + sizeof(vp->vp_ipv6addr), fr_dbuff_remaining(&our_in));
1520 return -1;
1521 }
1522
1523 FR_DBUFF_OUT_RETURN(&byte, &our_in);
1524 if (byte != 0) {
1525 fr_strerror_printf_push("Invalid ipv6addr prefix is non-zero (%02x)", byte);
1526 return -1;
1527 }
1528
1529 vp = fr_pair_afrom_da(ctx, parent);
1530 if (unlikely(!vp)) {
1531 fr_strerror_const_push("Out of memory");
1532 return -1;
1533 }
1534
1535 vp->vp_ip.af = AF_INET6;
1536 vp->vp_ip.prefix = 128;
1537 FR_DBUFF_OUT_MEMCPY_RETURN((uint8_t *) &vp->vp_ipv6addr, &our_in, sizeof(vp->vp_ipv6addr));
1538
1540
1541 return fr_dbuff_set(in, &our_in);
1542}
1543
1546{
1547 uint8_t byte;
1548 fr_pair_t *vp;
1549 fr_dbuff_t our_in = FR_DBUFF(in);
1550 size_t len = fr_dbuff_remaining(&our_in);
1551
1552 /*
1553 * RFC3779 Section 2.1.1.
1554 *
1555 * An IP address or prefix is encoded in the IP address delegation
1556 * extension as a DER-encoded ASN.1 BIT STRING containing the constant
1557 * most-significant bits. Recall [X.690] that the DER encoding of a BIT
1558 * STRING consists of the BIT STRING type (0x03), followed by (an
1559 * encoding of) the number of value octets, followed by the value. The
1560 * value consists of an "initial octet" that specifies the number of
1561 * unused bits in the last value octet, followed by the "subsequent
1562 * octets" that contain the octets of the bit string. (For IP
1563 * addresses, the encoding of the length will be just the length.)
1564 */
1565
1566 if (!len || (len > 1 + sizeof(vp->vp_ipv6addr))) {
1567 fr_strerror_printf_push("Invalid ipv6prefix size. Expected 1..%zu, got %zu",
1568 1 + sizeof(vp->vp_ipv6addr), len);
1569 return -1;
1570 }
1571 len--;
1572
1573 FR_DBUFF_OUT_RETURN(&byte, &our_in);
1574 if (byte > 7) {
1575 fr_strerror_printf_push("Invalid ipv6prefix is too large (%02x)", byte);
1576 return -1;
1577 }
1578
1579 vp = fr_pair_afrom_da(ctx, parent);
1580 if (unlikely(!vp)) {
1581 fr_strerror_const_push("Out of memory");
1582 return -1;
1583 }
1584
1585 vp->vp_ip.af = AF_INET6;
1586 vp->vp_ip.prefix = len * 8 - byte;
1587
1588 if (len) FR_DBUFF_OUT_MEMCPY_RETURN((uint8_t *) &vp->vp_ipv6addr, &our_in, len);
1589
1591
1592 return fr_dbuff_set(in, &our_in);
1593}
1594
1597{
1598 fr_pair_t *vp;
1599 fr_dbuff_t our_in = FR_DBUFF(in);
1600 size_t len = fr_dbuff_remaining(&our_in);
1601
1602 /*
1603 * RFC5280 Section 4.2.1.6
1604 *
1605 * When the subjectAltName extension contains an iPAddress, the address
1606 * MUST be stored in the octet string in "network byte order", as
1607 * specified in [RFC791]. The least significant bit (LSB) of each octet
1608 * is the LSB of the corresponding byte in the network address. For IP
1609 * version 4, as specified in [RFC791], the octet string MUST contain
1610 * exactly four octets. For IP version 6, as specified in
1611 * [RFC2460], the octet string MUST contain exactly sixteen octets.
1612 */
1613 if ((len != 4) && (len != 16)) {
1614 fr_strerror_printf_push("Invalid combo_ip_addr size. Expected 4 or 16, got %zu",
1615 len);
1616 return -1;
1617 }
1618
1619 vp = fr_pair_afrom_da(ctx, parent);
1620 if (unlikely(!vp)) {
1621 fr_strerror_const_push("Out of memory");
1622 return -1;
1623 }
1624
1625 if (len == 4) {
1626 vp->vp_ip.af = AF_INET;
1627 vp->vp_ip.prefix = 32;
1628 FR_DBUFF_OUT_MEMCPY_RETURN((uint8_t *) &vp->vp_ipv4addr, &our_in, sizeof(vp->vp_ipv4addr));
1629
1630 } else {
1631 vp->vp_ip.af = AF_INET6;
1632 vp->vp_ip.prefix = 128;
1633 FR_DBUFF_OUT_MEMCPY_RETURN((uint8_t *) &vp->vp_ipv6addr, &our_in, sizeof(vp->vp_ipv6addr));
1634 }
1635
1637
1638 return fr_dbuff_set(in, &our_in);
1639}
1640
1643{
1644 ssize_t slen;
1645 int i;
1646 fr_dict_attr_t const *da;
1647 fr_pair_t *vp;
1648
1650 .depth = 0,
1651 };
1652
1653 fr_assert(parent->type == FR_TYPE_ATTR);
1654
1655 /*
1656 * We don't use an intermediate dbuff here. We're not
1657 * doing anything with the dbuff, so an extra buffer
1658 * isn't necessary.
1659 */
1661 if (unlikely(slen <= 0)) return -1; /* OIDs of zero length are invalid */
1662
1663 vp = fr_pair_afrom_da(ctx, parent);
1664 if (unlikely(!vp)) {
1665 oom:
1666 fr_strerror_const_push("Out of memory");
1667 return -1;
1668 }
1669
1670 da = attr_oid_tree;
1671 for (i = 0; i < stack.depth; i++) {
1672 fr_dict_attr_t const *next;
1673
1674 next = fr_dict_attr_child_by_num(da, stack.oid[i]);
1675 if (!next) break;
1676 da = next;
1677 }
1678
1679 for (/* left over i */; i < stack.depth; i++) {
1681
1682 type = (i < (stack.depth - 1)) ? FR_TYPE_TLV : FR_TYPE_BOOL;
1683
1685 if (!da) {
1686 talloc_free(vp);
1687 goto oom;
1688 }
1689 }
1690
1691 vp->vp_attr = da;
1692 vp->data.enumv = attr_oid_tree;
1694 return slen;
1695}
1696
1697/** Decode an OID value pair
1698 *
1699 * @param[in] ctx Talloc context
1700 * @param[out] out Output list
1701 * @param[in] parent Parent attribute
1702 * @param[in] in Input buffer
1703 * @param[in] decode_ctx Decode context
1704 *
1705 * @return 0 on success, -1 on failure
1706 */
1708 fr_dbuff_t *in, fr_der_decode_ctx_t *decode_ctx)
1709{
1710 fr_dbuff_t our_in = FR_DBUFF(in);
1711 fr_dbuff_t oid_in;
1713 fr_pair_t *vp;
1714
1715 uint8_t tag;
1716 size_t oid_len;
1717 ssize_t slen;
1718
1719 FR_PROTO_TRACE("Decoding OID value pair");
1720
1722
1723 /*
1724 * A very common pattern in DER encoding is to have a sequence of set containing two things: an OID and a
1725 * value, where the OID is used to determine how to decode the value.
1726 * We will be decoding the OID first and then try to find the attribute associated with that OID to then
1727 * decode the value. If no attribute is found, one will be created and the value will be stored as raw
1728 * octets in the attribute.
1729 */
1730
1731 if (unlikely((slen = fr_der_decode_hdr(parent, &our_in, &tag, &oid_len, FR_DER_TAG_OID)) <= 0)) {
1732 error:
1733 fr_strerror_printf_push("Failed decoding %s OID header", parent->name);
1734 return slen;
1735 }
1736
1737 FR_PROTO_TRACE("Attribute %s, tag %u", parent->name, tag);
1738
1739 vp = fr_pair_afrom_da(ctx, parent);
1740 if (unlikely(vp == NULL)) {
1741 fr_strerror_const_push("Out of memory");
1742 return -1;
1743 }
1744
1745 uctx.ctx = vp;
1747 uctx.parent_list = &vp->vp_group;
1748
1749 fr_assert(uctx.parent_da != NULL);
1750
1751 /*
1752 * Limit the OID decoding to the length as given by the OID header.
1753 */
1754 oid_in = FR_DBUFF(&our_in);
1755 fr_dbuff_set_end(&oid_in, fr_dbuff_current(&oid_in) + oid_len);
1756
1757 slen = fr_der_decode_oid(&oid_in, fr_der_decode_oid_to_da, &uctx);
1758 if (unlikely(slen <= 0)) goto error;
1759
1760 /*
1761 * Skip the OID data.
1762 */
1763 FR_DBUFF_ADVANCE_RETURN(&our_in, oid_len);
1764
1765 if (unlikely(uctx.parent_da->flags.is_unknown)) {
1766 /*
1767 * This pair is not in the dictionary.
1768 * We will store the value as raw octets.
1769 */
1770 if (unlikely((slen = fr_der_decode_octetstring(uctx.ctx, uctx.parent_list, uctx.parent_da, &our_in,
1771 decode_ctx)) < 0)) {
1772 fr_strerror_printf_push("Failed decoding %s OID value", parent->name);
1773 return -1;
1774 }
1775 } else if (unlikely((slen = fr_der_decode_pair_dbuff(uctx.ctx, uctx.parent_list, uctx.parent_da, &our_in,
1776 decode_ctx)) < 0)) {
1777 fr_strerror_printf_push("Failed decoding %s OID value", parent->name);
1778 return -1;
1779 }
1780
1782
1783 return fr_dbuff_set(in, &our_in);
1784}
1785
1788 [FR_DER_TAG_INTEGER] = { .constructed = FR_DER_TAG_PRIMITIVE, .decode = fr_der_decode_integer },
1789 [FR_DER_TAG_OID] = { .constructed = FR_DER_TAG_PRIMITIVE, .decode = fr_der_decode_oid_wrapper },
1790 [FR_DER_TAG_BITSTRING] = { .constructed = FR_DER_TAG_PRIMITIVE, .decode = fr_der_decode_bitstring },
1792 [FR_DER_TAG_NULL] = { .constructed = FR_DER_TAG_PRIMITIVE, .decode = fr_der_decode_null },
1795 [FR_DER_TAG_SEQUENCE] = { .constructed = FR_DER_TAG_CONSTRUCTED, .decode = fr_der_decode_sequence },
1796 [FR_DER_TAG_SET] = { .constructed = FR_DER_TAG_CONSTRUCTED, .decode = fr_der_decode_set },
1801 [FR_DER_TAG_UTC_TIME] = { .constructed = FR_DER_TAG_PRIMITIVE, .decode = fr_der_decode_utc_time },
1808};
1809
1818
1822
1823/** Decode the tag and length fields of a DER encoded structure
1824 *
1825 * @param[in] parent Parent attribute
1826 * @param[in] in Input buffer
1827 * @param[out] tag Tag value
1828 * @param[out] len Length of the value field
1829 * @param[in] expected the expected / required tag
1830 *
1831 * @return 0 on success, -1 on failure
1832 */
1834 fr_der_tag_t expected)
1835{
1836 fr_dbuff_t our_in = FR_DBUFF(in);
1837 uint8_t tag_byte;
1838 uint8_t len_byte;
1839 fr_der_tag_decode_t const *func;
1840 fr_der_tag_class_t tag_class;
1841 fr_der_tag_constructed_t constructed;
1842 fr_der_attr_flags_t const *flags;
1843
1844 if (fr_dbuff_out(&tag_byte, &our_in) < 0) {
1845 error:
1846 fr_strerror_const_push("Failed decoding DER header - insufficient data");
1847 return -1;
1848 }
1849
1850 /*
1851 * Decode the tag flags
1852 */
1853 tag_class = (tag_byte & DER_TAG_CLASS_MASK);
1854 constructed = IS_DER_TAG_CONSTRUCTED(tag_byte);
1855
1856 /*
1857 * Decode the tag
1858 */
1859 if (IS_DER_TAG_CONTINUATION(tag_byte)) {
1860 /*
1861 * We have a multi-byte tag
1862 *
1863 * Note: Multi-byte tags would mean having a tag number that is greater than 30 (0x1E) (since tag
1864 * 31 would indicate a multi-byte tag). For most use-cases, this should not be needed, since all
1865 * of the basic ASN.1 types have values under 30, and if a CHOICE type were to have over 30 options
1866 * (meaning a multi-byte tag would be needed), that would be a very complex CHOICE type that
1867 * should probably be simplified.
1868 */
1869 fr_strerror_const_push("Multi-byte tags are not supported");
1870 return -1;
1871 }
1872
1873 *tag = tag_byte & DER_TAG_CONTINUATION;
1874
1875 /*
1876 * Check if the tag is not universal
1877 */
1878 switch (tag_class) {
1880 if ((*tag == FR_DER_TAG_INVALID) || (*tag >= FR_DER_TAG_VALUE_MAX)) {
1881 fr_strerror_printf_push("Invalid tag %u", *tag);
1882 return -1;
1883 }
1884
1885 if ((expected != FR_DER_TAG_INVALID) && (*tag != expected)) {
1886 fr_strerror_printf_push("Invalid tag %s. Expected tag %s",
1887 fr_der_tag_to_str(*tag), fr_der_tag_to_str(expected));
1888 return -1;
1889 }
1890 break;
1891
1892 default:
1893 /*
1894 * The data type will need to be resolved using the dictionary and the tag value
1895 */
1896 if (!parent) {
1897 fr_strerror_const_push("No parent attribute to resolve tag to class");
1898 return -1;
1899 }
1900 flags = fr_der_attr_flags(parent);
1901
1902 if (tag_class != flags->class) {
1903 fr_strerror_printf_push("Invalid DER class %02x for attribute %s. Expected DER class %02x",
1904 tag_class, parent->name, flags->class);
1905 return -1;
1906 }
1907
1908 /*
1909 * Doesn't match, check if it's optional.
1910 */
1911 if (flags->is_option) {
1912 if (*tag != flags->option) {
1913 if (flags->optional) return 0;
1914
1915 fr_strerror_printf_push("Invalid option %u for attribute %s. Expected option %u",
1916 *tag, parent->name, flags->option);
1917 return -1;
1918 }
1919
1920 *tag = flags->der_type;
1921
1922 } else {
1923 if (*tag != flags->der_type) {
1924 if (flags->optional) return 0;
1925
1926 fr_strerror_printf_push("Invalid tag %s for attribute %s. Expected tag %s",
1927 fr_der_tag_to_str(*tag), parent->name, fr_der_tag_to_str(flags->der_type));
1928 return -1;
1929 }
1930 }
1933 break;
1934 }
1935
1936 func = &tag_funcs[*tag];
1937 fr_assert(func != NULL);
1938
1939 if (unlikely(func->decode == NULL)) {
1940 fr_strerror_printf_push("No decode function for tag %u", *tag);
1941 return -1;
1942 }
1943
1944 if (IS_DER_TAG_CONSTRUCTED(func->constructed) != constructed) {
1945 fr_strerror_printf_push("Constructed flag mismatch for tag %u", *tag);
1946 return -1;
1947 }
1948
1949 if (fr_dbuff_out(&len_byte, &our_in) < 0) goto error;
1950
1951 /*
1952 * Check if the length is a multi-byte length field
1953 */
1954 if (IS_DER_LEN_MULTI_BYTE(len_byte)) {
1955 uint8_t len_len = len_byte & 0x7f;
1956 *len = 0;
1957
1958 /*
1959 * Length bits of zero is an indeterminate length field where
1960 * the length is encoded in the data instead.
1961 */
1962 if (len_len > 0) {
1963 if (unlikely(len_len > sizeof(*len))) {
1964 fr_strerror_printf_push("Length field too large (%" PRIu32 ")", len_len);
1965 return -1;
1966 }
1967
1968 while (len_len--) {
1969 if (fr_dbuff_out(&len_byte, &our_in) < 0) goto error;
1970 *len = (*len << 8) | len_byte;
1971 }
1972 } else if (!constructed) {
1973 fr_strerror_const_push("Primitive data with indefinite form length field is invalid");
1974 return -1;
1975 }
1976
1977 } else {
1978 *len = len_byte;
1979 }
1980
1981 /*
1982 * Ensure that there is the correct amount of data available to read.
1983 */
1984 if (*len && unlikely((fr_dbuff_extend_lowat(NULL, &our_in, *len) < *len))) {
1985 fr_strerror_printf_push("Insufficient data for length field (%zu)", *len);
1986 return -1;
1987 }
1988
1989 return fr_dbuff_set(in, &our_in);
1990}
1991
1992/** Decode a CHOICE type
1993 * This is where the actual decoding of the CHOICE type happens. The CHOICE type is a type that can have multiple
1994 * types, but only one of them can be present at a time. The type that is present is determined by the tag of the
1995 * data
1996 *
1997 * @param[in] ctx Talloc context
1998 * @param[in] out Output list
1999 * @param[in] parent Parent attribute
2000 * @param[in] in Input buffer
2001 * @param[in] decode_ctx Decode context
2002 */
2004 fr_dbuff_t *in, fr_der_decode_ctx_t *decode_ctx)
2005{
2006 fr_pair_t *vp;
2007 fr_dict_attr_t const *child = NULL;
2008 fr_dbuff_t our_in = FR_DBUFF(in);
2009 uint8_t tag;
2010 uint8_t tag_byte;
2011 uint8_t *current_marker = fr_dbuff_current(&our_in);
2012
2014
2015 FR_DBUFF_OUT_RETURN(&tag_byte, &our_in);
2016
2017 if (unlikely(IS_DER_TAG_CONTINUATION(tag_byte))) {
2018 fr_strerror_printf_push("Attribute %s is a choice, but received tag with continuation bit set",
2019 parent->name);
2020 return -1;
2021 }
2022
2023 tag = (tag_byte & DER_TAG_CONTINUATION);
2024
2025 child = fr_dict_attr_child_by_num(parent, tag);
2026 if (unlikely(!child)) {
2027 fr_strerror_printf_push("Attribute %s is a choice, but received unknown option %u",
2028 parent->name, tag);
2029 return -1;
2030 }
2031
2032 fr_dbuff_set(&our_in, current_marker);
2033
2034 vp = fr_pair_afrom_da(ctx, parent);
2035 if (unlikely(!vp)) {
2036 fr_strerror_const_push("Out of memory");
2037 return -1;
2038 }
2040
2041 if (unlikely(fr_der_decode_pair_dbuff(vp, &vp->vp_group, child, &our_in, decode_ctx) < 0)) {
2042 fr_strerror_printf_push("Failed decoding %s", vp->da->name);
2043 talloc_free(vp);
2044 return -1;
2045 }
2046
2048
2049 return fr_dbuff_set(in, &our_in);
2050}
2051
2052/** Decode an X509 Extentions Field
2053 *
2054 * @param[in] ctx Talloc context
2055 * @param[in] out Output list
2056 * @param[in] in Input buffer
2057 * @param[in] parent Parent attribute
2058 * @param[in] decode_ctx Decode context
2059 *
2060 * @return 0 on success, -1 on failure
2061 */
2063 fr_dict_attr_t const *parent, fr_der_decode_ctx_t *decode_ctx)
2064{
2065 fr_dbuff_t our_in = FR_DBUFF(in);
2066 fr_pair_t *vp, *vp2;
2067 fr_dict_attr_t const *ref;
2068
2069 uint8_t tag;
2070 uint64_t max;
2071 size_t len;
2072 ssize_t slen;
2073
2074 FR_PROTO_TRACE("Decoding extensions");
2075 FR_PROTO_TRACE("Attribute %s", parent->name);
2076 FR_PROTO_HEX_DUMP(fr_dbuff_current(in), fr_dbuff_remaining(in), "Top of extension decoding");
2077
2079
2080 /*
2081 * RFC 5280 Section 4.2
2082 * The extensions defined for X.509 v3 certificates provide methods for
2083 * associating additional attributes with users or public keys and for
2084 * managing relationships between CAs. The X.509 v3 certificate format
2085 * also allows communities to define private extensions to carry
2086 * information unique to those communities. Each extension in a
2087 * certificate is designated as either critical or non-critical.
2088 *
2089 * Each extension includes an OID and an ASN.1 structure. When an
2090 * extension appears in a certificate, the OID appears as the field
2091 * extnID and the corresponding ASN.1 DER encoded structure is the value
2092 * of the octet string extnValue.
2093 *
2094 * RFC 5280 Section A.1 Explicitly Tagged Module, 1988 Syntax
2095 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
2096 *
2097 * Extension ::= SEQUENCE {
2098 * extnID OBJECT IDENTIFIER,
2099 * critical BOOLEAN DEFAULT FALSE,
2100 * extnValue OCTET STRING
2101 * -- contains the DER encoding of an ASN.1 value
2102 * -- corresponding to the extension type identified
2103 * -- by extnID
2104 * }
2105 *
2106 * So the extensions are a SEQUENCE of SEQUENCEs containing an OID, a boolean and an OCTET STRING.
2107 * Note: If the boolean value is false, it should not be included in the encoding.
2108 */
2109
2110 /*
2111 * Get the overall length of the first inner sequence.
2112 * Ideally this should fill the entire outer sequence.
2113 */
2114 if (unlikely((slen = fr_der_decode_hdr(parent, &our_in, &tag, &len, FR_DER_TAG_SEQUENCE)) <= 0)) {
2115 fr_strerror_printf_push("Failed decoding %s sequence header", parent->name);
2116 return slen;
2117 }
2118
2119 if (len != fr_dbuff_remaining(&our_in)) {
2120 fr_strerror_printf_push("Inner %s x509extension sequence does not exactly fill the outer sequence",
2121 parent->name);
2122 return -1;
2123 }
2124
2125 /*
2126 * Normal extensions are decoded into the normal parent.
2127 */
2128 vp = fr_pair_afrom_da(ctx, parent);
2129 if (unlikely(!vp)) {
2130 oom:
2131 fr_strerror_const_push("Out of memory");
2132 return -1;
2133 }
2135
2136 /*
2137 * Critical extensions are decoded into the Critical parent.
2138 */
2139 ref = fr_dict_attr_ref(parent);
2140 fr_assert(ref != NULL);
2141 ref = fr_dict_attr_by_name(NULL, ref, "Critical");
2142 fr_assert(ref != NULL);
2143
2144 vp2 = fr_pair_afrom_da(vp, ref);
2145 if (unlikely(vp2 == NULL)) {
2146 talloc_free(vp);
2147 goto oom;
2148 }
2149 PAIR_ALLOCED(vp2);
2150
2151 max = fr_der_flag_max(parent); /* Maximum number of extensions which can be used here */
2152
2153 /*
2154 * Each extension is composed of a sequence containing the following objects:
2155 *
2156 * extnID OID - a printable string "1.2.3.4"
2157 * critical BOOLEAN OPTIONAL DEFAULT FALSE
2158 * extnValue OCTETSTRING - the DER encoding of the referenced ASN.1 extension
2159 */
2160 while (fr_dbuff_remaining(&our_in) > 0) {
2161 fr_dbuff_t seq_in = FR_DBUFF(&our_in);
2162 fr_dbuff_t oid_in;
2164 size_t seq_len, oid_len, ext_len;
2165
2166 FR_PROTO_HEX_DUMP(fr_dbuff_current(&our_in), fr_dbuff_remaining(&our_in), "inner x509 sequence");
2167
2168 if (!max) {
2169 fr_strerror_printf_push("Too many extensions - reached the limit of %" PRIu64, max);
2170 return -1;
2171 }
2172
2173 if (unlikely((slen = fr_der_decode_hdr(parent, &seq_in, &tag, &seq_len, FR_DER_TAG_SEQUENCE)) <= 0)) {
2174 fr_strerror_printf_push("Failed decoding %s extension inner sequence header",
2175 parent->name);
2176 error:
2177 talloc_free(vp);
2178 return slen;
2179 }
2180
2181 /*
2182 * Limit decoding for the inner sequence.
2183 */
2184 fr_dbuff_set_end(&seq_in, fr_dbuff_current(&seq_in) + seq_len);
2185
2186 /*
2187 * Start decoding the OID.
2188 */
2189 if (unlikely((slen = fr_der_decode_hdr(NULL, &seq_in, &tag, &oid_len, FR_DER_TAG_OID)) <= 0)) {
2190 fr_strerror_printf_push("Failed decoding %s OID header", parent->name);
2191 goto error;
2192 }
2193
2194 /*
2195 * Create a buffer where we can decode the OID. This lets us avoid any back and forth
2196 * with markers.
2197 *
2198 * The OID and extnValue will get decoded into a "critical" or "non-critical" vp,
2199 * depending on the value of the boolean Critical field. So we don't know where to
2200 * decode the OID until we see the Critical field. As a result, we have to save a
2201 * temporary OID buffer.
2202 */
2203 oid_in = FR_DBUFF(&seq_in);
2204 fr_dbuff_set_end(&oid_in, fr_dbuff_current(&oid_in) + oid_len);
2205
2206 FR_PROTO_TRACE("inner x509 OID length %zu", oid_len);
2207 FR_PROTO_HEX_DUMP(fr_dbuff_current(&oid_in), fr_dbuff_remaining(&oid_in), "inner x509 OID");
2208
2209 /*
2210 * Skip the OID data. We'll decode that later.
2211 */
2212 FR_DBUFF_ADVANCE_RETURN(&seq_in, oid_len);
2213
2214 /*
2215 * The next thing is either Critical, or is the extValue.
2216 */
2217 if (unlikely(fr_der_decode_hdr(NULL, &seq_in, &tag, &ext_len, FR_DER_TAG_INVALID) <= 0)) {
2218 fr_strerror_printf_push("Failed decoding %s extnValue", parent->name);
2219 slen = -1;
2220 goto error;
2221 }
2222
2223 uctx.ctx = vp;
2224 uctx.parent_da = vp->da;
2225 uctx.parent_list = &vp->vp_group;
2226
2227 /*
2228 * The optional boolean Critical field. This tells us where the extensions will be
2229 * decoded to.
2230 */
2231 if (tag == FR_DER_TAG_BOOLEAN) {
2232 uint8_t is_critical = false;
2233
2234 /*
2235 * This Extension has the Critical field.
2236 * If this value is true, we will be storing the pair in the critical list
2237 */
2238 if (unlikely(fr_dbuff_out(&is_critical, &seq_in) <= 0)) {
2239 fr_strerror_const_push("Insufficient data for isCritical field");
2240 slen = -1;
2241 goto error;
2242 }
2243
2244 /*
2245 * 0x00 is false. 0xff is true. But we don't care about invalid boolean values.
2246 */
2247 if (is_critical) {
2248 uctx.ctx = vp2;
2249 uctx.parent_da = vp2->da;
2250 uctx.parent_list = &vp2->vp_group;
2251 }
2252
2253 /*
2254 * The next header should be the extnValue
2255 */
2256 if (unlikely(fr_der_decode_hdr(NULL, &seq_in, &tag, &ext_len, FR_DER_TAG_OCTETSTRING) <= 0)) {
2257 fr_strerror_printf_push("Failed decoding %s extnValue", parent->name);
2258 slen = -1;
2259 goto error;
2260 }
2261 } else {
2262 /*
2263 * The extnValue is DER tag OCTETSTRING.
2264 */
2265 if (unlikely(tag != FR_DER_TAG_OCTETSTRING)) {
2266 fr_strerror_printf_push("Expected tag OCTETSTRING for the %s extnValue. Got tag %s",
2267 parent->name, fr_der_tag_to_str(tag));
2268 slen = -1;
2269 goto error;
2270 }
2271 }
2272
2273 /*
2274 * We leave the seq_in buffer at the extnValue field, which lets us decode it later.
2275 */
2277 "extnValue");
2278
2279 /*
2280 * Decode the OID, which gets us the DA which lets us know how to decode the extnValue.
2281 */
2282 if (unlikely((slen = fr_der_decode_oid(&oid_in, fr_der_decode_oid_to_da, &uctx)) <= 0)) {
2283 fr_strerror_const_push("Failed decoding OID in extension");
2284 goto error;
2285 }
2286
2287 /*
2288 * This has been updated with the OID reference.
2289 */
2290 fr_assert(uctx.parent_da != NULL);
2291
2292 FR_PROTO_HEX_DUMP(fr_dbuff_current(&seq_in), fr_dbuff_remaining(&seq_in), "inner x509 extnValue");
2293
2294 /*
2295 * The extension was not found in the dictionary. We will store the value as raw octets.
2296 */
2297 if (uctx.parent_da->flags.is_unknown) {
2298 slen = fr_der_decode_octetstring(uctx.ctx, uctx.parent_list, uctx.parent_da,
2299 &seq_in, decode_ctx);
2300 } else {
2301 slen = fr_der_decode_pair_dbuff(uctx.ctx, uctx.parent_list, uctx.parent_da, &seq_in,
2302 decode_ctx);
2303 }
2304 if (unlikely(slen < 0)) {
2305 fr_strerror_printf_push("Failed decoding %s extValue", parent->name);
2306 goto error;
2307 }
2308
2309 if (fr_dbuff_remaining(&seq_in)) {
2310 fr_strerror_printf_push("Failed to decode all of the data in the %s x509_extensions inner sequence",
2311 parent->name);
2312 return -1;
2313 }
2314
2316 "Remaining data after decoding all of the extension");
2317 max--;
2318
2319 (void) fr_dbuff_set(&our_in, &seq_in);
2320 }
2321
2322 if (fr_pair_list_num_elements(&vp2->children) > 0) {
2323 fr_pair_prepend(&vp->vp_group, vp2);
2324 } else {
2325 talloc_free(vp2);
2326 }
2327
2329
2330 return fr_dbuff_set(in, fr_dbuff_end(&our_in));
2331}
2332
2334 bool const allowed_chars[], UNUSED fr_der_decode_ctx_t *decode_ctx)
2335{
2336 fr_pair_t *vp;
2337 fr_dbuff_t our_in = FR_DBUFF(in);
2338 char *str = NULL;
2339
2340 size_t pos, len = fr_dbuff_remaining(&our_in);
2341
2343
2344 /*
2345 * ISO/IEC 8825-1:2021
2346 * 8.23 Encoding for values of the restricted character string types
2347 * 8.23.1 The data value consists of a string of characters from the character set specified in the ASN.1
2348 * type definition. 8.23.2 Each data value shall be encoded independently of other data values of
2349 * the same type.
2350 * 8.23.3 Each character string type shall be encoded as if it had been declared:
2351 * [UNIVERSAL x] IMPLICIT OCTET STRING
2352 * where x is the number of the universal class tag assigned to the character string type in
2353 * Rec. ITU-T X.680 | ISO/IEC 8824-1. The value of the octet string is specified in 8.23.4 and
2354 * 8.23.5.
2355 */
2356
2357 vp = fr_pair_afrom_da(ctx, parent);
2358 if (unlikely(!vp)) {
2359 oom:
2360 fr_strerror_const_push("Out of memory");
2361 return -1;
2362 }
2364
2365 if (unlikely(fr_pair_value_bstr_alloc(vp, &str, len, false) < 0)) {
2366 talloc_free(vp);
2367 goto oom;
2368 }
2369
2370 (void) fr_dbuff_out_memcpy((uint8_t *)str, &our_in, len); /* this can never fail */
2371
2372 if (allowed_chars && len) {
2373 fr_sbuff_t sbuff;
2374 sbuff = FR_SBUFF_OUT(str, len);
2375
2376 if ((pos = fr_sbuff_adv_past_allowed(&sbuff, SIZE_MAX, allowed_chars, NULL)) < len - 1) {
2377 invalid:
2378 fr_strerror_printf_push("Invalid character in a string (%" PRId32 ")", str[pos]);
2379 return -1;
2380 }
2381
2382 // Check the final character
2383 if (!allowed_chars[(uint8_t)str[pos]]) goto invalid;
2384 }
2385
2386 str[len] = '\0';
2387
2389
2390 return fr_dbuff_set(in, &our_in);
2391}
2392
2394 fr_dbuff_t *in, fr_der_decode_ctx_t *decode_ctx)
2395{
2396 fr_dbuff_t our_in = FR_DBUFF(in);
2397 fr_der_tag_decode_t const *func;
2398 ssize_t slen;
2399 uint8_t tag;
2400 size_t len;
2402
2403 /*
2404 * ISO/IEC 8825-1:2021
2405 * The structure of a DER encoding is as follows:
2406 *
2407 * +------------+--------+-------+
2408 * | IDENTIFIER | LENGTH | VALUE |
2409 * +------------+--------+-------+
2410 *
2411 * The IDENTIFIER is a tag that specifies the type of the value field and is encoded as follows:
2412 *
2413 * 8 7 6 5 4 3 2 1
2414 * +---+---+-----+---+---+---+---+---+
2415 * | Class | P/C | Tag Number |
2416 * +---+---+-----+---+---+---+---+---+
2417 * |
2418 * |- 0 = Primitive
2419 * |- 1 = Constructed
2420 *
2421 * The CLASS field specifies the encoding class of the tag and may be one of the following values:
2422 *
2423 * +------------------+-------+-------+
2424 * | Class | Bit 8 | Bit 7 |
2425 * +------------------+-------+-------+
2426 * | UNIVERSAL | 0 | 0 |
2427 * | APPLICATION | 0 | 1 |
2428 * | CONTEXT-SPECIFIC | 1 | 0 |
2429 * | PRIVATE | 1 | 1 |
2430 * +------------------+-------+-------+
2431 *
2432 * The P/C field specifies whether the value field is primitive or constructed.
2433 * The TAG NUMBER field specifies the tag number of the value field and is encoded as an unsigned binary
2434 * integer.
2435 *
2436 * The LENGTH field specifies the length of the VALUE field and is encoded as an unsigned binary integer
2437 * and may be encoded as a single byte or multiple bytes.
2438 *
2439 * The VALUE field contains LENGTH number of bytes and is encoded according to the tag.
2440 *
2441 */
2442
2443 /*
2444 * Ensure that we have at least 2 bytes for the header.
2445 */
2446 slen = fr_dbuff_extend_lowat(NULL, &our_in, 2);
2447 if (unlikely(slen < 0)) {
2448 fr_strerror_const("Failed trying to read more data");
2449 return -1;
2450 }
2451
2452 /*
2453 * One byte is not enough.
2454 */
2455 if (unlikely(slen == 1)) {
2456 fr_strerror_printf_push("Truncated header while trying to decode %s", parent->name);
2457 return -1;
2458 }
2459
2460 /*
2461 * No header, we may need to create a default value.
2462 */
2463 if (unlikely(slen == 0)) {
2464 fr_pair_t *vp;
2465
2466 if (likely(!flags->has_default_value)) return 0;
2467
2468 create_default:
2469 vp = fr_pair_afrom_da(ctx, parent);
2470 if (unlikely(!vp)) {
2471 fr_strerror_const_push("Out of memory");
2472 return -1;
2473 }
2475
2476 if (unlikely(fr_value_box_copy(vp, &vp->data, flags->default_value) < 0)) {
2477 talloc_free(vp);
2478 return -1;
2479 }
2480
2481 vp->data.enumv = vp->da;
2482
2484
2485 return 0;
2486 }
2487
2488 if (unlikely(flags->is_choice)) {
2489 slen = fr_der_decode_choice(ctx, out, parent, &our_in, decode_ctx);
2490
2491 if (unlikely(slen <= 0)) return slen;
2492
2493 return fr_dbuff_set(in, &our_in);
2494 }
2495
2496 slen = fr_der_decode_hdr(parent, &our_in, &tag, &len, FR_DER_TAG_INVALID);
2497 if ((slen == 0) && flags->optional) return 0;
2498 if (slen <= 0) {
2499 fr_strerror_printf_push("Failed decoding %s header", parent->name);
2500 return -1;
2501 }
2502
2503 FR_PROTO_TRACE("Attribute %s, tag %u", parent->name, tag);
2504
2505 /*
2506 * Limit the length of the data to be decoded.
2507 */
2508 fr_dbuff_set_end(&our_in, fr_dbuff_current(&our_in) + len);
2509
2510 /*
2511 * Unknown attributes have no defaults, and can be zero
2512 * length. We also ignore whatever tag and class is
2513 * being used.
2514 *
2515 * @todo - we need to store the tag and class somewhere,
2516 * so that re-encoding the "raw" data type will result in
2517 * the same data.
2518 */
2519 if (unlikely(parent->flags.is_unknown)) {
2521 goto decode_it;
2522 }
2523
2524 /*
2525 * No data? Try to set a default value, OR decode it as
2526 * NULL.
2527 */
2528 if (unlikely(fr_dbuff_remaining(&our_in) == 0)) {
2529 if (flags->has_default_value) goto create_default;
2530
2531 if (tag == FR_DER_TAG_NULL) {
2532 func = &tag_funcs[FR_DER_TAG_NULL];
2533 goto decode_it;
2534 }
2535
2536 }
2537
2538 /*
2539 * Hacks for serialNumber
2540 */
2541 if (unlikely((tag == FR_DER_TAG_INTEGER) && (parent->type == FR_TYPE_OCTETS))) {
2543 goto decode_it;
2544 }
2545
2546 /*
2547 * We didn't get the expected tag. If it's not allowed for this parent, OR it's not an
2548 * equivalent tag, then that is likely an error.
2549 *
2550 * The "compatible" check is to really to hack around Time and DirectoryString. It's technically
2551 * wrong, and should perhaps be fixed.
2552 *
2553 * @todo - parse 'string' and 'date', and then set flags->restrictions to allow any compatible
2554 * DER tags, as a hack. Doing that makes this a little more generic? Or, add support for data
2555 * types "Time" and "DirectoryString", and do the right thing. Or, define them as separate
2556 * attributes in dictionarty.common, and remove the "tags compatible" checks.
2557 */
2558 if (unlikely((tag != flags->der_type) &&
2559 (!fr_type_to_der_tag_valid(parent->type, tag) || !fr_der_tags_compatible(tag, flags->der_type)))) {
2560 /*
2561 * Optional or not, if we can create a default value, then do so.
2562 */
2563 if (flags->has_default_value) goto create_default;
2564
2565 /*
2566 * Optional means "decoded nothing". Otherwise it's a hard failure.
2567 */
2568 if (!flags->optional) {
2569 fr_strerror_printf_push("Failed decoding %s - got tag '%s', expected '%s'", parent->name,
2571 return -1;
2572 }
2573
2574 return 0;
2575 }
2576
2577 if (flags->is_extensions) {
2578 slen = fr_der_decode_x509_extensions(ctx, out, &our_in, parent, decode_ctx);
2579 if (slen <= 0) return slen;
2580
2581 return fr_dbuff_set(in, &our_in);
2582 }
2583
2584 func = &type_funcs[parent->type];
2585 if (!func->decode) func = &tag_funcs[tag];
2586 fr_assert(func != NULL);
2587 fr_assert(func->decode != NULL);
2588
2589 /*
2590 * Enforce limits on min/max.
2591 */
2592 switch (tag) {
2594 case FR_DER_TAG_SET:
2595 /*
2596 * min/max is the number of elements, NOT the number of bytes. The set / sequence
2597 * decoder has to validate its input.
2598 */
2599
2600 /*
2601 * If the sequence or set is an OID Value pair, then we decode it with the special OID
2602 * Value decoder.
2603 */
2604 if (flags->is_oid_and_value) func = &oid_and_value_func;
2605 break;
2606
2607 /*
2608 * min/max applies to the decoded values.
2609 */
2610 case FR_DER_TAG_INTEGER:
2612 break;
2613
2614 default:
2615 if (parent->flags.is_raw) break;
2616
2617 /*
2618 * min/max can be fixed width, but we only care for 'octets' and 'string'.
2619 *
2620 * @todo - when we support IP addresses (which DER usually encodes as strings), this
2621 * check will have to be updated.
2622 */
2623 if (parent->flags.is_known_width) {
2624 if (!fr_type_is_variable_size(parent->type)) break;
2625
2626 if (len != parent->flags.length) {
2627 fr_strerror_printf_push("Data length (%zu) is different from expected fixed size (%u)", len, parent->flags.length);
2628 return -1;
2629 }
2630
2631 break;
2632 }
2633
2634 if (flags->min && (len < flags->min)) {
2635 fr_strerror_printf_push("Data length (%zu) is smaller than expected minimum size (%u)", len, flags->min);
2636 return -1;
2637 }
2638
2639 fr_assert(flags->max <= DER_MAX_STR); /* 'max' is always set in the attr_valid() function */
2640
2641 if (unlikely(len > flags->max)) {
2642 fr_strerror_printf_push("Data length (%zu) exceeds max size (%" PRIu64 ")", len, flags->max);
2643 return -1;
2644 }
2645 break;
2646 }
2647
2648 /*
2649 * The decode function can return 0 if len==0. This is true for 'null' data types, and
2650 * for variable-sized types such as strings.
2651 */
2652decode_it:
2653 slen = func->decode(ctx, out, parent, &our_in, decode_ctx);
2654 if (unlikely(slen < 0)) return slen;
2655
2656 /*
2657 * There may be extra data, in which case we ignore it.
2658 *
2659 * @todo - if the data type is fixed size, then return an error.
2660 */
2661 if ((size_t) slen < len) {
2662 FR_PROTO_TRACE("Ignoring extra data");
2663 FR_PROTO_HEX_DUMP(fr_dbuff_current(&our_in), fr_dbuff_remaining(&our_in), " ");
2664
2665 fr_dbuff_advance(&our_in, len - (size_t) slen);
2666 }
2667
2668 return fr_dbuff_set(in, &our_in);
2669}
2670
2671static ssize_t fr_der_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len,
2672 void *proto_ctx)
2673{
2674 fr_dbuff_t our_in = FR_DBUFF_TMP(data, data_len);
2675
2677
2679 fr_strerror_printf_push("Invalid dictionary. DER decoding requires a specific dictionary.");
2680 return -1;
2681 }
2682
2683 return fr_der_decode_pair_dbuff(ctx, out, parent, &our_in, proto_ctx);
2684}
2685
2686/** Decode a DER structure using the specific dictionary
2687 *
2688 * @param[in] ctx to allocate new pairs in.
2689 * @param[in] out where new VPs will be added
2690 * @param[in] parent Parent attribute. This should be the root of the dictionary
2691 * we're using to decode DER data. This only specifies structures
2692 * like SEQUENCES. OID based pairs are resolved using the global
2693 * dictionary tree.
2694 * @param[in] data to decode.
2695 * @param[in] data_len Length of data.
2696 * @param[in] decode_ctx to pass to decode function.
2697 *
2698 */
2699static ssize_t decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data,
2700 size_t data_len, void *decode_ctx)
2701{
2703 fr_strerror_printf_push("Invalid dictionary. DER decoding requires a specific dictionary.");
2704 return -1;
2705 }
2706
2707 return fr_der_decode_pair_dbuff(ctx, out, parent, &FR_DBUFF_TMP(data, data_len), decode_ctx);
2708}
2709
2710/*
2711 * Test points
2712 */
2713static int decode_test_ctx(void **out, TALLOC_CTX *ctx, UNUSED fr_dict_t const *dict,
2714 UNUSED fr_dict_attr_t const *root_da)
2715{
2716 fr_der_decode_ctx_t *test_ctx;
2717
2718 test_ctx = talloc_zero(ctx, fr_der_decode_ctx_t);
2719 if (!test_ctx) return -1;
2720
2721 test_ctx->tmp_ctx = talloc_new(test_ctx);
2722
2723 *out = test_ctx;
2724
2725 return 0;
2726}
2727
2733
#define unlikely(_x)
Definition build.h:383
#define UNUSED
Definition build.h:317
#define NUM_ELEMENTS(_t)
Definition build.h:339
static size_t min(size_t x, size_t y)
Definition dbuff.c:66
#define fr_dbuff_advance(_dbuff_or_marker, _len)
Advance 'current' position in dbuff or marker by _len bytes.
Definition dbuff.h:1083
#define FR_DBUFF_ADVANCE_RETURN(_dbuff_or_marker, _len)
Advance the 'current' position in dbuff or marker by _len bytes returning if _len is out of range.
Definition dbuff.h:1099
struct fr_dbuff_marker_s fr_dbuff_marker_t
A position marker associated with a dbuff.
Definition dbuff.h:83
#define fr_dbuff_current(_dbuff_or_marker)
Return the 'current' position of a dbuff or marker.
Definition dbuff.h:921
#define fr_dbuff_set(_dst, _src)
Set the 'current' position in a dbuff or marker using another dbuff or marker, a char pointer,...
Definition dbuff.h:1014
#define fr_dbuff_out_memcpy(_out, _dbuff_or_marker, _outlen)
Copy exactly _outlen bytes from the dbuff.
Definition dbuff.h:1743
#define fr_dbuff_extend_lowat(_status, _dbuff_or_marker, _lowat)
Extend if we're below _lowat.
Definition dbuff.h:670
#define fr_dbuff_end(_dbuff_or_marker)
Return the current 'end' position of a dbuff or marker.
Definition dbuff.h:948
#define fr_dbuff_remaining(_dbuff_or_marker)
Return the number of bytes remaining between the dbuff or marker and the end of the buffer.
Definition dbuff.h:753
#define FR_DBUFF_OUT_MEMCPY_RETURN(_out, _dbuff_or_marker, _outlen)
Copy outlen bytes from the dbuff returning if there's insufficient data in the dbuff.
Definition dbuff.h:1763
static uint8_t * fr_dbuff_marker(fr_dbuff_marker_t *m, fr_dbuff_t *dbuff)
Initialises a new marker pointing to the 'current' position of the dbuff.
Definition dbuff.h:1203
#define FR_DBUFF(_dbuff_or_marker)
Create a new dbuff pointing to the same underlying buffer.
Definition dbuff.h:232
#define FR_DBUFF_OUT_RETURN(_out, _dbuff_or_marker)
Copy data from a dbuff or marker to a fixed sized C type returning if there is insufficient data.
Definition dbuff.h:1829
#define fr_dbuff_out(_out, _dbuff_or_marker)
Copy data from a dbuff or marker to a fixed sized C type.
Definition dbuff.h:1810
#define fr_dbuff_set_end(_dst, _end)
Set a new 'end' position in a dbuff or marker.
Definition dbuff.h:1061
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
Definition dbuff.h:524
fr_der_tag_t
Enumeration describing the data types in a DER encoded structure.
Definition der.h:34
@ FR_DER_TAG_IA5_STRING
String of IA5 (7bit) chars.
Definition der.h:48
@ FR_DER_TAG_SEQUENCE
A sequence of DER encoded data (a structure).
Definition der.h:44
@ FR_DER_TAG_SET
A set of DER encoded data (a structure).
Definition der.h:45
@ FR_DER_TAG_INTEGER
Arbitrary width signed integer.
Definition der.h:37
@ FR_DER_TAG_BOOLEAN
Boolean true/false.
Definition der.h:36
@ FR_DER_TAG_CHOICE
A choice of types. Techically not a DER tag, but used to represent a choice.
Definition der.h:56
@ FR_DER_TAG_UTF8_STRING
String of UTF8 chars.
Definition der.h:43
@ FR_DER_TAG_UTC_TIME
A time in UTC "YYMMDDhhmmssZ" format.
Definition der.h:49
@ FR_DER_TAG_GENERALIZED_TIME
A time in "YYYYMMDDHHMMSS[.fff]Z" format.
Definition der.h:50
@ FR_DER_TAG_INVALID
Invalid tag.
Definition der.h:35
@ FR_DER_TAG_NULL
An empty value.
Definition der.h:40
@ FR_DER_TAG_OCTETSTRING
String of octets (length field specifies bytes).
Definition der.h:39
@ FR_DER_TAG_VISIBLE_STRING
String of visible chars.
Definition der.h:51
@ FR_DER_TAG_BITSTRING
String of bits (length field specifies bits).
Definition der.h:38
@ FR_DER_TAG_T61_STRING
String of T61 (8bit) chars.
Definition der.h:47
@ FR_DER_TAG_ENUMERATED
An enumerated value.
Definition der.h:42
@ FR_DER_TAG_UNIVERSAL_STRING
String of universal chars.
Definition der.h:53
@ FR_DER_TAG_PRINTABLE_STRING
String of printable chars.
Definition der.h:46
@ FR_DER_TAG_GENERAL_STRING
String of general chars.
Definition der.h:52
@ FR_DER_TAG_OID
Reference to an OID based attribute.
Definition der.h:41
bool optional
optional, we MUST already have set 'option'
Definition der.h:106
bool is_extensions
a list of X.509 extensions
Definition der.h:110
fr_der_tag_t der_type
the DER type, which is different from the FreeRADIUS type
Definition der.h:95
bool is_option
has an option defined
Definition der.h:105
bool is_sequence_of
sequence_of has been defined
Definition der.h:107
TALLOC_CTX * tmp_ctx
ctx under which temporary data will be allocated
Definition der.h:117
#define DER_BOOLEAN_TRUE
DER encoded boolean true value.
Definition der.h:91
bool is_set_of
set_of has been defined
Definition der.h:108
#define DER_TAG_CONTINUATION
Mask to check if the tag is a continuation.
Definition der.h:86
#define DER_BOOLEAN_FALSE
DER encoded boolean false value.
Definition der.h:90
#define DER_TAG_CLASS_MASK
Mask to extract the class from the tag.
Definition der.h:82
#define fr_der_flag_max(_da)
Definition der.h:133
#define DER_UTC_TIME_LEN
Length of the UTC time string.
Definition der.h:78
fr_der_tag_constructed_t
Definition der.h:63
@ FR_DER_TAG_CONSTRUCTED
This is a sequence or set, it contains children.
Definition der.h:65
@ FR_DER_TAG_PRIMITIVE
This is a leaf value, it contains no children.
Definition der.h:64
#define DER_GENERALIZED_TIME_PRECISION_MAX
Maximum precision of the generalized time string.
Definition der.h:80
#define DER_MAX_STR
Definition der.h:76
uint8_t min
mininum count
Definition der.h:103
bool is_oid_and_value
is OID+value
Definition der.h:109
static fr_der_attr_flags_t const * fr_der_attr_flags(fr_dict_attr_t const *da)
Definition der.h:120
bool is_choice
DER name "choice".
Definition der.h:113
#define FR_DER_TAG_VALUE_MAX
tags >=max can't exist
Definition der.h:61
uint8_t option
an "attribute number" encoded in the tag field.
Definition der.h:104
bool has_default_value
a default value exists
Definition der.h:111
fr_der_tag_class_t class
tag Class
Definition der.h:94
#define DER_GENERALIZED_TIME_LEN_MIN
Minimum length of the generalized time string.
Definition der.h:79
uint64_t max
maximum count of items in a sequence, set, or string.
Definition der.h:101
fr_der_tag_class_t
Definition der.h:68
@ FR_DER_CLASS_UNIVERSAL
Definition der.h:69
fr_dict_attr_t const * fr_dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr_t const *parent, char const *attr))
Locate a fr_dict_attr_t by its name.
Definition dict_util.c:3532
#define FR_DICT_TLV_NEST_MAX
Maximum level of TLV nesting allowed.
Definition dict.h:507
static fr_dict_attr_t * fr_dict_attr_unknown_raw_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int attr)
Definition dict.h:613
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition dict_util.c:2669
@ FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC
Protocol specific extensions.
Definition dict.h:192
#define FR_DICT_MAX_TLV_STACK
Maximum TLV stack size.
Definition dict.h:519
fr_dict_attr_t const * fr_dict_attr_iterate_children(fr_dict_attr_t const *parent, fr_dict_attr_t const **prev)
Iterate over children of a DA.
Definition dict_util.c:5008
static fr_dict_attr_t * fr_dict_attr_unknown_typed_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int num, fr_type_t type)
Definition dict.h:598
fr_dict_attr_t const * fr_dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr)
Check if a child attribute exists in a parent using an attribute number.
Definition dict_util.c:3597
static fr_slen_t in
Definition dict.h:884
static void * fr_dict_attr_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
Definition dict_ext.h:121
static fr_dict_attr_t const * fr_dict_attr_ref(fr_dict_attr_t const *da)
Return the reference associated with a group type attribute.
Definition dict_ext.h:148
Test enumeration values.
Definition dict_test.h:92
HIDDEN fr_dict_t const * dict_der
Definition base.c:39
talloc_free(reap)
static char * stack[MAX_STACK]
Definition radmin.c:159
fr_type_t
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_TLV
Contains nested attributes.
@ FR_TYPE_IPV6_PREFIX
IPv6 Prefix.
@ FR_TYPE_MAX
Number of defined data types.
@ FR_TYPE_INT64
64 Bit signed integer.
@ FR_TYPE_IPV6_ADDR
128 Bit IPv6 Address.
@ FR_TYPE_IPV4_PREFIX
IPv4 Prefix.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
@ FR_TYPE_OCTETS
Raw octets.
long int ssize_t
unsigned char uint8_t
#define UINT8_MAX
static uint8_t depth(fr_minmax_heap_index_t i)
Definition minmax_heap.c:83
int fr_pair_value_memdup(fr_pair_t *vp, uint8_t const *src, size_t len, bool tainted)
Copy data into an "octets" data type.
Definition pair.c:2944
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
Definition pair.c:1348
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
Definition pair.c:289
int fr_pair_value_bstr_alloc(fr_pair_t *vp, char **out, size_t size, bool tainted)
Pre-allocate a memory buffer for a "string" type value pair.
Definition pair.c:2741
int fr_pair_value_mem_alloc(fr_pair_t *vp, uint8_t **out, size_t size, bool tainted)
Pre-allocate a memory buffer for a "octets" type value pair.
Definition pair.c:2893
int fr_pair_prepend(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the start of the list.
Definition pair.c:1317
static int decode_test_ctx(void **out, TALLOC_CTX *ctx, UNUSED fr_dict_t const *dict, UNUSED fr_dict_attr_t const *root_da)
Definition decode.c:102
HIDDEN fr_dict_attr_t const * attr_oid_tree
Definition base.c:40
bool fr_der_tags_compatible(fr_der_tag_t tag1, fr_der_tag_t tag2)
Definition base.c:103
bool fr_type_to_der_tag_valid(fr_type_t type, fr_der_tag_t tag)
Definition base.c:179
char const * fr_der_tag_to_str(fr_der_tag_t tag)
Definition base.c:80
ssize_t(* fr_der_decode_oid_t)(uint64_t subidentifier, void *uctx, bool is_last)
Definition decode.c:48
static ssize_t fr_der_decode_oid_to_da(uint64_t subidentifier, void *uctx, bool is_last)
Decode an OID to a dictionary attribute.
Definition decode.c:491
#define IS_DER_TAG_CONTINUATION(_tag)
Definition decode.c:44
static ssize_t fr_der_decode_oid_and_value(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, fr_der_decode_ctx_t *decode_ctx)
Decode an OID value pair.
Definition decode.c:1707
static ssize_t fr_der_decode_visible_string(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:1359
static ssize_t fr_der_decode_generalized_time(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:1217
TALLOC_CTX * ctx
Allocation context.
Definition decode.c:477
static ssize_t fr_der_decode_oid_wrapper(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:1641
static ssize_t fr_der_decode_t61_string(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:1088
fr_der_decode_t decode
Definition decode.c:60
unsigned int oid[FR_DICT_MAX_TLV_STACK]
Definition decode.c:449
static ssize_t fr_der_decode_universal_string(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:1391
static ssize_t fr_der_decode_hdr(fr_dict_attr_t const *parent, fr_dbuff_t *in, uint8_t *tag, size_t *len, fr_der_tag_t expected))
Decode the tag and length fields of a DER encoded structure.
Definition decode.c:1833
static ssize_t fr_der_decode_ipv4_addr(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:1397
#define IS_DER_LEN_MULTI_BYTE(_len)
Definition decode.c:46
static ssize_t fr_der_decode_general_string(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:1385
fr_test_point_proto_decode_t der_tp_decode_proto
Definition decode.c:2735
static const fr_der_tag_decode_t oid_and_value_func
Definition decode.c:1819
static ssize_t fr_der_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, void *proto_ctx)
Definition decode.c:2671
static ssize_t fr_der_decode_ipv6_addr(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:1496
static ssize_t fr_der_decode_integer(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:130
static const fr_der_tag_decode_t type_funcs[FR_TYPE_MAX]
Definition decode.c:1810
static ssize_t fr_der_decode_bitstring(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:220
static ssize_t fr_der_decode_choice(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, fr_der_decode_ctx_t *decode_ctx)
Decode a CHOICE type This is where the actual decoding of the CHOICE type happens.
Definition decode.c:2003
fr_der_tag_constructed_t constructed
Definition decode.c:59
static ssize_t fr_der_decode_octetstring(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:364
static ssize_t fr_der_decode_ia5_string(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:1129
ssize_t fr_der_decode_pair_dbuff(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:2393
static ssize_t fr_der_decode_null(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:419
#define fr_der_decode_enumerated
Definition decode.c:1383
fr_pair_list_t * parent_list
Parent pair list.
Definition decode.c:479
static ssize_t fr_der_decode_oid_to_stack(uint64_t subidentifier, void *uctx, UNUSED bool is_last)
Decode an OID to an exploded list.
Definition decode.c:461
static ssize_t fr_der_decode_x509_extensions(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dbuff_t *in, fr_dict_attr_t const *parent, fr_der_decode_ctx_t *decode_ctx)
Decode an X509 Extentions Field.
Definition decode.c:2062
static ssize_t fr_der_decode_utf8_string(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:714
static ssize_t fr_der_decode_printable_string(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:1074
static ssize_t fr_der_decode_oid(fr_dbuff_t *in, fr_der_decode_oid_t func, void *uctx)
Decode an OID from a DER encoded buffer using a callback.
Definition decode.c:567
static ssize_t fr_der_decode_utc_time(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:1141
static ssize_t fr_der_decode_ipv4_prefix(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:1445
#define IS_DER_TAG_CONSTRUCTED(_tag)
Definition decode.c:45
fr_dict_attr_t const * parent_da
Parent dictionary attribute.
Definition decode.c:478
ssize_t(* fr_der_decode_t)(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:55
static ssize_t fr_der_decode_string(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, bool const allowed_chars[], fr_der_decode_ctx_t *decode_ctx))
Function signature for DER decode functions.
static ssize_t fr_der_decode_set(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:887
static ssize_t fr_der_decode_ipv6_prefix(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:1544
static const fr_der_tag_decode_t tag_funcs[FR_DER_TAG_VALUE_MAX]
Definition decode.c:1786
static ssize_t fr_der_decode_boolean(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:80
fr_test_point_pair_decode_t der_tp_decode_pair
Definition decode.c:2729
static ssize_t fr_der_decode_combo_ip_addr(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:1595
static ssize_t fr_der_decode_sequence(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, fr_der_decode_ctx_t *decode_ctx)
Definition decode.c:724
static ssize_t decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *out, NDEBUG_UNUSED fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len, void *decode_ctx)
Definition decode.c:491
VQP attributes.
#define fr_assert(_expr)
Definition rad_assert.h:38
static char timestr[50]
Definition radsniff.c:55
static uint32_t mask
Definition rbmonkey.c:39
size_t fr_sbuff_adv_past_allowed(fr_sbuff_t *sbuff, size_t len, bool const allowed[static UINT8_MAX+1], fr_sbuff_term_t const *tt)
Wind position past characters in the allowed set.
Definition sbuff.c:1805
#define FR_SBUFF_OUT(_start, _len_or_end)
fr_aka_sim_id_type_t type
fr_pair_t * vp
ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len, void *decode_ctx, fr_pair_decode_value_t decode_value, fr_pair_decode_value_t decode_tlv)
Convert a STRUCT to one or more VPs.
Definition struct.c:32
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
Definition pair.h:69
fr_test_point_ctx_alloc_t test_ctx
Allocate a test ctx for the encoder.
Definition test_point.h:86
fr_test_point_ctx_alloc_t test_ctx
Allocate a test ctx for the encoder.
Definition test_point.h:68
Entry point for pair decoders.
Definition test_point.h:85
Entry point for protocol decoders.
Definition test_point.h:67
fr_unix_time_t fr_unix_time_from_tm(struct tm *tm)
Definition time.c:628
#define fr_time_delta_wrap(_time)
Definition time.h:152
#define fr_unix_time_add(_a, _b)
Add a time/time delta together.
Definition time.h:324
#define PAIR_ALLOCED(_x)
Definition pair.h:212
size_t fr_pair_list_num_elements(fr_pair_list_t const *list)
Get the length of a list of fr_pair_t.
static fr_slen_t parent
Definition pair.h:857
#define FR_PROTO_HEX_DUMP(_data, _data_len, _fmt,...)
Definition proto.h:42
#define FR_PROTO_TRACE(_fmt,...)
Definition proto.h:41
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition strerror.h:64
#define fr_strerror_printf_push(_fmt,...)
Add a message to an existing stack of messages at the tail.
Definition strerror.h:84
#define fr_strerror_const_push(_msg)
Definition strerror.h:227
#define fr_strerror_const(_msg)
Definition strerror.h:223
#define fr_type_is_group(_x)
Definition types.h:377
#define fr_type_is_octets(_x)
Definition types.h:350
#define fr_type_is_variable_size(_x)
Definition types.h:389
@ FR_TYPE_ATTR
A contains an attribute reference.
Definition types.h:84
#define fr_type_is_date(_x)
Definition types.h:370
#define fr_type_is_string(_x)
Definition types.h:349
#define fr_type_is_bool(_x)
Definition types.h:359
#define fr_type_is_tlv(_x)
Definition types.h:373
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
Definition types.h:455
#define fr_type_is_struct(_x)
Definition types.h:374
int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t *src)
Copy value data verbatim duplicating any buffers.
Definition value.c:4330
static fr_slen_t data
Definition value.h:1326
int nonnull(2, 5))
static size_t char ** out
Definition value.h:1023