69 char *caller_id_other;
75 if (strcmp(caller_id, caller_id_other)) {
98 ast_debug(3,
"Ignoring STIR/SHAKEN timestamp\n");
124 static const pj_str_t identity_str = {
"Identity", 8 };
125 char *identity_hdr_val;
133 char *public_cert_url;
148 encoded_val = strtok_r(identity_hdr_val,
".", &identity_hdr_val);
155 encoded_val = strtok_r(identity_hdr_val,
".", &identity_hdr_val);
163 signature = strtok_r(identity_hdr_val,
";", &identity_hdr_val);
170 strtok_r(identity_hdr_val,
"<", &identity_hdr_val);
171 public_cert_url = strtok_r(identity_hdr_val,
">", &identity_hdr_val);
183 algorithm = strtok_r(identity_hdr_val,
";", &identity_hdr_val);
213 static const pj_str_t identity_str = {
"Identity", 8 };
214 pjsip_generic_string_hdr *identity_hdr;
215 pj_str_t identity_val;
216 pjsip_fromto_hdr *old_identity;
217 pjsip_fromto_hdr *to;
230 size_t combined_size;
232 old_identity = pjsip_msg_find_hdr_by_name(tdata->msg, &identity_str,
NULL);
237 to = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_TO,
NULL);
239 ast_log(
LOG_ERROR,
"Failed to find To header while adding STIR/SHAKEN Identity header\n");
243 uri = pjsip_uri_get_uri(to->uri);
245 ast_log(
LOG_ERROR,
"Failed to retrieve URI from To header while adding STIR/SHAKEN Identity header\n");
258 json =
ast_json_pack(
"{s: {s: s, s: s, s: s}, s: {s: {s: s}, s: {s: s}}}",
259 "header",
"alg",
"ES256",
"ppt",
"shaken",
"typ",
"passport",
260 "payload",
"dest",
"tn", dest_tn,
"orig",
"tn",
277 if (!encoded_header) {
286 if (!encoded_payload) {
297 combined_size = strlen(encoded_header) + 1 + strlen(encoded_payload) + 1
298 + strlen(signature) + strlen(
";info=<>alg=;ppt=") + strlen(public_cert_url)
302 ast_log(
LOG_ERROR,
"Failed to allocate memory for STIR/SHAKEN identity string\n");
305 snprintf(combined_str, combined_size,
"%s.%s.%s;info=<%s>alg=%s;ppt=%s", encoded_header,
308 identity_val = pj_str(combined_str);
309 identity_hdr = pjsip_generic_string_hdr_create(tdata->pool, &identity_str, &identity_val);
315 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)identity_hdr);
322 static const pj_str_t date_str = {
"Date", 4 };
323 pjsip_fromto_hdr *old_date;
325 old_date = pjsip_msg_find_hdr_by_name(tdata->msg, &date_str,
NULL);
327 ast_debug(3,
"Found old STIR/SHAKEN date header, no need to add one\n");
372 #undef AST_BUILDOPT_SUM 373 #define AST_BUILDOPT_SUM "" 380 .requires =
"res_pjsip,res_pjsip_session,res_stir_shaken",
Main Channel structure associated with a channel.
struct ast_sip_endpoint * endpoint
char * ast_base64url_decode_string(const char *src)
Decode string from base64 URL.
char * str
Subscriber phone number (Malloced)
Asterisk main include file. File version handling, generic pbx functions.
unsigned char * signature
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
void ast_json_free(void *p)
Asterisk's custom JSON allocator. Exposed for use by unit tests.
static int load_module(void)
#define ast_json_dump_string(root)
Encode a JSON value to a compact string.
unsigned int ast_stir_shaken_get_signature_timeout(void)
Retrieve the value for 'signature_timeout' from 'general' config object.
static int add_identity_header(const struct ast_sip_session *session, pjsip_tx_data *tdata)
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
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.
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.
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)
Unregister a an supplement to SIP session processing.
static void add_date_header(const struct ast_sip_session *session, pjsip_tx_data *tdata)
A structure describing a SIP session.
#define ast_strlen_zero(foo)
#define ast_debug(level,...)
Log a DEBUG message.
struct ast_stir_shaken_payload * ast_stir_shaken_sign(struct ast_json *json)
Sign a JSON STIR/SHAKEN payload.
char * ast_sip_rdata_get_header_value(pjsip_rx_data *rdata, const pj_str_t str)
Get a specific header value from rdata.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
static struct ast_mansession session
static int compare_timestamp(const char *json_str)
Compare the current timestamp with the one in the payload. If the difference is greater than the sign...
char * ast_base64url_encode_string(const char *src)
Encode string in base64 URL.
struct ast_channel * channel
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
#define ast_malloc(len)
A wrapper for malloc()
#define STIR_SHAKEN_ENCRYPTION_ALGORITHM
static struct ast_sip_session_supplement stir_shaken_supplement
static char * get_attestation_from_payload(const char *json_str)
Get the attestation from the payload.
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.
void ast_sip_add_date_header(pjsip_tx_data *tdata)
Adds a Date header to the tdata, formatted like: Date: Wed, 01 Jan 2021 14:53:01 GMT.
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.
#define ast_calloc(num, len)
A wrapper for calloc()
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.
static void stir_shaken_outgoing_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
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",)
A supplement to SIP message processing.
struct ast_json * payload
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
static int compare_caller_id(char *caller_id, const char *json_str)
Compare the caller ID from the INVITE with the one in the payload.
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Abstract JSON element (object, array, string, int, ...).
void ast_stir_shaken_payload_free(struct ast_stir_shaken_payload *payload)
Free a STIR/SHAKEN payload.
static int unload_module(void)
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
unsigned char valid
TRUE if the number information is valid/present.
#define ast_sip_session_register_supplement(supplement)
static int stir_shaken_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
struct ast_party_number number
Subscriber phone number.