26#define _TRACE_PREFIX_ "v",__LINE__, ""
46#define AST_DB_FAMILY "STIR_SHAKEN"
51#define BEGIN_CERTIFICATE_STR "-----BEGIN CERTIFICATE-----"
112 const char *cache_control_header,
const char *expires_header)
117 time_t current_time = time(
NULL);
118 time_t max_age_hdr = 0;
119 time_t expires_hdr = 0;
120 ASN1_TIME *notAfter =
NULL;
121 time_t cert_expires = 0;
122 time_t config_expires = 0;
126 config_expires = current_time + cfg->vcfg_common.max_cache_entry_age;
131 str_max_age = strstr(cache_control_header,
"s-maxage");
133 str_max_age = strstr(cache_control_header,
"max-age");
138 char *equal = strchr(str_max_age,
'=');
140 max_age_hdr = current_time + m;
146 struct ast_tm expires_time;
148 ast_strptime(expires_header,
"%a, %d %b %Y %T %z", &expires_time);
150 expires_hdr =
ast_mktime(&expires_time,
"GMT").tv_sec;
153 notAfter = X509_get_notAfter(cert->
xcert);
172 expires = config_expires;
174 if (max_age_hdr > expires) {
175 expires = max_age_hdr;
178 if (expires_hdr > expires) {
179 expires = expires_hdr;
186 if (cert_expires && cert_expires < expires) {
187 expires = cert_expires;
190 snprintf(time_buf,
sizeof(time_buf),
"%ld", expires);
201 const char *cache_control_hdr,
const char *expires_hdr)
226 struct timeval current_time =
ast_tvnow();
227 struct timeval expires = { .tv_sec = 0, .tv_usec = 0 };
229 SCOPE_ENTER(3,
"Checking for cache expiration: %s\n", expiration);
239 ast_trace(2,
"Expiration comparison: exp: %" PRIu64
" curr: %" PRIu64
" Diff: %" PRIu64
".\n",
240 expires.tv_sec, current_time.tv_sec, expires.tv_sec - current_time.tv_sec);
242 res = (
ast_tvcmp(current_time, expires) == -1 ? 0 : 1);
246#define ASN1_TAG_TNAUTH_SPC 0
247#define ASN1_TAG_TNAUTH_TN_RANGE 1
248#define ASN1_TAG_TNAUTH_TN 2
250#define IS_GET_OBJ_ERR(ret) (ret & 0x80)
255 ASN1_OCTET_STRING *tn_exten;
256 const unsigned char* octet_str_data =
NULL;
265 LOG_ERROR,
"%s: Cert '%s' doesn't have a TNAuthList extension\n",
268 octet_str_data = tn_exten->data;
271 ret = ASN1_get_object(&octet_str_data, &xlen, &tag, &xclass, tn_exten->length);
278 if (ret != V_ASN1_CONSTRUCTED || tag != V_ASN1_SEQUENCE) {
280 LOG_ERROR,
"%s: Cert '%s' has malformed TNAuthList extension (tag %d != V_ASN1_SEQUENCE)\n",
295 ret = ASN1_get_object(&octet_str_data, &xlen, &tag, &xclass, tn_exten->length);
304 LOG_ERROR,
"%s: Cert '%s' has malformed TNAuthList extension (tag %d != ASN1_TAG_TNAUTH_SPC(0))\n",
309 ret = ASN1_get_object(&octet_str_data, &xlen, &tag, &xclass, tn_exten->length);
312 LOG_ERROR,
"%s: Cert '%s' has malformed TNAuthList extension (no SPC)\n",
337 LOG_ERROR,
"%s: Cert '%s' has no commonName(CN) in Subject '%s'\n",
346 ast_trace(3,
"%s: Checking ctx against CA ctx\n", ctx->
tag);
350 LOG_ERROR,
"%s: Cert '%s' not trusted: %s\n",
354 ast_trace(3,
"%s: Attempting to get the raw pubkey\n", ctx->
tag);
359 LOG_ERROR,
"%s: Unable to extract raw public key from '%s'\n",
363 ast_trace(3,
"%s: Checking cert '%s' validity dates\n",
367 LOG_ERROR,
"%s: Cert '%s' dates not valid\n",
372 "%s: Cert '%s' with SPC: %s CN: %s is valid\n",
390 const char *cache_control;
392 SCOPE_ENTER(2,
"%s: Attempting to retrieve '%s' from net\n",
395 if (!
header_data || !write_data || !open_socket_data) {
397 LOG_ERROR,
"%s: Unable to allocate memory for curl '%s' transaction\n",
403 write_data->max_download_bytes = 8192;
404 write_data->stream_buffer =
NULL;
408 if (!
header_data->debug_info || !write_data->debug_info ||
409 !open_socket_data->debug_info) {
411 LOG_ERROR,
"%s: Unable to allocate memory for curl '%s' transaction\n",
419 if (http_code / 100 != 2) {
421 LOG_ERROR,
"%s: Failed to retrieve cert %s: code %ld\n",
427 LOG_ERROR,
"%s: Cert '%s' contains invalid data\n",
432 write_data->stream_bytes_downloaded);
435 LOG_ERROR,
"%s: Cert '%s' was not parseable as an X509 certificate\n",
441 X509_free(ctx->
xcert);
447 cert_file = fopen(ctx->
filename,
"w");
449 X509_free(ctx->
xcert);
452 LOG_ERROR,
"%s: Failed to write cert %s: file '%s' %s (%d)\n",
456 rc = fputs(write_data->stream_buffer, cert_file);
459 X509_free(ctx->
xcert);
462 LOG_ERROR,
"%s: Failed to write cert %s: file '%s' %s (%d)\n",
466 ast_trace(2,
"%s: Cert '%s' written to file '%s'\n",
469 ast_trace(2,
"%s: Adding cert '%s' to astdb",
476 X509_free(ctx->
xcert);
479 LOG_ERROR,
"%s: Unable to add cert '%s' to ASTDB\n",
484 "%s: Cert '%s' successfully retrieved from internet and cached\n",
494 SCOPE_ENTER(2,
"%s: Attempting to retrieve cert '%s' from cache\n",
500 "%s: No cert found in astdb for '%s'\n",
508 "%s: No cert found in astdb for '%s'\n",
515 "%s: Cert file '%s' was not found or was not readable for '%s'\n",
522 "%s: Cert file '%s' cache entry was expired for '%s'\n",
530 "%s: Cert file '%s' was not parseable as an X509 certificate for '%s'\n",
536 X509_free(ctx->
xcert);
543 "%s: Cert '%s' successfully retrieved from cache\n",
587 ast_trace(1,
"%s: No valid cert for '%s' available in cache\n",
589 ast_trace(1,
"%s: Retrieving cert directly from url '%s'\n",
599 "%s: Unable to retrieve cert '%s' from cache or internet\n",
613 const char *date_hdr)
646 X509_free(ctx->
xcert);
663 if (vs->global_disable) {
665 "%s: Globally disabled\n", t);
670 "%s: Disabled due to missing profile name\n", t);
676 LOG_ERROR,
"%s: No profile for profile name '%s'. Call will continue\n",
tag,
682 "%s: Disabled by profile '%s'\n", t, profile_name);
692 LOG_ERROR,
"%s: Must provide caller_id\n", t);
714 ctx->eprofile = profile;
725 struct ast_tm date_hdr_tm;
726 struct timeval date_hdr_timeval;
727 struct timeval current_timeval;
729 char timezone[80] = { 0 };
736 LOG_ERROR,
"%s: Failed to parse: '%s'\n",
740 sscanf(remainder,
"%79s", timezone);
744 LOG_ERROR,
"%s: A timezone is required: '%s'\n",
748 date_hdr_timeval =
ast_mktime(&date_hdr_tm, timezone);
752 time_diff =
ast_tvdiff_ms(current_timeval, date_hdr_timeval);
753 ast_trace(3,
"%zu %zu %zu %d\n", current_timeval.tv_sec,
754 date_hdr_timeval.tv_sec,
755 (current_timeval.tv_sec - date_hdr_timeval.tv_sec), (
int)time_diff);
763 LOG_ERROR,
"%s: More than %u seconds old: '%s'\n",
771#define FULL_URL_REGEX "^([a-zA-Z]+)://(([^@]+@[^:]+):)?(([^:/?]+)|([0-9.]+)|([[][0-9a-fA-F:]+[]]))(:([0-9]+))?(/([^#\\?]+))?(\\?([^#]+))?(#(.*))?"
772#define FULL_URL_REGEX_GROUPS 15
790#define URL_MATCH_SCHEME 1
791#define URL_MATCH_USERPASS 3
792#define URL_MATCH_HOST 4
793#define URL_MATCH_PORT 9
794#define URL_MATCH_PATH 11
795#define URL_MATCH_QUERY 13
796#define URL_MATCH_FRAGMENT 15
798#define get_match_string(__x5u, __pmatch, __i) \
800 char *__match = NULL; \
801 if (__pmatch[__i].rm_so >= 0) { \
802 regoff_t __len = __pmatch[__i].rm_eo - __pmatch[__i].rm_so; \
803 const char *__start = __x5u + __pmatch[__i].rm_so; \
804 __match = ast_alloca(__len + 1); \
805 ast_copy_string(__match, __start, __len + 1); \
810#define DUMP_X5U_MATCH() \
813 if (TRACE_ATLEAST(4)) { \
814 ast_trace(-1, "%s: x5u: %s\n", ctx->tag, x5u); \
815 for (i=0;i<FULL_URL_REGEX_GROUPS;i++) { \
816 const char *m = get_match_string(x5u, pmatch, i); \
818 ast_trace(-1, "%s: %2d %s\n", ctx->tag, i, m); \
828 regmatch_t pmatch[max_groups];
834 char regex_error[512];
837 "%s: x5u '%s' in Identity header failed basic URL validation: %s\n",
838 ctx->
tag, x5u, regex_error);
842 != relax_x5u_port_scheme_restrictions_YES) {
849 "%s: x5u '%s': scheme '%s' not https\n",
850 ctx->
tag, x5u, scheme);
857 "%s: x5u '%s': port '%s' not port 443 or 8443\n",
858 ctx->
tag, x5u, port);
864 != relax_x5u_path_restrictions_YES) {
873 "%s: x5u '%s' contains user:password, query parameters or fragment\n",
888 char *grants_str =
NULL;
890 const char *ppt_header =
NULL;
891 const char *grant =
NULL;
892 time_t now_s = time(
NULL);
902 "%s: No context object!\n",
"NULL");
907 "%s: No identity header in ctx\n", ctx->
tag);
915 "%s: Failed to allocate memory for encoded jwt\n", ctx->
tag);
919 jwt_encoded[
len - 1] =
'\0';
921 jwt_decode(&jwt, jwt_encoded,
NULL, 0);
923 ppt_header = jwt_get_header(jwt,
"ppt");
932 "%s: Date header verification failed\n", ctx->
tag);
935 x5u = jwt_get_header(jwt,
"x5u");
938 "%s: No x5u in Identity header\n", ctx->
tag);
944 "%s: x5u URL verification failed\n", ctx->
tag);
947 ast_trace(3,
"%s: Decoded enough to get x5u: '%s'\n", ctx->
tag, x5u);
950 "%s: Failed to set public_url '%s'\n", ctx->
tag, x5u);
953 iat = jwt_get_grant_int(jwt,
"iat");
956 "%s: No 'iat' in Identity header\n", ctx->
tag);
958 ast_trace(1,
"date_hdr: %zu iat: %zu diff: %zu\n",
962 "%s: iat %ld older than %u seconds\n", ctx->
tag,
970 "%s: Unable to populate ctx\n", ctx->
tag);
976 "%s: Could not get valid cert from '%s'\n", ctx->
tag, ctx->
public_url);
985 LOG_ERROR,
"%s: Signature validation failed for '%s'\n",
991 ppt_header = jwt_get_header(jwt,
"alg");
994 "%s: %s\n", ctx->
tag,
998 ppt_header = jwt_get_header(jwt,
"ppt");
1001 "%s: %s\n", ctx->
tag,
1005 ppt_header = jwt_get_header(jwt,
"typ");
1008 "%s: %s\n", ctx->
tag,
1012 grants_str = jwt_get_grants_json(jwt,
NULL);
1015 "%s: %s\n", ctx->
tag,
1018 ast_trace(1,
"grants: %s\n", grants_str);
1023 "%s: %s\n", ctx->
tag,
1030 "%s: No 'attest' in Identity header\n", ctx->
tag);
1032 if (grant[0] <
'A' || grant[0] >
'C') {
1034 "%s: Invalid attest value '%s'\n", ctx->
tag, grant);
1037 ast_trace(1,
"got attest: %s\n", grant);
1042 "%s: No 'dest' in Identity header\n", ctx->
tag);
1053 "%s: No 'orig' in Identity header\n", ctx->
tag);
1063 "%s: No 'orig.tn' in Indentity header\n", ctx->
tag);
1068 "%s: Mismatched cid '%s' and orig_tn '%s'\n", ctx->
tag,
1075 "%s: No 'origid' in Identity header\n", ctx->
tag);
1079 "%s: verification succeeded\n", ctx->
tag);
1109 char regex_error[512];
1111 ast_log(
LOG_ERROR,
"Verification service URL regex failed to compile: %s\n", regex_error);
1116 ast_log(
LOG_ERROR,
"The verification service URL regex was updated without updating FULL_URL_REGEX_GROUPS\n");
Access Control of various sorts.
Persistent data storage (akin to *doze registry)
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
Get key value specified by family/key.
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
int ast_db_deltree(const char *family, const char *keytree)
Delete one or more entries in astdb.
int ast_db_exists(const char *family, const char *key)
Check if family/key exitsts.
Asterisk main include file. File version handling, generic pbx functions.
void ast_std_free(void *ptr)
#define ast_strdup(str)
A wrapper for strdup()
#define ast_calloc(num, len)
A wrapper for calloc()
#define ast_malloc(len)
A wrapper for malloc()
@ AO2_ALLOC_OPT_LOCK_NOLOCK
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_alloc_options(data_size, destructor_fn, options)
General Asterisk PBX channel definitions.
const char * ast_channel_name(const struct ast_channel *chan)
Standard Command Line Interface.
char * canonicalize_tn_alloc(const char *tn)
Canonicalize a TN into nre buffer.
int vs_config_reload(void)
struct verification_cfg * vs_get_cfg(void)
struct profile_cfg * eprofile_get_cfg(const char *id)
#define PROFILE_ALLOW_VERIFY(__profile)
int vs_config_unload(void)
Conversion utility functions.
int ast_str_to_uint(const char *str, unsigned int *res)
Convert the given string to an unsigned integer.
int ast_str_to_ulong(const char *str, unsigned long *res)
Convert the given string to an unsigned long.
Provide cryptographic signature routines.
X509 * crypto_load_cert_from_memory(const char *buffer, size_t size)
Load an X509 Cert from a NULL terminated buffer.
int crypto_is_cert_trusted(struct crypto_cert_store *store, X509 *cert, const char **err_msg)
Check if the cert is trusted.
void crypto_log_openssl(int level, char *file, int line, const char *function, const char *fmt,...)
Print a log message with any OpenSSL errors appended.
int crypto_get_raw_pubkey_from_cert(X509 *cert, unsigned char **buffer)
Retrieve RAW public key from cert.
time_t crypto_asn_time_as_time_t(ASN1_TIME *at)
Return a time_t for an ASN1_TIME.
char * crypto_get_cert_subject(X509 *cert, const char *short_name)
Returns the Subject (or component of Subject) from a certificate.
int crypto_is_cert_time_valid(X509 *cert, time_t reftime)
Check if the reftime is within the cert's valid dates.
X509 * crypto_load_cert_from_file(const char *filename)
Load an X509 Cert from a file.
ASN1_OCTET_STRING * crypto_get_cert_extension_data(X509 *cert, int nid, const char *short_name)
Return the data from a specific extension in a cert.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void curl_write_data_free(void *obj)
void curl_open_socket_data_free(void *obj)
#define TRACE_ATLEAST(level)
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
#define SCOPE_EXIT_LOG_RTN_VALUE(__value, __log_level,...)
#define SCOPE_ENTER(level,...)
#define ast_trace(level,...)
long curler(const char *url, int request_timeout, struct curl_write_data *write_data, struct curl_header_data *header_data, struct curl_open_socket_data *open_socket_data)
Perform a curl request.
Configuration File Parser.
const char * ast_variable_find_in_list(const struct ast_variable *list, const char *variable)
Gets the value of a variable from a variable list by name.
Support for logging to various files, console and syslog Configuration in file logger....
Asterisk JSON abstraction layer.
#define ast_json_object_string_get(object, key)
Get a string field from a JSON object.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
void ast_json_free(void *p)
Asterisk's custom JSON allocator. Exposed for use by unit tests.
#define ast_json_dump_string(root)
Encode a JSON value to a compact string.
struct ast_json * ast_json_load_string(const char *input, struct ast_json_error *error)
Parse null terminated string into a JSON object or array.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Custom localtime functions for multiple timezones.
struct timeval ast_mktime(struct ast_tm *const tmp, const char *zone)
Timezone-independent version of mktime(3).
char * ast_strptime(const char *s, const char *format, struct ast_tm *tm)
Special version of strptime(3) which places the answer in the common structure ast_tm....
Asterisk module definitions.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Asterisk file paths, configured in asterisk.conf.
int get_tn_auth_nid(void)
Retrieves the OpenSSL NID for the TN Auth list extension.
ast_stir_shaken_vs_response_code
@ AST_STIR_SHAKEN_VS_CERT_DATE_INVALID
@ AST_STIR_SHAKEN_VS_NO_DATE_HDR
@ AST_STIR_SHAKEN_VS_SUCCESS
@ AST_STIR_SHAKEN_VS_INVALID_OR_NO_ATTEST
@ AST_STIR_SHAKEN_VS_INVALID_OR_NO_TYP
@ AST_STIR_SHAKEN_VS_CID_ORIG_TN_MISMATCH
@ AST_STIR_SHAKEN_VS_NO_JWT_HDR
@ AST_STIR_SHAKEN_VS_NO_DEST_TN
@ AST_STIR_SHAKEN_VS_IAT_EXPIRED
@ AST_STIR_SHAKEN_VS_NO_IDENTITY_HDR
@ AST_STIR_SHAKEN_VS_NO_RAW_KEY
@ AST_STIR_SHAKEN_VS_DATE_HDR_EXPIRED
@ AST_STIR_SHAKEN_VS_INVALID_ARGUMENTS
@ AST_STIR_SHAKEN_VS_SIGNATURE_VALIDATION
@ AST_STIR_SHAKEN_VS_INVALID_OR_NO_ALG
@ AST_STIR_SHAKEN_VS_CERT_CONTENTS_INVALID
@ AST_STIR_SHAKEN_VS_NO_ORIGID
@ AST_STIR_SHAKEN_VS_INVALID_HEADER
@ AST_STIR_SHAKEN_VS_CERT_CACHE_INVALID
@ AST_STIR_SHAKEN_VS_INVALID_GRANT
@ AST_STIR_SHAKEN_VS_DISABLED
@ AST_STIR_SHAKEN_VS_CERT_CACHE_MISS
@ AST_STIR_SHAKEN_VS_CERT_CACHE_EXPIRED
@ AST_STIR_SHAKEN_VS_NO_IAT
@ AST_STIR_SHAKEN_VS_NO_ORIG_TN
@ AST_STIR_SHAKEN_VS_INVALID_OR_NO_PPT
@ AST_STIR_SHAKEN_VS_CERT_NOT_TRUSTED
@ AST_STIR_SHAKEN_VS_DATE_HDR_PARSE_FAILURE
@ AST_STIR_SHAKEN_VS_INTERNAL_ERROR
@ AST_STIR_SHAKEN_VS_CERT_NO_SPC_IN_TN_AUTH_EXT
@ AST_STIR_SHAKEN_VS_INVALID_OR_NO_GRANTS
@ AST_STIR_SHAKEN_VS_INVALID_OR_NO_X5U
@ AST_STIR_SHAKEN_VS_CERT_RETRIEVAL_FAILURE
@ AST_STIR_SHAKEN_VS_CERT_NO_TN_AUTH_EXT
stir_shaken_failure_action_enum
Sorcery Data Access Layer API.
#define STIR_SHAKEN_ENCRYPTION_ALGORITHM
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
static force_inline int attribute_pure ast_strlen_zero(const char *s)
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
Main Channel structure associated with a channel.
Abstract JSON element (object, array, string, int, ...).
const ast_string_field public_url
const ast_string_field orig_tn
const ast_string_field hash
const ast_string_field hash_family
const ast_string_field tag
const ast_string_field date_hdr
struct profile_cfg * eprofile
const ast_string_field identity_hdr
struct ast_channel * chan
const ast_string_field filename
const ast_string_field url_family
const ast_string_field caller_id
const ast_string_field cert_cn
time_t validity_check_time
const ast_string_field cert_spc
enum ast_stir_shaken_vs_response_code failure_reason
Context structure passed to ast_curl_open_socket_default_cb.
Context structure passed to ast_curl_write_default_cb.
Profile configuration for stir/shaken.
struct verification_cfg_common vcfg_common
struct crypto_cert_store * tcs
enum stir_shaken_failure_action_enum stir_shaken_failure_action
enum use_rfc9410_responses_enum use_rfc9410_responses
const ast_string_field cert_cache_dir
enum relax_x5u_path_restrictions_enum relax_x5u_path_restrictions
unsigned int curl_timeout
enum relax_x5u_port_scheme_restrictions_enum relax_x5u_port_scheme_restrictions
unsigned int max_date_header_age
struct ast_acl_list * acl
Time-related functions and macros.
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compress two struct timeval instances returning -1, 0, 1 if the first arg is smaller,...
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
int ast_file_is_readable(const char *filename)
Test that a file exists and is readable by the effective user.
#define ARRAY_IN_BOUNDS(v, a)
Checks to see if value is within the bounds of the given array.
void ast_sha1_hash(char *output, const char *input)
Produces SHA1 hash based on input string.
static enum ast_stir_shaken_vs_response_code retrieve_cert_from_url(struct ast_stir_shaken_vs_ctx *ctx)
static regex_t url_match_regex
enum ast_stir_shaken_vs_response_code ast_stir_shaken_vs_ctx_add_date_hdr(struct ast_stir_shaken_vs_ctx *ctx, const char *date_hdr)
Add the received Date header value to the VS context.
static const char * vs_rc_map[]
static int check_x5u_url(struct ast_stir_shaken_vs_ctx *ctx, const char *x5u)
#define FULL_URL_REGEX_GROUPS
#define URL_MATCH_USERPASS
#define IS_GET_OBJ_ERR(ret)
static int is_cert_cache_entry_expired(char *expiration)
static enum ast_stir_shaken_vs_response_code check_cert(struct ast_stir_shaken_vs_ctx *ctx)
enum stir_shaken_failure_action_enum ast_stir_shaken_vs_get_failure_action(struct ast_stir_shaken_vs_ctx *ctx)
Get failure_action from context.
const char * vs_response_code_to_str(enum ast_stir_shaken_vs_response_code vs_rc)
Return string version of VS response code.
#define get_match_string(__x5u, __pmatch, __i)
#define ASN1_TAG_TNAUTH_SPC
static enum ast_stir_shaken_vs_response_code retrieve_verification_cert(struct ast_stir_shaken_vs_ctx *ctx)
static int add_cert_expiration_to_astdb(struct ast_stir_shaken_vs_ctx *cert, const char *cache_control_header, const char *expires_header)
static enum ast_stir_shaken_vs_response_code check_date_header(struct ast_stir_shaken_vs_ctx *ctx)
enum ast_stir_shaken_vs_response_code ast_stir_shaken_vs_verify(struct ast_stir_shaken_vs_ctx *ctx)
Perform incoming call verification.
int ast_stir_shaken_vs_get_use_rfc9410_responses(struct ast_stir_shaken_vs_ctx *ctx)
Get use_rfc9410_responses from context.
#define URL_MATCH_FRAGMENT
enum ast_stir_shaken_vs_response_code ast_stir_shaken_vs_ctx_create(const char *caller_id, struct ast_channel *chan, const char *profile_name, const char *tag, struct ast_stir_shaken_vs_ctx **ctxout)
Create Verification Service context.
enum ast_stir_shaken_vs_response_code ast_stir_shaken_vs_ctx_add_identity_hdr(struct ast_stir_shaken_vs_ctx *ctx, const char *identity_hdr)
Add the received Identity header value to the VS context.
static void ctx_destructor(void *obj)
static int add_cert_key_to_astdb(struct ast_stir_shaken_vs_ctx *cert, const char *cache_control_hdr, const char *expires_hdr)
#define BEGIN_CERTIFICATE_STR
static enum ast_stir_shaken_vs_response_code check_tn_auth_list(struct ast_stir_shaken_vs_ctx *ctx)
int vs_load()
Load the stir/shaken verification service.
int vs_unload()
Unload the stir/shaken verification service.
void ast_stir_shaken_vs_ctx_set_response_code(struct ast_stir_shaken_vs_ctx *ctx, enum ast_stir_shaken_vs_response_code vs_rc)
Sets response code on VS context.
int vs_reload()
Reload the stir/shaken verification service.
static enum ast_stir_shaken_vs_response_code retrieve_cert_from_cache(struct ast_stir_shaken_vs_ctx *ctx)
static void cleanup_cert_from_astdb_and_fs(struct ast_stir_shaken_vs_ctx *ctx)
static enum ast_stir_shaken_vs_response_code ctx_populate(struct ast_stir_shaken_vs_ctx *ctx)