28 RCSID(
"$Id: 4fa8e1c270abb2153e1a77cc7fc6ae16449c52a8 $")
30 #include <freeradius-devel/server/base.h>
31 #include <freeradius-devel/server/module_rlm.h>
32 #include <freeradius-devel/tls/base.h>
33 #include <freeradius-devel/tls/cert.h>
34 #include <freeradius-devel/tls/log.h>
35 #include <freeradius-devel/tls/strerror.h>
36 #include <freeradius-devel/util/debug.h>
37 #include <freeradius-devel/unlang/xlat_func.h>
38 #include <freeradius-devel/unlang/xlat.h>
40 #include <freeradius-devel/tls/openssl_user_macros.h>
41 #include <openssl/crypto.h>
42 #include <openssl/pem.h>
43 #include <openssl/evp.h>
44 #include <openssl/rsa.h>
45 #include <openssl/x509.h>
88 {
L(
"DH"), EVP_PKEY_DH },
89 {
L(
"DSA"), EVP_PKEY_DSA },
90 {
L(
"EC"), EVP_PKEY_EC },
91 {
L(
"RSA"), EVP_PKEY_RSA }
99 {
L(
"none"), RSA_NO_PADDING },
100 {
L(
"oaep"), RSA_PKCS1_OAEP_PADDING },
101 {
L(
"pkcs"), RSA_PKCS1_PADDING },
102 #if OPENSSL_VERSION_NUMBER < 0x30000000L
103 {
L(
"ssl"), RSA_SSLV23_PADDING },
105 {
L(
"x931"), RSA_X931_PADDING }
257 char const *type_str;
260 md = EVP_get_digestbyname(type_str);
262 cf_log_err(ci,
"Invalid digest type \"%s\"", type_str);
266 *((EVP_MD
const **)
out) = md;
286 char const *type_str;
291 cf_log_err(ci,
"Invalid padding type \"%s\"", type_str);
314 char const *type_str;
323 cf_log_err(ci,
"Invalid cipher type \"%s\"", type_str);
350 ERROR(
"Certificate encrypted but no private_key_password configured");
354 pass = talloc_get_type_abort(u,
char);
355 len = talloc_array_length(pass);
356 if (len > (
size_t)size) {
357 ERROR(
"Password too long. Maximum length is %i bytes", size - 1);
360 memcpy(buf, pass, len);
407 char const *filename;
414 fp = fopen(filename,
"r");
425 fr_tls_strerror_printf(NULL);
426 cf_log_perr(ci,
"Error loading private certificate file \"%s\"", filename);
431 pkey_type = EVP_PKEY_type(EVP_PKEY_id(pkey));
432 if (pkey_type != EVP_PKEY_RSA) {
433 cf_log_err(ci,
"Expected certificate to contain %s private key, got %s private key",
441 talloc_set_type(pkey, EVP_PKEY);
442 (void)talloc_steal(ctx, pkey);
466 char const *filename;
475 fp = fopen(filename,
"r");
484 cert = PEM_read_X509(fp, NULL, NULL, NULL);
488 fr_tls_strerror_printf(NULL);
489 cf_log_perr(ci,
"Error loading certificate file \"%s\"", filename);
499 talloc_set_type(cert, X509);
500 (void)talloc_steal(ctx, cert);
506 pkey = X509_get_pubkey(cert);
508 fr_tls_strerror_printf(NULL);
509 cf_log_perr(ci,
"Failed extracting public key from certificate");
514 pkey_type = EVP_PKEY_type(EVP_PKEY_id(pkey));
515 if (pkey_type != EVP_PKEY_RSA) {
516 cf_log_err(ci,
"Expected certificate to contain %s public key, got %s public key",
529 cf_log_debug(ci,
"Certificate validity starts at %pV and ends at %pV",
557 talloc_set_type(pkey, EVP_PKEY);
558 (void)talloc_steal(cert, pkey);
562 *(EVP_PKEY **)
out = pkey;
590 char const *plaintext;
591 size_t plaintext_len;
594 size_t ciphertext_len;
599 plaintext = in_head->vb_strvalue;
600 plaintext_len = in_head->vb_length;
605 RHEXDUMP3((
uint8_t const *)plaintext, plaintext_len,
"Plaintext (%zu bytes)", plaintext_len);
607 (
unsigned char const *)plaintext, plaintext_len) <= 0) {
608 fr_tls_log(request,
"Failed getting length of encrypted plaintext");
615 (
unsigned char const *)plaintext, plaintext_len) <= 0) {
616 fr_tls_log(request,
"Failed encrypting plaintext");
620 RHEXDUMP3(ciphertext, ciphertext_len,
"Ciphertext (%zu bytes)", ciphertext_len);
658 unsigned int digest_len = 0;
663 msg = in_head->vb_strvalue;
664 msg_len = in_head->vb_length;
670 fr_tls_log(request,
"Failed initialising message digest");
675 fr_tls_log(request,
"Failed ingesting message");
680 fr_tls_log(request,
"Failed finalising message digest");
689 fr_tls_log(request,
"Failed getting length of digest");
696 fr_tls_log(request,
"Failed signing message digest");
730 size_t ciphertext_len;
733 size_t plaintext_len;
738 ciphertext = in_head->vb_octets;
739 ciphertext_len = in_head->vb_length;
744 RHEXDUMP3(ciphertext, ciphertext_len,
"Ciphertext (%zu bytes)", ciphertext_len);
745 if (EVP_PKEY_decrypt(t->
evp_decrypt_ctx, NULL, &plaintext_len, ciphertext, ciphertext_len) <= 0) {
746 fr_tls_log(request,
"Failed getting length of cleartext");
752 if (EVP_PKEY_decrypt(t->
evp_decrypt_ctx, (
unsigned char *)plaintext, &plaintext_len,
753 ciphertext, ciphertext_len) <= 0) {
754 fr_tls_log(request,
"Failed decrypting ciphertext");
758 RHEXDUMP3((
uint8_t const *)plaintext, plaintext_len,
"Plaintext (%zu bytes)", plaintext_len);
798 unsigned int digest_len = 0;
810 REDEBUG(
"Signature argument wrong type, expected %s, got %s. "
811 "Use %%base64.decode(<text>) or %%hex_decode(<text>) if signature is armoured",
816 sig = in_head->vb_octets;
817 sig_len = in_head->vb_length;
822 args = fr_value_box_list_head(
in);
827 REDEBUG(
"Failed concatenating arguments to form plaintext");
831 msg_len =
args->vb_length;
834 REDEBUG(
"Zero length message data");
842 fr_tls_log(request,
"Failed initialising message digest");
847 fr_tls_log(request,
"Failed ingesting message");
852 fr_tls_log(request,
"Failed finalising message digest");
874 fr_tls_log(request,
"Failed validating signature");
883 { .required =
false, .concat =
false, .single =
true, .type =
FR_TYPE_STRING },
908 if (!fr_value_box_list_next(
in, fr_value_box_list_head(
in))) {
909 REDEBUG(
"Missing digest argument");
916 md_name = ((
fr_value_box_t *)fr_value_box_list_next(
in, fr_value_box_list_head(
in)))->vb_strvalue;
917 md = EVP_get_digestbyname(md_name);
919 REDEBUG(
"Specified digest \"%s\" is not a valid digest type", md_name);
923 md_len = EVP_MD_size(md);
927 if (X509_digest(
inst->rsa->x509_certificate_file, md, digest, (
unsigned int *)&md_len) != 1) {
928 fr_tls_log(request,
"Failed calculating certificate fingerprint");
951 ASN1_INTEGER
const *serial;
954 serial = X509_get0_serialNumber(
inst->rsa->x509_certificate_file);
956 fr_tls_log(request,
"Failed retrieving certificate serial");
973 char const *attribute = fr_value_box_list_head(
in)->vb_strvalue;
978 REDEBUG(
"Unknown certificate attribute \"%s\"", attribute);
989 vb->vb_date =
inst->rsa->not_before;
996 vb->vb_date =
inst->rsa->not_after;
1010 EVP_PKEY_CTX_free(evp_pkey_ctx);
1022 EVP_MD_CTX_destroy(evp_md_ctx);
1029 if (
unlikely(EVP_PKEY_CTX_set_rsa_padding(evp_pkey_ctx, rsa_inst->
padding)) <= 0) {
1030 fr_tls_strerror_printf(NULL);
1031 PERROR(
"%s: Failed setting RSA padding type", __FUNCTION__);
1036 case RSA_NO_PADDING:
1037 case RSA_X931_PADDING:
1038 #if OPENSSL_VERSION_NUMBER < 0x30000000L
1039 case RSA_SSLV23_PADDING:
1041 case RSA_PKCS1_PADDING:
1047 case RSA_PKCS1_OAEP_PADDING:
1049 fr_tls_strerror_printf(NULL);
1050 PERROR(
"%s: Failed setting OAEP digest", __FUNCTION__);
1055 fr_tls_strerror_printf(NULL);
1056 PERROR(
"%s: Failed setting MGF1 digest", __FUNCTION__);
1062 size_t label_len = talloc_array_length(rsa_inst->
oaep->
label) - 1;
1072 if (
unlikely(EVP_PKEY_CTX_set0_rsa_oaep_label(evp_pkey_ctx, label, label_len) <= 0)) {
1073 fr_tls_strerror_printf(NULL);
1074 PERROR(
"%s: Failed setting OAEP padding label", __FUNCTION__);
1075 OPENSSL_free(label);
1107 if (
inst->rsa->certificate_file) {
1113 fr_tls_strerror_printf(NULL);
1114 PERROR(
"%s: Failed allocating encrypt EVP_PKEY_CTX", __FUNCTION__);
1125 fr_tls_strerror_printf(NULL);
1126 PERROR(
"%s: Failed initialising encrypt EVP_PKEY_CTX", __FUNCTION__);
1130 ERROR(
"%s: Failed setting padding for encrypt EVP_PKEY_CTX", __FUNCTION__);
1139 fr_tls_strerror_printf(NULL);
1140 PERROR(
"%s: Failed allocating verify EVP_PKEY_CTX", __FUNCTION__);
1151 fr_tls_strerror_printf(NULL);
1152 PERROR(
"%s: Failed initialising verify EVP_PKEY_CTX", __FUNCTION__);
1159 if (
inst->rsa->padding != RSA_PKCS1_OAEP_PADDING) {
1161 ERROR(
"%s: Failed setting padding for verify EVP_PKEY_CTX", __FUNCTION__);
1167 fr_tls_strerror_printf(NULL);
1168 PERROR(
"%s: Failed setting signature digest type", __FUNCTION__);
1173 if (
inst->rsa->private_key_file) {
1179 fr_tls_strerror_printf(NULL);
1180 PERROR(
"%s: Failed allocating decrypt EVP_PKEY_CTX", __FUNCTION__);
1191 fr_tls_strerror_printf(NULL);
1192 PERROR(
"%s: Failed initialising decrypt EVP_PKEY_CTX", __FUNCTION__);
1196 ERROR(
"%s: Failed setting padding for decrypt EVP_PKEY_CTX", __FUNCTION__);
1205 fr_tls_strerror_printf(NULL);
1206 PERROR(
"%s: Failed allocating sign EVP_PKEY_CTX", __FUNCTION__);
1217 fr_tls_strerror_printf(NULL);
1218 PERROR(
"%s: Failed initialising sign EVP_PKEY_CTX", __FUNCTION__);
1225 if (
inst->rsa->padding != RSA_PKCS1_OAEP_PADDING) {
1227 ERROR(
"%s: Failed setting padding for sign EVP_PKEY_CTX", __FUNCTION__);
1233 fr_tls_strerror_printf(NULL);
1234 PERROR(
"%s: Failed setting signature digest type", __FUNCTION__);
1243 fr_tls_strerror_printf(NULL);
1244 PERROR(
"%s: Failed allocating EVP_MD_CTX", __FUNCTION__);
1286 cf_log_err(
conf,
"type = rsa, but no 'rsa { ... }' configuration section provided");
1290 if (!
inst->rsa->private_key_file && !
inst->rsa->certificate_file) {
1292 "'private_key_file' nor 'certificate_file' configured");
1296 if (
inst->rsa->private_key_file) {
1312 if (
inst->rsa->certificate_file) {
1322 if (
inst->rsa->private_key_file &&
inst->rsa->x509_certificate_file) {
1323 if (X509_check_private_key(
inst->rsa->x509_certificate_file,
1324 inst->rsa->private_key_file) == 0) {
1325 fr_tls_strerror_printf(NULL);
1326 cf_log_perr(
conf,
"Private key does not match the certificate public key");
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define L(_str)
Helper for initialising arrays of string literals.
int cf_table_parse_int(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
Generic function for parsing conf pair values as int.
#define CONF_PARSER_TERMINATOR
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
#define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs)
conf_parser_t which populates a sub-struct using a CONF_SECTION
@ CONF_FLAG_SECRET
Only print value if debug level >= 3.
@ CONF_FLAG_NOT_EMPTY
CONF_PAIR is required to have a non zero length value.
#define FR_CONF_OFFSET_TYPE_FLAGS(_name, _type, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Defines a CONF_PAIR to C data type mapping.
Common header for all CONF_* types.
A section grouping multiple CONF_PAIR.
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
#define cf_log_err(_cf, _fmt,...)
#define cf_log_perr(_cf, _fmt,...)
#define cf_log_pwarn(_cf, _fmt,...)
#define cf_log_debug(_cf, _fmt,...)
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
void *_CONST data
Module instance's parsed configuration.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
CONF_SECTION *_CONST conf
Module's instance configuration.
static xlat_action_t cipher_rsa_decrypt_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Decrypt input data.
static xlat_action_t cipher_rsa_encrypt_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Encrypt input data.
static xlat_action_t cipher_rsa_sign_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Sign input data.
static xlat_action_t cipher_serial_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, UNUSED fr_value_box_list_t *in)
Return the serial of the public certificate.
static xlat_action_t cipher_rsa_verify_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Verify input data.
static xlat_action_t cipher_fingerprint_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Return the fingerprint of the public certificate.
#define RHEXDUMP3(_data, _len, _fmt,...)
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_DATE
Unix time stamp, always has value >2^31.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_OCTETS
Raw octets.
void * thread
Thread specific instance data.
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
void * thread
Thread instance data.
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
Temporary structure to hold arguments for instantiation calls.
Temporary structure to hold arguments for thread_instantiation calls.
module_t common
Common fields presented by all modules.
EVP_PKEY_CTX * evp_verify_ctx
Pre-allocated evp_pkey_ctx.
static size_t cipher_rsa_padding_len
static int cipher_type_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
Checks if the specified cipher type is valid.
static const conf_parser_t rsa_oaep_config[]
Configuration for the RSA-PCKS1-OAEP padding scheme.
static int cipher_rsa_private_key_file_load(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
cipher_rsa_oaep_t * oaep
OAEP can use a configurable message digest type.
X509 * x509_certificate_file
Needed for extracting certificate attributes.
cipher_cert_verify_mode_t verify_mode
How hard we try to verify the certificate.
static xlat_arg_parser_t const cipher_rsa_verify_xlat_arg[]
static fr_table_num_sorted_t const cipher_rsa_padding[]
The type of padding used.
static fr_table_num_sorted_t const cert_attributes[]
Public key types.
cipher_cert_verify_mode_t
Certificate validation modes.
@ CIPHER_CERT_VERIFY_HARD
Fail if the certificate isn't valid.
@ CIPHER_CERT_VERIFY_SOFT
Warn if the certificate isn't valid.
@ CIPHER_CERT_VERIFY_NONE
Don't check to see if the we're between notBefore or notAfter.
@ CIPHER_CERT_VERIFY_INVALID
static const conf_parser_t rsa_config[]
Configuration for the RSA cipher type.
static int cipher_rsa_padding_params_set(EVP_PKEY_CTX *evp_pkey_ctx, cipher_rsa_t const *rsa_inst)
cipher_type_t type
Type of encryption to use.
static size_t cipher_cert_verify_mode_table_len
@ CIPHER_CERT_ATTR_NOT_AFTER
Time the certificate expires.
@ CIPHER_CERT_ATTR_SERIAL
Certificate's serial number.
@ CIPHER_CERT_ATTR_UNKNOWN
Unrecognised attribute.
@ CIPHER_CERT_ATTR_FINGERPRINT
Dynamically calculated fingerprint.
@ CIPHER_CERT_ATTR_NOT_BEFORE
Time the certificate becomes valid.
char const * label
Additional input to the hashing function.
EVP_MD_CTX * evp_md_ctx
Pre-allocated evp_md_ctx for sign and verify.
static int _get_private_key_password(char *buf, int size, UNUSED int rwflag, void *u)
Return the static private key password we have configured.
int padding
Type of padding to apply to the plaintext or ciphertext before feeding it to RSA crypto functions.
static int mod_bootstrap(module_inst_ctx_t const *mctx)
static int digest_type_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
Calls EVP_get_digestbyname() to convert the digest type.
uint8_t * digest_buff
Pre-allocated digest buffer.
EVP_MD * mgf1_digest
Masking function digest.
static xlat_arg_parser_t const cipher_rsa_decrypt_xlat_arg[]
static fr_table_num_sorted_t const cipher_cert_verify_mode_table[]
@ RLM_CIPHER_TYPE_INVALID
static xlat_arg_parser_t const cipher_rsa_sign_xlat_arg[]
static int _evp_pkey_free(EVP_PKEY *pkey)
Talloc destructor for freeing an EVP_PKEY (representing a certificate)
fr_unix_time_t not_before
Certificate isn't valid before this time.
static xlat_arg_parser_t const cipher_rsa_encrypt_xlat_arg[]
fr_unix_time_t not_after
Certificate isn't valid after this time.
char const * private_key_password
Password to decrypt the private key.
static int cipher_rsa_thread_instantiate(module_thread_inst_ctx_t const *mctx)
Pre-initialises the EVP_PKEY_CTX necessary for performing RSA encryption/decryption/sign/verify.
static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
EVP_PKEY * certificate_file
Public (certificate) file.
EVP_PKEY * private_key_file
Private key file.
static size_t cipher_type_len
static int cipher_rsa_padding_type_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
Checks if the specified padding type is valid.
static int _x509_cert_free(X509 *cert)
Talloc destructor for freeing an X509 struct (representing a public certificate)
static int _evp_md_ctx_free(EVP_MD_CTX *evp_md_ctx)
Talloc destructor for freeing an EVP_MD_CTX.
static xlat_arg_parser_t const cipher_certificate_xlat_args[]
static fr_table_num_sorted_t const cipher_type[]
EVP_PKEY_CTX * evp_decrypt_ctx
Pre-allocated evp_pkey_ctx.
EVP_PKEY_CTX * evp_encrypt_ctx
Pre-allocated evp_pkey_ctx.
static const conf_parser_t module_config[]
static int cipher_rsa_certificate_file_load(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
static xlat_action_t cipher_certificate_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
static size_t cert_attributes_len
EVP_PKEY_CTX * evp_sign_ctx
Pre-allocated evp_pkey_ctx.
static int _evp_pkey_ctx_free(EVP_PKEY_CTX *evp_pkey_ctx)
Talloc destructor for freeing an EVP_PKEY_CTX.
static size_t pkey_types_len
EVP_MD * sig_digest
Signature digest type.
char const * random_file
If set, we read 10K of data (or the complete file) and use it to seed OpenSSL's PRNG.
static fr_table_num_sorted_t const pkey_types[]
Public key types.
EVP_MD * oaep_digest
Padding digest type.
Configuration for the OAEP padding method.
Configuration for RSA encryption/decryption/signing.
@ MODULE_TYPE_THREAD_SAFE
Module is threadsafe.
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
fr_aka_sim_id_type_t type
eap_type_t type
The preferred EAP-Type of this instance of the EAP-SIM/AKA/AKA' state machine.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
An element in a lexicographically sorted array of name to num mappings.
char * talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen)
Binary safe strndup function.
#define talloc_get_type_abort_const
bool required
Argument must be present, and non-empty.
@ XLAT_ARG_VARIADIC_EMPTY_SQUASH
Empty argument groups are removed.
#define XLAT_ARG_PARSER_TERMINATOR
@ XLAT_ACTION_FAIL
An xlat function failed.
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition for a single argument consumend by an xlat function.
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
int fr_value_box_mem_alloc(TALLOC_CTX *ctx, uint8_t **out, fr_value_box_t *dst, fr_dict_attr_t const *enumv, size_t len, bool tainted)
Pre-allocate an octets buffer for filling by the caller.
int fr_value_box_mem_realloc(TALLOC_CTX *ctx, uint8_t **out, fr_value_box_t *dst, size_t len)
Change the length of a buffer already allocated to a value box.
int fr_value_box_bstr_alloc(TALLOC_CTX *ctx, char **out, fr_value_box_t *dst, fr_dict_attr_t const *enumv, size_t len, bool tainted)
Alloc and assign an empty \0 terminated string to a fr_value_box_t.
int fr_value_box_bstr_realloc(TALLOC_CTX *ctx, char **out, fr_value_box_t *dst, size_t len)
Change the length of a buffer already allocated to a value box.
int fr_value_box_memdup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, uint8_t const *src, size_t len, bool tainted)
Copy a buffer to a fr_value_box_t.
int fr_value_box_list_concat_in_place(TALLOC_CTX *ctx, fr_value_box_t *out, fr_value_box_list_t *list, fr_type_t type, fr_value_box_list_action_t proc_action, bool flatten, size_t max_size)
Concatenate a list of value boxes.
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
static size_t char ** out
#define fr_box_date(_val)
module_ctx_t const * mctx
Synthesised module calling ctx.
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
int xlat_func_mono_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the argument of an xlat.
xlat_t * xlat_func_register_module(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx, char const *name, xlat_func_t func, fr_type_t return_type)
Register an xlat function for a module.