Asterisk - The Open Source Telephony Project GIT-master-a358458
Enumerations | Functions
res_stir_shaken.h File Reference
#include "asterisk/sorcery.h"
Include dependency graph for res_stir_shaken.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  ast_stir_shaken_as_response_code {
  AST_STIR_SHAKEN_AS_SUCCESS = 0 , AST_STIR_SHAKEN_AS_DISABLED , AST_STIR_SHAKEN_AS_INVALID_ARGUMENTS , AST_STIR_SHAKEN_AS_MISSING_PARAMETERS ,
  AST_STIR_SHAKEN_AS_INTERNAL_ERROR , AST_STIR_SHAKEN_AS_NO_TN_FOR_CALLERID , AST_STIR_SHAKEN_AS_NO_PRIVATE_KEY_AVAIL , AST_STIR_SHAKEN_AS_NO_PUBLIC_CERT_URL_AVAIL ,
  AST_STIR_SHAKEN_AS_NO_ATTEST_LEVEL , AST_STIR_SHAKEN_AS_IDENTITY_HDR_EXISTS , AST_STIR_SHAKEN_AS_NO_TO_HDR , AST_STIR_SHAKEN_AS_TO_HDR_BAD_URI ,
  AST_STIR_SHAKEN_AS_SIGN_ENCODE_FAILURE , AST_STIR_SHAKEN_AS_RESPONSE_CODE_MAX
}
 
enum  ast_stir_shaken_vs_response_code {
  AST_STIR_SHAKEN_VS_SUCCESS = 0 , AST_STIR_SHAKEN_VS_DISABLED , AST_STIR_SHAKEN_VS_INVALID_ARGUMENTS , AST_STIR_SHAKEN_VS_INTERNAL_ERROR ,
  AST_STIR_SHAKEN_VS_NO_IDENTITY_HDR , AST_STIR_SHAKEN_VS_NO_DATE_HDR , AST_STIR_SHAKEN_VS_DATE_HDR_PARSE_FAILURE , AST_STIR_SHAKEN_VS_DATE_HDR_EXPIRED ,
  AST_STIR_SHAKEN_VS_NO_JWT_HDR , AST_STIR_SHAKEN_VS_INVALID_OR_NO_X5U , AST_STIR_SHAKEN_VS_CERT_CACHE_MISS , AST_STIR_SHAKEN_VS_CERT_CACHE_INVALID ,
  AST_STIR_SHAKEN_VS_CERT_CACHE_EXPIRED , AST_STIR_SHAKEN_VS_CERT_RETRIEVAL_FAILURE , AST_STIR_SHAKEN_VS_CERT_CONTENTS_INVALID , AST_STIR_SHAKEN_VS_CERT_NOT_TRUSTED ,
  AST_STIR_SHAKEN_VS_CERT_DATE_INVALID , AST_STIR_SHAKEN_VS_CERT_NO_TN_AUTH_EXT , AST_STIR_SHAKEN_VS_CERT_NO_SPC_IN_TN_AUTH_EXT , AST_STIR_SHAKEN_VS_NO_RAW_KEY ,
  AST_STIR_SHAKEN_VS_SIGNATURE_VALIDATION , AST_STIR_SHAKEN_VS_NO_IAT , AST_STIR_SHAKEN_VS_IAT_EXPIRED , AST_STIR_SHAKEN_VS_INVALID_OR_NO_PPT ,
  AST_STIR_SHAKEN_VS_INVALID_OR_NO_ALG , AST_STIR_SHAKEN_VS_INVALID_OR_NO_TYP , AST_STIR_SHAKEN_VS_INVALID_OR_NO_GRANTS , AST_STIR_SHAKEN_VS_INVALID_OR_NO_ATTEST ,
  AST_STIR_SHAKEN_VS_NO_ORIGID , AST_STIR_SHAKEN_VS_NO_ORIG_TN , AST_STIR_SHAKEN_VS_CID_ORIG_TN_MISMATCH , AST_STIR_SHAKEN_VS_NO_DEST_TN ,
  AST_STIR_SHAKEN_VS_INVALID_HEADER , AST_STIR_SHAKEN_VS_INVALID_GRANT , AST_STIR_SHAKEN_VS_RESPONSE_CODE_MAX
}
 
enum  stir_shaken_failure_action_enum {
  stir_shaken_failure_action_UNKNOWN = -1 , stir_shaken_failure_action_CONTINUE = 0 , stir_shaken_failure_action_REJECT_REQUEST , stir_shaken_failure_action_CONTINUE_RETURN_REASON ,
  stir_shaken_failure_action_NOT_SET
}
 

Functions

int ast_stir_shaken_add_result_to_channel (struct ast_stir_shaken_vs_ctx *ctx)
 Add a STIR/SHAKEN verification result to a channel. More...
 
enum ast_stir_shaken_as_response_code ast_stir_shaken_as_ctx_add_fingerprint (struct ast_stir_shaken_as_ctx *ctx, const char *alg, const char *fingerprint)
 Add DTLS fingerprints to AS context. More...
 
enum ast_stir_shaken_as_response_code ast_stir_shaken_as_ctx_create (const char *caller_id, const char *dest_tn, struct ast_channel *chan, const char *profile_name, const char *tag, struct ast_stir_shaken_as_ctx **ctxout)
 Create Attestation Service Context. More...
 
int ast_stir_shaken_as_ctx_wants_fingerprints (struct ast_stir_shaken_as_ctx *ctx)
 Indicates if the AS context needs DTLS fingerprints. More...
 
enum ast_stir_shaken_as_response_code ast_stir_shaken_attest (struct ast_stir_shaken_as_ctx *ctx, char **header)
 Attest and return Identity header value. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
int ast_stir_shaken_vs_get_use_rfc9410_responses (struct ast_stir_shaken_vs_ctx *ctx)
 Get use_rfc9410_responses from context. More...
 
enum ast_stir_shaken_vs_response_code ast_stir_shaken_vs_verify (struct ast_stir_shaken_vs_ctx *ctx)
 Perform incoming call verification. More...
 

Enumeration Type Documentation

◆ ast_stir_shaken_as_response_code

Enumerator
AST_STIR_SHAKEN_AS_SUCCESS 
AST_STIR_SHAKEN_AS_DISABLED 
AST_STIR_SHAKEN_AS_INVALID_ARGUMENTS 
AST_STIR_SHAKEN_AS_MISSING_PARAMETERS 
AST_STIR_SHAKEN_AS_INTERNAL_ERROR 
AST_STIR_SHAKEN_AS_NO_TN_FOR_CALLERID 
AST_STIR_SHAKEN_AS_NO_PRIVATE_KEY_AVAIL 
AST_STIR_SHAKEN_AS_NO_PUBLIC_CERT_URL_AVAIL 
AST_STIR_SHAKEN_AS_NO_ATTEST_LEVEL 
AST_STIR_SHAKEN_AS_IDENTITY_HDR_EXISTS 
AST_STIR_SHAKEN_AS_NO_TO_HDR 
AST_STIR_SHAKEN_AS_TO_HDR_BAD_URI 
AST_STIR_SHAKEN_AS_SIGN_ENCODE_FAILURE 
AST_STIR_SHAKEN_AS_RESPONSE_CODE_MAX 

Definition at line 61 of file res_stir_shaken.h.

61 {
76};
@ AST_STIR_SHAKEN_AS_NO_TN_FOR_CALLERID
@ AST_STIR_SHAKEN_AS_INVALID_ARGUMENTS
@ AST_STIR_SHAKEN_AS_TO_HDR_BAD_URI
@ AST_STIR_SHAKEN_AS_MISSING_PARAMETERS
@ AST_STIR_SHAKEN_AS_NO_PRIVATE_KEY_AVAIL
@ AST_STIR_SHAKEN_AS_DISABLED
@ AST_STIR_SHAKEN_AS_SIGN_ENCODE_FAILURE
@ AST_STIR_SHAKEN_AS_NO_TO_HDR
@ AST_STIR_SHAKEN_AS_NO_PUBLIC_CERT_URL_AVAIL
@ AST_STIR_SHAKEN_AS_SUCCESS
@ AST_STIR_SHAKEN_AS_RESPONSE_CODE_MAX
@ AST_STIR_SHAKEN_AS_INTERNAL_ERROR
@ AST_STIR_SHAKEN_AS_IDENTITY_HDR_EXISTS
@ AST_STIR_SHAKEN_AS_NO_ATTEST_LEVEL

◆ ast_stir_shaken_vs_response_code

Enumerator
AST_STIR_SHAKEN_VS_SUCCESS 
AST_STIR_SHAKEN_VS_DISABLED 
AST_STIR_SHAKEN_VS_INVALID_ARGUMENTS 
AST_STIR_SHAKEN_VS_INTERNAL_ERROR 
AST_STIR_SHAKEN_VS_NO_IDENTITY_HDR 
AST_STIR_SHAKEN_VS_NO_DATE_HDR 
AST_STIR_SHAKEN_VS_DATE_HDR_PARSE_FAILURE 
AST_STIR_SHAKEN_VS_DATE_HDR_EXPIRED 
AST_STIR_SHAKEN_VS_NO_JWT_HDR 
AST_STIR_SHAKEN_VS_INVALID_OR_NO_X5U 
AST_STIR_SHAKEN_VS_CERT_CACHE_MISS 
AST_STIR_SHAKEN_VS_CERT_CACHE_INVALID 
AST_STIR_SHAKEN_VS_CERT_CACHE_EXPIRED 
AST_STIR_SHAKEN_VS_CERT_RETRIEVAL_FAILURE 
AST_STIR_SHAKEN_VS_CERT_CONTENTS_INVALID 
AST_STIR_SHAKEN_VS_CERT_NOT_TRUSTED 
AST_STIR_SHAKEN_VS_CERT_DATE_INVALID 
AST_STIR_SHAKEN_VS_CERT_NO_TN_AUTH_EXT 
AST_STIR_SHAKEN_VS_CERT_NO_SPC_IN_TN_AUTH_EXT 
AST_STIR_SHAKEN_VS_NO_RAW_KEY 
AST_STIR_SHAKEN_VS_SIGNATURE_VALIDATION 
AST_STIR_SHAKEN_VS_NO_IAT 
AST_STIR_SHAKEN_VS_IAT_EXPIRED 
AST_STIR_SHAKEN_VS_INVALID_OR_NO_PPT 
AST_STIR_SHAKEN_VS_INVALID_OR_NO_ALG 
AST_STIR_SHAKEN_VS_INVALID_OR_NO_TYP 
AST_STIR_SHAKEN_VS_INVALID_OR_NO_GRANTS 
AST_STIR_SHAKEN_VS_INVALID_OR_NO_ATTEST 
AST_STIR_SHAKEN_VS_NO_ORIGID 
AST_STIR_SHAKEN_VS_NO_ORIG_TN 
AST_STIR_SHAKEN_VS_CID_ORIG_TN_MISMATCH 
AST_STIR_SHAKEN_VS_NO_DEST_TN 
AST_STIR_SHAKEN_VS_INVALID_HEADER 
AST_STIR_SHAKEN_VS_INVALID_GRANT 
AST_STIR_SHAKEN_VS_RESPONSE_CODE_MAX 

Definition at line 23 of file res_stir_shaken.h.

23 {
59};
@ 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_CERT_NO_SPC_IN_TN_AUTH_EXT
@ AST_STIR_SHAKEN_VS_RESPONSE_CODE_MAX
@ 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

Enumerator
stir_shaken_failure_action_UNKNOWN 

Unknown value

stir_shaken_failure_action_CONTINUE 

Continue and let dialplan decide action

stir_shaken_failure_action_REJECT_REQUEST 

Reject request with respone codes defined in RFC8224

stir_shaken_failure_action_CONTINUE_RETURN_REASON 

Continue but return a Reason header in next provisional response

stir_shaken_failure_action_NOT_SET 

Not set in config

Definition at line 78 of file res_stir_shaken.h.

78 {
79 /*! Unknown value */
81 /*! Continue and let dialplan decide action */
83 /*! Reject request with respone codes defined in RFC8224 */
85 /*! Continue but return a Reason header in next provisional response */
87 /*! Not set in config */
89};
@ stir_shaken_failure_action_CONTINUE
@ stir_shaken_failure_action_CONTINUE_RETURN_REASON
@ stir_shaken_failure_action_UNKNOWN
@ stir_shaken_failure_action_NOT_SET
@ stir_shaken_failure_action_REJECT_REQUEST

Function Documentation

◆ ast_stir_shaken_add_result_to_channel()

int ast_stir_shaken_add_result_to_channel ( struct ast_stir_shaken_vs_ctx ctx)

Add a STIR/SHAKEN verification result to a channel.

Parameters
ctxVS context
Return values
-1on failure
0on success

Definition at line 89 of file res_stir_shaken.c.

91{
93 struct ast_datastore *chan_datastore;
94 const char *chan_name;
95
96 if (!ctx->chan) {
97 ast_log(LOG_ERROR, "Channel is required to add STIR/SHAKEN verification\n");
98 return -1;
99 }
100
101 chan_name = ast_channel_name(ctx->chan);
102
103 if (!ctx->identity_hdr) {
104 ast_log(LOG_ERROR, "No identity to add STIR/SHAKEN verification to channel "
105 "%s\n", chan_name);
106 return -1;
107 }
108
109 if (!ctx->attestation) {
110 ast_log(LOG_ERROR, "Attestation cannot be NULL to add STIR/SHAKEN verification to "
111 "channel %s\n", chan_name);
112 return -1;
113 }
114
116 if (!stir_datastore) {
117 ast_log(LOG_ERROR, "Failed to allocate space for STIR/SHAKEN datastore for "
118 "channel %s\n", chan_name);
119 return -1;
120 }
121
123 if (!stir_datastore->identity) {
124 ast_log(LOG_ERROR, "Failed to allocate space for STIR/SHAKEN datastore "
125 "identity for channel %s\n", chan_name);
127 return -1;
128 }
129
132 ast_log(LOG_ERROR, "Failed to allocate space for STIR/SHAKEN datastore "
133 "attestation for channel %s\n", chan_name);
135 return -1;
136 }
137
139
141 if (!chan_datastore) {
142 ast_log(LOG_ERROR, "Failed to allocate space for datastore for channel "
143 "%s\n", chan_name);
145 return -1;
146 }
147
148 chan_datastore->data = stir_datastore;
149
151 ast_channel_datastore_add(ctx->chan, chan_datastore);
153
154 return 0;
155}
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
const char * ast_channel_name(const struct ast_channel *chan)
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2385
#define ast_channel_lock(chan)
Definition: channel.h:2922
#define ast_channel_unlock(chan)
Definition: channel.h:2923
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
#define LOG_ERROR
static const struct ast_datastore_info stir_shaken_datastore_info
static void stir_datastore_free(struct stir_datastore *datastore)
Frees a stir_shaken_datastore structure.
#define NULL
Definition: resample.c:96
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66
const ast_string_field attestation
Definition: verification.h:39
const ast_string_field identity_hdr
Definition: verification.h:39
struct ast_channel * chan
Definition: verification.h:41
enum ast_stir_shaken_vs_response_code failure_reason
Definition: verification.h:48
enum ast_stir_shaken_vs_response_code verify_result

References ast_calloc, ast_channel_datastore_add(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_datastore_alloc, ast_log, ast_strdup, stir_datastore::attestation, ast_stir_shaken_vs_ctx::attestation, ast_stir_shaken_vs_ctx::chan, ast_datastore::data, ast_stir_shaken_vs_ctx::failure_reason, stir_datastore::identity, ast_stir_shaken_vs_ctx::identity_hdr, LOG_ERROR, NULL, stir_datastore_free(), stir_shaken_datastore_info, and stir_datastore::verify_result.

Referenced by process_failure(), and stir_shaken_incoming_request().

◆ ast_stir_shaken_as_ctx_add_fingerprint()

enum ast_stir_shaken_as_response_code ast_stir_shaken_as_ctx_add_fingerprint ( struct ast_stir_shaken_as_ctx ctx,
const char *  alg,
const char *  fingerprint 
)

Add DTLS fingerprints to AS context.

Parameters
ctxAS context
algFingerprint algorithm ("sha-1" or "sha-256")
fingerprintFingerprint
Return values
AST_STIR_SHAKEN_AS_SUCCESSif successful
OtherAST_STIR_SHAKEN_AS errors.

Definition at line 202 of file attestation.c.

204{
205 char *compacted_fp = ast_alloca(strlen(fingerprint) + 1);
206 const char *f = fingerprint;
207 char *fp = compacted_fp;
208 char *combined;
209 int rc;
210 SCOPE_ENTER(4, "%s: Add fingerprint %s:%s\n", ctx ? ctx->tag : "",
211 alg, fingerprint);
212
213 if (!ctx || ast_strlen_zero(alg) || ast_strlen_zero(fingerprint)) {
215 "%s: Missing arguments\n", ctx->tag);
216 }
217
218 if (!ENUM_BOOL(ctx->etn->acfg_common.send_mky, send_mky)) {
220 "%s: Not needed\n", ctx->tag);
221 }
222
223 /* De-colonize */
224 while (*f != '\0') {
225 if (*f != ':') {
226 *fp++ = *f;
227 }
228 f++;
229 }
230 *fp = '\0';
231 rc = ast_asprintf(&combined, "%s:%s", alg, compacted_fp);
232 if (rc < 0) {
234 "%s: Can't allocate memory for comobined string\n", ctx->tag);
235 }
236
237 rc = AST_VECTOR_ADD_SORTED(&ctx->fingerprints, combined, strcasecmp);
238 if (rc < 0) {
240 "%s: Can't add entry to vector\n", ctx->tag);
241 }
242
244 "%s: Done\n", ctx->tag);
245}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
#define ENUM_BOOL(__enum1, __field)
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
#define SCOPE_ENTER(level,...)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
struct tn_cfg * etn
Definition: attestation.h:32
const ast_string_field tag
Definition: attestation.h:29
struct ast_vector_string fingerprints
Definition: attestation.h:31
enum send_mky_enum send_mky
struct attestation_cfg_common acfg_common
#define AST_VECTOR_ADD_SORTED(vec, elem, cmp)
Add an element into a sorted vector.
Definition: vector.h:371

References tn_cfg::acfg_common, ast_alloca, ast_asprintf, AST_STIR_SHAKEN_AS_DISABLED, AST_STIR_SHAKEN_AS_INTERNAL_ERROR, AST_STIR_SHAKEN_AS_INVALID_ARGUMENTS, AST_STIR_SHAKEN_AS_SUCCESS, ast_strlen_zero(), AST_VECTOR_ADD_SORTED, ENUM_BOOL, ast_stir_shaken_as_ctx::etn, ast_stir_shaken_as_ctx::fingerprints, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, attestation_cfg_common::send_mky, and ast_stir_shaken_as_ctx::tag.

Referenced by add_fingerprints_if_present().

◆ ast_stir_shaken_as_ctx_create()

enum ast_stir_shaken_as_response_code ast_stir_shaken_as_ctx_create ( const char *  caller_id,
const char *  dest_tn,
struct ast_channel chan,
const char *  profile_name,
const char *  tag,
struct ast_stir_shaken_as_ctx **  ctxout 
)

Create Attestation Service Context.

Parameters
caller_idThe caller_id for the outgoing call
dest_tnCanonicalized destination tn
chanThe outgoing channel
profile_nameThe profile name on the endpoint May be NULL.
tagIdentifying string to output in log and trace messages.
ctxoutReceives a pointer to the newly created context The caller must release with ao2_ref or ao2_cleanup.
Return values
AST_STIR_SHAKEN_AS_SUCCESSif successful.
AST_STIR_SHAKEN_AS_DISABLEDif attestation is disabled by the endpoint itself, the profile or globally.
OtherAST_STIR_SHAKEN_AS errors.

Definition at line 66 of file attestation.c.

70{
72 RAII_VAR(struct profile_cfg *, eprofile, NULL, ao2_cleanup);
73 RAII_VAR(struct attestation_cfg *, as_cfg, NULL, ao2_cleanup);
74 RAII_VAR(struct tn_cfg *, etn, NULL, ao2_cleanup);
75 SCOPE_ENTER(3, "%s: Enter\n", tag);
76
77 if (ast_strlen_zero(orig_tn)) {
79 LOG_ERROR, "%s: Must provide caller_id/orig_tn\n", tag);
80 }
81
82 if (ast_strlen_zero(dest_tn)) {
84 LOG_ERROR, "%s: Must provide dest_tn\n", tag);
85 }
86
87 if (ast_strlen_zero(tag)) {
89 LOG_ERROR, "%s: Must provide tag\n", tag);
90 }
91
92 if (!ctxout) {
94 LOG_ERROR, "%s: Must provide ctxout\n", tag);
95 }
96
97 if (ast_strlen_zero(profile_name)) {
99 "%s: Disabled due to missing profile name\n", tag);
100 }
101
102 as_cfg = as_get_cfg();
103 if (as_cfg->global_disable) {
105 "%s: Globally disabled\n", tag);
106 }
107
108 eprofile = eprofile_get_cfg(profile_name);
109 if (!eprofile) {
111 LOG_ERROR, "%s: No profile for profile name '%s'. Call will continue\n", tag,
112 profile_name);
113 }
114
115 if (!PROFILE_ALLOW_ATTEST(eprofile)) {
117 "%s: Disabled by profile\n", tag);
118 }
119
120 etn = tn_get_etn(orig_tn, eprofile);
121 if (!etn) {
123 "%s: No tn for orig_tn '%s'\n", tag, orig_tn);
124 }
125
126 /* We don't need eprofile or as_cfg anymore so let's clean em up */
127 ao2_cleanup(as_cfg);
128 as_cfg = NULL;
129 ao2_cleanup(eprofile);
130 eprofile = NULL;
131
132
133 if (etn->acfg_common.attest_level == attest_level_NOT_SET) {
135 LOG_ERROR,
136 "'%s': No attest_level specified in tn, profile or attestation objects\n",
137 tag);
138 }
139
140 if (ast_strlen_zero(etn->acfg_common.public_cert_url)) {
142 LOG_ERROR, "%s: No public cert url in tn %s, profile or attestation objects\n",
143 tag, orig_tn);
144 }
145
146 if (etn->acfg_common.raw_key_length == 0) {
148 LOG_ERROR, "%s: No private key in tn %s, profile or attestation objects\n",
149 orig_tn, tag);
150 }
151
152 ctx = ao2_alloc_options(sizeof(*ctx), ctx_destructor,
154 if (!ctx) {
156 LOG_ERROR, "%s: Unable to allocate memory for ctx\n", tag);
157 }
158
159 if (ast_string_field_init(ctx, 1024) != 0) {
161 LOG_ERROR, "%s: Unable to allocate memory for ctx\n", tag);
162 }
163
164 if (ast_string_field_set(ctx, tag, tag) != 0) {
166 LOG_ERROR, "%s: Unable to allocate memory for ctx\n", tag);
167 }
168
169 if (ast_string_field_set(ctx, orig_tn, orig_tn) != 0) {
171 LOG_ERROR, "%s: Unable to allocate memory for ctx\n", tag);
172 }
173
174 if (ast_string_field_set(ctx, dest_tn, dest_tn)) {
176 LOG_ERROR, "%s: Unable to allocate memory for ctx\n", tag);
177 }
178
179 ctx->chan = chan;
180 ast_channel_ref(ctx->chan);
181
182 if (AST_VECTOR_INIT(&ctx->fingerprints, 1) != 0) {
184 LOG_ERROR, "%s: Unable to allocate memory for ctx\n", tag);
185 }
186
187 /* Transfer the references */
188 ctx->etn = etn;
189 etn = NULL;
190 *ctxout = ctx;
191 ctx = NULL;
192
194}
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
static void ctx_destructor(void *obj)
Definition: attestation.c:54
struct attestation_cfg * as_get_cfg(void)
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2947
struct profile_cfg * eprofile_get_cfg(const char *id)
#define PROFILE_ALLOW_ATTEST(__profile)
struct tn_cfg * tn_get_etn(const char *tn, struct profile_cfg *eprofile)
Definition: tn_config.c:116
#define SCOPE_EXIT_LOG_RTN_VALUE(__value, __log_level,...)
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
Profile configuration for stir/shaken.
TN configuration for stir/shaken.
#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:941
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113

References tn_cfg::acfg_common, AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, as_get_cfg(), ast_channel_ref, AST_STIR_SHAKEN_AS_DISABLED, AST_STIR_SHAKEN_AS_INTERNAL_ERROR, AST_STIR_SHAKEN_AS_INVALID_ARGUMENTS, AST_STIR_SHAKEN_AS_MISSING_PARAMETERS, AST_STIR_SHAKEN_AS_NO_PRIVATE_KEY_AVAIL, AST_STIR_SHAKEN_AS_NO_PUBLIC_CERT_URL_AVAIL, AST_STIR_SHAKEN_AS_SUCCESS, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), AST_VECTOR_INIT, attestation_cfg_common::attest_level, ast_stir_shaken_as_ctx::chan, ctx_destructor(), ast_stir_shaken_as_ctx::dest_tn, eprofile_get_cfg(), ast_stir_shaken_as_ctx::etn, LOG_ERROR, NULL, ast_stir_shaken_as_ctx::orig_tn, PROFILE_ALLOW_ATTEST, attestation_cfg_common::public_cert_url, RAII_VAR, attestation_cfg_common::raw_key_length, SCOPE_ENTER, SCOPE_EXIT_LOG_RTN_VALUE, SCOPE_EXIT_RTN_VALUE, ast_stir_shaken_as_ctx::tag, and tn_get_etn().

Referenced by stir_shaken_outgoing_request().

◆ ast_stir_shaken_as_ctx_wants_fingerprints()

int ast_stir_shaken_as_ctx_wants_fingerprints ( struct ast_stir_shaken_as_ctx ctx)

Indicates if the AS context needs DTLS fingerprints.

Parameters
ctxAS Context
Return values
0Not needed
1Needed

Definition at line 196 of file attestation.c.

197{
198 return ENUM_BOOL(ctx->etn->acfg_common.send_mky, send_mky);
199}

References tn_cfg::acfg_common, ENUM_BOOL, ast_stir_shaken_as_ctx::etn, and attestation_cfg_common::send_mky.

Referenced by add_fingerprints_if_present().

◆ ast_stir_shaken_attest()

enum ast_stir_shaken_as_response_code ast_stir_shaken_attest ( struct ast_stir_shaken_as_ctx ctx,
char **  header 
)

Attest and return Identity header value.

Parameters
ctxAS Context
headerPointer to buffer to receive the header value Must be freed with ast_free when done
Return values
AST_STIR_SHAKEN_AS_SUCCESSif successful
OtherAST_STIR_SHAKEN_AS errors.

Definition at line 360 of file attestation.c.

362{
363 RAII_VAR(jwt_t *, jwt, NULL, jwt_free);
364 jwt_alg_t alg;
365 char *encoded = NULL;
367 int rc = 0;
368 SCOPE_ENTER(3, "%s: Attestation: orig: %s dest: %s\n",
369 ctx ? ctx->tag : "NULL", ctx ? ctx->orig_tn : "NULL",
370 ctx ? ctx->dest_tn : "NULL");
371
372 if (!ctx) {
374 "%s: No context object!\n", "NULL");
375 }
376
377 if (header == NULL) {
379 LOG_ERROR, "%s: Header buffer was NULL\n", ctx->tag);
380 }
381
382 rc = jwt_new(&jwt);
383 if (rc != 0) {
385 LOG_ERROR, "%s: Cannot create JWT\n", ctx->tag);
386 }
387
388 /*
389 * All headers added need to be in alphabetical order!
390 */
391 alg = jwt_str_alg(STIR_SHAKEN_ENCRYPTION_ALGORITHM);
392 jwt_set_alg(jwt, alg, (const unsigned char *)ctx->etn->acfg_common.raw_key,
394 jwt_add_header(jwt, "ppt", STIR_SHAKEN_PPT);
395 jwt_add_header(jwt, "typ", STIR_SHAKEN_TYPE);
396 jwt_add_header(jwt, "x5u", ctx->etn->acfg_common.public_cert_url);
397
398 as_rc = pack_payload(ctx, jwt);
399 if (as_rc != AST_STIR_SHAKEN_AS_SUCCESS) {
401 LOG_ERROR, "%s: Cannot pack payload\n", ctx->tag);
402 }
403
404 encoded = jwt_encode_str(jwt);
405 if (!encoded) {
407 LOG_ERROR, "%s: Unable to sign/encode JWT\n", ctx->tag);
408 }
409
410 rc = ast_asprintf(header, "%s;info=<%s>;alg=%s;ppt=%s",
411 encoded, ctx->etn->acfg_common.public_cert_url, jwt_alg_str(alg),
413 ast_std_free(encoded);
414 if (rc < 0) {
416 LOG_ERROR, "%s: Unable to allocate memory for identity header\n",
417 ctx->tag);
418 }
419
421}
void ast_std_free(void *ptr)
Definition: astmm.c:1734
static enum ast_stir_shaken_as_response_code pack_payload(struct ast_stir_shaken_as_ctx *ctx, jwt_t *jwt)
Definition: attestation.c:286
ast_stir_shaken_as_response_code
#define STIR_SHAKEN_ENCRYPTION_ALGORITHM
Definition: stir_shaken.h:28
#define STIR_SHAKEN_PPT
Definition: stir_shaken.h:29
#define STIR_SHAKEN_TYPE
Definition: stir_shaken.h:30
const ast_string_field dest_tn
Definition: attestation.h:29
const ast_string_field orig_tn
Definition: attestation.h:29
unsigned char * raw_key
const ast_string_field public_cert_url

References tn_cfg::acfg_common, ast_asprintf, ast_std_free(), AST_STIR_SHAKEN_AS_INTERNAL_ERROR, AST_STIR_SHAKEN_AS_INVALID_ARGUMENTS, AST_STIR_SHAKEN_AS_SIGN_ENCODE_FAILURE, AST_STIR_SHAKEN_AS_SUCCESS, AST_STIR_SHAKEN_VS_INTERNAL_ERROR, ast_stir_shaken_as_ctx::dest_tn, ast_stir_shaken_as_ctx::etn, LOG_ERROR, NULL, ast_stir_shaken_as_ctx::orig_tn, pack_payload(), attestation_cfg_common::public_cert_url, RAII_VAR, attestation_cfg_common::raw_key, attestation_cfg_common::raw_key_length, SCOPE_ENTER, SCOPE_EXIT_LOG_RTN_VALUE, SCOPE_EXIT_RTN_VALUE, STIR_SHAKEN_ENCRYPTION_ALGORITHM, STIR_SHAKEN_PPT, STIR_SHAKEN_TYPE, and ast_stir_shaken_as_ctx::tag.

Referenced by stir_shaken_outgoing_request().

◆ ast_stir_shaken_vs_ctx_add_date_hdr()

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.

Parameters
ctxVS context
date_hdrDate header value
Return values
AST_STIR_SHAKEN_VS_SUCCESSif successful
OtherAST_STIR_SHAKEN_VS errors.

Definition at line 613 of file verification.c.

615{
616 return ast_string_field_set(ctx, date_hdr, date_hdr) == 0 ?
618}

References AST_STIR_SHAKEN_VS_INTERNAL_ERROR, AST_STIR_SHAKEN_VS_SUCCESS, and ast_string_field_set.

Referenced by stir_shaken_incoming_request().

◆ ast_stir_shaken_vs_ctx_add_identity_hdr()

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.

Parameters
ctxVS context
identity_hdrIdentity header value
Return values
AST_STIR_SHAKEN_VS_SUCCESSif successful
OtherAST_STIR_SHAKEN_VS errors.

Definition at line 605 of file verification.c.

607{
608 return ast_string_field_set(ctx, identity_hdr, identity_hdr) == 0 ?
610}

References AST_STIR_SHAKEN_VS_INTERNAL_ERROR, AST_STIR_SHAKEN_VS_SUCCESS, and ast_string_field_set.

Referenced by stir_shaken_incoming_request().

◆ ast_stir_shaken_vs_ctx_create()

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.

Parameters
caller_idIncoming caller id
chanIncoming channel
profile_nameThe profile name on the endpoint May be NULL.
endpoint_behaviorBehavior associated to the specific endpoint
tagIdentifying string to output in log and trace messages.
ctxoutReceives a pointer to the newly created context The caller must release with ao2_ref or ao2_cleanup.
Return values
AST_STIR_SHAKEN_VS_SUCCESSif successful.
AST_STIR_SHAKEN_VS_DISABLEDif verification is disabled by the endpoint itself, the profile or globally.
OtherAST_STIR_SHAKEN_VS errors.

Definition at line 651 of file verification.c.

654{
656 RAII_VAR(struct profile_cfg *, profile, NULL, ao2_cleanup);
658 const char *t = S_OR(tag, S_COR(chan, ast_channel_name(chan), ""));
659 SCOPE_ENTER(3, "%s: Enter\n", t);
660
661 if (ast_strlen_zero(tag)) {
663 LOG_ERROR, "%s: Must provide tag\n", t);
664 }
665
666 if (ast_strlen_zero(caller_id)) {
668 LOG_ERROR, "%s: Must provide caller_id\n", t);
669 }
670
671 if (ast_strlen_zero(profile_name)) {
673 "%s: Disabled due to missing profile name\n", t);
674 }
675
676 vs = vs_get_cfg();
677 if (vs->global_disable) {
679 "%s: Globally disabled\n", t);
680 }
681
682 profile = eprofile_get_cfg(profile_name);
683 if (!profile) {
685 LOG_ERROR, "%s: No profile for profile name '%s'. Call will continue\n", tag,
686 profile_name);
687 }
688
689 if (!PROFILE_ALLOW_VERIFY(profile)) {
691 "%s: Disabled by profile\n", t);
692 }
693
694 ctx = ao2_alloc_options(sizeof(*ctx), ctx_destructor,
696 if (!ctx) {
698 }
699 if (ast_string_field_init(ctx, 1024) != 0) {
701 }
702
703 if (ast_string_field_set(ctx, tag, tag) != 0) {
705 }
706
707 ctx->chan = chan;
708 if (ast_string_field_set(ctx, caller_id, caller_id) != 0) {
710 }
711
712 /* Transfer references to ctx */
713 ctx->eprofile = profile;
714 profile = NULL;
715
716 ao2_ref(ctx, +1);
717 *ctxout = ctx;
719}
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
struct verification_cfg * vs_get_cfg(void)
#define PROFILE_ALLOW_VERIFY(__profile)
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:87
static void ctx_destructor(void *obj)
Definition: verification.c:640

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_ref, ast_channel_name(), AST_STIR_SHAKEN_VS_DISABLED, AST_STIR_SHAKEN_VS_INTERNAL_ERROR, AST_STIR_SHAKEN_VS_INVALID_ARGUMENTS, AST_STIR_SHAKEN_VS_SUCCESS, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_stir_shaken_vs_ctx::caller_id, ast_stir_shaken_vs_ctx::chan, ctx_destructor(), eprofile_get_cfg(), LOG_ERROR, NULL, PROFILE_ALLOW_VERIFY, RAII_VAR, S_COR, S_OR, SCOPE_ENTER, SCOPE_EXIT_LOG_RTN_VALUE, SCOPE_EXIT_RTN_VALUE, ast_stir_shaken_vs_ctx::tag, and vs_get_cfg().

Referenced by stir_shaken_incoming_request().

◆ ast_stir_shaken_vs_ctx_set_response_code()

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.

Parameters
ctxVS context
vs_rcast_stir_shaken_vs_response_code to set

Definition at line 633 of file verification.c.

636{
637 ctx->failure_reason = vs_rc;
638}

References ast_stir_shaken_vs_ctx::failure_reason.

Referenced by process_failure().

◆ ast_stir_shaken_vs_get_failure_action()

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.

Parameters
ctxVS context
Return values
ast_stir_shaken_failure_action

Definition at line 621 of file verification.c.

623{
625}
struct profile_cfg * eprofile
Definition: verification.h:40
struct verification_cfg_common vcfg_common
enum stir_shaken_failure_action_enum stir_shaken_failure_action

References ast_stir_shaken_vs_ctx::eprofile, verification_cfg_common::stir_shaken_failure_action, and profile_cfg::vcfg_common.

Referenced by process_failure().

◆ ast_stir_shaken_vs_get_use_rfc9410_responses()

int ast_stir_shaken_vs_get_use_rfc9410_responses ( struct ast_stir_shaken_vs_ctx ctx)

Get use_rfc9410_responses from context.

Parameters
ctxVS context
Return values
1if true
0if false

Definition at line 627 of file verification.c.

629{
631}
enum use_rfc9410_responses_enum use_rfc9410_responses

References ast_stir_shaken_vs_ctx::eprofile, verification_cfg_common::use_rfc9410_responses, and profile_cfg::vcfg_common.

Referenced by process_failure().

◆ ast_stir_shaken_vs_verify()

enum ast_stir_shaken_vs_response_code ast_stir_shaken_vs_verify ( struct ast_stir_shaken_vs_ctx ctx)

Perform incoming call verification.

Parameters
ctxVS context
Return values
AST_STIR_SHAKEN_AS_SUCCESSif successful
OtherAST_STIR_SHAKEN_AS errors.

Definition at line 881 of file verification.c.

882{
883 RAII_VAR(char *, jwt_encoded, NULL, ast_free);
884 RAII_VAR(jwt_t *, jwt, NULL, jwt_free);
885 RAII_VAR(struct ast_json *, grants, NULL, ast_json_unref);
886 char *p = NULL;
887 char *grants_str = NULL;
888 const char *x5u;
889 const char *ppt_header = NULL;
890 const char *grant = NULL;
891 time_t now_s = time(NULL);
892 time_t iat;
893 struct ast_json *grant_obj = NULL;
894 int len;
895 int rc;
897 SCOPE_ENTER(3, "%s: Verifying\n", ctx ? ctx->tag : "NULL");
898
899 if (!ctx) {
901 "%s: No context object!\n", "NULL");
902 }
903
904 if (ast_strlen_zero(ctx->identity_hdr)) {
906 "%s: No identity header in ctx\n", ctx->tag);
907 }
908
909 p = strchr(ctx->identity_hdr, ';');
910 len = p - ctx->identity_hdr + 1;
911 jwt_encoded = ast_malloc(len);
912 if (!jwt_encoded) {
914 "%s: Failed to allocate memory for encoded jwt\n", ctx->tag);
915 }
916
917 memcpy(jwt_encoded, ctx->identity_hdr, len);
918 jwt_encoded[len - 1] = '\0';
919
920 jwt_decode(&jwt, jwt_encoded, NULL, 0);
921
922 ppt_header = jwt_get_header(jwt, "ppt");
923 if (!ppt_header || strcmp(ppt_header, STIR_SHAKEN_PPT)) {
926 }
927
928 vs_rc = check_date_header(ctx);
929 if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
931 "%s: Date header verification failed\n", ctx->tag);
932 }
933
934 x5u = jwt_get_header(jwt, "x5u");
935 if (ast_strlen_zero(x5u)) {
937 "%s: No x5u in Identity header\n", ctx->tag);
938 }
939
940 rc = check_x5u_url(ctx, x5u);
941 if (rc != AST_STIR_SHAKEN_VS_SUCCESS) {
943 "%s: x5u URL verification failed\n", ctx->tag);
944 }
945
946 ast_trace(3, "%s: Decoded enough to get x5u: '%s'\n", ctx->tag, x5u);
947 if (ast_string_field_set(ctx, public_url, x5u) != 0) {
949 "%s: Failed to set public_url '%s'\n", ctx->tag, x5u);
950 }
951
952 iat = jwt_get_grant_int(jwt, "iat");
953 if (iat == 0) {
955 "%s: No 'iat' in Identity header\n", ctx->tag);
956 }
957 ast_trace(1, "date_hdr: %zu iat: %zu diff: %zu\n",
958 ctx->date_hdr_time, iat, ctx->date_hdr_time - iat);
959 if (iat + ctx->eprofile->vcfg_common.max_iat_age < now_s) {
961 "%s: iat %ld older than %u seconds\n", ctx->tag,
962 iat, ctx->eprofile->vcfg_common.max_iat_age);
963 }
964 ctx->validity_check_time = iat;
965
966 vs_rc = ctx_populate(ctx);
967 if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
969 "%s: Unable to populate ctx\n", ctx->tag);
970 }
971
972 vs_rc = retrieve_verification_cert(ctx);
973 if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
975 "%s: Could not get valid cert from '%s'\n", ctx->tag, ctx->public_url);
976 }
977
978 jwt_free(jwt);
979 jwt = NULL;
980
981 rc = jwt_decode(&jwt, jwt_encoded, ctx->raw_key, ctx->raw_key_len);
982 if (rc != 0) {
984 LOG_ERROR, "%s: Signature validation failed for '%s'\n",
985 ctx->tag, ctx->public_url);
986 }
987
988 ast_trace(1, "%s: Decoding succeeded\n", ctx->tag);
989
990 ppt_header = jwt_get_header(jwt, "alg");
991 if (!ppt_header || strcmp(ppt_header, STIR_SHAKEN_ENCRYPTION_ALGORITHM)) {
993 "%s: %s\n", ctx->tag,
995 }
996
997 ppt_header = jwt_get_header(jwt, "ppt");
998 if (!ppt_header || strcmp(ppt_header, STIR_SHAKEN_PPT)) {
1000 "%s: %s\n", ctx->tag,
1002 }
1003
1004 ppt_header = jwt_get_header(jwt, "typ");
1005 if (!ppt_header || strcmp(ppt_header, STIR_SHAKEN_TYPE)) {
1007 "%s: %s\n", ctx->tag,
1009 }
1010
1011 grants_str = jwt_get_grants_json(jwt, NULL);
1012 if (ast_strlen_zero(grants_str)) {
1014 "%s: %s\n", ctx->tag,
1016 }
1017 ast_trace(1, "grants: %s\n", grants_str);
1018 grants = ast_json_load_string(grants_str, NULL);
1019 ast_std_free(grants_str);
1020 if (!grants) {
1022 "%s: %s\n", ctx->tag,
1024 }
1025
1026 grant = ast_json_object_string_get(grants, "attest");
1027 if (ast_strlen_zero(grant)) {
1029 "%s: No 'attest' in Identity header\n", ctx->tag);
1030 }
1031 if (grant[0] < 'A' || grant[0] > 'C') {
1033 "%s: Invalid attest value '%s'\n", ctx->tag, grant);
1034 }
1035 ast_string_field_set(ctx, attestation, grant);
1036 ast_trace(1, "got attest: %s\n", grant);
1037
1038 grant_obj = ast_json_object_get(grants, "dest");
1039 if (!grant_obj) {
1041 "%s: No 'dest' in Identity header\n", ctx->tag);
1042 }
1043 if (TRACE_ATLEAST(3)) {
1044 char *otn = ast_json_dump_string(grant_obj);
1045 ast_trace(1, "got dest: %s\n", otn);
1046 ast_json_free(otn);
1047 }
1048
1049 grant_obj = ast_json_object_get(grants, "orig");
1050 if (!grant_obj) {
1052 "%s: No 'orig' in Identity header\n", ctx->tag);
1053 }
1054 if (TRACE_ATLEAST(3)) {
1055 char *otn = ast_json_dump_string(grant_obj);
1056 ast_trace(1, "got orig: %s\n", otn);
1057 ast_json_free(otn);
1058 }
1059 grant = ast_json_object_string_get(grant_obj, "tn");
1060 if (!grant) {
1062 "%s: No 'orig.tn' in Indentity header\n", ctx->tag);
1063 }
1064 ast_string_field_set(ctx, orig_tn, grant);
1065 if (strcmp(ctx->caller_id, ctx->orig_tn) != 0) {
1067 "%s: Mismatched cid '%s' and orig_tn '%s'\n", ctx->tag,
1068 ctx->caller_id, grant);
1069 }
1070
1071 grant = ast_json_object_string_get(grants, "origid");
1072 if (ast_strlen_zero(grant)) {
1074 "%s: No 'origid' in Identity header\n", ctx->tag);
1075 }
1076
1078 "%s: verification succeeded\n", ctx->tag);
1079}
#define ast_free(a)
Definition: astmm.h:180
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define TRACE_ATLEAST(level)
#define ast_trace(level,...)
#define ast_json_object_string_get(object, key)
Get a string field from a JSON object.
Definition: json.h:600
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
void ast_json_free(void *p)
Asterisk's custom JSON allocator. Exposed for use by unit tests.
Definition: json.c:52
#define ast_json_dump_string(root)
Encode a JSON value to a compact string.
Definition: json.h:810
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:567
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:407
ast_stir_shaken_vs_response_code
Abstract JSON element (object, array, string, int, ...).
const ast_string_field public_url
Definition: verification.h:39
const ast_string_field orig_tn
Definition: verification.h:39
unsigned char * raw_key
Definition: verification.h:45
const ast_string_field tag
Definition: verification.h:39
const ast_string_field caller_id
Definition: verification.h:39
static int check_x5u_url(struct ast_stir_shaken_vs_ctx *ctx, const char *x5u)
Definition: verification.c:823
const char * vs_response_code_to_str(enum ast_stir_shaken_vs_response_code vs_rc)
Return string version of VS response code.
Definition: verification.c:90
static enum ast_stir_shaken_vs_response_code retrieve_verification_cert(struct ast_stir_shaken_vs_ctx *ctx)
Definition: verification.c:576
static enum ast_stir_shaken_vs_response_code check_date_header(struct ast_stir_shaken_vs_ctx *ctx)
Definition: verification.c:721
static enum ast_stir_shaken_vs_response_code ctx_populate(struct ast_stir_shaken_vs_ctx *ctx)
Definition: verification.c:548

References ast_free, ast_json_dump_string, ast_json_free(), ast_json_load_string(), ast_json_object_get(), ast_json_object_string_get, ast_json_unref(), ast_malloc, ast_std_free(), AST_STIR_SHAKEN_VS_CID_ORIG_TN_MISMATCH, AST_STIR_SHAKEN_VS_IAT_EXPIRED, AST_STIR_SHAKEN_VS_INTERNAL_ERROR, AST_STIR_SHAKEN_VS_INVALID_OR_NO_ALG, AST_STIR_SHAKEN_VS_INVALID_OR_NO_ATTEST, AST_STIR_SHAKEN_VS_INVALID_OR_NO_GRANTS, AST_STIR_SHAKEN_VS_INVALID_OR_NO_PPT, AST_STIR_SHAKEN_VS_INVALID_OR_NO_TYP, AST_STIR_SHAKEN_VS_INVALID_OR_NO_X5U, AST_STIR_SHAKEN_VS_NO_DEST_TN, AST_STIR_SHAKEN_VS_NO_IAT, AST_STIR_SHAKEN_VS_NO_ORIG_TN, AST_STIR_SHAKEN_VS_NO_ORIGID, AST_STIR_SHAKEN_VS_SIGNATURE_VALIDATION, AST_STIR_SHAKEN_VS_SUCCESS, ast_string_field_set, ast_strlen_zero(), ast_trace, ast_stir_shaken_vs_ctx::caller_id, check_date_header(), check_x5u_url(), ctx_populate(), ast_stir_shaken_vs_ctx::date_hdr_time, ast_stir_shaken_vs_ctx::eprofile, ast_stir_shaken_vs_ctx::identity_hdr, len(), LOG_ERROR, verification_cfg_common::max_iat_age, NULL, ast_stir_shaken_vs_ctx::orig_tn, ast_stir_shaken_vs_ctx::public_url, RAII_VAR, ast_stir_shaken_vs_ctx::raw_key, ast_stir_shaken_vs_ctx::raw_key_len, retrieve_verification_cert(), SCOPE_ENTER, SCOPE_EXIT_LOG_RTN_VALUE, SCOPE_EXIT_RTN_VALUE, STIR_SHAKEN_ENCRYPTION_ALGORITHM, STIR_SHAKEN_PPT, STIR_SHAKEN_TYPE, ast_stir_shaken_vs_ctx::tag, TRACE_ATLEAST, ast_stir_shaken_vs_ctx::validity_check_time, profile_cfg::vcfg_common, and vs_response_code_to_str().

Referenced by stir_shaken_incoming_request().