26#define _TRACE_PREFIX_ "v",__LINE__, "" 
   46#define AST_DB_FAMILY "STIR_SHAKEN" 
   51#define BEGIN_CERTIFICATE_STR "-----BEGIN CERTIFICATE-----" 
  113    const char *cache_control_header, 
const char *expires_header)
 
  118    time_t current_time = time(
NULL);
 
  119    time_t max_age_hdr = 0;
 
  120    time_t expires_hdr = 0;
 
  121    ASN1_TIME *notAfter = 
NULL;
 
  122    time_t cert_expires = 0;
 
  123    time_t config_expires = 0;
 
  127    config_expires = current_time + cfg->vcfg_common.max_cache_entry_age;
 
  132        str_max_age = strstr(cache_control_header, 
"s-maxage");
 
  134            str_max_age = strstr(cache_control_header, 
"max-age");
 
  139            char *equal = strchr(str_max_age, 
'=');
 
  141                max_age_hdr = current_time + m;
 
  147        struct ast_tm expires_time;
 
  149        ast_strptime(expires_header, 
"%a, %d %b %Y %T %z", &expires_time);
 
  151        expires_hdr = 
ast_mktime(&expires_time, 
"GMT").tv_sec;
 
  154    notAfter = X509_get_notAfter(cert->
xcert);
 
  173    expires = config_expires;
 
  175    if (max_age_hdr > expires) {
 
  176        expires = max_age_hdr;
 
  179    if (expires_hdr > expires) {
 
  180        expires = expires_hdr;
 
  187    if (cert_expires && cert_expires < expires) {
 
  188        expires = cert_expires;
 
  191    snprintf(time_buf, 
sizeof(time_buf), 
"%ld", expires);
 
 
  202    const char *cache_control_hdr, 
const char *expires_hdr)
 
 
  227    struct timeval current_time = 
ast_tvnow();
 
  228    struct timeval expires = { .tv_sec = 0, .tv_usec = 0 };
 
  230    SCOPE_ENTER(3, 
"Checking for cache expiration: %s\n", expiration);
 
  240    ast_trace(2, 
"Expiration comparison: exp: %" PRIu64 
"  curr: %" PRIu64 
"  Diff: %" PRIu64 
".\n",
 
  241        expires.tv_sec, current_time.tv_sec, expires.tv_sec - current_time.tv_sec);
 
  243    res = (
ast_tvcmp(current_time, expires) == -1 ? 0 : 1);
 
 
  247#define ASN1_TAG_TNAUTH_SPC 0 
  248#define ASN1_TAG_TNAUTH_TN_RANGE 1 
  249#define ASN1_TAG_TNAUTH_TN 2 
  251#define IS_GET_OBJ_ERR(ret) (ret & 0x80) 
  256    ASN1_OCTET_STRING *tn_exten;
 
  257    const unsigned char* octet_str_data = 
NULL;
 
  266            LOG_ERROR, 
"%s: Cert '%s' doesn't have a TNAuthList extension\n",
 
  269    octet_str_data = tn_exten->data;
 
  272    ret = ASN1_get_object(&octet_str_data, &xlen, &tag, &xclass, tn_exten->length);
 
  279    if (ret != V_ASN1_CONSTRUCTED || tag != V_ASN1_SEQUENCE) {
 
  281            LOG_ERROR, 
"%s: Cert '%s' has malformed TNAuthList extension (tag %d != V_ASN1_SEQUENCE)\n",
 
  296    ret = ASN1_get_object(&octet_str_data, &xlen, &tag, &xclass, tn_exten->length);
 
  305            LOG_ERROR, 
"%s: Cert '%s' has malformed TNAuthList extension (tag %d != ASN1_TAG_TNAUTH_SPC(0))\n",
 
  310    ret = ASN1_get_object(&octet_str_data, &xlen, &tag, &xclass, tn_exten->length);
 
  313            LOG_ERROR, 
"%s: Cert '%s' has malformed TNAuthList extension (no SPC)\n",
 
 
  338            LOG_ERROR, 
"%s: Cert '%s' has no commonName(CN) in Subject '%s'\n",
 
  347    ast_trace(3,
"%s: Checking ctx against CA ctx\n", ctx->
tag);
 
  349        ctx->cert_chain, &err_msg);
 
  352            LOG_ERROR, 
"%s: Cert '%s' not trusted: %s\n",
 
  356    ast_trace(3,
"%s: Attempting to get the raw pubkey\n", ctx->
tag);
 
  361            LOG_ERROR, 
"%s: Unable to extract raw public key from '%s'\n",
 
  365    ast_trace(3,
"%s: Checking cert '%s' validity dates\n",
 
  369            LOG_ERROR, 
"%s: Cert '%s' dates not valid\n",
 
  374        "%s: Cert '%s' with SPC: %s CN: %s is valid\n",
 
 
  392    const char *cache_control;
 
  394    SCOPE_ENTER(2, 
"%s: Attempting to retrieve '%s' from net\n",
 
  397    if (!
header_data || !write_data || !open_socket_data) {
 
  399            LOG_ERROR, 
"%s: Unable to allocate memory for curl '%s' transaction\n",
 
  405    write_data->max_download_bytes = 8192;
 
  406    write_data->stream_buffer = 
NULL;
 
  410    if (!
header_data->debug_info || !write_data->debug_info ||
 
  411        !open_socket_data->debug_info) {
 
  413            LOG_ERROR, 
"%s: Unable to allocate memory for curl '%s' transaction\n",
 
  421    if (http_code / 100 != 2) {
 
  423            LOG_ERROR, 
"%s: Failed to retrieve cert %s: code %ld\n",
 
  429            LOG_ERROR, 
"%s: Cert '%s' contains invalid data\n",
 
  434        write_data->stream_bytes_downloaded, &ctx->cert_chain);
 
  437            LOG_ERROR, 
"%s: Cert '%s' was not parseable as an X509 certificate\n",
 
  443        X509_free(ctx->
xcert);
 
  449    cert_file = fopen(ctx->
filename, 
"w");
 
  451        X509_free(ctx->
xcert);
 
  454            LOG_ERROR, 
"%s: Failed to write cert %s: file '%s' %s (%d)\n",
 
  458    rc = fputs(write_data->stream_buffer, cert_file);
 
  461        X509_free(ctx->
xcert);
 
  464            LOG_ERROR, 
"%s: Failed to write cert %s: file '%s' %s (%d)\n",
 
  468    ast_trace(2, 
"%s: Cert '%s' written to file '%s'\n",
 
  471    ast_trace(2, 
"%s: Adding cert '%s' to astdb",
 
  478        X509_free(ctx->
xcert);
 
  481            LOG_ERROR, 
"%s: Unable to add cert '%s' to ASTDB\n",
 
  486        "%s: Cert '%s' successfully retrieved from internet and cached\n",
 
 
  496    SCOPE_ENTER(2, 
"%s: Attempting to retrieve cert '%s' from cache\n",
 
  502            "%s: No cert found in astdb for '%s'\n",
 
  510            "%s: No cert found in astdb for '%s'\n",
 
  517            "%s: Cert file '%s' was not found or was not readable for '%s'\n",
 
  524            "%s: Cert file '%s' cache entry was expired for '%s'\n",
 
  532            "%s: Cert file '%s' was not parseable as an X509 certificate for '%s'\n",
 
  538        X509_free(ctx->
xcert);
 
  545        "%s: Cert '%s' successfully retrieved from cache\n",
 
 
  589    ast_trace(1, 
"%s: No valid cert for '%s' available in cache\n",
 
  591    ast_trace(1, 
"%s: Retrieving cert directly from url '%s'\n",
 
  601        "%s: Unable to retrieve cert '%s' from cache or internet\n",
 
 
  615    const char *date_hdr)
 
 
  654    X509_free(ctx->
xcert);
 
  655    sk_X509_free(ctx->cert_chain);
 
 
  672    if (vs->global_disable) {
 
  674            "%s: Globally disabled\n", t);
 
  679            "%s: Disabled due to missing profile name\n", t);
 
  685        LOG_ERROR, 
"%s: No profile for profile name '%s'.  Call will continue\n", 
tag,
 
  691            "%s: Disabled by profile '%s'\n", t, profile_name);
 
  718    ctx->eprofile = profile;
 
 
  729    struct ast_tm date_hdr_tm;
 
  730    struct timeval date_hdr_timeval;
 
  731    struct timeval current_timeval;
 
  733    char timezone[80] = { 0 };
 
  741                "%s: ignore_sip_date_header set\n", ctx->
tag);
 
  749            LOG_ERROR, 
"%s: Failed to parse: '%s'\n",
 
  753    sscanf(remainder, 
"%79s", timezone);
 
  757            LOG_ERROR, 
"%s: A timezone is required: '%s'\n",
 
  761    date_hdr_timeval = 
ast_mktime(&date_hdr_tm, timezone);
 
  765    time_diff = 
ast_tvdiff_ms(current_timeval, date_hdr_timeval);
 
  766    ast_trace(3, 
"%zu  %zu  %zu %d\n", current_timeval.tv_sec,
 
  767        date_hdr_timeval.tv_sec,
 
  768        (current_timeval.tv_sec - date_hdr_timeval.tv_sec), (
int)time_diff);
 
  776            LOG_ERROR, 
"%s: More than %u seconds old: '%s'\n",
 
 
  784#define FULL_URL_REGEX   "^([a-zA-Z]+)://(([^@]+@[^:]+):)?(([^:/?]+)|([0-9.]+)|([[][0-9a-fA-F:]+[]]))(:([0-9]+))?(/([^#\\?]+))?(\\?([^#]+))?(#(.*))?" 
  785#define FULL_URL_REGEX_GROUPS 15 
  803#define URL_MATCH_SCHEME   1 
  804#define URL_MATCH_USERPASS 3 
  805#define URL_MATCH_HOST     4 
  806#define URL_MATCH_PORT     9 
  807#define URL_MATCH_PATH     11 
  808#define URL_MATCH_QUERY    13 
  809#define URL_MATCH_FRAGMENT 15 
  811#define get_match_string(__x5u, __pmatch, __i) \ 
  813    char *__match = NULL; \ 
  814    if (__pmatch[__i].rm_so >= 0) { \ 
  815        regoff_t __len = __pmatch[__i].rm_eo - __pmatch[__i].rm_so; \ 
  816        const char *__start = __x5u + __pmatch[__i].rm_so; \ 
  817        __match = ast_alloca(__len + 1); \ 
  818        ast_copy_string(__match, __start, __len + 1); \ 
 
  823#define DUMP_X5U_MATCH() \ 
  826    if (TRACE_ATLEAST(4)) { \ 
  827        ast_trace(-1, "%s: x5u: %s\n", ctx->tag, x5u); \ 
  828        for (i=0;i<FULL_URL_REGEX_GROUPS;i++) { \ 
  829            const char *m = get_match_string(x5u, pmatch, i); \ 
  831                ast_trace(-1, "%s: %2d %s\n", ctx->tag, i, m); \ 
 
  841    regmatch_t pmatch[max_groups];
 
  847        char regex_error[512];
 
  850            "%s: x5u '%s' in Identity header failed basic URL validation: %s\n",
 
  851            ctx->
tag, x5u, regex_error);
 
  855        != relax_x5u_port_scheme_restrictions_YES) {
 
  862                "%s: x5u '%s': scheme '%s' not https\n",
 
  863                ctx->
tag, x5u, scheme);
 
  870                    "%s: x5u '%s': port '%s' not port 443 or 8443\n",
 
  871                    ctx->
tag, x5u, port);
 
  877        != relax_x5u_path_restrictions_YES) {
 
  886                "%s: x5u '%s' contains user:password, query parameters or fragment\n",
 
 
  901    char *grants_str = 
NULL;
 
  903    const char *ppt_header = 
NULL;
 
  904    const char *grant = 
NULL;
 
  905    time_t now_s = time(
NULL);
 
  915            "%s: No context object!\n", 
"NULL");
 
  920            "%s: No identity header in ctx\n", ctx->
tag);
 
  926            LOG_ERROR, 
"%s: Malformed identity header\n", ctx->
tag);
 
  933            "%s: Failed to allocate memory for encoded jwt\n", ctx->
tag);
 
  937    jwt_encoded[
len - 1] = 
'\0';
 
  939    rc = jwt_decode(&jwt, jwt_encoded, 
NULL, 0);
 
  945    ppt_header = jwt_get_header(jwt, 
"ppt");
 
  954            "%s: Date header verification failed\n", ctx->
tag);
 
  957    x5u = jwt_get_header(jwt, 
"x5u");
 
  960            "%s: No x5u in Identity header\n", ctx->
tag);
 
  966            "%s: x5u URL verification failed\n", ctx->
tag);
 
  969    ast_trace(3, 
"%s: Decoded enough to get x5u: '%s'\n", ctx->
tag, x5u);
 
  972            "%s: Failed to set public_url '%s'\n", ctx->
tag, x5u);
 
  975    iat = jwt_get_grant_int(jwt, 
"iat");
 
  978            "%s: No 'iat' in Identity header\n", ctx->
tag);
 
  985            "%s: iat %ld older than %u seconds\n", ctx->
tag,
 
  993            "%s: Unable to populate ctx\n", ctx->
tag);
 
  999            "%s: Could not get valid cert from '%s'\n", ctx->
tag, ctx->
public_url);
 
 1008            LOG_ERROR, 
"%s: Signature validation failed for '%s'\n",
 
 1014    ppt_header = jwt_get_header(jwt, 
"alg");
 
 1017            "%s: %s\n", ctx->
tag,
 
 1021    ppt_header = jwt_get_header(jwt, 
"ppt");
 
 1024            "%s: %s\n", ctx->
tag,
 
 1028    ppt_header = jwt_get_header(jwt, 
"typ");
 
 1031            "%s: %s\n", ctx->
tag,
 
 1035    grants_str = jwt_get_grants_json(jwt, 
NULL);
 
 1038            "%s: %s\n", ctx->
tag,
 
 1041    ast_trace(1, 
"grants: %s\n", grants_str);
 
 1046            "%s: %s\n", ctx->
tag,
 
 1053            "%s: No 'attest' in Identity header\n", ctx->
tag);
 
 1055    if (grant[0] < 
'A' || grant[0] > 
'C') {
 
 1057            "%s: Invalid attest value '%s'\n", ctx->
tag, grant);
 
 1060    ast_trace(1, 
"got attest: %s\n", grant);
 
 1065            "%s: No 'dest' in Identity header\n", ctx->
tag);
 
 1076            "%s: No 'orig' in Identity header\n", ctx->
tag);
 
 1086            "%s: No 'orig.tn' in Indentity header\n", ctx->
tag);
 
 1091            "%s: Mismatched cid '%s' and orig_tn '%s'\n", ctx->
tag,
 
 1098            "%s: No 'origid' in Identity header\n", ctx->
tag);
 
 1102        "%s: verification succeeded\n", ctx->
tag);
 
 
 1132        char regex_error[512];
 
 1134        ast_log(
LOG_ERROR, 
"Verification service URL regex failed to compile: %s\n", regex_error);
 
 1139        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_chain_from_memory(const char *buffer, size_t size, STACK_OF(X509) **cert_chain)
Load an X509 Cert and any chained certs from a NULL terminated buffer.
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.
X509 * crypto_load_cert_chain_from_file(const char *filename, STACK_OF(X509) **cert_chain)
Load an X509 Cert and any chained certs from a file.
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.
int crypto_is_cert_trusted(struct crypto_cert_store *store, X509 *cert, STACK_OF(X509) *cert_chain, const char **err_msg)
Check if the cert is trusted.
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_INVALID_OR_NO_CID
@ 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 ignore_sip_date_header_enum ignore_sip_date_header
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
const char * ast_stir_shaken_vs_get_caller_id(struct ast_stir_shaken_vs_ctx *ctx)
Get caller_id from context.
#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)