28 #include <openssl/evp.h> 147 #define AST_DB_FAMILY "STIR_SHAKEN" 150 #define STIR_SHAKEN_DIR_NAME "stir_shaken" 153 #define MAX_PATH_LEN 256 158 #define EXPIRATION_BUFFER 15 220 return "Verification not present";
222 return "Signature failed";
224 return "Verification mismatch";
226 return "Verification passed";
273 .
type =
"STIR/SHAKEN VERIFICATION",
282 const char *chan_name;
285 ast_log(
LOG_ERROR,
"Channel is required to add STIR/SHAKEN verification\n");
292 ast_log(
LOG_ERROR,
"No identity to add STIR/SHAKEN verification to channel " 298 ast_log(
LOG_ERROR,
"Attestation cannot be NULL to add STIR/SHAKEN verification to " 299 "channel %s\n", chan_name);
303 ss_datastore =
ast_calloc(1,
sizeof(*ss_datastore));
305 ast_log(
LOG_ERROR,
"Failed to allocate space for STIR/SHAKEN datastore for " 306 "channel %s\n", chan_name);
313 "identity for channel %s\n", chan_name);
321 "attestation for channel %s\n", chan_name);
336 datastore->
data = ss_datastore;
356 struct timeval actual_expires =
ast_tvnow();
365 str_max_age = strstr(value,
"s-maxage");
367 str_max_age = strstr(value,
"max-age");
371 unsigned int max_age;
372 char *equal = strchr(str_max_age,
'=');
374 actual_expires.tv_sec += max_age;
380 struct tm expires_time;
382 strptime(value,
"%a, %d %b %Y %T %z", &expires_time);
383 expires_time.tm_isdst = -1;
384 actual_expires.tv_sec = mktime(&expires_time);
392 snprintf(time_buf,
sizeof(time_buf),
"%30lu", actual_expires.tv_sec);
407 struct timeval current_time =
ast_tvnow();
408 struct timeval expires = { .tv_sec = 0, .tv_usec = 0 };
413 ast_db_get(hash,
"expiration", expiration,
sizeof(expiration));
423 return ast_tvcmp(current_time, expires) == -1 ? 0 : 1;
441 ast_db_get(hash,
"path", file_path,
sizeof(file_path));
479 ast_db_get(hash,
"path", filepath,
sizeof(filepath));
500 EVP_MD_CTX *mdctx =
NULL;
502 unsigned char *decoded_signature;
503 size_t signature_length, decoded_signature_length;
505 mdctx = EVP_MD_CTX_create();
511 ret = EVP_DigestVerifyInit(mdctx,
NULL, EVP_sha256(),
NULL, public_key);
514 EVP_MD_CTX_destroy(mdctx);
518 ret = EVP_DigestVerifyUpdate(mdctx, (
unsigned char *)msg, strlen(msg));
521 EVP_MD_CTX_destroy(mdctx);
527 signature_length = strlen(signature);
528 decoded_signature_length = (signature_length * 3 / 4);
529 decoded_signature =
ast_calloc(1, decoded_signature_length);
532 ret = EVP_DigestVerifyFinal(mdctx, decoded_signature, decoded_signature_length);
535 EVP_MD_CTX_destroy(mdctx);
540 EVP_MD_CTX_destroy(mdctx);
570 ast_log(
LOG_ERROR,
"Could not retrieve public key for '%s'\n", public_cert_url);
603 filename =
run_curl(public_cert_url, path);
624 EVP_PKEY *public_key;
629 size_t combined_size;
642 ast_log(
LOG_ERROR,
"'signature' is required for STIR/SHAKEN verification\n");
647 ast_log(
LOG_ERROR,
"'algorithm' is required for STIR/SHAKEN verification\n");
652 ast_log(
LOG_ERROR,
"'public_cert_url' is required for STIR/SHAKEN verification\n");
682 file_path =
run_curl(public_cert_url, dir_path);
699 ast_debug(3,
"Public cert '%s' is expired\n", public_cert_url);
716 ast_debug(3,
"Failed first read of public key file '%s'\n", file_path);
735 combined_size = strlen(header) + strlen(payload) + 2;
739 EVP_PKEY_free(public_key);
742 snprintf(combined_str, combined_size,
"%s.%s", header, payload);
745 EVP_PKEY_free(public_key);
750 EVP_PKEY_free(public_key);
752 ret_payload =
ast_calloc(1,
sizeof(*ret_payload));
759 if (!ret_payload->
header) {
803 ast_log(
LOG_ERROR,
"STIR/SHAKEN JWT did not have the required field 'header'\n");
816 ast_log(
LOG_ERROR,
"STIR/SHAKEN JWT did not have the required field 'ppt'\n");
828 ast_log(
LOG_ERROR,
"STIR/SHAKEN JWT did not have the required field 'typ'\n");
858 ast_log(
LOG_ERROR,
"STIR/SHAKEN payload JWT did not have required field 'payload'\n");
865 ast_log(
LOG_ERROR,
"STIR/SHAKEN JWT did not have required field 'orig->tn'\n");
894 EVP_MD_CTX *mdctx =
NULL;
896 unsigned char *encoded_signature =
NULL;
898 size_t encoded_length = 0;
899 size_t signature_length = 0;
901 mdctx = EVP_MD_CTX_create();
907 ret = EVP_DigestSignInit(mdctx,
NULL, EVP_sha256(),
NULL, private_key);
913 ret = EVP_DigestSignUpdate(mdctx, json_str, strlen(json_str));
919 ret = EVP_DigestSignFinal(mdctx,
NULL, &signature_length);
921 ast_log(
LOG_ERROR,
"Failed initial phase of Message Digest Context signing\n");
925 signature =
ast_calloc(1,
sizeof(
unsigned char) * signature_length);
931 ret = EVP_DigestSignFinal(mdctx, signature, &signature_length);
933 ast_log(
LOG_ERROR,
"Failed final phase of Message Digest Context signing\n");
942 encoded_length = ((signature_length * 4 / 3 + 3) & ~3) + 1;
943 encoded_signature =
ast_calloc(1, encoded_length);
944 if (!encoded_signature) {
953 EVP_MD_CTX_destroy(mdctx);
957 return encoded_signature;
1040 timestamp = tv.tv_sec + tv.tv_usec / 1000;
1051 const char *caller_id_num;
1068 if (!caller_id_num) {
1076 "'%s'\n", caller_id_num);
1107 msg_len = strlen(header) + strlen(payload) + 2;
1113 snprintf(msg, msg_len,
"%s.%s", header, payload);
1146 char *data,
char *
buf,
size_t len)
1153 unsigned int target_index, current_index = 0;
1182 if (!strcasecmp(first,
"count")) {
1193 if (datastore->
info != &stir_shaken_datastore_info) {
1200 snprintf(buf, len,
"%zu", count);
1208 ast_log(
LOG_ERROR,
"Retrieving a value using %s requires two paramaters (index, value) " 1209 "- only index was given\n",
function);
1214 ast_log(
LOG_ERROR,
"Failed to convert index %s to integer for function %s\n",
1222 if (datastore->
info != &stir_shaken_datastore_info) {
1226 if (current_index == target_index) {
1233 if (current_index != target_index || !datastore) {
1237 ss_datastore = datastore->
data;
1239 if (!strcasecmp(second,
"identity")) {
1241 }
else if (!strcasecmp(second,
"attestation")) {
1243 }
else if (!strcasecmp(second,
"verify_result")) {
1254 .
name =
"STIR_SHAKEN",
1258 #ifdef TEST_FRAMEWORK 1268 snprintf(time_buf,
sizeof(time_buf),
"%30lu", expires.tv_sec + 300);
1287 char *
type =
private ?
"private" :
"public";
1288 char *private_data =
1289 "-----BEGIN EC PRIVATE KEY-----\n" 1290 "MHcCAQEEIC+xv2GKNTDd81vJM8rwGAGNqgklKKxz9Qejn+pcRPC1oAoGCCqGSM49\n" 1291 "AwEHoUQDQgAEq12QXu8lH295ZMZ4udKy5VV8wVgE4qSOnkdofn3hEDsh6QTKTZg9\n" 1292 "W6PncYAVnmOFRL4cTGRbmAIShN4naZk2Yg==\n" 1293 "-----END EC PRIVATE KEY-----";
1295 "-----BEGIN CERTIFICATE-----\n" 1296 "MIIBzDCCAXGgAwIBAgIUXDt6EC0OixT1iRSSPV3jB/zQAlQwCgYIKoZIzj0EAwIw\n" 1297 "RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu\n" 1298 "dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTA0MTMwNjM3MjRaFw0yMzA3MTcw\n" 1299 "NjM3MjRaMGoxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJWQTESMBAGA1UEBwwJU29t\n" 1300 "ZXdoZXJlMRowGAYDVQQKDBFBY21lVGVsZWNvbSwgSW5jLjENMAsGA1UECwwEVk9J\n" 1301 "UDEPMA0GA1UEAwwGU0hBS0VOMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEq12Q\n" 1302 "Xu8lH295ZMZ4udKy5VV8wVgE4qSOnkdofn3hEDsh6QTKTZg9W6PncYAVnmOFRL4c\n" 1303 "TGRbmAIShN4naZk2YqMaMBgwFgYIKwYBBQUHARoECjAIoAYWBDEwMDEwCgYIKoZI\n" 1304 "zj0EAwIDSQAwRgIhAMa9Ky38DgVaIgVm9Mgws/qN3zxjMQXfxEExAbDwyq/WAiEA\n" 1305 "zbC29mvtSulwbvQJ4fBdFU84cFC3Ctu1QrCeFOiZHc4=\n" 1306 "-----END CERTIFICATE-----";
1308 fd = mkstemp(file_path);
1314 file = fdopen(fd,
"w");
1321 data =
private ? private_data : public_data;
1322 if (fputs(data, file) == EOF) {
1335 char *caller_id_number =
"1234567";
1336 char file_path[] =
"/tmp/stir_shaken_private.XXXXXX";
1337 RAII_VAR(
char *, rm_on_exit, file_path, unlink);
1343 info->name =
"stir_shaken_sign";
1344 info->category =
"/res/res_stir_shaken/";
1345 info->summary =
"STIR/SHAKEN sign unit test";
1347 "Tests signing a JWT with a private key.";
1358 json =
ast_json_pack(
"{s: {s: {s: s}}}",
"payload",
"orig",
"tn", caller_id_number);
1368 json =
ast_json_pack(
"{s: {s: s, s: s, s: s, s: s}}",
"header",
"alg",
1370 "x5u",
"http://testing123");
1380 json =
ast_json_pack(
"{s: {s: s, s: s, s: s}, s: {s: {s: s}}}",
"header",
"ppt",
1382 "orig",
"tn", caller_id_number);
1392 json =
ast_json_pack(
"{s: {s: s, s: s, s: s, s: s}, s: {s: {s: s}}}",
"header",
"alg",
1394 "x5u",
"http://testing123",
"payload",
"orig",
"tn", caller_id_number);
1404 json =
ast_json_pack(
"{s: {s: s, s: s, s: s}, s: {s: {s: s}}}",
"header",
"alg",
1406 "payload",
"orig",
"tn", caller_id_number);
1416 json =
ast_json_pack(
"{s: {s: s, s: s, s: s, s: s}, s: {s: {s: s}}}",
"header",
"alg",
1418 "x5u",
"http://testing123",
"payload",
"orig",
"tn", caller_id_number);
1428 json =
ast_json_pack(
"{s: {s: s, s: s, s: s}, s: {s: {s: s}}}",
"header",
"alg",
1430 "payload",
"orig",
"tn", caller_id_number);
1440 json =
ast_json_pack(
"{s: {s: s, s: s, s: s, s: s}, s: {s: {s: s}}}",
"header",
"alg",
1442 "x5u",
"http://testing123",
"payload",
"orig",
"tn", caller_id_number);
1452 json =
ast_json_pack(
"{s: {s: s, s: s, s: s, s: s}, s: {s: s}}",
"header",
"alg",
1454 "x5u",
"http://testing123",
"payload",
"filler",
"filler");
1464 json =
ast_json_pack(
"{s: {s: s, s: s, s: s, s: s}, s: {s: s}}",
"header",
"alg",
1466 "x5u",
"http://testing123",
"payload",
"orig",
"filler");
1476 json =
ast_json_pack(
"{s: {s: s, s: s, s: s, s: s}, s: {s: {s: s}}}",
"header",
"alg",
1478 "x5u",
"http://testing123",
"payload",
"orig",
"tn", caller_id_number);
1493 char *caller_id_number =
"1234567";
1498 char public_path[] =
"/tmp/stir_shaken_public.XXXXXX";
1499 char private_path[] =
"/tmp/stir_shaken_public.XXXXXX";
1500 RAII_VAR(
char *, rm_on_exit_public, public_path, unlink);
1501 RAII_VAR(
char *, rm_on_exit_private, private_path, unlink);
1508 info->name =
"stir_shaken_verify";
1509 info->category =
"/res/res_stir_shaken/";
1510 info->summary =
"STIR/SHAKEN verify unit test";
1512 "Tests verifying a signature with a public key";
1525 json =
ast_json_pack(
"{s: {s: s, s: s, s: s, s: s}, s: {s: {s: s}}}",
"header",
"alg",
1527 "x5u", public_cert_url,
"payload",
"orig",
"tn", caller_id_number);
1529 if (!signed_payload) {
1544 if (returned_payload) {
1553 if (returned_payload) {
1562 if (returned_payload) {
1570 "", public_cert_url);
1571 if (returned_payload) {
1580 if (returned_payload) {
1592 if (!returned_payload) {
1610 if (stir_shaken_sorcery) {
1626 stir_shaken_sorcery =
NULL;
1676 .requires =
"res_curl",
struct stir_shaken_general * stir_shaken_general_get()
Retrieve the stir/shaken 'general' configuration object.
static void stir_shaken_datastore_free(struct stir_shaken_datastore *datastore)
Frees a stir_shaken_datastore structure.
#define ast_channel_lock(chan)
Main Channel structure associated with a channel.
Asterisk main include file. File version handling, generic pbx functions.
int ast_stir_shaken_add_verification(struct ast_channel *chan, const char *identity, const char *attestation, enum ast_stir_shaken_verification_result result)
Add a STIR/SHAKEN verification result to a channel.
unsigned char * signature
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
static int stir_shaken_add_iat(struct ast_json *json)
Adds the 'iat' field to the JWT.
static const char * stir_shaken_verification_result_to_string(enum ast_stir_shaken_verification_result result)
Convert an ast_stir_shaken_verification_result to string representation.
static const struct ast_datastore_info stir_shaken_datastore_info
Time-related functions and macros.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
int stir_shaken_general_unload(void)
Unload time cleanup for the stir/shaken 'general' configuration.
void curl_cb_data_free(struct curl_cb_data *data)
Free a curl_cb_data struct.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
static unsigned char * stir_shaken_sign(char *json_str, EVP_PKEY *private_key)
Signs the payload and returns the signature.
static char * run_curl(const char *public_cert_url, const char *path)
CURL the file located at public_cert_url to the specified path.
static void stir_shaken_datastore_destroy_cb(void *data)
The callback to destroy a stir_shaken_datastore.
void ast_json_free(void *p)
Asterisk's custom JSON allocator. Exposed for use by unit tests.
EVP_PKEY * stir_shaken_read_key(const char *path, int priv)
Reads the public (or private) key from the specified path.
globally accessible channel datastores
static struct ast_sorcery * stir_shaken_sorcery
static void remove_public_key_from_astdb(const char *public_cert_url)
Remove the public key details and associated information from AstDB.
#define ast_json_dump_string(root)
Encode a JSON value to a compact string.
#define AST_TEST_REGISTER(cb)
Full structure for sorcery.
Structure for a data store type.
void ast_stir_shaken_payload_free(struct ast_stir_shaken_payload *payload)
Free a STIR/SHAKEN payload.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
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.
#define EXPIRATION_BUFFER
#define ast_strdup(str)
A wrapper for strdup()
Structure for a data store object.
unsigned char * ast_stir_shaken_payload_get_signature(const struct ast_stir_shaken_payload *payload)
Retrieve the value for 'signature' from an ast_stir_shaken_payload.
struct ast_sorcery * ast_stir_shaken_sorcery(void)
Retrieve the stir/shaken sorcery context.
char * ast_stir_shaken_payload_get_public_cert_url(const struct ast_stir_shaken_payload *payload)
Retrieve the value for 'public_cert_url' from an ast_stir_shaken_payload.
const char * stir_shaken_certificate_get_attestation(struct stir_shaken_certificate *cert)
Get the attestation level associated with a certificate.
static struct ast_custom_function stir_shaken_function
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
static void add_public_key_to_astdb(const char *public_cert_url, const char *filepath)
Add the public key details and file path to AstDB.
int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
Set a field in a JSON object.
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
#define ast_strlen_zero(foo)
AST_TEST_DEFINE(test_stir_shaken_sign)
unsigned int ast_stir_shaken_signature_timeout(const struct stir_shaken_general *cfg)
Retrieve the 'signature_timeout' general configuration option value.
#define ast_sorcery_unref(sorcery)
Decrease the reference count of a sorcery structure.
int stir_shaken_certificate_load(void)
Load time initialization for the stir/shaken 'certificate' configuration.
static char * curl_and_check_expiration(const char *public_cert_url, const char *path, int *curl)
Downloads the public cert from public_cert_url. If curl is non-zero, that signals CURL has already be...
#define ast_debug(level,...)
Log a DEBUG message.
int ast_base64url_decode(unsigned char *dst, const char *src, int max)
Decode data from base64 URL.
static struct ast_stir_shaken_payload * stir_shaken_verify_json(struct ast_json *json)
Verifies the necessary contents are in the JSON and returns a ast_stir_shaken_payload with the extrac...
char * curl_public_key(const char *public_cert_url, const char *path, struct curl_cb_data *data)
CURL the public key from the provided URL to the specified path.
Asterisk JSON abstraction layer.
Asterisk file paths, configured in asterisk.conf.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define ast_test_status_update(a, b, c...)
ast_stir_shaken_verification_result
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
Data structure associated with a custom dialplan function.
struct ast_stir_shaken_payload * ast_stir_shaken_sign(struct ast_json *json)
Sign a JSON STIR/SHAKEN payload.
static int stir_shaken_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
Retrieves STIR/SHAKEN verification information for the channel via dialplan. Examples: ...
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
struct ast_datastore_list * ast_channel_datastores(struct ast_channel *chan)
const struct ast_datastore_info * info
Conversion utility functions.
int stir_shaken_certificate_unload(void)
Unload time cleanup for the stir/shaken 'certificate' configuration.
#define ast_strdupa(s)
duplicate a string in memory from the stack
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
#define STIR_SHAKEN_ENCRYPTION_ALGORITHM
char * curl_cb_data_get_expires(const struct curl_cb_data *data)
Get the expires field from a curl_cb_data struct.
Core PBX routines and definitions.
char * curl_cb_data_get_cache_control(const struct curl_cb_data *data)
Get the cache_control field from a curl_cb_data struct.
void ast_sha1_hash(char *output, const char *input)
Produces SHA1 hash based on input string.
const char * ast_config_AST_DATA_DIR
int test_stir_shaken_create_cert(const char *caller_id_number, const char *file_path)
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compres two struct timeval instances returning -1, 0, 1 if the first arg is smaller, equal or greater to the second.
struct stir_shaken_certificate * stir_shaken_certificate_get_by_caller_id_number(const char *caller_id_number)
Get a STIR/SHAKEN certificate by caller ID number.
#define AST_TEST_UNREGISTER(cb)
static int stir_shaken_add_x5u(struct ast_json *json, const char *x5u)
Adds the 'x5u' (public key URL) field to the JWT.
int test_stir_shaken_cleanup_cert(const char *caller_id_number)
static int unload_module(void)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct sla_ringing_trunk * first
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
static int reload_module(void)
#define ast_channel_unlock(chan)
int ast_base64url_encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64 URL.
static void parse(struct mgcp_request *req)
#define ast_calloc(num, len)
A wrapper for calloc()
enum ast_stir_shaken_verification_result verify_result
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Module has failed to load, may be in an inconsistent state.
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
Get key value specified by family/key.
int ast_str_to_ulong(const char *str, unsigned long *res)
Convert the given string to an unsigned long.
int ast_str_to_uint(const char *str, unsigned int *res)
Convert the given string to an unsigned integer.
static void * cleanup(void *unused)
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
struct ast_json * payload
static void set_public_key_expiration(const char *public_cert_url, const struct curl_cb_data *data)
Sets the expiration for the public key based on the provided fields. If Cache-Control is present...
void ast_sorcery_load(const struct ast_sorcery *sorcery)
Inform any wizards to load persistent objects.
void ast_sorcery_reload(const struct ast_sorcery *sorcery)
Inform any wizards to reload persistent objects.
static int load_module(void)
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
EVP_PKEY * stir_shaken_certificate_get_private_key(struct stir_shaken_certificate *cert)
Get the private key associated with a certificate.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
int stir_shaken_store_unload(void)
Unload time cleanup for the stir/shaken 'store' configuration.
static int test_stir_shaken_write_temp_key(char *file_path, int private)
Create a private or public key certificate.
const char * ast_channel_name(const struct ast_channel *chan)
unsigned int ast_stir_shaken_get_signature_timeout(void)
Retrieve the value for 'signature_timeout' from 'general' config object.
struct curl_cb_data * curl_cb_data_create(void)
Allocate memory for a curl_cb_data struct.
#define ast_sorcery_open()
Abstract JSON element (object, array, string, int, ...).
static int stir_shaken_verify_signature(const char *msg, const char *signature, EVP_PKEY *public_key)
Verifies the signature using a public key.
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
#define ast_datastore_alloc(info, uid)
static int stir_shaken_add_attest(struct ast_json *json, const char *attest)
Adds the 'attest' field to the JWT.
int stir_shaken_general_load(void)
Load time initialization for the stir/shaken 'general' configuration.
static char * get_path_to_public_key(const char *public_cert_url)
Returns the path to the downloaded file for the provided URL.
#define STIR_SHAKEN_DIR_NAME
#define ASTERISK_GPL_KEY
The text the key() function should return.
static void test_stir_shaken_add_fake_astdb_entry(const char *public_cert_url, const char *file_path)
Asterisk module definitions.
int stir_shaken_store_load(void)
Load time initialization for the stir/shaken 'store' configuration.
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Persistant data storage (akin to *doze registry)
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
static int public_key_is_expired(const char *public_cert_url)
Check to see if the public key is expired.
#define ast_custom_function_register(acf)
Register a custom function.
int ast_db_deltree(const char *family, const char *keytree)
Delete one or more entries in astdb.
const char * stir_shaken_certificate_get_public_cert_url(struct stir_shaken_certificate *cert)
Get the public key URL associated with a certificate.
struct ast_json * ast_json_deep_copy(const struct ast_json *value)
Copy a JSON value, and its children.
static int stir_shaken_add_origid(struct ast_json *json)
Adds the 'origid' field to the JWT.
Sorcery Data Access Layer API.
#define AST_APP_ARG(name)
Define an application argument.
struct ast_json * ast_json_integer_create(intmax_t value)
Create a JSON integer.
struct ast_stir_shaken_payload * ast_stir_shaken_verify(const char *header, const char *payload, const char *signature, const char *algorithm, const char *public_cert_url)
Verify a JSON STIR/SHAKEN payload.