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);
351 LOG_ERROR,
"%s: Cert '%s' not trusted: %s\n",
355 ast_trace(3,
"%s: Attempting to get the raw pubkey\n", ctx->
tag);
360 LOG_ERROR,
"%s: Unable to extract raw public key from '%s'\n",
364 ast_trace(3,
"%s: Checking cert '%s' validity dates\n",
368 LOG_ERROR,
"%s: Cert '%s' dates not valid\n",
373 "%s: Cert '%s' with SPC: %s CN: %s is valid\n",
391 const char *cache_control;
393 SCOPE_ENTER(2,
"%s: Attempting to retrieve '%s' from net\n",
396 if (!
header_data || !write_data || !open_socket_data) {
398 LOG_ERROR,
"%s: Unable to allocate memory for curl '%s' transaction\n",
404 write_data->max_download_bytes = 8192;
405 write_data->stream_buffer =
NULL;
409 if (!
header_data->debug_info || !write_data->debug_info ||
410 !open_socket_data->debug_info) {
412 LOG_ERROR,
"%s: Unable to allocate memory for curl '%s' transaction\n",
420 if (http_code / 100 != 2) {
422 LOG_ERROR,
"%s: Failed to retrieve cert %s: code %ld\n",
428 LOG_ERROR,
"%s: Cert '%s' contains invalid data\n",
433 write_data->stream_bytes_downloaded);
436 LOG_ERROR,
"%s: Cert '%s' was not parseable as an X509 certificate\n",
442 X509_free(ctx->
xcert);
448 cert_file = fopen(ctx->
filename,
"w");
450 X509_free(ctx->
xcert);
453 LOG_ERROR,
"%s: Failed to write cert %s: file '%s' %s (%d)\n",
457 rc = fputs(write_data->stream_buffer, cert_file);
460 X509_free(ctx->
xcert);
463 LOG_ERROR,
"%s: Failed to write cert %s: file '%s' %s (%d)\n",
467 ast_trace(2,
"%s: Cert '%s' written to file '%s'\n",
470 ast_trace(2,
"%s: Adding cert '%s' to astdb",
477 X509_free(ctx->
xcert);
480 LOG_ERROR,
"%s: Unable to add cert '%s' to ASTDB\n",
485 "%s: Cert '%s' successfully retrieved from internet and cached\n",
495 SCOPE_ENTER(2,
"%s: Attempting to retrieve cert '%s' from cache\n",
501 "%s: No cert found in astdb for '%s'\n",
509 "%s: No cert found in astdb for '%s'\n",
516 "%s: Cert file '%s' was not found or was not readable for '%s'\n",
523 "%s: Cert file '%s' cache entry was expired for '%s'\n",
531 "%s: Cert file '%s' was not parseable as an X509 certificate for '%s'\n",
537 X509_free(ctx->
xcert);
544 "%s: Cert '%s' successfully retrieved from cache\n",
588 ast_trace(1,
"%s: No valid cert for '%s' available in cache\n",
590 ast_trace(1,
"%s: Retrieving cert directly from url '%s'\n",
600 "%s: Unable to retrieve cert '%s' from cache or internet\n",
614 const char *date_hdr)
653 X509_free(ctx->
xcert);
670 if (vs->global_disable) {
672 "%s: Globally disabled\n", t);
677 "%s: Disabled due to missing profile name\n", t);
683 LOG_ERROR,
"%s: No profile for profile name '%s'. Call will continue\n",
tag,
689 "%s: Disabled by profile '%s'\n", t, profile_name);
716 ctx->eprofile = profile;
727 struct ast_tm date_hdr_tm;
728 struct timeval date_hdr_timeval;
729 struct timeval current_timeval;
731 char timezone[80] = { 0 };
738 LOG_ERROR,
"%s: Failed to parse: '%s'\n",
742 sscanf(remainder,
"%79s", timezone);
746 LOG_ERROR,
"%s: A timezone is required: '%s'\n",
750 date_hdr_timeval =
ast_mktime(&date_hdr_tm, timezone);
754 time_diff =
ast_tvdiff_ms(current_timeval, date_hdr_timeval);
755 ast_trace(3,
"%zu %zu %zu %d\n", current_timeval.tv_sec,
756 date_hdr_timeval.tv_sec,
757 (current_timeval.tv_sec - date_hdr_timeval.tv_sec), (
int)time_diff);
765 LOG_ERROR,
"%s: More than %u seconds old: '%s'\n",
773#define FULL_URL_REGEX "^([a-zA-Z]+)://(([^@]+@[^:]+):)?(([^:/?]+)|([0-9.]+)|([[][0-9a-fA-F:]+[]]))(:([0-9]+))?(/([^#\\?]+))?(\\?([^#]+))?(#(.*))?"
774#define FULL_URL_REGEX_GROUPS 15
792#define URL_MATCH_SCHEME 1
793#define URL_MATCH_USERPASS 3
794#define URL_MATCH_HOST 4
795#define URL_MATCH_PORT 9
796#define URL_MATCH_PATH 11
797#define URL_MATCH_QUERY 13
798#define URL_MATCH_FRAGMENT 15
800#define get_match_string(__x5u, __pmatch, __i) \
802 char *__match = NULL; \
803 if (__pmatch[__i].rm_so >= 0) { \
804 regoff_t __len = __pmatch[__i].rm_eo - __pmatch[__i].rm_so; \
805 const char *__start = __x5u + __pmatch[__i].rm_so; \
806 __match = ast_alloca(__len + 1); \
807 ast_copy_string(__match, __start, __len + 1); \
812#define DUMP_X5U_MATCH() \
815 if (TRACE_ATLEAST(4)) { \
816 ast_trace(-1, "%s: x5u: %s\n", ctx->tag, x5u); \
817 for (i=0;i<FULL_URL_REGEX_GROUPS;i++) { \
818 const char *m = get_match_string(x5u, pmatch, i); \
820 ast_trace(-1, "%s: %2d %s\n", ctx->tag, i, m); \
830 regmatch_t pmatch[max_groups];
836 char regex_error[512];
839 "%s: x5u '%s' in Identity header failed basic URL validation: %s\n",
840 ctx->
tag, x5u, regex_error);
844 != relax_x5u_port_scheme_restrictions_YES) {
851 "%s: x5u '%s': scheme '%s' not https\n",
852 ctx->
tag, x5u, scheme);
859 "%s: x5u '%s': port '%s' not port 443 or 8443\n",
860 ctx->
tag, x5u, port);
866 != relax_x5u_path_restrictions_YES) {
875 "%s: x5u '%s' contains user:password, query parameters or fragment\n",
890 char *grants_str =
NULL;
892 const char *ppt_header =
NULL;
893 const char *grant =
NULL;
894 time_t now_s = time(
NULL);
904 "%s: No context object!\n",
"NULL");
909 "%s: No identity header in ctx\n", ctx->
tag);
917 "%s: Failed to allocate memory for encoded jwt\n", ctx->
tag);
921 jwt_encoded[
len - 1] =
'\0';
923 jwt_decode(&jwt, jwt_encoded,
NULL, 0);
925 ppt_header = jwt_get_header(jwt,
"ppt");
934 "%s: Date header verification failed\n", ctx->
tag);
937 x5u = jwt_get_header(jwt,
"x5u");
940 "%s: No x5u in Identity header\n", ctx->
tag);
946 "%s: x5u URL verification failed\n", ctx->
tag);
949 ast_trace(3,
"%s: Decoded enough to get x5u: '%s'\n", ctx->
tag, x5u);
952 "%s: Failed to set public_url '%s'\n", ctx->
tag, x5u);
955 iat = jwt_get_grant_int(jwt,
"iat");
958 "%s: No 'iat' in Identity header\n", ctx->
tag);
960 ast_trace(1,
"date_hdr: %zu iat: %zu diff: %zu\n",
964 "%s: iat %ld older than %u seconds\n", ctx->
tag,
972 "%s: Unable to populate ctx\n", ctx->
tag);
978 "%s: Could not get valid cert from '%s'\n", ctx->
tag, ctx->
public_url);
987 LOG_ERROR,
"%s: Signature validation failed for '%s'\n",
993 ppt_header = jwt_get_header(jwt,
"alg");
996 "%s: %s\n", ctx->
tag,
1000 ppt_header = jwt_get_header(jwt,
"ppt");
1003 "%s: %s\n", ctx->
tag,
1007 ppt_header = jwt_get_header(jwt,
"typ");
1010 "%s: %s\n", ctx->
tag,
1014 grants_str = jwt_get_grants_json(jwt,
NULL);
1017 "%s: %s\n", ctx->
tag,
1020 ast_trace(1,
"grants: %s\n", grants_str);
1025 "%s: %s\n", ctx->
tag,
1032 "%s: No 'attest' in Identity header\n", ctx->
tag);
1034 if (grant[0] <
'A' || grant[0] >
'C') {
1036 "%s: Invalid attest value '%s'\n", ctx->
tag, grant);
1039 ast_trace(1,
"got attest: %s\n", grant);
1044 "%s: No 'dest' in Identity header\n", ctx->
tag);
1055 "%s: No 'orig' in Identity header\n", ctx->
tag);
1065 "%s: No 'orig.tn' in Indentity header\n", ctx->
tag);
1070 "%s: Mismatched cid '%s' and orig_tn '%s'\n", ctx->
tag,
1077 "%s: No 'origid' in Identity header\n", ctx->
tag);
1081 "%s: verification succeeded\n", ctx->
tag);
1111 char regex_error[512];
1113 ast_log(
LOG_ERROR,
"Verification service URL regex failed to compile: %s\n", regex_error);
1118 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_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 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)