Asterisk - The Open Source Telephony Project GIT-master-55f4e6d
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 205 of file attestation.c.

207{
208 char *compacted_fp = ast_alloca(strlen(fingerprint) + 1);
209 const char *f = fingerprint;
210 char *fp = compacted_fp;
211 char *combined;
212 int rc;
213 SCOPE_ENTER(4, "%s: Add fingerprint %s:%s\n", ctx ? ctx->tag : "",
214 alg, fingerprint);
215
216 if (!ctx || ast_strlen_zero(alg) || ast_strlen_zero(fingerprint)) {
218 "%s: Missing arguments\n", ctx->tag);
219 }
220
221 if (!ENUM_BOOL(ctx->etn->acfg_common.send_mky, send_mky)) {
223 "%s: Not needed\n", ctx->tag);
224 }
225
226 /* De-colonize */
227 while (*f != '\0') {
228 if (*f != ':') {
229 *fp++ = *f;
230 }
231 f++;
232 }
233 *fp = '\0';
234 rc = ast_asprintf(&combined, "%s:%s", alg, compacted_fp);
235 if (rc < 0) {
237 "%s: Can't allocate memory for comobined string\n", ctx->tag);
238 }
239
240 rc = AST_VECTOR_ADD_SORTED(&ctx->fingerprints, combined, strcasecmp);
241 if (rc < 0) {
243 "%s: Can't add entry to vector\n", ctx->tag);
244 }
245
247 "%s: Done\n", ctx->tag);
248}
#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 SCOPE_ENTER(3, "%s: Enter\n", tag);
79
80 if (!canon_orig_tn) {
82 LOG_ERROR, "%s: Must provide caller_id/orig_tn\n", tag);
83 }
84
85 if (!canon_dest_tn) {
87 LOG_ERROR, "%s: Must provide dest_tn\n", tag);
88 }
89
90 if (ast_strlen_zero(tag)) {
92 LOG_ERROR, "%s: Must provide tag\n", tag);
93 }
94
95 if (!ctxout) {
97 LOG_ERROR, "%s: Must provide ctxout\n", tag);
98 }
99
100 if (ast_strlen_zero(profile_name)) {
102 "%s: Disabled due to missing profile name\n", tag);
103 }
104
105 as_cfg = as_get_cfg();
106 if (as_cfg->global_disable) {
108 "%s: Globally disabled\n", tag);
109 }
110
111 eprofile = eprofile_get_cfg(profile_name);
112 if (!eprofile) {
114 LOG_ERROR, "%s: No profile for profile name '%s'. Call will continue\n", tag,
115 profile_name);
116 }
117
118 if (!PROFILE_ALLOW_ATTEST(eprofile)) {
120 "%s: Disabled by profile\n", tag);
121 }
122
123 etn = tn_get_etn(canon_orig_tn, eprofile);
124 if (!etn) {
126 "%s: No tn for orig_tn '%s'\n", tag, canon_orig_tn);
127 }
128
129 /* We don't need eprofile or as_cfg anymore so let's clean em up */
130 ao2_cleanup(as_cfg);
131 as_cfg = NULL;
132 ao2_cleanup(eprofile);
133 eprofile = NULL;
134
135
136 if (etn->acfg_common.attest_level == attest_level_NOT_SET) {
138 LOG_ERROR,
139 "'%s': No attest_level specified in tn, profile or attestation objects\n",
140 tag);
141 }
142
143 if (ast_strlen_zero(etn->acfg_common.public_cert_url)) {
145 LOG_ERROR, "%s: No public cert url in tn %s, profile or attestation objects\n",
146 tag, canon_orig_tn);
147 }
148
149 if (etn->acfg_common.raw_key_length == 0) {
151 LOG_ERROR, "%s: No private key in tn %s, profile or attestation objects\n",
152 canon_orig_tn, tag);
153 }
154
155 ctx = ao2_alloc_options(sizeof(*ctx), ctx_destructor,
157 if (!ctx) {
159 LOG_ERROR, "%s: Unable to allocate memory for ctx\n", tag);
160 }
161
162 if (ast_string_field_init(ctx, 1024) != 0) {
164 LOG_ERROR, "%s: Unable to allocate memory for ctx\n", tag);
165 }
166
167 if (ast_string_field_set(ctx, tag, tag) != 0) {
169 LOG_ERROR, "%s: Unable to allocate memory for ctx\n", tag);
170 }
171
172 if (ast_string_field_set(ctx, orig_tn, canon_orig_tn) != 0) {
174 LOG_ERROR, "%s: Unable to allocate memory for ctx\n", tag);
175 }
176
177 if (ast_string_field_set(ctx, dest_tn, canon_dest_tn)) {
179 LOG_ERROR, "%s: Unable to allocate memory for ctx\n", tag);
180 }
181
182 ctx->chan = chan;
183 ast_channel_ref(ctx->chan);
184
185 if (AST_VECTOR_INIT(&ctx->fingerprints, 1) != 0) {
187 LOG_ERROR, "%s: Unable to allocate memory for ctx\n", tag);
188 }
189
190 /* Transfer the references */
191 ctx->etn = etn;
192 etn = NULL;
193 *ctxout = ctx;
194 ctx = NULL;
195
197}
#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:2947
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: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_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, 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 199 of file attestation.c.

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

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

365{
366 RAII_VAR(jwt_t *, jwt, NULL, jwt_free);
367 jwt_alg_t alg;
368 char *encoded = NULL;
370 int rc = 0;
371 SCOPE_ENTER(3, "%s: Attestation: orig: %s dest: %s\n",
372 ctx ? ctx->tag : "NULL", ctx ? ctx->orig_tn : "NULL",
373 ctx ? ctx->dest_tn : "NULL");
374
375 if (!ctx) {
377 "%s: No context object!\n", "NULL");
378 }
379
380 if (header == NULL) {
382 LOG_ERROR, "%s: Header buffer was NULL\n", ctx->tag);
383 }
384
385 rc = jwt_new(&jwt);
386 if (rc != 0) {
388 LOG_ERROR, "%s: Cannot create JWT\n", ctx->tag);
389 }
390
391 /*
392 * All headers added need to be in alphabetical order!
393 */
394 alg = jwt_str_alg(STIR_SHAKEN_ENCRYPTION_ALGORITHM);
395 jwt_set_alg(jwt, alg, (const unsigned char *)ctx->etn->acfg_common.raw_key,
397 jwt_add_header(jwt, "ppt", STIR_SHAKEN_PPT);
398 jwt_add_header(jwt, "typ", STIR_SHAKEN_TYPE);
399 jwt_add_header(jwt, "x5u", ctx->etn->acfg_common.public_cert_url);
400
401 as_rc = pack_payload(ctx, jwt);
402 if (as_rc != AST_STIR_SHAKEN_AS_SUCCESS) {
404 LOG_ERROR, "%s: Cannot pack payload\n", ctx->tag);
405 }
406
407 encoded = jwt_encode_str(jwt);
408 if (!encoded) {
410 LOG_ERROR, "%s: Unable to sign/encode JWT\n", ctx->tag);
411 }
412
413 rc = ast_asprintf(header, "%s;info=<%s>;alg=%s;ppt=%s",
414 encoded, ctx->etn->acfg_common.public_cert_url, jwt_alg_str(alg),
416 ast_std_free(encoded);
417 if (rc < 0) {
419 LOG_ERROR, "%s: Unable to allocate memory for identity header\n",
420 ctx->tag);
421 }
422
424}
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:289
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 RAII_VAR(char *, canon_caller_id , canonicalize_tn_alloc(caller_id), ast_free);
659
660 const char *t = S_OR(tag, S_COR(chan, ast_channel_name(chan), ""));
661 SCOPE_ENTER(3, "%s: Enter\n", t);
662
663 if (ast_strlen_zero(tag)) {
665 LOG_ERROR, "%s: Must provide tag\n", t);
666 }
667
668 if (ast_strlen_zero(canon_caller_id)) {
670 LOG_ERROR, "%s: Must provide caller_id\n", t);
671 }
672
673 if (ast_strlen_zero(profile_name)) {
675 "%s: Disabled due to missing profile name\n", t);
676 }
677
678 vs = vs_get_cfg();
679 if (vs->global_disable) {
681 "%s: Globally disabled\n", t);
682 }
683
684 profile = eprofile_get_cfg(profile_name);
685 if (!profile) {
687 LOG_ERROR, "%s: No profile for profile name '%s'. Call will continue\n", tag,
688 profile_name);
689 }
690
691 if (!PROFILE_ALLOW_VERIFY(profile)) {
693 "%s: Disabled by profile\n", t);
694 }
695
696 ctx = ao2_alloc_options(sizeof(*ctx), ctx_destructor,
698 if (!ctx) {
700 }
701 if (ast_string_field_init(ctx, 1024) != 0) {
703 }
704
705 if (ast_string_field_set(ctx, tag, tag) != 0) {
707 }
708
709 ctx->chan = chan;
710 if (ast_string_field_set(ctx, caller_id, canon_caller_id) != 0) {
712 }
713
714 /* Transfer references to ctx */
715 ctx->eprofile = profile;
716 profile = NULL;
717
718 ao2_ref(ctx, +1);
719 *ctxout = ctx;
721}
#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_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 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 883 of file verification.c.

884{
885 RAII_VAR(char *, jwt_encoded, NULL, ast_free);
886 RAII_VAR(jwt_t *, jwt, NULL, jwt_free);
887 RAII_VAR(struct ast_json *, grants, NULL, ast_json_unref);
888 char *p = NULL;
889 char *grants_str = NULL;
890 const char *x5u;
891 const char *ppt_header = NULL;
892 const char *grant = NULL;
893 time_t now_s = time(NULL);
894 time_t iat;
895 struct ast_json *grant_obj = NULL;
896 int len;
897 int rc;
899 SCOPE_ENTER(3, "%s: Verifying\n", ctx ? ctx->tag : "NULL");
900
901 if (!ctx) {
903 "%s: No context object!\n", "NULL");
904 }
905
906 if (ast_strlen_zero(ctx->identity_hdr)) {
908 "%s: No identity header in ctx\n", ctx->tag);
909 }
910
911 p = strchr(ctx->identity_hdr, ';');
912 len = p - ctx->identity_hdr + 1;
913 jwt_encoded = ast_malloc(len);
914 if (!jwt_encoded) {
916 "%s: Failed to allocate memory for encoded jwt\n", ctx->tag);
917 }
918
919 memcpy(jwt_encoded, ctx->identity_hdr, len);
920 jwt_encoded[len - 1] = '\0';
921
922 jwt_decode(&jwt, jwt_encoded, NULL, 0);
923
924 ppt_header = jwt_get_header(jwt, "ppt");
925 if (!ppt_header || strcmp(ppt_header, STIR_SHAKEN_PPT)) {
928 }
929
930 vs_rc = check_date_header(ctx);
931 if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
933 "%s: Date header verification failed\n", ctx->tag);
934 }
935
936 x5u = jwt_get_header(jwt, "x5u");
937 if (ast_strlen_zero(x5u)) {
939 "%s: No x5u in Identity header\n", ctx->tag);
940 }
941
942 rc = check_x5u_url(ctx, x5u);
943 if (rc != AST_STIR_SHAKEN_VS_SUCCESS) {
945 "%s: x5u URL verification failed\n", ctx->tag);
946 }
947
948 ast_trace(3, "%s: Decoded enough to get x5u: '%s'\n", ctx->tag, x5u);
949 if (ast_string_field_set(ctx, public_url, x5u) != 0) {
951 "%s: Failed to set public_url '%s'\n", ctx->tag, x5u);
952 }
953
954 iat = jwt_get_grant_int(jwt, "iat");
955 if (iat == 0) {
957 "%s: No 'iat' in Identity header\n", ctx->tag);
958 }
959 ast_trace(1, "date_hdr: %zu iat: %zu diff: %zu\n",
960 ctx->date_hdr_time, iat, ctx->date_hdr_time - iat);
961 if (iat + ctx->eprofile->vcfg_common.max_iat_age < now_s) {
963 "%s: iat %ld older than %u seconds\n", ctx->tag,
964 iat, ctx->eprofile->vcfg_common.max_iat_age);
965 }
966 ctx->validity_check_time = iat;
967
968 vs_rc = ctx_populate(ctx);
969 if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
971 "%s: Unable to populate ctx\n", ctx->tag);
972 }
973
974 vs_rc = retrieve_verification_cert(ctx);
975 if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
977 "%s: Could not get valid cert from '%s'\n", ctx->tag, ctx->public_url);
978 }
979
980 jwt_free(jwt);
981 jwt = NULL;
982
983 rc = jwt_decode(&jwt, jwt_encoded, ctx->raw_key, ctx->raw_key_len);
984 if (rc != 0) {
986 LOG_ERROR, "%s: Signature validation failed for '%s'\n",
987 ctx->tag, ctx->public_url);
988 }
989
990 ast_trace(1, "%s: Decoding succeeded\n", ctx->tag);
991
992 ppt_header = jwt_get_header(jwt, "alg");
993 if (!ppt_header || strcmp(ppt_header, STIR_SHAKEN_ENCRYPTION_ALGORITHM)) {
995 "%s: %s\n", ctx->tag,
997 }
998
999 ppt_header = jwt_get_header(jwt, "ppt");
1000 if (!ppt_header || strcmp(ppt_header, STIR_SHAKEN_PPT)) {
1002 "%s: %s\n", ctx->tag,
1004 }
1005
1006 ppt_header = jwt_get_header(jwt, "typ");
1007 if (!ppt_header || strcmp(ppt_header, STIR_SHAKEN_TYPE)) {
1009 "%s: %s\n", ctx->tag,
1011 }
1012
1013 grants_str = jwt_get_grants_json(jwt, NULL);
1014 if (ast_strlen_zero(grants_str)) {
1016 "%s: %s\n", ctx->tag,
1018 }
1019 ast_trace(1, "grants: %s\n", grants_str);
1020 grants = ast_json_load_string(grants_str, NULL);
1021 ast_std_free(grants_str);
1022 if (!grants) {
1024 "%s: %s\n", ctx->tag,
1026 }
1027
1028 grant = ast_json_object_string_get(grants, "attest");
1029 if (ast_strlen_zero(grant)) {
1031 "%s: No 'attest' in Identity header\n", ctx->tag);
1032 }
1033 if (grant[0] < 'A' || grant[0] > 'C') {
1035 "%s: Invalid attest value '%s'\n", ctx->tag, grant);
1036 }
1037 ast_string_field_set(ctx, attestation, grant);
1038 ast_trace(1, "got attest: %s\n", grant);
1039
1040 grant_obj = ast_json_object_get(grants, "dest");
1041 if (!grant_obj) {
1043 "%s: No 'dest' in Identity header\n", ctx->tag);
1044 }
1045 if (TRACE_ATLEAST(3)) {
1046 char *otn = ast_json_dump_string(grant_obj);
1047 ast_trace(1, "got dest: %s\n", otn);
1048 ast_json_free(otn);
1049 }
1050
1051 grant_obj = ast_json_object_get(grants, "orig");
1052 if (!grant_obj) {
1054 "%s: No 'orig' in Identity header\n", ctx->tag);
1055 }
1056 if (TRACE_ATLEAST(3)) {
1057 char *otn = ast_json_dump_string(grant_obj);
1058 ast_trace(1, "got orig: %s\n", otn);
1059 ast_json_free(otn);
1060 }
1061 grant = ast_json_object_string_get(grant_obj, "tn");
1062 if (!grant) {
1064 "%s: No 'orig.tn' in Indentity header\n", ctx->tag);
1065 }
1066 ast_string_field_set(ctx, orig_tn, grant);
1067 if (strcmp(ctx->caller_id, ctx->orig_tn) != 0) {
1069 "%s: Mismatched cid '%s' and orig_tn '%s'\n", ctx->tag,
1070 ctx->caller_id, grant);
1071 }
1072
1073 grant = ast_json_object_string_get(grants, "origid");
1074 if (ast_strlen_zero(grant)) {
1076 "%s: No 'origid' in Identity header\n", ctx->tag);
1077 }
1078
1080 "%s: verification succeeded\n", ctx->tag);
1081}
#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:825
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:723
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().