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