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