Asterisk - The Open Source Telephony Project  18.5.0
Macros | Enumerations | Functions
res_stir_shaken.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define STIR_SHAKEN_ENCRYPTION_ALGORITHM   "ES256"
 
#define STIR_SHAKEN_PPT   "shaken"
 
#define STIR_SHAKEN_TYPE   "passport"
 

Enumerations

enum  ast_stir_shaken_verification_result { AST_STIR_SHAKEN_VERIFY_NOT_PRESENT, AST_STIR_SHAKEN_VERIFY_SIGNATURE_FAILED, AST_STIR_SHAKEN_VERIFY_MISMATCH, AST_STIR_SHAKEN_VERIFY_PASSED }
 

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. More...
 
unsigned int ast_stir_shaken_get_signature_timeout (void)
 Retrieve the value for 'signature_timeout' from 'general' config object. More...
 
void ast_stir_shaken_payload_free (struct ast_stir_shaken_payload *payload)
 Free a STIR/SHAKEN payload. More...
 
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. More...
 
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. More...
 
struct ast_stir_shaken_payloadast_stir_shaken_sign (struct ast_json *json)
 Sign a JSON STIR/SHAKEN payload. More...
 
struct ast_sorceryast_stir_shaken_sorcery (void)
 Retrieve the stir/shaken sorcery context. More...
 
struct ast_stir_shaken_payloadast_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. More...
 

Macro Definition Documentation

◆ STIR_SHAKEN_ENCRYPTION_ALGORITHM

#define STIR_SHAKEN_ENCRYPTION_ALGORITHM   "ES256"

Definition at line 21 of file res_stir_shaken.h.

Referenced by add_identity_header(), AST_TEST_DEFINE(), and stir_shaken_verify_json().

◆ STIR_SHAKEN_PPT

#define STIR_SHAKEN_PPT   "shaken"

Definition at line 22 of file res_stir_shaken.h.

Referenced by add_identity_header(), AST_TEST_DEFINE(), and stir_shaken_verify_json().

◆ STIR_SHAKEN_TYPE

#define STIR_SHAKEN_TYPE   "passport"

Definition at line 23 of file res_stir_shaken.h.

Referenced by AST_TEST_DEFINE(), and stir_shaken_verify_json().

Enumeration Type Documentation

◆ ast_stir_shaken_verification_result

Enumerator
AST_STIR_SHAKEN_VERIFY_NOT_PRESENT 
AST_STIR_SHAKEN_VERIFY_SIGNATURE_FAILED 

No STIR/SHAKEN information was available

AST_STIR_SHAKEN_VERIFY_MISMATCH 

Signature verification failed

AST_STIR_SHAKEN_VERIFY_PASSED 

Contents of the signaling and the STIR/SHAKEN payload did not match

Definition at line 25 of file res_stir_shaken.h.

25  {
26  AST_STIR_SHAKEN_VERIFY_NOT_PRESENT, /*! No STIR/SHAKEN information was available */
27  AST_STIR_SHAKEN_VERIFY_SIGNATURE_FAILED, /*! Signature verification failed */
28  AST_STIR_SHAKEN_VERIFY_MISMATCH, /*! Contents of the signaling and the STIR/SHAKEN payload did not match */
29  AST_STIR_SHAKEN_VERIFY_PASSED, /*! Signature verified and contents match signaling */
30 };

Function Documentation

◆ ast_stir_shaken_add_verification()

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.

Parameters
chanThe channel
identityThe identity
attestationThe attestation
resultThe verification result
Return values
-1on failure
0on success

Definition at line 277 of file res_stir_shaken.c.

References ast_calloc, ast_channel_datastore_add(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_datastore_alloc, ast_log, ast_strdup, stir_shaken_datastore::attestation, ast_datastore::data, stir_shaken_datastore::identity, LOG_ERROR, NULL, result, stir_shaken_datastore_free(), and stir_shaken_datastore::verify_result.

Referenced by stir_shaken_incoming_request().

279 {
280  struct stir_shaken_datastore *ss_datastore;
281  struct ast_datastore *datastore;
282  const char *chan_name;
283 
284  if (!chan) {
285  ast_log(LOG_ERROR, "Channel is required to add STIR/SHAKEN verification\n");
286  return -1;
287  }
288 
289  chan_name = ast_channel_name(chan);
290 
291  if (!identity) {
292  ast_log(LOG_ERROR, "No identity to add STIR/SHAKEN verification to channel "
293  "%s\n", chan_name);
294  return -1;
295  }
296 
297  if (!attestation) {
298  ast_log(LOG_ERROR, "Attestation cannot be NULL to add STIR/SHAKEN verification to "
299  "channel %s\n", chan_name);
300  return -1;
301  }
302 
303  ss_datastore = ast_calloc(1, sizeof(*ss_datastore));
304  if (!ss_datastore) {
305  ast_log(LOG_ERROR, "Failed to allocate space for STIR/SHAKEN datastore for "
306  "channel %s\n", chan_name);
307  return -1;
308  }
309 
310  ss_datastore->identity = ast_strdup(identity);
311  if (!ss_datastore->identity) {
312  ast_log(LOG_ERROR, "Failed to allocate space for STIR/SHAKEN datastore "
313  "identity for channel %s\n", chan_name);
314  stir_shaken_datastore_free(ss_datastore);
315  return -1;
316  }
317 
318  ss_datastore->attestation = ast_strdup(attestation);
319  if (!ss_datastore->attestation) {
320  ast_log(LOG_ERROR, "Failed to allocate space for STIR/SHAKEN datastore "
321  "attestation for channel %s\n", chan_name);
322  stir_shaken_datastore_free(ss_datastore);
323  return -1;
324  }
325 
326  ss_datastore->verify_result = result;
327 
329  if (!datastore) {
330  ast_log(LOG_ERROR, "Failed to allocate space for datastore for channel "
331  "%s\n", chan_name);
332  stir_shaken_datastore_free(ss_datastore);
333  return -1;
334  }
335 
336  datastore->data = ss_datastore;
337 
338  ast_channel_lock(chan);
339  ast_channel_datastore_add(chan, datastore);
340  ast_channel_unlock(chan);
341 
342  return 0;
343 }
static void stir_shaken_datastore_free(struct stir_shaken_datastore *datastore)
Frees a stir_shaken_datastore structure.
#define ast_channel_lock(chan)
Definition: channel.h:2945
static const struct ast_datastore_info stir_shaken_datastore_info
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
Structure for a data store object.
Definition: datastore.h:68
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
enum ast_stir_shaken_verification_result verify_result
void * data
Definition: datastore.h:70
const char * ast_channel_name(const struct ast_channel *chan)
static PGresult * result
Definition: cel_pgsql.c:88
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:89
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2390

◆ ast_stir_shaken_get_signature_timeout()

unsigned int ast_stir_shaken_get_signature_timeout ( void  )

Retrieve the value for 'signature_timeout' from 'general' config object.

Return values
Thesignature timeout

Definition at line 203 of file res_stir_shaken.c.

References ast_stir_shaken_signature_timeout(), and stir_shaken_general_get().

Referenced by compare_timestamp().

204 {
206 }
struct stir_shaken_general * stir_shaken_general_get()
Retrieve the stir/shaken 'general' configuration object.
Definition: general.c:54
unsigned int ast_stir_shaken_signature_timeout(const struct stir_shaken_general *cfg)
Retrieve the 'signature_timeout' general configuration option value.
Definition: general.c:92

◆ ast_stir_shaken_payload_free()

void ast_stir_shaken_payload_free ( struct ast_stir_shaken_payload payload)

Free a STIR/SHAKEN payload.

Definition at line 178 of file res_stir_shaken.c.

References ast_stir_shaken_payload::algorithm, ast_free, ast_json_unref(), ast_stir_shaken_payload::header, ast_stir_shaken_payload::payload, ast_stir_shaken_payload::public_cert_url, and ast_stir_shaken_payload::signature.

Referenced by add_identity_header(), ast_stir_shaken_sign(), ast_stir_shaken_verify(), AST_TEST_DEFINE(), stir_shaken_incoming_request(), and stir_shaken_verify_json().

179 {
180  if (!payload) {
181  return;
182  }
183 
184  ast_json_unref(payload->header);
185  ast_json_unref(payload->payload);
186  ast_free(payload->algorithm);
187  ast_free(payload->public_cert_url);
188  ast_free(payload->signature);
189 
190  ast_free(payload);
191 }
struct ast_json * header
unsigned char * signature
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
#define ast_free(a)
Definition: astmm.h:182
struct ast_json * payload

◆ ast_stir_shaken_payload_get_public_cert_url()

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.

Parameters
payloadThe payload
Return values
Thepublic key URL

Definition at line 198 of file res_stir_shaken.c.

References NULL, and ast_stir_shaken_payload::public_cert_url.

Referenced by add_identity_header().

199 {
200  return payload ? payload->public_cert_url : NULL;
201 }
#define NULL
Definition: resample.c:96

◆ ast_stir_shaken_payload_get_signature()

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.

Parameters
payloadThe payload
Return values
Thesignature

Definition at line 193 of file res_stir_shaken.c.

References NULL, and ast_stir_shaken_payload::signature.

Referenced by add_identity_header().

194 {
195  return payload ? payload->signature : NULL;
196 }
unsigned char * signature
#define NULL
Definition: resample.c:96

◆ ast_stir_shaken_sign()

struct ast_stir_shaken_payload* ast_stir_shaken_sign ( struct ast_json json)

Sign a JSON STIR/SHAKEN payload.

Note
This function will automatically add the "attest", "iat", and "origid" fields.
Parameters
jsonThe JWT to sign
Return values
ast_stir_shaken_payloadon success
NULLon failure

Definition at line 1046 of file res_stir_shaken.c.

References ao2_cleanup, ast_calloc, ast_free, ast_json_dump_string, ast_json_object_get(), ast_json_string_get(), ast_log, ast_stir_shaken_payload_free(), ast_strdup, cleanup(), ast_stir_shaken_payload::header, LOG_ERROR, NULL, ast_stir_shaken_payload::payload, ast_stir_shaken_payload::public_cert_url, ast_stir_shaken_payload::signature, stir_shaken_add_attest(), stir_shaken_add_iat(), stir_shaken_add_origid(), stir_shaken_add_x5u(), stir_shaken_certificate_get_attestation(), stir_shaken_certificate_get_by_caller_id_number(), stir_shaken_certificate_get_private_key(), stir_shaken_certificate_get_public_cert_url(), stir_shaken_sign(), and stir_shaken_verify_json().

Referenced by add_identity_header(), and AST_TEST_DEFINE().

1047 {
1048  struct ast_stir_shaken_payload *ss_payload;
1049  unsigned char *signature;
1050  const char *public_cert_url;
1051  const char *caller_id_num;
1052  const char *header;
1053  const char *payload;
1054  struct ast_json *tmp_json;
1055  char *msg = NULL;
1056  size_t msg_len;
1057  struct stir_shaken_certificate *cert = NULL;
1058 
1059  ss_payload = stir_shaken_verify_json(json);
1060  if (!ss_payload) {
1061  return NULL;
1062  }
1063 
1064  /* From the payload section of the JSON, get the orig section, and then get
1065  * the value of tn. This will be the caller ID number */
1067  ast_json_object_get(json, "payload"), "orig"), "tn"));
1068  if (!caller_id_num) {
1069  ast_log(LOG_ERROR, "Failed to get caller ID number from JWT\n");
1070  goto cleanup;
1071  }
1072 
1074  if (!cert) {
1075  ast_log(LOG_ERROR, "Failed to retrieve certificate for caller ID "
1076  "'%s'\n", caller_id_num);
1077  goto cleanup;
1078  }
1079 
1080  public_cert_url = stir_shaken_certificate_get_public_cert_url(cert);
1081  if (stir_shaken_add_x5u(json, public_cert_url)) {
1082  ast_log(LOG_ERROR, "Failed to add 'x5u' (public cert URL) to payload\n");
1083  goto cleanup;
1084  }
1085  ss_payload->public_cert_url = ast_strdup(public_cert_url);
1086 
1088  ast_log(LOG_ERROR, "Failed to add 'attest' to payload\n");
1089  goto cleanup;
1090  }
1091 
1092  if (stir_shaken_add_origid(json)) {
1093  ast_log(LOG_ERROR, "Failed to add 'origid' to payload\n");
1094  goto cleanup;
1095  }
1096 
1097  if (stir_shaken_add_iat(json)) {
1098  ast_log(LOG_ERROR, "Failed to add 'iat' to payload\n");
1099  goto cleanup;
1100  }
1101 
1102  /* Get the header and the payload. Combine them to get the message to sign */
1103  tmp_json = ast_json_object_get(json, "header");
1104  header = ast_json_dump_string(tmp_json);
1105  tmp_json = ast_json_object_get(json, "payload");
1106  payload = ast_json_dump_string(tmp_json);
1107  msg_len = strlen(header) + strlen(payload) + 2;
1108  msg = ast_calloc(1, msg_len);
1109  if (!msg) {
1110  ast_log(LOG_ERROR, "Failed to allocate space for message to sign\n");
1111  goto cleanup;
1112  }
1113  snprintf(msg, msg_len, "%s.%s", header, payload);
1114 
1116  if (!signature) {
1117  goto cleanup;
1118  }
1119 
1120  ss_payload->signature = signature;
1121  ao2_cleanup(cert);
1122  ast_free(msg);
1123 
1124  return ss_payload;
1125 
1126 cleanup:
1127  ao2_cleanup(cert);
1128  ast_stir_shaken_payload_free(ss_payload);
1129  ast_free(msg);
1130  return NULL;
1131 }
struct ast_json * header
unsigned char * signature
static int stir_shaken_add_iat(struct ast_json *json)
Adds the 'iat' field to the JWT.
static unsigned char * stir_shaken_sign(char *json_str, EVP_PKEY *private_key)
Signs the payload and returns the signature.
#define ast_json_dump_string(root)
Encode a JSON value to a compact string.
Definition: json.h:763
void ast_stir_shaken_payload_free(struct ast_stir_shaken_payload *payload)
Free a STIR/SHAKEN payload.
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
const char * stir_shaken_certificate_get_attestation(struct stir_shaken_certificate *cert)
Get the attestation level associated with a certificate.
Definition: certificate.c:101
#define ast_log
Definition: astobj2.c:42
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...
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:273
#define LOG_ERROR
Definition: logger.h:285
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.
Definition: certificate.c:84
static int stir_shaken_add_x5u(struct ast_json *json, const char *x5u)
Adds the 'x5u' (public key URL) field to the JWT.
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static void * cleanup(void *unused)
Definition: pbx_realtime.c:124
struct ast_json * payload
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:397
EVP_PKEY * stir_shaken_certificate_get_private_key(struct stir_shaken_certificate *cert)
Get the private key associated with a certificate.
Definition: certificate.c:106
Abstract JSON element (object, array, string, int, ...).
static int stir_shaken_add_attest(struct ast_json *json, const char *attest)
Adds the 'attest' field to the JWT.
const char * stir_shaken_certificate_get_public_cert_url(struct stir_shaken_certificate *cert)
Get the public key URL associated with a certificate.
Definition: certificate.c:96
static int stir_shaken_add_origid(struct ast_json *json)
Adds the 'origid' field to the JWT.

◆ ast_stir_shaken_sorcery()

struct ast_sorcery* ast_stir_shaken_sorcery ( void  )

◆ ast_stir_shaken_verify()

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.

Parameters
headerThe payload header
payloadThe payload section
signatureThe payload signature
algorithmThe signature algorithm
public_cert_urlThe public key URL
Return values
ast_stir_shaken_payloadon success
NULLon failure

Definition at line 620 of file res_stir_shaken.c.

References add_public_key_to_astdb(), ast_stir_shaken_payload::algorithm, ast_asprintf, ast_calloc, ast_config_AST_DATA_DIR, ast_debug, ast_free, ast_json_load_string(), ast_log, ast_stir_shaken_payload_free(), ast_strdup, ast_strlen_zero, curl_and_check_expiration(), get_path_to_public_key(), ast_stir_shaken_payload::header, LOG_ERROR, NULL, ast_stir_shaken_payload::payload, ast_stir_shaken_payload::public_cert_url, public_key_is_expired(), RAII_VAR, remove_public_key_from_astdb(), run_curl(), ast_stir_shaken_payload::signature, STIR_SHAKEN_DIR_NAME, stir_shaken_read_key(), and stir_shaken_verify_signature().

Referenced by AST_TEST_DEFINE(), and stir_shaken_incoming_request().

622 {
623  struct ast_stir_shaken_payload *ret_payload;
624  EVP_PKEY *public_key;
625  int curl = 0;
626  RAII_VAR(char *, file_path, NULL, ast_free);
627  RAII_VAR(char *, dir_path, NULL, ast_free);
628  RAII_VAR(char *, combined_str, NULL, ast_free);
629  size_t combined_size;
630 
631  if (ast_strlen_zero(header)) {
632  ast_log(LOG_ERROR, "'header' is required for STIR/SHAKEN verification\n");
633  return NULL;
634  }
635 
636  if (ast_strlen_zero(payload)) {
637  ast_log(LOG_ERROR, "'payload' is required for STIR/SHAKEN verification\n");
638  return NULL;
639  }
640 
641  if (ast_strlen_zero(signature)) {
642  ast_log(LOG_ERROR, "'signature' is required for STIR/SHAKEN verification\n");
643  return NULL;
644  }
645 
646  if (ast_strlen_zero(algorithm)) {
647  ast_log(LOG_ERROR, "'algorithm' is required for STIR/SHAKEN verification\n");
648  return NULL;
649  }
650 
652  ast_log(LOG_ERROR, "'public_cert_url' is required for STIR/SHAKEN verification\n");
653  return NULL;
654  }
655 
656  /* Check to see if we have already downloaded this public cert. The reason we
657  * store the file path is because:
658  *
659  * 1. If, for some reason, the default directory changes, we still know where
660  * to look for the files we already have.
661  *
662  * 2. In the future, if we want to add a way to store the certs in multiple
663  * {configurable) directories, we already have the storage mechanism in place.
664  * The only thing that would be left to do is pull from the configuration.
665  */
667  if (ast_asprintf(&dir_path, "%s/keys/%s", ast_config_AST_DATA_DIR, STIR_SHAKEN_DIR_NAME) < 0) {
668  return NULL;
669  }
670 
671  /* If we don't have an entry in AstDB, CURL from the provided URL */
672  if (ast_strlen_zero(file_path)) {
673  /* Remove this entry from the database, since we will be
674  * downloading a new file anyways.
675  */
677 
678  /* Go ahead and free file_path, in case anything was allocated above */
679  ast_free(file_path);
680 
681  /* Download to the default path */
682  file_path = run_curl(public_cert_url, dir_path);
683  if (!file_path) {
684  return NULL;
685  }
686 
687  /* Signal that we have already downloaded a new file, no reason to do it again */
688  curl = 1;
689 
690  /* We should have a successful download at this point, so
691  * add an entry to the database.
692  */
694  }
695 
696  /* Check to see if the cert we downloaded (or already had) is expired */
698 
699  ast_debug(3, "Public cert '%s' is expired\n", public_cert_url);
700 
702 
703  /* If this fails, then there's nothing we can do */
704  ast_free(file_path);
705  file_path = curl_and_check_expiration(public_cert_url, dir_path, &curl);
706  if (!file_path) {
707  return NULL;
708  }
709  }
710 
711  /* First attempt to read the key. If it fails, try downloading the file,
712  * unless we already did. Check for expiration again */
713  public_key = stir_shaken_read_key(file_path, 0);
714  if (!public_key) {
715 
716  ast_debug(3, "Failed first read of public key file '%s'\n", file_path);
717 
719 
720  ast_free(file_path);
721  file_path = curl_and_check_expiration(public_cert_url, dir_path, &curl);
722  if (!file_path) {
723  return NULL;
724  }
725 
726  public_key = stir_shaken_read_key(file_path, 0);
727  if (!public_key) {
728  ast_log(LOG_ERROR, "Failed to read public key from '%s'\n", file_path);
730  return NULL;
731  }
732  }
733 
734  /* Combine the header and payload to get the original signed message: header.payload */
735  combined_size = strlen(header) + strlen(payload) + 2;
736  combined_str = ast_calloc(1, combined_size);
737  if (!combined_str) {
738  ast_log(LOG_ERROR, "Failed to allocate space for message to verify\n");
739  EVP_PKEY_free(public_key);
740  return NULL;
741  }
742  snprintf(combined_str, combined_size, "%s.%s", header, payload);
743  if (stir_shaken_verify_signature(combined_str, signature, public_key)) {
744  ast_log(LOG_ERROR, "Failed to verify signature\n");
745  EVP_PKEY_free(public_key);
746  return NULL;
747  }
748 
749  /* We don't need the public key anymore */
750  EVP_PKEY_free(public_key);
751 
752  ret_payload = ast_calloc(1, sizeof(*ret_payload));
753  if (!ret_payload) {
754  ast_log(LOG_ERROR, "Failed to allocate STIR/SHAKEN payload\n");
755  return NULL;
756  }
757 
758  ret_payload->header = ast_json_load_string(header, NULL);
759  if (!ret_payload->header) {
760  ast_log(LOG_ERROR, "Failed to create JSON from header\n");
761  ast_stir_shaken_payload_free(ret_payload);
762  return NULL;
763  }
764 
765  ret_payload->payload = ast_json_load_string(payload, NULL);
766  if (!ret_payload->payload) {
767  ast_log(LOG_ERROR, "Failed to create JSON from payload\n");
768  ast_stir_shaken_payload_free(ret_payload);
769  return NULL;
770  }
771 
772  ret_payload->signature = (unsigned char *)ast_strdup(signature);
773  ret_payload->algorithm = ast_strdup(algorithm);
775 
776  return ret_payload;
777 }
struct ast_json * header
unsigned char * 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.
EVP_PKEY * stir_shaken_read_key(const char *path, int priv)
Reads the public (or private) key from the specified path.
Definition: stir_shaken.c:89
static void remove_public_key_from_astdb(const char *public_cert_url)
Remove the public key details and associated information from AstDB.
void ast_stir_shaken_payload_free(struct ast_stir_shaken_payload *payload)
Free a STIR/SHAKEN payload.
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.
Definition: json.c:546
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
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.
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:269
#define ast_strlen_zero(foo)
Definition: strings.h:52
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.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
const char * ast_config_AST_DATA_DIR
Definition: options.c:158
#define LOG_ERROR
Definition: logger.h:285
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
struct ast_json * payload
static int stir_shaken_verify_signature(const char *msg, const char *signature, EVP_PKEY *public_key)
Verifies the signature using a public key.
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
static int public_key_is_expired(const char *public_cert_url)
Check to see if the public key is expired.