<p>Benjamin Keith Ford has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/15814">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">STIR/SHAKEN: Switch to base64 URL encoding.<br><br>STIR/SHAKEN encodes using base64 URL format. Currently, we just use<br>base64. New functions have been added that convert to and from base64<br>encoding.<br><br>The origid field should also be an UUID. This means there's no reason to<br>have it as an option in stir_shaken.conf, as we can simply generate one<br>when creating the Identity header.<br><br>https://wiki.asterisk.org/wiki/display/AST/OpenSIPit+2021<br><br>Change-Id: Icf094a2a54e87db91d6b12244c9f5ba4fc2e0b8c<br>---<br>M configs/samples/stir_shaken.conf.sample<br>M include/asterisk/utils.h<br>M main/utils.c<br>M res/res_pjsip_stir_shaken.c<br>M res/res_stir_shaken.c<br>M res/res_stir_shaken/certificate.c<br>M res/res_stir_shaken/certificate.h<br>7 files changed, 199 insertions(+), 46 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/14/15814/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/configs/samples/stir_shaken.conf.sample b/configs/samples/stir_shaken.conf.sample</span><br><span>index 957fd14..f89cf14 100644</span><br><span>--- a/configs/samples/stir_shaken.conf.sample</span><br><span>+++ b/configs/samples/stir_shaken.conf.sample</span><br><span>@@ -56,6 +56,3 @@</span><br><span> ;</span><br><span> ; Must have an attestation of A, B, or C</span><br><span> ;attestation=C</span><br><span style="color: hsl(0, 100%, 40%);">-;</span><br><span style="color: hsl(0, 100%, 40%);">-; The origination identifier for the certificate</span><br><span style="color: hsl(0, 100%, 40%);">-;origid=MyAsterisk</span><br><span>diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h</span><br><span>index 0ee11ee..a6255d1 100644</span><br><span>--- a/include/asterisk/utils.h</span><br><span>+++ b/include/asterisk/utils.h</span><br><span>@@ -276,6 +276,55 @@</span><br><span>  */</span><br><span> char *ast_base64decode_string(const char *src);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Decode data from base64 URL</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param dst The destination buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param src The source buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param max The maximum number of bytes to write into the destination</span><br><span style="color: hsl(120, 100%, 40%);">+ *            buffer. Note that this function will not ensure that the</span><br><span style="color: hsl(120, 100%, 40%);">+ *            destination buffer is NULL terminated. So, in general,</span><br><span style="color: hsl(120, 100%, 40%);">+ *            this parametre should be sizeof(dst) - 1</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_base64url_decode(unsigned char *dst, const char *src, int max);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_base64url_encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Encode data in base64 URL</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param dst The destination buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param src The source data to be encoded</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param srclen The number of bytes present in the source buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param max The maximum number of bytes to write into the destination</span><br><span style="color: hsl(120, 100%, 40%);">+ *            buffer, including the terminating NULL character</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_base64url_encode(char *dst, const unsigned char *src, int srclen, int max);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Decode data from base64 URL</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \note The returned string will need to be freed later</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param src The source buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval NULL on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval Decoded string on success</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+char *ast_base64url_decode_string(const char *src);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Encode data in base64 URL</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \note The returned string will need to be freed later</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param src The source data to be encoded</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval NULL on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval Encoded string on success</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+char *ast_base64url_encode_string(const char *src);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #define AST_URI_ALPHANUM     (1 << 0)</span><br><span> #define AST_URI_MARK         (1 << 1)</span><br><span> #define AST_URI_UNRESERVED   (AST_URI_ALPHANUM | AST_URI_MARK)</span><br><span>diff --git a/main/utils.c b/main/utils.c</span><br><span>index 827ee2e..e0e33c3 100644</span><br><span>--- a/main/utils.c</span><br><span>+++ b/main/utils.c</span><br><span>@@ -71,7 +71,9 @@</span><br><span> #include "asterisk/alertpipe.h"</span><br><span> </span><br><span> static char base64[64];</span><br><span style="color: hsl(120, 100%, 40%);">+static char base64url[64];</span><br><span> static char b2a[256];</span><br><span style="color: hsl(120, 100%, 40%);">+static char b2a_url[256];</span><br><span> </span><br><span> AST_THREADSTORAGE(inet_ntoa_buf);</span><br><span> </span><br><span>@@ -417,28 +419,150 @@</span><br><span>    return encoded_string;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int ast_base64url_decode(unsigned char *dst, const char *src, int max)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    int cnt = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  unsigned int byte = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+        unsigned int bits = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      while (*src && (cnt < max)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              byte <<= 6;</span><br><span style="color: hsl(120, 100%, 40%);">+             byte |= (b2a_url[(int)(*src)]) & 0x3f;</span><br><span style="color: hsl(120, 100%, 40%);">+            bits += 6;</span><br><span style="color: hsl(120, 100%, 40%);">+            src++;</span><br><span style="color: hsl(120, 100%, 40%);">+                if (bits >= 8) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   bits -= 8;</span><br><span style="color: hsl(120, 100%, 40%);">+                    *dst = (byte >> bits) & 0xff;</span><br><span style="color: hsl(120, 100%, 40%);">+                       dst++;</span><br><span style="color: hsl(120, 100%, 40%);">+                        cnt++;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     return cnt;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+char *ast_base64url_decode_string(const char *src)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       size_t decoded_len;</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned char *decoded_string;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (ast_strlen_zero(src)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   decoded_len = strlen(src) * 3 / 4;</span><br><span style="color: hsl(120, 100%, 40%);">+    decoded_string = ast_malloc(decoded_len + 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!decoded_string) {</span><br><span style="color: hsl(120, 100%, 40%);">+                return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_base64url_decode(decoded_string, src, decoded_len);</span><br><span style="color: hsl(120, 100%, 40%);">+       decoded_string[decoded_len] = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return (char *)decoded_string;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_base64url_encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       int cnt = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  int col = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  unsigned int byte = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+        int bits = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ int cntin = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      max--;</span><br><span style="color: hsl(120, 100%, 40%);">+        while ((cntin < srclen) && (cnt < max)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               byte <<= 8;</span><br><span style="color: hsl(120, 100%, 40%);">+             byte |= *(src++);</span><br><span style="color: hsl(120, 100%, 40%);">+             bits += 8;</span><br><span style="color: hsl(120, 100%, 40%);">+            cntin++;</span><br><span style="color: hsl(120, 100%, 40%);">+              if ((bits == 24) && (cnt + 4 <= max)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    *dst++ = base64url[(byte >> 18) & 0x3f];</span><br><span style="color: hsl(120, 100%, 40%);">+                    *dst++ = base64url[(byte >> 12) & 0x3f];</span><br><span style="color: hsl(120, 100%, 40%);">+                    *dst++ = base64url[(byte >> 6) & 0x3f];</span><br><span style="color: hsl(120, 100%, 40%);">+                     *dst++ = base64url[(byte) & 0x3f];</span><br><span style="color: hsl(120, 100%, 40%);">+                        cnt += 4;</span><br><span style="color: hsl(120, 100%, 40%);">+                     col += 4;</span><br><span style="color: hsl(120, 100%, 40%);">+                     bits = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                     byte = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (linebreaks && (cnt < max) && (col == 64)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    *dst++ = '\n';</span><br><span style="color: hsl(120, 100%, 40%);">+                        cnt++;</span><br><span style="color: hsl(120, 100%, 40%);">+                        col = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (bits && (cnt + 4 <= max)) {</span><br><span style="color: hsl(120, 100%, 40%);">+            byte <<= 24 - bits;</span><br><span style="color: hsl(120, 100%, 40%);">+             *dst++ = base64url[(byte >> 18) & 0x3f];</span><br><span style="color: hsl(120, 100%, 40%);">+            *dst++ = base64url[(byte >> 12) & 0x3f];</span><br><span style="color: hsl(120, 100%, 40%);">+            if (bits == 16) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     *dst++ = base64url[(byte >> 6) & 0x3f];</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             cnt += 4;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (linebreaks && (cnt < max)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           *dst++ = '\n';</span><br><span style="color: hsl(120, 100%, 40%);">+                cnt++;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     *dst = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+  return cnt;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_base64url_encode(char *dst, const unsigned char *src, int srclen, int max)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       return ast_base64url_encode_full(dst, src, srclen, max, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+char *ast_base64url_encode_string(const char *src)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       size_t encoded_len;</span><br><span style="color: hsl(120, 100%, 40%);">+   char *encoded_string;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (ast_strlen_zero(src)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   encoded_len = ((strlen(src) * 4 / 3 + 3) & ~3) + 1;</span><br><span style="color: hsl(120, 100%, 40%);">+       encoded_string = ast_malloc(encoded_len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_base64url_encode(encoded_string, (const unsigned char *)src, strlen(src), encoded_len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return encoded_string;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void base64_init(void)</span><br><span> {</span><br><span>    int x;</span><br><span>       memset(b2a, -1, sizeof(b2a));</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(b2a_url, -1, sizeof(b2a_url));</span><br><span>        /* Initialize base-64 Conversion table */</span><br><span>    for (x = 0; x < 26; x++) {</span><br><span>                /* A-Z */</span><br><span>            base64[x] = 'A' + x;</span><br><span style="color: hsl(120, 100%, 40%);">+          base64url[x] = 'A' + x;</span><br><span>              b2a['A' + x] = x;</span><br><span style="color: hsl(120, 100%, 40%);">+             b2a_url['A' + x] = x;</span><br><span>                /* a-z */</span><br><span>            base64[x + 26] = 'a' + x;</span><br><span style="color: hsl(120, 100%, 40%);">+             base64url[x + 26] = 'a' + x;</span><br><span>                 b2a['a' + x] = x + 26;</span><br><span style="color: hsl(120, 100%, 40%);">+                b2a_url['a' + x] = x + 26;</span><br><span>           /* 0-9 */</span><br><span>            if (x < 10) {</span><br><span>                     base64[x + 52] = '0' + x;</span><br><span style="color: hsl(120, 100%, 40%);">+                     base64url[x + 52] = '0' + x;</span><br><span>                         b2a['0' + x] = x + 52;</span><br><span style="color: hsl(120, 100%, 40%);">+                        b2a_url['0' + x] = x + 52;</span><br><span>           }</span><br><span>    }</span><br><span>    base64[62] = '+';</span><br><span>    base64[63] = '/';</span><br><span style="color: hsl(120, 100%, 40%);">+     base64url[62] = '-';</span><br><span style="color: hsl(120, 100%, 40%);">+  base64url[63] = '_';</span><br><span>         b2a[(int)'+'] = 62;</span><br><span>  b2a[(int)'/'] = 63;</span><br><span style="color: hsl(120, 100%, 40%);">+   b2a_url[(int)'-'] = 62;</span><br><span style="color: hsl(120, 100%, 40%);">+       b2a_url[(int)'_'] = 63;</span><br><span> }</span><br><span> </span><br><span> const struct ast_flags ast_uri_http = {AST_URI_UNRESERVED};</span><br><span>diff --git a/res/res_pjsip_stir_shaken.c b/res/res_pjsip_stir_shaken.c</span><br><span>index 8c1c70f..38e1160 100644</span><br><span>--- a/res/res_pjsip_stir_shaken.c</span><br><span>+++ b/res/res_pjsip_stir_shaken.c</span><br><span>@@ -146,14 +146,14 @@</span><br><span>     }</span><br><span> </span><br><span>        encoded_val = strtok_r(identity_hdr_val, ".", &identity_hdr_val);</span><br><span style="color: hsl(0, 100%, 40%);">- header = ast_base64decode_string(encoded_val);</span><br><span style="color: hsl(120, 100%, 40%);">+        header = ast_base64url_decode_string(encoded_val);</span><br><span>   if (ast_strlen_zero(header)) {</span><br><span>               ast_stir_shaken_add_verification(chan, caller_id, "", AST_STIR_SHAKEN_VERIFY_SIGNATURE_FAILED);</span><br><span>            return 0;</span><br><span>    }</span><br><span> </span><br><span>        encoded_val = strtok_r(identity_hdr_val, ".", &identity_hdr_val);</span><br><span style="color: hsl(0, 100%, 40%);">- payload = ast_base64decode_string(encoded_val);</span><br><span style="color: hsl(120, 100%, 40%);">+       payload = ast_base64url_decode_string(encoded_val);</span><br><span>  if (ast_strlen_zero(payload)) {</span><br><span>              ast_stir_shaken_add_verification(chan, caller_id, "", AST_STIR_SHAKEN_VERIFY_SIGNATURE_FAILED);</span><br><span>            return 0;</span><br><span>@@ -241,7 +241,7 @@</span><br><span> </span><br><span>  header = ast_json_object_get(json, "header");</span><br><span>      dumped_string = ast_json_dump_string(header);</span><br><span style="color: hsl(0, 100%, 40%);">-   encoded_header = ast_base64encode_string(dumped_string);</span><br><span style="color: hsl(120, 100%, 40%);">+      encoded_header = ast_base64url_encode_string(dumped_string);</span><br><span>         ast_json_free(dumped_string);</span><br><span>        if (!encoded_header) {</span><br><span>               ast_log(LOG_ERROR, "Failed to encode STIR/SHAKEN header\n");</span><br><span>@@ -250,7 +250,7 @@</span><br><span> </span><br><span>     payload = ast_json_object_get(json, "payload");</span><br><span>    dumped_string = ast_json_dump_string(payload);</span><br><span style="color: hsl(0, 100%, 40%);">-  encoded_payload = ast_base64encode_string(dumped_string);</span><br><span style="color: hsl(120, 100%, 40%);">+     encoded_payload = ast_base64url_encode_string(dumped_string);</span><br><span>        ast_json_free(dumped_string);</span><br><span>        if (!encoded_payload) {</span><br><span>              ast_log(LOG_ERROR, "Failed to encode STIR/SHAKEN payload\n");</span><br><span>diff --git a/res/res_stir_shaken.c b/res/res_stir_shaken.c</span><br><span>index a9f861b..f560039 100644</span><br><span>--- a/res/res_stir_shaken.c</span><br><span>+++ b/res/res_stir_shaken.c</span><br><span>@@ -104,9 +104,6 @@</span><br><span>                               <configOption name="attestation"></span><br><span>                                    <synopsis>Attestation level</synopsis></span><br><span>                           </configOption></span><br><span style="color: hsl(0, 100%, 40%);">-                           <configOption name="origid" default=""></span><br><span style="color: hsl(0, 100%, 40%);">-                                       <synopsis>The origination ID</synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-                             </configOption></span><br><span>                                <configOption name="caller_id_number" default=""></span><br><span>                                  <synopsis>The caller ID number to match on.</synopsis></span><br><span>                           </configOption></span><br><span>@@ -503,7 +500,7 @@</span><br><span>  EVP_MD_CTX *mdctx = NULL;</span><br><span>    int ret = 0;</span><br><span>         unsigned char *decoded_signature;</span><br><span style="color: hsl(0, 100%, 40%);">-       size_t signature_length, decoded_signature_length, padding = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+       size_t signature_length, decoded_signature_length;</span><br><span> </span><br><span>       mdctx = EVP_MD_CTX_create();</span><br><span>         if (!mdctx) {</span><br><span>@@ -525,19 +522,12 @@</span><br><span>                return -1;</span><br><span>   }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* We need to decode the signature from base64 to bytes. Make sure we have</span><br><span style="color: hsl(120, 100%, 40%);">+    /* We need to decode the signature from base64 URL to bytes. Make sure we have</span><br><span>        * at least enough characters for this check */</span><br><span>      signature_length = strlen(signature);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (signature_length > 2 && signature[signature_length - 1] == '=') {</span><br><span style="color: hsl(0, 100%, 40%);">-                padding++;</span><br><span style="color: hsl(0, 100%, 40%);">-              if (signature[signature_length - 2] == '=') {</span><br><span style="color: hsl(0, 100%, 40%);">-                   padding++;</span><br><span style="color: hsl(0, 100%, 40%);">-              }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       decoded_signature_length = (signature_length / 4 * 3) - padding;</span><br><span style="color: hsl(120, 100%, 40%);">+      decoded_signature_length = (signature_length * 3 / 4);</span><br><span>       decoded_signature = ast_calloc(1, decoded_signature_length);</span><br><span style="color: hsl(0, 100%, 40%);">-    ast_base64decode(decoded_signature, signature, decoded_signature_length);</span><br><span style="color: hsl(120, 100%, 40%);">+     ast_base64url_decode(decoded_signature, signature, decoded_signature_length);</span><br><span> </span><br><span>    ret = EVP_DigestVerifyFinal(mdctx, decoded_signature, decoded_signature_length);</span><br><span>     if (ret != 1) {</span><br><span>@@ -932,7 +922,7 @@</span><br><span>                goto cleanup;</span><br><span>        }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* There are 6 bits to 1 base64 digit, so in order to get the size of the base64 encoded</span><br><span style="color: hsl(120, 100%, 40%);">+      /* There are 6 bits to 1 base64 URL digit, so in order to get the size of the base64 encoded</span><br><span>          * signature, we need to multiply by the number of bits in a byte and divide by 6. Since</span><br><span>      * there's rounding when doing base64 conversions, add 3 bytes, just in case, and account</span><br><span>         * for padding. Add another byte for the NULL-terminator.</span><br><span>@@ -944,7 +934,7 @@</span><br><span>              goto cleanup;</span><br><span>        }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ast_base64encode((char *)encoded_signature, signature, signature_length, encoded_length);</span><br><span style="color: hsl(120, 100%, 40%);">+     ast_base64url_encode((char *)encoded_signature, signature, signature_length, encoded_length);</span><br><span> </span><br><span> cleanup:</span><br><span>        if (mdctx) {</span><br><span>@@ -1001,20 +991,31 @@</span><br><span>  * \brief Adds the 'origid' field to the JWT.</span><br><span>  *</span><br><span>  * \param json The JWT</span><br><span style="color: hsl(0, 100%, 40%);">- * \param origid The value to set origid to</span><br><span>  *</span><br><span>  * \retval 0 on success</span><br><span>  * \retval -1 on failure</span><br><span>  */</span><br><span style="color: hsl(0, 100%, 40%);">-static int stir_shaken_add_origid(struct ast_json *json, const char *origid)</span><br><span style="color: hsl(120, 100%, 40%);">+static int stir_shaken_add_origid(struct ast_json *json)</span><br><span> {</span><br><span>     struct ast_json *value;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct ast_uuid *uuid;</span><br><span style="color: hsl(120, 100%, 40%);">+        char *uuid_str;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     value = ast_json_string_create(origid);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!origid) {</span><br><span style="color: hsl(120, 100%, 40%);">+        uuid = ast_uuid_generate();</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!uuid) {</span><br><span>                 return -1;</span><br><span>   }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ uuid_str = ast_malloc(AST_UUID_STR_LEN);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!uuid_str) {</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_free(uuid);</span><br><span style="color: hsl(120, 100%, 40%);">+               return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   value = ast_json_string_create(ast_uuid_to_str(uuid, uuid_str, AST_UUID_STR_LEN));</span><br><span style="color: hsl(120, 100%, 40%);">+    ast_free(uuid_str);</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_free(uuid);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    return ast_json_object_set(ast_json_object_get(json, "payload"), "origid", value);</span><br><span> }</span><br><span> </span><br><span>@@ -1085,7 +1086,7 @@</span><br><span>              goto cleanup;</span><br><span>        }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (stir_shaken_add_origid(json, stir_shaken_certificate_get_origid(cert))) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (stir_shaken_add_origid(json)) {</span><br><span>          ast_log(LOG_ERROR, "Failed to add 'origid' to payload\n");</span><br><span>                 goto cleanup;</span><br><span>        }</span><br><span>diff --git a/res/res_stir_shaken/certificate.c b/res/res_stir_shaken/certificate.c</span><br><span>index 1a1447e..162d267 100644</span><br><span>--- a/res/res_stir_shaken/certificate.c</span><br><span>+++ b/res/res_stir_shaken/certificate.c</span><br><span>@@ -40,8 +40,6 @@</span><br><span>               AST_STRING_FIELD(caller_id_number);</span><br><span>          /*! The attestation level for this certificate */</span><br><span>            AST_STRING_FIELD(attestation);</span><br><span style="color: hsl(0, 100%, 40%);">-          /*! The origination ID for this certificate */</span><br><span style="color: hsl(0, 100%, 40%);">-          AST_STRING_FIELD(origid);</span><br><span>    );</span><br><span>   /*! The private key for the certificate */</span><br><span>   EVP_PKEY *private_key;</span><br><span>@@ -105,11 +103,6 @@</span><br><span>        return cert ? cert->attestation : NULL;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-const char *stir_shaken_certificate_get_origid(struct stir_shaken_certificate *cert)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        return cert ? cert->origid : NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> EVP_PKEY *stir_shaken_certificate_get_private_key(struct stir_shaken_certificate *cert)</span><br><span> {</span><br><span>       return cert ? cert->private_key : NULL;</span><br><span>@@ -378,7 +371,6 @@</span><br><span>             on_load_public_key_url, public_key_url_to_str, NULL, 0, 0);</span><br><span>  ast_sorcery_object_field_register_custom(sorcery, CONFIG_TYPE, "attestation", "",</span><br><span>                on_load_attestation, attestation_to_str, NULL, 0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-   ast_sorcery_object_field_register(sorcery, CONFIG_TYPE, "origid", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct stir_shaken_certificate, origid));</span><br><span>  ast_sorcery_object_field_register(sorcery, CONFIG_TYPE, "caller_id_number", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct stir_shaken_certificate, caller_id_number));</span><br><span> </span><br><span>  ast_cli_register_multiple(stir_shaken_certificate_cli,</span><br><span>diff --git a/res/res_stir_shaken/certificate.h b/res/res_stir_shaken/certificate.h</span><br><span>index 6eeb36b..829371b 100644</span><br><span>--- a/res/res_stir_shaken/certificate.h</span><br><span>+++ b/res/res_stir_shaken/certificate.h</span><br><span>@@ -55,16 +55,6 @@</span><br><span> const char *stir_shaken_certificate_get_attestation(struct stir_shaken_certificate *cert);</span><br><span> </span><br><span> /*!</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief Get the origination ID associated with a certificate</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * \param cert The certificate</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval NULL on failure</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval The origid on success</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-const char *stir_shaken_certificate_get_origid(struct stir_shaken_certificate *cert);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*!</span><br><span>  * \brief Get the private key associated with a certificate</span><br><span>  *</span><br><span>  * \param cert The certificate to get the private key from</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/15814">change 15814</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/15814"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Icf094a2a54e87db91d6b12244c9f5ba4fc2e0b8c </div>
<div style="display:none"> Gerrit-Change-Number: 15814 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Benjamin Keith Ford <bford@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>