30#include <freeradius-devel/io/test_point.h>
31#include <freeradius-devel/util/dbuff.h>
32#include <freeradius-devel/util/decode.h>
33#include <freeradius-devel/util/dict.h>
34#include <freeradius-devel/util/pair.h>
35#include <freeradius-devel/util/proto.h>
36#include <freeradius-devel/util/sbuff.h>
37#include <freeradius-devel/util/struct.h>
38#include <freeradius-devel/util/time.h>
39#include <freeradius-devel/util/dict_ext.h>
44#define IS_DER_TAG_CONTINUATION(_tag) (((_tag) & DER_TAG_CONTINUATION) == DER_TAG_CONTINUATION)
45#define IS_DER_TAG_CONSTRUCTED(_tag) (((_tag) & 0x20) == 0x20)
46#define IS_DER_LEN_MULTI_BYTE(_len) (((_len) & DER_LEN_MULTI_BYTE) == DER_LEN_MULTI_BYTE)
146 if (len >
sizeof(
value)) {
175 value = ~(uint64_t) 0xff;
191 if ((((
value & 0xff) == 0xff) && (
byte & 0x80)) || (((~
value & 0xff) == 0xff) && !(
byte & 0x80))) {
199 for (i = 2; i < len; i++) {
227 ssize_t data_len = 0, index = 0;
276 if ((len == 1) && unused_bits) {
307 data[0] = unused_bits;
310 for (; index < data_len; index++) {
335 if (
unlikely(slen < data_len - 1)) {
470 if (decode_ctx->
oid_buff[0] ==
'\0') {
480 fr_sbuff_marker(&marker, &sb);
482 decode_ctx->
marker = marker;
489 fr_sbuff_marker(&marker, &sb);
491 decode_ctx->
marker = marker;
512 decode_ctx->
ctx =
vp;
544 FR_PROTO_TRACE(
"decode context - Parent Name: %s Sub-Identifier %" PRIu64, parent_da->name, subidentifier);
592 decode_ctx->
ctx =
vp;
672 if ((
byte & 0x80) != 0) {
684 uint64_t first_component;
689 }
else if (oid < 80) {
702 FR_PROTO_TRACE(
"decode context - first OID: %" PRIu64, first_component);
703 if (
unlikely(func(first_component, uctx, (len == 0)) <= 0))
return -1;
707 if (
unlikely(func(oid, uctx, (len == 0)) <= 0))
return -1;
814 if (!child)
goto error;
821 child_flags->
option = current_tag;
825 }
else if (
unlikely(current_tag != flags->sequence_of)) {
827 goto unexpected_class;
901 size_t previous_len = 0;
971 uint8_t prev_byte = 0, curr_byte = 0;
980 if (prev_byte > curr_byte) {
986 if (prev_byte < curr_byte) {
994 "Set tags are not in ascending order. Previous item has more data");
1000 previous_tag = current_tag;
1003 previous_marker = current_value_marker;
1037 if (
unlikely(current_tag < previous_tag)) {
1043 previous_tag = current_tag;
1083 static bool const allowed_chars[
UINT8_MAX + 1] = {
1084 [
' '] =
true, [
'\''] =
true, [
'('] =
true, [
')'] =
true,
1085 [
'+'] =
true, [
','] =
true, [
'-'] =
true, [
'.'] =
true,
1086 [
'/'] =
true, [
':'] =
true, [
'='] =
true, [
'?'] =
true,
1087 [
'A' ...
'Z'] =
true, [
'a' ...
'z'] =
true,
1088 [
'0' ...
'9'] =
true,
1097 static bool const allowed_chars[
UINT8_MAX + 1] = {
1098 [0x08] =
true, [0x0A] =
true, [0x0C] =
true, [0x0D] =
true,
1099 [0x0E] =
true, [0x0F] =
true, [0x19] =
true, [0x1A] =
true,
1100 [0x1B] =
true, [0x1D] =
true, [
' '] =
true, [
'!'] =
true,
1101 [
'"'] =
true, [
'%'] =
true, [
'&'] =
true, [
'\''] =
true,
1102 [
'('] =
true, [
')'] =
true, [
'*'] =
true, [
'+'] =
true,
1103 [
','] =
true, [
'-'] =
true, [
'.'] =
true, [
'/'] =
true,
1104 [
':'] =
true, [
';'] =
true, [
'<'] =
true, [
'='] =
true,
1105 [
'>'] =
true, [
'?'] =
true, [
'@'] =
true, [
'['] =
true,
1106 [
']'] =
true, [
'_'] =
true, [
'|'] =
true, [0x7F] =
true,
1107 [0x8B] =
true, [0x8C] =
true, [0x9B] =
true, [0xA0] =
true,
1108 [0xA1] =
true, [0xA2] =
true, [0xA3] =
true, [0xA4] =
true,
1109 [0xA5] =
true, [0xA6] =
true, [0xA7] =
true, [0xA8] =
true,
1110 [0xAB] =
true, [0xB0] =
true, [0xB1] =
true, [0xB2] =
true,
1111 [0xB3] =
true, [0xB4] =
true, [0xB5] =
true, [0xB6] =
true,
1112 [0xB7] =
true, [0xB8] =
true, [0xBB] =
true, [0xBC] =
true,
1113 [0xBD] =
true, [0xBE] =
true, [0xBF] =
true, [0xC1] =
true,
1114 [0xC2] =
true, [0xC3] =
true, [0xC4] =
true, [0xC5] =
true,
1115 [0xC6] =
true, [0xC7] =
true, [0xC8] =
true, [0xC9] =
true,
1116 [0xCA] =
true, [0xCB] =
true, [0xCC] =
true, [0xCD] =
true,
1117 [0xCE] =
true, [0xCF] =
true, [0xE0] =
true, [0xE1] =
true,
1118 [0xE2] =
true, [0xE3] =
true, [0xE4] =
true, [0xE5] =
true,
1119 [0xE7] =
true, [0xE8] =
true, [0xE9] =
true, [0xEA] =
true,
1120 [0xEB] =
true, [0xEC] =
true, [0xED] =
true, [0xEE] =
true,
1121 [0xEF] =
true, [0xF0] =
true, [0xF1] =
true, [0xF2] =
true,
1122 [0xF3] =
true, [0xF4] =
true, [0xF5] =
true, [0xF6] =
true,
1123 [0xF7] =
true, [0xF8] =
true, [0xF9] =
true, [0xFA] =
true,
1124 [0xFB] =
true, [0xFC] =
true, [0xFD] =
true, [0xFE] =
true,
1125 [
'A' ...
'Z'] =
true, [
'a' ...
'z'] =
true,
1126 [
'0' ...
'9'] =
true,
1139 static bool const allowed_chars[
UINT8_MAX + 1] = {
1140 [0x00 ... 0x7f] =
true,
1203 p = strptime(
timestr,
"%y%m%d%H%M%SZ", &tm);
1205 if (
unlikely(p == NULL) || *p !=
'\0') {
1230 unsigned long subseconds = 0;
1314 if (memchr(subsecstring,
'\0', precision) != NULL) {
1324 subseconds = strtoul(subsecstring, NULL, 10);
1329 subseconds *= 1000000;
1339 p = strptime(
timestr,
"%Y%m%d%H%M%SZ", &tm);
1368 static bool const allowed_chars[
UINT8_MAX + 1] = {
1369 [
' '] =
true, [
'!'] =
true, [
'"'] =
true, [
'#'] =
true,
1370 [
'$'] =
true, [
'%'] =
true, [
'&'] =
true, [
'\''] =
true,
1371 [
'('] =
true, [
')'] =
true, [
'*'] =
true, [
'+'] =
true,
1372 [
','] =
true, [
'-'] =
true, [
'.'] =
true, [
'/'] =
true,
1373 [
':'] =
true, [
';'] =
true, [
'<'] =
true, [
'='] =
true,
1374 [
'>'] =
true, [
'?'] =
true, [
'@'] =
true, [
'['] =
true,
1375 [
'\\'] =
true, [
']'] =
true, [
'^'] =
true, [
'_'] =
true,
1376 [
'`'] =
true, [
'{'] =
true, [
'|'] =
true, [
'}'] =
true,
1377 [
'A' ...
'Z'] =
true, [
'a' ...
'z'] =
true,
1378 [
'0' ...
'9'] =
true,
1389#define fr_der_decode_enumerated fr_der_decode_integer
1442 vp->vp_ip.af = AF_INET;
1443 vp->vp_ip.prefix = 32;
1473 if (!len || (len > 1 +
sizeof(
vp->vp_ipv4addr))) {
1475 1 +
sizeof(
vp->vp_ipv4addr), len);
1492 vp->vp_ip.af = AF_INET;
1493 vp->vp_ip.prefix = len * 8 - byte;
1541 vp->vp_ip.af = AF_INET6;
1542 vp->vp_ip.prefix = 128;
1572 if (!len || (len > 1 +
sizeof(
vp->vp_ipv6addr))) {
1574 1 +
sizeof(
vp->vp_ipv6addr), len);
1591 vp->vp_ip.af = AF_INET6;
1592 vp->vp_ip.prefix = len * 8 - byte;
1619 if ((len != 4) && (len != 16)) {
1632 vp->vp_ip.af = AF_INET;
1633 vp->vp_ip.prefix = 32;
1637 vp->vp_ip.af = AF_INET6;
1638 vp->vp_ip.prefix = 128;
1665 if (
unlikely(slen <= 0))
return -1;
1731 if (
unlikely(slen <= 0))
goto error;
1744 decode_ctx)) < 0)) {
1749 decode_ctx)) < 0)) {
1851 switch (tag_class) {
1875 if (tag_class != flags->
class) {
1885 if (*tag != flags->
option) {
1928 uint8_t len_len = len_byte & 0x7f;
1936 if (
unlikely(len_len >
sizeof(*len))) {
1943 *len = (*len << 8) | len_byte;
1945 }
else if (!constructed) {
2134 size_t seq_len, oid_len, ext_len;
2269 &seq_in, decode_ctx);
2286 "Remaining data after decoding all of the extension");
2341 if (allowed_chars && len) {
2352 if (!allowed_chars[(
uint8_t)str[pos]])
goto invalid;
2459 if (
unlikely(slen <= 0))
return slen;
2465 if ((slen == 0) && flags->
optional)
return 0;
2547 if (slen <= 0)
return slen;
2583 if (
parent->flags.is_raw)
break;
2591 if (
parent->flags.is_known_width) {
2594 if (len !=
parent->flags.length) {
2602 if (flags->
min && (len < flags->
min)) {
2622 if (
unlikely(slen < 0))
return slen;
2629 if ((
size_t) slen < len) {
2665 size_t data_len,
void *decode_ctx)
2683 if (!test_ctx)
return -1;
2685 test_ctx->
tmp_ctx = talloc_new(test_ctx);
static size_t min(size_t x, size_t y)
#define fr_dbuff_advance(_dbuff_or_marker, _len)
Advance 'current' position in dbuff or marker by _len bytes.
#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.
struct fr_dbuff_marker_s fr_dbuff_marker_t
A position marker associated with a dbuff.
#define fr_dbuff_current(_dbuff_or_marker)
Return the 'current' position of a dbuff or marker.
#define fr_dbuff_set(_dst, _src)
Set the 'current' position in a dbuff or marker using another dbuff or marker, a char pointer,...
#define fr_dbuff_out_memcpy(_out, _dbuff_or_marker, _outlen)
Copy exactly _outlen bytes from the dbuff.
#define fr_dbuff_extend_lowat(_status, _dbuff_or_marker, _lowat)
Extend if we're below _lowat.
#define fr_dbuff_end(_dbuff_or_marker)
Return the current 'end' position of a dbuff or marker.
#define fr_dbuff_remaining(_dbuff_or_marker)
Return the number of bytes remaining between the dbuff or marker and the end of the buffer.
#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.
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.
#define FR_DBUFF(_dbuff_or_marker)
Create a new dbuff pointing to the same underlying buffer.
#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.
#define fr_dbuff_out(_out, _dbuff_or_marker)
Copy data from a dbuff or marker to a fixed sized C type.
#define fr_dbuff_set_end(_dst, _end)
Set a new 'end' position in a dbuff or marker.
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
fr_der_tag_t
Enumeration describing the data types in a DER encoded structure.
@ FR_DER_TAG_IA5_STRING
String of IA5 (7bit) chars.
@ FR_DER_TAG_SEQUENCE
A sequence of DER encoded data (a structure).
@ FR_DER_TAG_SET
A set of DER encoded data (a structure).
@ FR_DER_TAG_INTEGER
Arbitrary width signed integer.
@ FR_DER_TAG_BOOLEAN
Boolean true/false.
@ FR_DER_TAG_CHOICE
A choice of types. Techically not a DER tag, but used to represent a choice.
@ FR_DER_TAG_UTF8_STRING
String of UTF8 chars.
@ FR_DER_TAG_UTC_TIME
A time in UTC "YYMMDDhhmmssZ" format.
@ FR_DER_TAG_GENERALIZED_TIME
A time in "YYYYMMDDHHMMSS[.fff]Z" format.
@ FR_DER_TAG_INVALID
Invalid tag.
@ FR_DER_TAG_NULL
An empty value.
@ FR_DER_TAG_OCTETSTRING
String of octets (length field specifies bytes).
@ FR_DER_TAG_VISIBLE_STRING
String of visible chars.
@ FR_DER_TAG_BITSTRING
String of bits (length field specifies bits).
@ FR_DER_TAG_T61_STRING
String of T61 (8bit) chars.
@ FR_DER_TAG_ENUMERATED
An enumerated value.
@ FR_DER_TAG_UNIVERSAL_STRING
String of universal chars.
@ FR_DER_TAG_PRINTABLE_STRING
String of printable chars.
@ FR_DER_TAG_GENERAL_STRING
String of general chars.
@ FR_DER_TAG_OID
Reference to an OID based attribute.
bool optional
optional, we MUST already have set 'option'
bool is_extensions
a list of X.509 extensions
fr_der_tag_t der_type
the DER type, which is different from the FreeRADIUS type
bool is_option
has an option defined
bool is_sequence_of
sequence_of has been defined
TALLOC_CTX * tmp_ctx
ctx under which temporary data will be allocated
#define DER_BOOLEAN_TRUE
DER encoded boolean true value.
bool is_set_of
set_of has been defined
#define DER_TAG_CONTINUATION
Mask to check if the tag is a continuation.
#define DER_BOOLEAN_FALSE
DER encoded boolean false value.
#define DER_TAG_CLASS_MASK
Mask to extract the class from the tag.
#define fr_der_flag_max(_da)
#define DER_UTC_TIME_LEN
Length of the UTC time string.
@ FR_DER_TAG_CONSTRUCTED
This is a sequence or set, it contains children.
@ FR_DER_TAG_PRIMITIVE
This is a leaf value, it contains no children.
#define DER_GENERALIZED_TIME_PRECISION_MAX
Maximum precision of the generalized time string.
bool is_oid_and_value
is OID+value
static fr_der_attr_flags_t const * fr_der_attr_flags(fr_dict_attr_t const *da)
bool is_choice
DER name "choice".
#define FR_DER_TAG_VALUE_MAX
tags >=max can't exist
uint8_t option
an "attribute number" encoded in the tag field.
bool has_default_value
a default value exists
fr_der_tag_class_t class
tag Class
#define DER_GENERALIZED_TIME_LEN_MIN
Minimum length of the generalized time string.
uint64_t max
maximum count of items in a sequence, set, or string.
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.
static fr_dict_attr_t * fr_dict_attr_unknown_raw_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int attr)
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
@ FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC
Protocol specific extensions.
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.
static fr_dict_attr_t * fr_dict_attr_unknown_typed_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int num, fr_type_t type)
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.
static void * fr_dict_attr_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
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.
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_TLV
Contains nested attributes.
@ FR_TYPE_IPV6_PREFIX
IPv6 Prefix.
@ FR_TYPE_MAX
Number of defined data types.
@ FR_TYPE_INT64
64 Bit signed integer.
@ FR_TYPE_IPV6_ADDR
128 Bit IPv6 Address.
@ FR_TYPE_IPV4_PREFIX
IPv4 Prefix.
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
@ FR_TYPE_OCTETS
Raw octets.
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.
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
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.
int fr_pair_value_bstrndup(fr_pair_t *vp, char const *src, size_t len, bool tainted)
Copy data into a "string" type value pair.
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.
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.
int fr_pair_prepend(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the start of the list.
static int decode_test_ctx(void **out, TALLOC_CTX *ctx, UNUSED fr_dict_t const *dict)
HIDDEN fr_dict_t const * dict_der
bool fr_der_tags_compatible(fr_der_tag_t tag1, fr_der_tag_t tag2)
bool fr_type_to_der_tag_valid(fr_type_t type, fr_der_tag_t tag)
char const * fr_der_tag_to_str(fr_der_tag_t tag)
ssize_t(* fr_der_decode_oid_t)(uint64_t subidentifier, void *uctx, bool is_last)
static ssize_t fr_der_decode_oid_to_da(uint64_t subidentifier, void *uctx, bool is_last)
Decode an OID to a dictionary attribute.
#define IS_DER_TAG_CONTINUATION(_tag)
char oid_buff[1024]
Buffer to store the OID string.
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.
static ssize_t fr_der_decode_visible_string(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
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)
TALLOC_CTX * ctx
Allocation context.
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)
static ssize_t fr_der_decode_t61_string(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
static ssize_t fr_der_decode_universal_string(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
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.
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)
#define IS_DER_LEN_MULTI_BYTE(_len)
static ssize_t fr_der_decode_general_string(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
fr_test_point_proto_decode_t der_tp_decode_proto
static const fr_der_tag_decode_t oid_and_value_func
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)
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)
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)
static const fr_der_tag_decode_t type_funcs[FR_TYPE_MAX]
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)
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.
fr_der_tag_constructed_t constructed
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)
static ssize_t fr_der_decode_ia5_string(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
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)
fr_dict_attr_t const * parent_da
Parent dictionary attribute.
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)
#define fr_der_decode_enumerated
fr_sbuff_marker_t marker
Marker of the current position in the OID buffer.
fr_pair_list_t * parent_list
Parent pair list.
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.
static ssize_t fr_der_decode_oid_to_str(uint64_t subidentifier, void *uctx, bool is_last)
Decode an OID to a string.
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)
static ssize_t fr_der_decode_printable_string(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *in, UNUSED fr_der_decode_ctx_t *decode_ctx)
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.
TALLOC_CTX * ctx
Allocation context.
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)
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)
#define IS_DER_TAG_CONSTRUCTED(_tag)
fr_dict_attr_t const * parent_da
Parent dictionary attribute.
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)
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)
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)
static const fr_der_tag_decode_t tag_funcs[FR_DER_TAG_VALUE_MAX]
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)
fr_test_point_pair_decode_t der_tp_decode_pair
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)
fr_pair_list_t * parent_list
Parent pair list.
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)
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)
size_t fr_sbuff_adv_past_allowed(fr_sbuff_t *sbuff, size_t len, bool const allowed[static UINT8_MAX+1], fr_sbuff_term_t const *tt)
Wind position past characters in the allowed set.
ssize_t fr_sbuff_in_sprintf(fr_sbuff_t *sbuff, char const *fmt,...)
Print using a fmt string to an sbuff.
#define fr_sbuff_set(_dst, _src)
#define FR_SBUFF_IN_SPRINTF_RETURN(...)
#define FR_SBUFF_OUT(_start, _len_or_end)
#define fr_sbuff_used(_sbuff_or_marker)
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.
Stores an attribute, a value and various bits of other data.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
fr_test_point_ctx_alloc_t test_ctx
Allocate a test ctx for the encoder.
fr_test_point_ctx_alloc_t test_ctx
Allocate a test ctx for the encoder.
Entry point for pair decoders.
Entry point for protocol decoders.
fr_unix_time_t fr_unix_time_from_tm(struct tm *tm)
#define fr_time_delta_wrap(_time)
#define fr_unix_time_add(_a, _b)
Add a time/time delta together.
size_t fr_pair_list_num_elements(fr_pair_list_t const *list)
Get the length of a list of fr_pair_t.
#define FR_PROTO_HEX_DUMP(_data, _data_len, _fmt,...)
#define FR_PROTO_TRACE(_fmt,...)
#define fr_strerror_printf_push(_fmt,...)
Add a message to an existing stack of messages at the tail.
#define fr_strerror_const_push(_msg)
#define fr_strerror_const(_msg)
#define fr_type_is_group(_x)
#define fr_type_is_octets(_x)
#define fr_type_is_variable_size(_x)
#define fr_type_is_date(_x)
#define fr_type_is_string(_x)
#define fr_type_is_bool(_x)
#define fr_type_is_tlv(_x)
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
#define fr_type_is_struct(_x)
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.
static size_t char ** out