summaryrefslogtreecommitdiff
path: root/src/core/base64_url.h
diff options
context:
space:
mode:
authorsss <sss@dark-alexandr.net>2023-01-17 00:38:19 +0300
committersss <sss@dark-alexandr.net>2023-01-17 00:38:19 +0300
commitcc3f33db7a8d3c4ad373e646b199808e01bc5d9b (patch)
treeec09d690c7656ab5f2cc72607e05fb359c24d8b2 /src/core/base64_url.h
added webrdp public code
Diffstat (limited to 'src/core/base64_url.h')
-rw-r--r--src/core/base64_url.h187
1 files changed, 187 insertions, 0 deletions
diff --git a/src/core/base64_url.h b/src/core/base64_url.h
new file mode 100644
index 0000000..0f7741a
--- /dev/null
+++ b/src/core/base64_url.h
@@ -0,0 +1,187 @@
+/*-
+ * Copyright (c) 2003 - 2016 Rozhuk Ivan <rozhuk.im@gmail.com>
+ * Copyright (c) 2018 sss <sss at dark-alexandr dot net>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+static const uint8_t *base64_url_tbl_coding = (const uint8_t
+ *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
+static const uint8_t base64_url_tbl_decoding[256] = {64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 62, 64, 64, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
+ 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 63, 64, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64};
+
+static inline int
+base64_url_encode(uint8_t *src, size_t src_size, uint8_t *dst, size_t dst_size,
+ size_t *enc_size)
+{
+ size_t tm, src_m3_size;
+ register uint8_t *wpos, *rpos, *src_m3_max;
+
+ if (NULL == src || 0 == src_size)
+ return (EINVAL);
+ /* dst buf size calculation. */
+ tm = (src_size / 3);
+ src_m3_size = (tm * 3);
+ if (src_m3_size != src_size)
+ { /* is multiple of 3? */
+ tm++;
+ }
+ tm *= 4;
+ if (NULL != enc_size)
+ {
+ (*enc_size) = tm;
+ }
+ if (dst_size < tm) /* Is dst buf too small? */
+ return (ENOBUFS);
+ if (NULL == dst)
+ return (EINVAL);
+ wpos = dst;
+ rpos = src;
+ /* Main loop: encode 3 -> 4 */
+ for (src_m3_max = (src + src_m3_size); rpos < src_m3_max; rpos += 3)
+ {
+ (*wpos++) = base64_url_tbl_coding[rpos[0] >> 2]; /* c1 */
+ (*wpos++)
+ = base64_url_tbl_coding[((rpos[0] << 4) & 0x30)
+ | ((rpos[1] >> 4) & 0x0f)]; /* c2 */
+ (*wpos++)
+ = base64_url_tbl_coding[((rpos[1] << 2) & 0x3c)
+ | ((rpos[2] >> 6) & 0x03)]; /* c3 */
+ (*wpos++) = base64_url_tbl_coding[rpos[2] & 0x3f]; /* c4 */
+ }
+ /* Tail special encoding. */
+ if (src_size != src_m3_size)
+ { /* If src_size was not a multiple of 3: 1-2 bytes tail special coding.
+ */
+ (*wpos++) = base64_url_tbl_coding[rpos[0] >> 2]; /* c1 */
+ if (1 == (src_size - src_m3_size))
+ { /* 1 byte tail. */
+ (*wpos++) = base64_url_tbl_coding[(
+ (rpos[0] << 4) & 0x30)]; /* c2 */
+ (*wpos++) = '='; /* c3: tail padding. */
+ }
+ else
+ { /* 2 bytes tail. */
+ (*wpos++)
+ = base64_url_tbl_coding[((rpos[0] << 4) & 0x30)
+ | ((rpos[1] >> 4)
+ & 0x0f)]; /* c2 */
+ (*wpos++) = base64_url_tbl_coding[(
+ (rpos[1] << 2) & 0x3c)]; /* c3 */
+ }
+ (*wpos++) = '='; /* c4: tail padding. */
+ }
+ (*wpos) = 0;
+#if 0
+ if ((wpos - dst) != tm) { /* Must be euqual! */
+ (*enc_size) = (wpos - dst);
+ }
+#endif
+
+ return (0);
+}
+
+static inline int
+base64_url_decode(uint8_t *src, size_t src_size, uint8_t *dst, size_t dst_size,
+ size_t *dcd_size)
+{
+ size_t tm, src_m4_size;
+ register uint8_t *wpos, *rpos, *src_m4_max;
+
+ if (NULL == src || 2 > src_size)
+ return (EINVAL);
+ /* Remove tail padding. */
+ for (; 0 < src_size; src_size--)
+ {
+ if ('=' != src[(src_size - 1)])
+ break;
+ }
+ if (2 > src_size) /* Check again: at least 2 byte needed for decoder. */
+ return (EINVAL);
+ /* dst buf size calculation. */
+ tm = (src_size / 4);
+ src_m4_size = (tm * 4);
+ if (src_m4_size != src_size)
+ { /* is multiple of 4? */
+ tm++;
+ }
+ tm *= 3;
+ if (dst_size < tm)
+ { /* Is dst buf too small? */
+ if (NULL != dcd_size)
+ {
+ (*dcd_size) = tm;
+ }
+ return (ENOBUFS);
+ }
+ if (NULL == dst)
+ return (EINVAL);
+ wpos = dst;
+ rpos = src;
+ /* Main loop: decode 4 -> 3 */
+ for (src_m4_max = (src + src_m4_size); rpos < src_m4_max; rpos += 4)
+ {
+ (*wpos++) = (base64_url_tbl_decoding[rpos[0]] << 2
+ | base64_url_tbl_decoding[rpos[1]] >> 4);
+ (*wpos++) = (base64_url_tbl_decoding[rpos[1]] << 4
+ | base64_url_tbl_decoding[rpos[2]] >> 2);
+ (*wpos++) = (base64_url_tbl_decoding[rpos[2]] << 6
+ | base64_url_tbl_decoding[rpos[3]]);
+ }
+ /* Tail special decoding. */
+ switch ((src_size - src_m4_size))
+ {
+ case 2:
+ (*wpos++) = (base64_url_tbl_decoding[rpos[0]] << 2
+ | base64_url_tbl_decoding[rpos[1]] >> 4);
+ break;
+ case 3:
+ (*wpos++) = (base64_url_tbl_decoding[rpos[0]] << 2
+ | base64_url_tbl_decoding[rpos[1]] >> 4);
+ (*wpos++) = (base64_url_tbl_decoding[rpos[1]] << 4
+ | base64_url_tbl_decoding[rpos[2]] >> 2);
+ break;
+ }
+ (*wpos) = 0;
+ if (NULL != dcd_size)
+ { /* Real decoded size can be smaller than calculated. */
+ (*dcd_size) = (wpos - dst);
+ }
+
+ return (0);
+}