Asterisk - The Open Source Telephony Project GIT-master-97770a9
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:2404
#define ast_channel_lock(chan)
Definition: channel.h:2968
#define ast_channel_unlock(chan)
Definition: channel.h:2969
#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 206 of file attestation.c.

208{
209 char *compacted_fp = ast_alloca(strlen(fingerprint) + 1);
210 const char *f = fingerprint;
211 char *fp = compacted_fp;
212 char *combined;
213 int rc;
214 SCOPE_ENTER(4, "%s: Add fingerprint %s:%s\n", ctx ? ctx->tag : "",
215 alg, fingerprint);
216
217 if (!ctx || ast_strlen_zero(alg) || ast_strlen_zero(fingerprint)) {
219 "%s: Missing arguments\n", ctx->tag);
220 }
221
222 if (!ENUM_BOOL(ctx->etn->acfg_common.send_mky, send_mky)) {
224 "%s: Not needed\n", ctx->tag);
225 }
226
227 /* De-colonize */
228 while (*f != '\0') {
229 if (*f != ':') {
230 *fp++ = *f;
231 }
232 f++;
233 }
234 *fp = '\0';
235 rc = ast_asprintf(&combined, "%s:%s", alg, compacted_fp);
236 if (rc < 0) {
238 "%s: Can't allocate memory for comobined string\n", ctx->tag);
239 }
240
241 rc = AST_VECTOR_ADD_SORTED(&ctx->fingerprints, combined, strcasecmp);
242 if (rc < 0) {
244 "%s: Can't add entry to vector\n", ctx->tag);
245 }
246
248 "%s: Done\n", ctx->tag);
249}
#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 RAII_VAR(char *, canon_dest_tn , canonicalize_tn_alloc(dest_tn), ast_free);
76 RAII_VAR(char *, canon_orig_tn , canonicalize_tn_alloc(orig_tn), ast_free);
77
78 const char *t = S_OR(tag, S_COR(chan, ast_channel_name(chan), ""));
79 SCOPE_ENTER(3, "%s: Enter\n", t);
80
81 as_cfg = as_get_cfg();
82 if (as_cfg->global_disable) {
84 "%s: Globally disabled\n", t);
85 }
86
87 if (ast_strlen_zero(profile_name)) {
89 "%s: Disabled due to missing profile name\n", t);
90 }
91
92 eprofile = eprofile_get_cfg(profile_name);
93 if (!eprofile) {
95 LOG_ERROR, "%s: No profile for profile name '%s'. Call will continue\n", tag,
96 profile_name);
97 }
98
99 if (!PROFILE_ALLOW_ATTEST(eprofile)) {
101 "%s: Disabled by profile '%s'\n", t, profile_name);
102 }
103
104 if (ast_strlen_zero(tag)) {
106 LOG_ERROR, "%s: Must provide tag\n", t);
107 }
108
109 if (!canon_orig_tn) {
111 LOG_ERROR, "%s: Must provide caller_id/orig_tn\n", tag);
112 }
113
114 if (!canon_dest_tn) {
116 LOG_ERROR, "%s: Must provide dest_tn\n", tag);
117 }
118
119 if (!ctxout) {
121 LOG_ERROR, "%s: Must provide ctxout\n", tag);
122 }
123
124 etn = tn_get_etn(canon_orig_tn, eprofile);
125 if (!etn) {
127 "%s: No tn for orig_tn '%s'\n", tag, canon_orig_tn);
128 }
129
130 /* We don't need eprofile or as_cfg anymore so let's clean em up */
131 ao2_cleanup(as_cfg);
132 as_cfg = NULL;
133 ao2_cleanup(eprofile);
134 eprofile = NULL;
135
136
137 if (etn->acfg_common.attest_level == attest_level_NOT_SET) {
139 LOG_ERROR,
140 "'%s': No attest_level specified in tn, profile or attestation objects\n",
141 tag);
142 }
143
144 if (ast_strlen_zero(etn->acfg_common.public_cert_url)) {
146 LOG_ERROR, "%s: No public cert url in tn %s, profile or attestation objects\n",
147 tag, canon_orig_tn);
148 }
149
150 if (etn->acfg_common.raw_key_length == 0) {
152 LOG_ERROR, "%s: No private key in tn %s, profile or attestation objects\n",
153 canon_orig_tn, tag);
154 }
155
156 ctx = ao2_alloc_options(sizeof(*ctx), ctx_destructor,
158 if (!ctx) {
160 LOG_ERROR, "%s: Unable to allocate memory for ctx\n", tag);
161 }
162
163 if (ast_string_field_init(ctx, 1024) != 0) {
165 LOG_ERROR, "%s: Unable to allocate memory for ctx\n", tag);
166 }
167
168 if (ast_string_field_set(ctx, tag, tag) != 0) {
170 LOG_ERROR, "%s: Unable to allocate memory for ctx\n", tag);
171 }
172
173 if (ast_string_field_set(ctx, orig_tn, canon_orig_tn) != 0) {
175 LOG_ERROR, "%s: Unable to allocate memory for ctx\n", tag);
176 }
177
178 if (ast_string_field_set(ctx, dest_tn, canon_dest_tn)) {
180 LOG_ERROR, "%s: Unable to allocate memory for ctx\n", tag);
181 }
182
183 ctx->chan = chan;
184 ast_channel_ref(ctx->chan);
185
186 if (AST_VECTOR_INIT(&ctx->fingerprints, 1) != 0) {
188 LOG_ERROR, "%s: Unable to allocate memory for ctx\n", tag);
189 }
190
191 /* Transfer the references */
192 ctx->etn = etn;
193 etn = NULL;
194 *ctxout = ctx;
195 ctx = NULL;
196
198}
#define ast_free(a)
Definition: astmm.h:180
@ 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:2993
char * canonicalize_tn_alloc(const char *tn)
Canonicalize a TN into nre buffer.
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:109
#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
#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
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_name(), ast_channel_ref, ast_free, 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, canonicalize_tn_alloc(), 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, S_COR, S_OR, 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 200 of file attestation.c.

201{
202 return ENUM_BOOL(ctx->etn->acfg_common.send_mky, send_mky);
203}

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 364 of file attestation.c.

366{
367 RAII_VAR(jwt_t *, jwt, NULL, jwt_free);
368 jwt_alg_t alg;
369 char *encoded = NULL;
371 int rc = 0;
372 SCOPE_ENTER(3, "%s: Attestation: orig: %s dest: %s\n",
373 ctx ? ctx->tag : "NULL", ctx ? ctx->orig_tn : "NULL",
374 ctx ? ctx->dest_tn : "NULL");
375
376 if (!ctx) {
378 "%s: No context object!\n", "NULL");
379 }
380
381 if (header == NULL) {
383 LOG_ERROR, "%s: Header buffer was NULL\n", ctx->tag);
384 }
385
386 rc = jwt_new(&jwt);
387 if (rc != 0) {
389 LOG_ERROR, "%s: Cannot create JWT\n", ctx->tag);
390 }
391
392 /*
393 * All headers added need to be in alphabetical order!
394 */
395 alg = jwt_str_alg(STIR_SHAKEN_ENCRYPTION_ALGORITHM);
396 jwt_set_alg(jwt, alg, (const unsigned char *)ctx->etn->acfg_common.raw_key,
398 jwt_add_header(jwt, "ppt", STIR_SHAKEN_PPT);
399 jwt_add_header(jwt, "typ", STIR_SHAKEN_TYPE);
400 jwt_add_header(jwt, "x5u", ctx->etn->acfg_common.public_cert_url);
401
402 as_rc = pack_payload(ctx, jwt);
403 if (as_rc != AST_STIR_SHAKEN_AS_SUCCESS) {
405 LOG_ERROR, "%s: Cannot pack payload\n", ctx->tag);
406 }
407
408 encoded = jwt_encode_str(jwt);
409 if (!encoded) {
411 LOG_ERROR, "%s: Unable to sign/encode JWT\n", ctx->tag);
412 }
413
414 rc = ast_asprintf(header, "%s;info=<%s>;alg=%s;ppt=%s",
415 encoded, ctx->etn->acfg_common.public_cert_url, jwt_alg_str(alg),
417 ast_std_free(encoded);
418 if (rc < 0) {
420 LOG_ERROR, "%s: Unable to allocate memory for identity header\n",
421 ctx->tag);
422 }
423
425}
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:290
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 612 of file verification.c.

614{
615 return ast_string_field_set(ctx, date_hdr, date_hdr) == 0 ?
617}

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 604 of file verification.c.

606{
607 return ast_string_field_set(ctx, identity_hdr, identity_hdr) == 0 ?
609}

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 650 of file verification.c.

653{
655 RAII_VAR(struct profile_cfg *, profile, NULL, ao2_cleanup);
657 RAII_VAR(char *, canon_caller_id , canonicalize_tn_alloc(caller_id), ast_free);
658
659 const char *t = S_OR(tag, S_COR(chan, ast_channel_name(chan), ""));
660 SCOPE_ENTER(3, "%s: Enter\n", t);
661
662 vs = vs_get_cfg();
663 if (vs->global_disable) {
665 "%s: Globally disabled\n", t);
666 }
667
668 if (ast_strlen_zero(profile_name)) {
670 "%s: Disabled due to missing profile name\n", t);
671 }
672
673 profile = eprofile_get_cfg(profile_name);
674 if (!profile) {
676 LOG_ERROR, "%s: No profile for profile name '%s'. Call will continue\n", tag,
677 profile_name);
678 }
679
680 if (!PROFILE_ALLOW_VERIFY(profile)) {
682 "%s: Disabled by profile '%s'\n", t, profile_name);
683 }
684
685 if (ast_strlen_zero(tag)) {
687 LOG_ERROR, "%s: Must provide tag\n", t);
688 }
689
690 if (ast_strlen_zero(canon_caller_id)) {
692 LOG_ERROR, "%s: Must provide caller_id\n", t);
693 }
694
695 ctx = ao2_alloc_options(sizeof(*ctx), ctx_destructor,
697 if (!ctx) {
699 }
700 if (ast_string_field_init(ctx, 1024) != 0) {
702 }
703
704 if (ast_string_field_set(ctx, tag, tag) != 0) {
706 }
707
708 ctx->chan = chan;
709 if (ast_string_field_set(ctx, caller_id, canon_caller_id) != 0) {
711 }
712
713 /* Transfer references to ctx */
714 ctx->eprofile = profile;
715 profile = NULL;
716
717 ao2_ref(ctx, +1);
718 *ctxout = ctx;
720}
#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)
static void ctx_destructor(void *obj)
Definition: verification.c:639

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_ref, ast_channel_name(), ast_free, 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, canonicalize_tn_alloc(), 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 632 of file verification.c.

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

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 620 of file verification.c.

622{
624}
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 626 of file verification.c.

628{
630}
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 882 of file verification.c.

883{
884 RAII_VAR(char *, jwt_encoded, NULL, ast_free);
885 RAII_VAR(jwt_t *, jwt, NULL, jwt_free);
886 RAII_VAR(struct ast_json *, grants, NULL, ast_json_unref);
887 char *p = NULL;
888 char *grants_str = NULL;
889 const char *x5u;
890 const char *ppt_header = NULL;
891 const char *grant = NULL;
892 time_t now_s = time(NULL);
893 time_t iat;
894 struct ast_json *grant_obj = NULL;
895 int len;
896 int rc;
898 SCOPE_ENTER(3, "%s: Verifying\n", ctx ? ctx->tag : "NULL");
899
900 if (!ctx) {
902 "%s: No context object!\n", "NULL");
903 }
904
905 if (ast_strlen_zero(ctx->identity_hdr)) {
907 "%s: No identity header in ctx\n", ctx->tag);
908 }
909
910 p = strchr(ctx->identity_hdr, ';');
911 len = p - ctx->identity_hdr + 1;
912 jwt_encoded = ast_malloc(len);
913 if (!jwt_encoded) {
915 "%s: Failed to allocate memory for encoded jwt\n", ctx->tag);
916 }
917
918 memcpy(jwt_encoded, ctx->identity_hdr, len);
919 jwt_encoded[len - 1] = '\0';
920
921 jwt_decode(&jwt, jwt_encoded, NULL, 0);
922
923 ppt_header = jwt_get_header(jwt, "ppt");
924 if (!ppt_header || strcmp(ppt_header, STIR_SHAKEN_PPT)) {
927 }
928
929 vs_rc = check_date_header(ctx);
930 if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
932 "%s: Date header verification failed\n", ctx->tag);
933 }
934
935 x5u = jwt_get_header(jwt, "x5u");
936 if (ast_strlen_zero(x5u)) {
938 "%s: No x5u in Identity header\n", ctx->tag);
939 }
940
941 rc = check_x5u_url(ctx, x5u);
942 if (rc != AST_STIR_SHAKEN_VS_SUCCESS) {
944 "%s: x5u URL verification failed\n", ctx->tag);
945 }
946
947 ast_trace(3, "%s: Decoded enough to get x5u: '%s'\n", ctx->tag, x5u);
948 if (ast_string_field_set(ctx, public_url, x5u) != 0) {
950 "%s: Failed to set public_url '%s'\n", ctx->tag, x5u);
951 }
952
953 iat = jwt_get_grant_int(jwt, "iat");
954 if (iat == 0) {
956 "%s: No 'iat' in Identity header\n", ctx->tag);
957 }
958 ast_trace(1, "date_hdr: %zu iat: %zu diff: %zu\n",
959 ctx->date_hdr_time, iat, ctx->date_hdr_time - iat);
960 if (iat + ctx->eprofile->vcfg_common.max_iat_age < now_s) {
962 "%s: iat %ld older than %u seconds\n", ctx->tag,
963 iat, ctx->eprofile->vcfg_common.max_iat_age);
964 }
965 ctx->validity_check_time = iat;
966
967 vs_rc = ctx_populate(ctx);
968 if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
970 "%s: Unable to populate ctx\n", ctx->tag);
971 }
972
973 vs_rc = retrieve_verification_cert(ctx);
974 if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
976 "%s: Could not get valid cert from '%s'\n", ctx->tag, ctx->public_url);
977 }
978
979 jwt_free(jwt);
980 jwt = NULL;
981
982 rc = jwt_decode(&jwt, jwt_encoded, ctx->raw_key, ctx->raw_key_len);
983 if (rc != 0) {
985 LOG_ERROR, "%s: Signature validation failed for '%s'\n",
986 ctx->tag, ctx->public_url);
987 }
988
989 ast_trace(1, "%s: Decoding succeeded\n", ctx->tag);
990
991 ppt_header = jwt_get_header(jwt, "alg");
992 if (!ppt_header || strcmp(ppt_header, STIR_SHAKEN_ENCRYPTION_ALGORITHM)) {
994 "%s: %s\n", ctx->tag,
996 }
997
998 ppt_header = jwt_get_header(jwt, "ppt");
999 if (!ppt_header || strcmp(ppt_header, STIR_SHAKEN_PPT)) {
1001 "%s: %s\n", ctx->tag,
1003 }
1004
1005 ppt_header = jwt_get_header(jwt, "typ");
1006 if (!ppt_header || strcmp(ppt_header, STIR_SHAKEN_TYPE)) {
1008 "%s: %s\n", ctx->tag,
1010 }
1011
1012 grants_str = jwt_get_grants_json(jwt, NULL);
1013 if (ast_strlen_zero(grants_str)) {
1015 "%s: %s\n", ctx->tag,
1017 }
1018 ast_trace(1, "grants: %s\n", grants_str);
1019 grants = ast_json_load_string(grants_str, NULL);
1020 ast_std_free(grants_str);
1021 if (!grants) {
1023 "%s: %s\n", ctx->tag,
1025 }
1026
1027 grant = ast_json_object_string_get(grants, "attest");
1028 if (ast_strlen_zero(grant)) {
1030 "%s: No 'attest' in Identity header\n", ctx->tag);
1031 }
1032 if (grant[0] < 'A' || grant[0] > 'C') {
1034 "%s: Invalid attest value '%s'\n", ctx->tag, grant);
1035 }
1036 ast_string_field_set(ctx, attestation, grant);
1037 ast_trace(1, "got attest: %s\n", grant);
1038
1039 grant_obj = ast_json_object_get(grants, "dest");
1040 if (!grant_obj) {
1042 "%s: No 'dest' in Identity header\n", ctx->tag);
1043 }
1044 if (TRACE_ATLEAST(3)) {
1045 char *otn = ast_json_dump_string(grant_obj);
1046 ast_trace(1, "got dest: %s\n", otn);
1047 ast_json_free(otn);
1048 }
1049
1050 grant_obj = ast_json_object_get(grants, "orig");
1051 if (!grant_obj) {
1053 "%s: No 'orig' in Identity header\n", ctx->tag);
1054 }
1055 if (TRACE_ATLEAST(3)) {
1056 char *otn = ast_json_dump_string(grant_obj);
1057 ast_trace(1, "got orig: %s\n", otn);
1058 ast_json_free(otn);
1059 }
1060 grant = ast_json_object_string_get(grant_obj, "tn");
1061 if (!grant) {
1063 "%s: No 'orig.tn' in Indentity header\n", ctx->tag);
1064 }
1065 ast_string_field_set(ctx, orig_tn, grant);
1066 if (strcmp(ctx->caller_id, ctx->orig_tn) != 0) {
1068 "%s: Mismatched cid '%s' and orig_tn '%s'\n", ctx->tag,
1069 ctx->caller_id, grant);
1070 }
1071
1072 grant = ast_json_object_string_get(grants, "origid");
1073 if (ast_strlen_zero(grant)) {
1075 "%s: No 'origid' in Identity header\n", ctx->tag);
1076 }
1077
1079 "%s: verification succeeded\n", ctx->tag);
1080}
#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:824
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:89
static enum ast_stir_shaken_vs_response_code retrieve_verification_cert(struct ast_stir_shaken_vs_ctx *ctx)
Definition: verification.c:575
static enum ast_stir_shaken_vs_response_code check_date_header(struct ast_stir_shaken_vs_ctx *ctx)
Definition: verification.c:722
static enum ast_stir_shaken_vs_response_code ctx_populate(struct ast_stir_shaken_vs_ctx *ctx)
Definition: verification.c:547

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().