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