<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> 
<base href="https://wiki.asterisk.org/wiki" /> 
<title>Message Title</title>  
<style type="text/css">@media only screen and (max-device-width: 480px) {.mobile-only {
        width: auto !important;
        height: auto !important;
        overflow: visible !important;
        line-height: normal !important;
        font-size: inherit !important;
        mso-hide: all;
}

.desktop-only {
        display: none !important;
}

/* iPhone 3GS fix for unwanted 20px right margin */
body { min-width: 100% !important; padding: 0; margin: 0; }

#center-content-table { max-width: none; !important; }
#header-pattern-container { padding: 10px 10px 10px 10px !important; line-height: 20px !important; }
#header-avatar-image-container { padding-right: 8px !important; }
#email-content-container { padding: 0 !important; }
.mobile-expand { border-radius: 0 !important; border-left: 0 !important; border-right: 0 !important; padding-left: 26px !important;}
.mobile-resize-text { font-size: 16px !important; line-height: 22px !important; }
#page-title-pattern-header { font-size: 20px !important; line-height: 28px !important; }
#page-title-pattern-icon-image-container-cell { padding-top: 7px !important; }
#inline-user-pattern { display: block !important; }
#inline-user-pattern-avatar { padding-top: 3px !important; }
.contextual-area-pattern { border-bottom: 1px solid #ccc !important; padding: 15px 10px 0 10px !important;}
.users-involved-pattern-column-table { width: 100% !important;  }
.users-involved-pattern-avatar-table-cell { padding: 3px 5px 5px 0 !important; }
.users-involved-pattern-column-container { padding-right: 0 !important; }
.contextual-excerpt-pattern, #users-involved-pattern { border: 0 !important; }

/** Aui Typography upsized for mobile **/
#content-excerpt-pattern-container, #contextual-excerpt-pattern-text-container { font-size: 16px !important; line-height: 22px !important; }
#content-excerpt-pattern-container h1, #contextual-excerpt-pattern-text-container h1 { font-size: 24px !important; line-height: 28px !important; }
#content-excerpt-pattern-container h2, #contextual-excerpt-pattern-text-container h2 { font-size: 20px !important; line-height: 28px !important; }
#content-excerpt-pattern-container h3, #contextual-excerpt-pattern-text-container h3 { font-size: 18px !important; line-height: 24px !important; }
#content-excerpt-pattern-container h4, #contextual-excerpt-pattern-text-container h4 { font-size: 16px !important; line-height: 22px !important; }
#content-excerpt-pattern-container h5, #contextual-excerpt-pattern-text-container h5 { font-size: 14px !important; line-height: 20px !important; }
#content-excerpt-pattern-container h6, #contextual-excerpt-pattern-text-container h6 { font-size: 14px !important; line-height: 20px !important; }
.user-mention { line-height: 18px !important; }
/** Aui Typography end **/

/* Show appropriate footer logo on mobile, display links vertically */
#footer-pattern { padding: 15px 10px !important; }
#footer-pattern-logo-desktop-container { padding: 0 !important; }
#footer-pattern-logo-desktop { width: 0 !important; height: 0 !important; }
#footer-pattern-logo-mobile {
    padding-top: 10px !important;
    width: 30px !important;
    height: 27px !important;
    display: inline !important;
}
#footer-pattern-text {
    display: block !important;
}
#footer-pattern-links-container { line-height: 0 !important;}
.footer-pattern-links.mobile-resize-text,
.footer-pattern-links.mobile-resize-text,
#footer-pattern-text.mobile-resize-text,
#footer-pattern-links-container.no-footer-links {
    font-size: 14px !important;
    line-height: 20px !important;
}
.footer-link { display: block !important; }
#footer-pattern-links-container table { display: inline-block !important; float: none !important; }
#footer-pattern-links-container, #footer-pattern-text { text-align: center !important; }
#footer-pattern-links { padding-bottom: 5px !important; }

/** Team Calendar overrides, these should be removed when notifications are updated in Team Calendars. For now CSS
    overrides are being used because the structure of the content can't change without rereleasing the plugin */
.mail-calendar-container .day-header + table tr td:first-child {
    vertical-align: top !important;
    padding-top: 5px !important;
}}
@media (min-width: 900px) {#center-content-table { width: 900px; }}
@media all {#outlook a {padding:0;} /* Force Outlook to provide a "view in browser" menu link. */
/* Prevent Webkit and Windows Mobile platforms from changing default font sizes.*/
body{-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;}
.ExternalClass {width:100%;} /* Force Hotmail to display emails at full width */
#background-table {margin:0; padding:0; width:100% !important; }
/* Needed to override highlighting on date and time links in iOS */
.grey a {color: #707070; text-decoration: none; }/* These styles are appended to the head element of a notification in order to prevent Apple Mail and similar
   clients from underlining the due dates with a blue hyperlink */
/* a lozenge outside an inline task should always be #333, lozenges inside an inline task should be
   colored according to their upcoming due dates, a completed task date lozenge or deleted task date
   lozenge should always be #707070 */
.date-time-lozenge a {color: #333333; text-decoration: none; }
.inline-task-text-container .date-time-lozenge.date-upcoming a {color: #DF6F00; text-decoration: none; }
.inline-task-text-container .date-time-lozenge.date-past a {color: #D04437; text-decoration: none; }
.inline-task-text-container.content-deleted-color .date-time-lozenge a,
.inline-task-text-container.checked .date-time-lozenge a {
    color: #707070; text-decoration: none;
}}
</style> 
</head>
<body>
<table id="background-table" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; background-color: #f5f5f5"> 
<tbody> 
<tr> 
<td id="header-pattern-container" style="padding: 0px; border-collapse: collapse; padding: 10px 20px"> 
<table id="header-pattern" cellspacing="0" cellpadding="0" border="0" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td id="header-avatar-image-container" valign="top" style="padding: 0px; border-collapse: collapse; vertical-align: top; width: 32px; padding-right: 9px"><a href="https://wiki.asterisk.org/wiki/display/~jcolp?src=email" style="color: #3b73af; text-decoration: none"><img id="header-avatar-image" class="image_fix" src="cid:avatar_72d18d2d9f6a7c208e7edb4531f793b7" height="32" width="32" border="0" style="border-radius: 3px; vertical-align: top" /></a></td>
<td id="header-text-container" valign="middle" style="padding: 0px; border-collapse: collapse; vertical-align: middle; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px">Joshua C. Colp <strong>created</strong> a page</td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<!-- End Header pattern --> 
<tr> 
<td id="email-content-container" style="padding: 0px; border-collapse: collapse; padding: 0 20px"> 
<table id="email-content-table" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; border-spacing: 0; border-collapse: separate"> 
<tbody> 
<tr> 
<td class="email-content-rounded-top mobile-expand" style="padding: 0px; border-collapse: collapse; color: #fff; padding: 0 15px 0 16px; height: 15px; background-color: #fff; border-left: 1px solid #ccc; border-top: 1px solid #ccc; border-right: 1px solid #ccc; border-bottom: 0; border-top-right-radius: 5px; border-top-left-radius: 5px"> </td> 
</tr> 
<tr> 
<td class="email-content-main mobile-expand" style="padding: 0px; border-collapse: collapse; border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: 0; border-bottom: 0; padding: 0 15px 15px 16px; background-color: #fff"> 
<table id="page-title-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td id="page-title-pattern-icon-image-container" valign="top" style="padding: 0px; border-collapse: collapse; width: 16px; vertical-align: top"> 
<table cellspacing="0" cellpadding="0" border="0" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td id="page-title-pattern-icon-image-container-cell" style="padding: 0px; border-collapse: collapse; width: 16px; padding: 9px 8px 0px 0px; mso-text-raise: 5px; mso-line-height-rule: exactly"><a href="https://wiki.asterisk.org/wiki/pages/viewpage.action?pageId=44370563&src=email" title="page icon" style="vertical-align: top;; color: #3b73af; text-decoration: none"><img style="vertical-align: top; display: block;" src="cid:page-icon" alt="page icon" title="page icon" height="16" width="16" border="0" /></a></td> 
</tr> 
</tbody> 
</table> </td>
<td style="vertical-align: top;; padding: 0px; border-collapse: collapse; padding-right: 5px; font-size: 20px; line-height: 30px; mso-line-height-rule: exactly" id="page-title-pattern-header-container"><span id="page-title-pattern-header" style="font-family: Arial, sans-serif; padding: 0; font-size: 20px; line-height: 30px; mso-text-raise: 2px; mso-line-height-rule: exactly; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/pages/viewpage.action?pageId=44370563&src=email" title="STIR/SHAKEN" style="color: #3b73af; text-decoration: none">STIR/SHAKEN</a></span></td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td class="email-content-main mobile-expand" style="padding: 0px; border-collapse: collapse; border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: 0; border-bottom: 0; padding: 0 15px 15px 16px; background-color: #fff"> 
<table class="content-excerpt-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px"> 
<tbody> 
<tr> 
<td class="content-excerpt-pattern-container mobile-resize-text " style="padding: 0px; border-collapse: collapse; padding: 0 0 0 24px"> 
<div class="aui-message problem shadowed information-macro"> 
<span class="aui-icon icon-problem">Icon</span> 
<div class="message-content"> 
<p style="margin: 10px 0 0 0; margin-top: 0">STIR/Shaken from a technical perspective has improved quite a lot, so much so that some companies have been able to do interop and it does work. The problematic area is really the foundational aspects and policy side of things. It's one thing to say "oh you use private key to sign some stuff" but who issues such things? Who actually does the work of signing and verifying? Are the certificates short lived ephemeral ones? Do you have to use a proprietary API to some upstream to manage things? There's still lots to flush out there by the industry and governments.</p> 
</div> 
</div> <h2 id="STIR/SHAKEN-Welcometotheparty!" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Welcome to the party!</h2> <p style="margin: 10px 0 0 0">Welcome to a page about making callerid non-fictional in an effort to stop robocallers! Will it actually work out in the end? Who knows, but hey have a design for implementing such a thing in Asterisk! This design was done in such a way as to allow drop-in to all currently supported versions of Asterisk that use PJSIP. It is also flexible in that we could add different ways to manage certificates since that may be an unknown at this point.</p> <p style="margin: 10px 0 0 0">The design is broken down into two modules:</p> 
<ol style="margin: 10px 0 0 0"> 
<li>res_stir_shaken</li> 
<li>res_pjsip_stir_shaken</li> 
</ol> <h2 id="STIR/SHAKEN-Background" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Background</h2> <p style="margin: 10px 0 0 0">Before we dive into things how about a bit of a TLDR on STIR/SHAKEN? From a purely technical perspective STIR/SHAKEN is actually fairly simple. It is based around a phone number (or a block of numbers) having a certificate that conveys that you have permission to use it. This certificate is comprised of a private and public key. As the name says the private one only you have while the public one is handed out and made available. When you go to use a phone number for callerid you construct a payload that conveys what you're doing (I am X calling Y on this date at this time) and sign it using your private key. The receiver can then look at this payload and signature and use your public key (after retrieving it from the URL provided with the payload) to verify that it is you who made the payload - thus giving trust that you have permission. Once this is done the receiver can then examine the call to see if the data matches (your call said you are X, your payload said you are X). It's then up to local policy as to what to do with the information. To be effective, though, everyone has to buy into this system and use it. Receiving a call without the information has to become abnormal or non-existent so that you don't have to let calls through regardless.</p> <h1 id="STIR/SHAKEN-Implementation" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Implementation</h1> 
<div class="aui-message warning shadowed information-macro"> 
<span class="aui-icon icon-warning">Icon</span> 
<div class="message-content"> 
<p style="margin: 10px 0 0 0; margin-top: 0">If you're actually planning to work on this here's some handy links!</p> 
<p style="margin: 10px 0 0 0"> <a href="https://tools.ietf.org/html/rfc8224" class="external-link" rel="nofollow" style="color: #3b73af; text-decoration: none">https://tools.ietf.org/html/rfc8224</a> </p> 
<p style="margin: 10px 0 0 0"> <a href="https://tools.ietf.org/html/rfc8225" class="external-link" rel="nofollow" style="color: #3b73af; text-decoration: none">https://tools.ietf.org/html/rfc8225</a> </p> 
<p style="margin: 10px 0 0 0"> <a href="https://tools.ietf.org/html/rfc8226" class="external-link" rel="nofollow" style="color: #3b73af; text-decoration: none">https://tools.ietf.org/html/rfc8226</a> </p> 
<p style="margin: 10px 0 0 0"> <a href="https://datatracker.ietf.org/doc/draft-ietf-stir-cert-delegation/" class="external-link" rel="nofollow" style="color: #3b73af; text-decoration: none">https://datatracker.ietf.org/doc/draft-ietf-stir-cert-delegation/</a> </p> 
<p style="margin: 10px 0 0 0"> <a href="http://nanc-chair.org/docs/mtg_docs/May_18_Call_Authentication_Trust_Anchor_NANC_Final_Report.pdf" class="external-link" rel="nofollow" style="color: #3b73af; text-decoration: none">http://nanc-chair.org/docs/mtg_docs/May_18_Call_Authentication_Trust_Anchor_NANC_Final_Report.pdf</a> </p> 
<p style="margin: 10px 0 0 0"> <a href="https://transnexus.com/whitepapers/understanding-stir-shaken/" class="external-link" rel="nofollow" style="color: #3b73af; text-decoration: none">https://transnexus.com/whitepapers/understanding-stir-shaken/</a> </p> 
<p style="margin: 10px 0 0 0"> <a href="https://www.telecompaper.com/news/atis-picks-iconectiv-as-policy-administrator-of-shakenstir-framework--1295009" class="external-link" rel="nofollow" style="color: #3b73af; text-decoration: none">https://www.telecompaper.com/news/atis-picks-iconectiv-as-policy-administrator-of-shakenstir-framework--1295009</a> </p> 
</div> 
</div> <p style="margin: 10px 0 0 0"> </p> <h2 id="STIR/SHAKEN-res_stir_shaken" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">res_stir_shaken</h2> <p style="margin: 10px 0 0 0">The res_stir_shaken module is responsible for certificate management, signing, verification, and information exposure. It's generic in the sense that protocol specific users need to be written to actually use the information. It is architected as such:</p> <h3 id="STIR/SHAKEN-Configuration" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">Configuration</h3> <p style="margin: 10px 0 0 0">Configuration is done using a stir_shaken.conf configuration file. Due to the amount of state required it is implemented using ACO. If we truly feel we need realtime in some way we could use sorcery but it doesn't seem reasonable to allow what most people would consider realtime (looking up at use time). This module will support reload so if things change on disk or in configuration, it can be reloaded by using a reload command.</p> <p style="margin: 10px 0 0 0"> </p> <p style="margin: 10px 0 0 0">As STIR/SHAKEN requires retrieving and using a public key it is advantageous to keep a cache of public keys to minimize call handling time. This is configured in the "general" section. The certificate authority information is also configured here.</p> 
<div class="code panel pdl" style="border-width: 1px;"> 
<div class="codeContent panelContent pdl"> 
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px;; margin: 10px 0 0 0; margin-top: 0">[general]
ca_file=/etc/stir/theca.crt
ca_path=/etc/stir/ca
cache_max_size=1000</pre> 
</div> 
</div> <p style="margin: 10px 0 0 0"> </p> <p style="margin: 10px 0 0 0">Individual certificates can be configured using the "certificate" type.</p> 
<div class="code panel pdl" style="border-width: 1px;"> 
<div class="codeContent panelContent pdl"> 
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px;; margin: 10px 0 0 0; margin-top: 0">[jcolp]
type=certificate
path=/etc/stir/jcolp.crt
public_key_url=http://joshua-colp.com/jcolp.crt</pre> 
</div> 
</div> <p style="margin: 10px 0 0 0"> </p> <p style="margin: 10px 0 0 0">A group of certificates can be configured using the "store" type.</p> 
<div class="code panel pdl" style="border-width: 1px;"> 
<div class="codeContent panelContent pdl"> 
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px;; margin: 10px 0 0 0; margin-top: 0">[certificates]
type=store
path=/etc/stir
public_key_url=http://joshua-colp.com/${CERTIFICATE}.crt</pre> 
</div> 
</div> <p style="margin: 10px 0 0 0">If the "store" type is used then all certificates in the directory will be examined and loaded. The public key URL is generated based on the filename and variable substitution.</p> <p style="margin: 10px 0 0 0"> </p> <p style="margin: 10px 0 0 0">In both cases the certificate is examined to determine what phone numbers or SIP URIs it is applicable to and this is then stored away in state information. Note that a certificate may not have any phone numbers or SIP URIs associated with it, but can still be used for signing. This merely conveys where the call came from - not that there is permission to use the phone number for callerid.</p> <p style="margin: 10px 0 0 0">The use of "type" is deliberate so that this could be extended to allow other methods of retrieving certificates or even potentially signing, such as relying on a REST API to generate short lived certificates.</p> <h3 id="STIR/SHAKEN-Structures" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">Structures</h3> <p style="margin: 10px 0 0 0">The APIs provided by the module will expose a structure to provide payload information.</p> 
<div class="code panel pdl" style="border-width: 1px;"> 
<div class="codeContent panelContent pdl"> 
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px;; margin: 10px 0 0 0; margin-top: 0">struct ast_stir_shaken_payload {
        /* This is actually a JWT (JSON Web Token) so this may need to change, but for this page it'll do */

                /*! The JWT header */
        struct ast_json *header;
                /*! The JWT payload */
        struct ast_json *payload;
                /*! Signature for the payload */
        char *signature;
                /*! The algorithm used */
        char *algorithm;
                /*! The URL to the public key for the certificate */
        char *public_key_url;
};

/*!
 * \brief Free a STIR/SHAKEN payload
 */
void ast_stir_shaken_payload_free(struct ast_stir_shaken_payload *payload);</pre> 
</div> 
</div> <p style="margin: 10px 0 0 0">The structure could be made opaque with accessors if we desired.</p> <h3 id="STIR/SHAKEN-Signing" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">Signing</h3> <p style="margin: 10px 0 0 0">The module will expose a single API call that can be used to sign a payload.</p> 
<div class="code panel pdl" style="border-width: 1px;"> 
<div class="codeContent panelContent pdl"> 
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px;; margin: 10px 0 0 0; margin-top: 0">/*!
 * \brief Sign a JSON STIR/SHAKEN payload
 *
 * \note This function will automatically add the "attest", "iat", and "origid" fields.
 */
struct ast_stir_shaken_payload *ast_stir_shaken_sign(struct ast_json *json);</pre> 
</div> 
</div> <p class="auto-cursor-target" style="margin: 10px 0 0 0">The API call will:</p> 
<ol style="margin: 10px 0 0 0"> 
<li>Ensure JSON has been passed in and passes minimal requirements</li> 
<li>Examine the JSON to find the appropriate certificate</li> 
<li>Iterate through state to find an appropriate certificate</li> 
<li>If no certificate is available then the function will return NULL</li> 
<li>Sign the payload using the available certificate</li> 
<li>The function will construct an ast_stir_shaken_payload and return it</li> 
</ol> <h3 id="STIR/SHAKEN-Verifying" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">Verifying</h3> <p style="margin: 10px 0 0 0">The module will expose a single API call that can be used to verify a payload.</p> 
<div class="code panel pdl" style="border-width: 1px;"> 
<div class="codeContent panelContent pdl"> 
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px;; margin: 10px 0 0 0; margin-top: 0">/*!
 * \brief Verify a JSON STIR/SHAKEN payload
 */
struct ast_stir_shaken_payload *ast_stir_shaken_verify(const char *header, const char *payload, const char *signature, const char *algorithm, const char *public_key_url);</pre> 
</div> 
</div> <p style="margin: 10px 0 0 0">The API call will:</p> 
<ol style="margin: 10px 0 0 0"> 
<li>Ensure all the required fields are non-empty</li> 
<li>Retrieve the given public key from the local cache if available or from the given URL</li> 
<li>If the public key is not available then the function will return early with NULL</li> 
<li>Verify the payload using the signature and public key, ensuring chain of trust</li> 
<li>If verification or chain of trust fails then the function will return early with NULL</li> 
<li>The function will construct an ast_stir_shaken_payload and return it</li> 
</ol> <h3 id="STIR/SHAKEN-DialplanFunction" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">Dialplan Function</h3> <p style="margin: 10px 0 0 0">A dialplan function will be made available to examine STIR/SHAKEN verification and attestation results.</p> 
<div class="code panel pdl" style="border-width: 1px;"> 
<div class="codeContent panelContent pdl"> 
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px;; margin: 10px 0 0 0; margin-top: 0">/*!
 * \brief STIR/SHAKEN verification results
 */
enum ast_stir_shaken_verification_result {
        AST_STIR_SHAKEN_VERIFY_NOT_PRESENT, /*! No STIR/SHAKEN information was available */
        AST_STIR_SHAKEN_VERIFY_SIGNATURE_FAILED, /*! Signature verification failed */
        AST_STIR_SHAKEN_VERIFY_MISMATCH, /*!< Contents of the signaling and the STIR/SHAKEN payload did not match */
        AST_STIR_SHAKEN_VERIFY_PASSED, /*! Signature verified and contents match signaling */
};

/*!
 * \brief Add a STIR/SHAKEN verification result to a channel
 */
int ast_stir_shaken_add_verification(struct ast_channel *chan, const char *identity, const char *attestation, enum ast_stir_shaken_verification_result result);</pre> 
</div> 
</div> <p style="margin: 10px 0 0 0">The API call will use a datastore to place STIR/SHAKEN verify results on the channel for usage in the dialplan.</p> 
<div class="code panel pdl" style="border-width: 1px;"> 
<div class="codeContent panelContent pdl"> 
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px;; margin: 10px 0 0 0; margin-top: 0">exten => s,1,NoOp(Number of STIR/SHAKEN identities: ${STIR_SHAKEN(count)})
exten => s,n,NoOp(First STIR/SHAKEN identity: ${STIR_SHAKEN(0,identity)})
exten => s,n,NoOp(First STIR/SHAKEN attestation: ${STIR_SHAKEN(0,attestation)})
exten => s,n,NoOp(First STIR/SHAKEN verify result: ${STIR_SHAKEN(0,verify_result)})</pre> 
</div> 
</div> <p style="margin: 10px 0 0 0">In the dialplan the STIR/SHAKEN identities can then be iterated or examine and based on that the user can choose what to do.</p> <h2 id="STIR/SHAKEN-res_pjsip_stir_shaken" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">res_pjsip_stir_shaken</h2> <p style="margin: 10px 0 0 0">The res_pjsip_stir_shaken module acts as the boundary between SIP and the core of STIR/SHAKEN. It implements the SIP side of things and does not care about certificate storage or signing and is effectively stateless. It acts on messages as they enter and leave the system. It will do this by adding a session supplement that is only invoked on INVITE requests.</p> <h3 id="STIR/SHAKEN-InboundINVITE" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">Inbound INVITE</h3> 
<ol style="margin: 10px 0 0 0"> 
<li>Examine message for Identity header - if not present then call ast_stir_shaken_add_verification to add an AST_STIR_SHAKEN_VERIFY_NOT_PRESENT result based on the callerid as the identity</li> 
<li>Parse the Identity header to get the header, payload, signature, algorithm, and public key URL</li> 
<li>Invoke ast_stir_shaken_verify with parsed values</li> 
<li>If ast_stir_shaken_verify returns NULL then call ast_stir_shaken_add_verification to add an AST_STIR_SHAKEN_VERIFY_SIGNATURE_FAILED result based on the callerid as the identity</li> 
<li>Examine the STIR/SHAKEN payload and compare it against the attributes of the SIP signaling to ensure it matches</li> 
<li>If the payload doesn't match then call ast_stir_shaken_add_verification to add an AST_STIR_SHAKEN_VERIFY_MISMATCH result based on the callerid as the identity</li> 
<li>Call ast_stir_shaken_add_verification to add an AST_STIR_SHAKEN_VERIFY_PASSED result based on the callerid as the identity</li> 
</ol> <h3 id="STIR/SHAKEN-OutboundINVITE" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">Outbound INVITE</h3> 
<ol style="margin: 10px 0 0 0"> 
<li>Retrieve the callerid from the INVITE</li> 
<li>Construct a JSON payload using the callerid and other attributes of the SIP INVITE (such as dialed number)</li> 
<li>Call ast_stir_shaken_sign with JSON payload</li> 
<li>If ast_stir_shaken_sign returns NULL then do not add an Identity header and return early</li> 
<li>Base64 encode the STIR/SHAKEN payload according to spec and add Identity header to SIP INVITE</li> 
</ol> <h3 id="STIR/SHAKEN-Configuration.1" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">Configuration</h3> <p style="margin: 10px 0 0 0">The only configuration that will exist will be an extended sorcery attribute on the PJSIP endpoint, in the form of "@stir". If set to "no" (the default) then none of this is done. If set to "yes" then inbound and outbound would be done.</p> <h1 id="STIR/SHAKEN-Testing" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Testing</h1> <h2 id="STIR/SHAKEN-res_stir_shaken.1" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0; margin-top: 10px">res_stir_shaken</h2> <p style="margin: 10px 0 0 0">Unfortunately this module requires configuration as well as HTTP access which makes it difficult to test from a self contained perspective. It may be possible to test this from a unit test perspective if the unit test is written inside the module and also if the Asterisk HTTP server is running. A specific configuration can be used for certificates and the public key URL could point to localhost. The API could then be used by having it sign using the certificate, and then verify against itself.</p> <h2 id="STIR/SHAKEN-res_pjsip_stir_shaken.1" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">res_pjsip_stir_shaken</h2> <p style="margin: 10px 0 0 0">The testsuite is the best choice of action for testing this module. Using 2 Asterisk instances, certificates for each, and the Asterisk HTTP server we could place calls between them under various conditions and examine the result in dialplan - raising different user events to indicate success or failure.</p> </td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td class="email-content-main mobile-expand action-padding last-row-padding" style="padding: 0px; border-collapse: collapse; border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: 0; border-bottom: 0; padding: 0 15px 15px 16px; background-color: #fff; padding-bottom: 10px; padding-bottom: 10px"> 
<table id="actions-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px"> 
<tbody> 
<tr> 
<td id="actions-pattern-container" valign="middle" style="padding: 0px; border-collapse: collapse; padding: 15px 0 0 24px; vertical-align: middle"> 
<table align="left" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td class="actions-pattern-action-icon-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 0px; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/pages/viewpage.action?pageId=44370563&src=email" title="View page Icon" style="color: #3b73af; text-decoration: none"><img class="actions-pattern-action-icon-image" height="16" width="16" border="0" title="View page Icon" src="cid:com.atlassian.confluence.plugins.confluence-email-resources%3Aview-page-email-adg-footer-item%3Aicon" alt="View page Icon" style="vertical-align: middle" /></a></td>
<td class="actions-pattern-action-text-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; padding-left: 5px; white-space: nowrap"><a href="https://wiki.asterisk.org/wiki/pages/viewpage.action?pageId=44370563&src=email" title="View page" style="color: #3b73af; text-decoration: none">View page</a></td>
<td class="actions-pattern-action-bull" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; color: #999; padding: 0 5px">•</td> 
</tr> 
</tbody> 
</table> 
<table align="left" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td class="actions-pattern-action-icon-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 0px; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/pages/viewpage.action?pageId=44370563&showComments=true&showCommentArea=true&src=email#addcomment" title="Add comment Icon" style="color: #3b73af; text-decoration: none"><img class="actions-pattern-action-icon-image" height="16" width="16" border="0" title="Add comment Icon" src="cid:com.atlassian.confluence.plugins.confluence-email-resources%3Aadd-comment-to-content-email-adg-footer-item%3Aicon" alt="Add comment Icon" style="vertical-align: middle" /></a></td>
<td class="actions-pattern-action-text-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; padding-left: 5px; white-space: nowrap"><a href="https://wiki.asterisk.org/wiki/pages/viewpage.action?pageId=44370563&showComments=true&showCommentArea=true&src=email#addcomment" title="Add comment" style="color: #3b73af; text-decoration: none">Add comment</a></td>
<td class="actions-pattern-action-bull" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; color: #999; padding: 0 5px">•</td> 
</tr> 
</tbody> 
</table> 
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td class="actions-pattern-action-icon-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 0px; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/plugins/likes/like.action?contentId=44370563&src=email" title="Like Icon" style="color: #3b73af; text-decoration: none"><img class="actions-pattern-action-icon-image" height="16" width="16" border="0" title="Like Icon" src="cid:com.atlassian.confluence.plugins.confluence-like%3Aview-email-adg-content-item%3Aicon" alt="Like Icon" style="vertical-align: middle" /></a></td>
<td class="actions-pattern-action-text-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; padding-left: 5px; white-space: nowrap"><a href="https://wiki.asterisk.org/wiki/plugins/likes/like.action?contentId=44370563&src=email" title="Like" style="color: #3b73af; text-decoration: none">Like</a></td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td class="email-content-rounded-bottom mobile-expand" style="padding: 0px; border-collapse: collapse; color: #fff; height: 5px; line-height: 5px; padding: 0 15px 0 16px; background-color: #fff; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; border-top: 0; border-left: 1px solid #ccc; border-bottom: 1px solid #ccc; border-right: 1px solid #ccc; mso-line-height-rule: exactly"> </td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td id="footer-pattern" style="padding: 0px; border-collapse: collapse; padding: 12px 20px"> 
<table id="footer-pattern-container" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td id="footer-pattern-links-container" width="100%" style="padding: 0px; border-collapse: collapse; color: #999; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px"> 
<table align="left" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px"> 
<tbody> 
<tr> 
<td class="footer-pattern-links mobile-resize-text" style="padding: 0px; border-collapse: collapse"><a href="https://wiki.asterisk.org/wiki/users/removespacenotification.action?spaceKey=AST&src=email" title="" style="color: #3b73af; text-decoration: none">Stop watching space</a></td>
<td class="footer-pattern-links-bull" style="padding: 0px; border-collapse: collapse; padding: 0 5px; color: #999">•</td> 
</tr> 
</tbody> 
</table> 
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px"> 
<tbody> 
<tr> 
<td class="footer-pattern-links mobile-resize-text" style="padding: 0px; border-collapse: collapse"><a href="https://wiki.asterisk.org/wiki/users/editmyemailsettings.action?src=email" title="" style="color: #3b73af; text-decoration: none">Manage notifications</a></td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td id="footer-pattern-text" class="mobile-resize-text" width="100%" style="padding: 0px; border-collapse: collapse; color: #999; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px; display: none">This message was sent by Atlassian Confluence 5.6.6</td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
</tbody> 
</table> 
<table id="sealed-section" border="0" cellpadding="0" cellspacing="0" width="0" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; display: none"> 
<tbody> 
<tr> 
<td style="padding: 0px; border-collapse: collapse; border: 0; font-size: 0px; line-height: 0; mso-line-height-rule: exactly"></td> 
</tr> 
</tbody> 
</table>
</body>
</html>