diff options
author | sss <sss@dark-alexandr.net> | 2023-01-17 00:38:19 +0300 |
---|---|---|
committer | sss <sss@dark-alexandr.net> | 2023-01-17 00:38:19 +0300 |
commit | cc3f33db7a8d3c4ad373e646b199808e01bc5d9b (patch) | |
tree | ec09d690c7656ab5f2cc72607e05fb359c24d8b2 /src/core/base64_url.h |
added webrdp public code
Diffstat (limited to 'src/core/base64_url.h')
-rw-r--r-- | src/core/base64_url.h | 187 |
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); +} |