Annotation of libaitwww/src/base64.c, revision 1.4
1.2 misho 1: /*************************************************************************
2: * (C) 2012 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
3: * by Michael Pounov <misho@elwix.org>
4: *
5: * $Author: misho $
1.4 ! misho 6: * $Id: base64.c,v 1.3.6.1 2016/09/14 15:08:24 misho Exp $
1.2 misho 7: *
8: **************************************************************************
9: The ELWIX and AITNET software is distributed under the following
10: terms:
11:
12: All of the documentation and software included in the ELWIX and AITNET
13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
14:
1.4 ! misho 15: Copyright 2004 - 2016
1.2 misho 16: by Michael Pounov <misho@elwix.org>. All rights reserved.
17:
18: Redistribution and use in source and binary forms, with or without
19: modification, are permitted provided that the following conditions
20: are met:
21: 1. Redistributions of source code must retain the above copyright
22: notice, this list of conditions and the following disclaimer.
23: 2. Redistributions in binary form must reproduce the above copyright
24: notice, this list of conditions and the following disclaimer in the
25: documentation and/or other materials provided with the distribution.
26: 3. All advertising materials mentioning features or use of this software
27: must display the following acknowledgement:
28: This product includes software developed by Michael Pounov <misho@elwix.org>
29: ELWIX - Embedded LightWeight unIX and its contributors.
30: 4. Neither the name of AITNET nor the names of its contributors
31: may be used to endorse or promote products derived from this software
32: without specific prior written permission.
33:
34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37: ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44: SUCH DAMAGE.
45: */
46: #include "global.h"
47:
48:
49: static const unsigned char base64_table[65] =
50: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
51:
52:
53: /*
54: * www_b64encode() - Base64 encode function
55: *
56: * @src = source data
1.3 misho 57: * return: NULL error or !=NULL encoded variable, after use call ait_freeVar()
1.2 misho 58: */
59: ait_val_t *
60: www_b64encode(ait_val_t * __restrict src)
61: {
1.4 ! misho 62: ait_val_t v = AIT_VAL_INIT, *ret = NULL;
1.2 misho 63: size_t olen;
64: const u_char *in, *end;
65: u_char *pos, *out;
66: int len = 0;
67:
68: if (!src || AIT_ISEMPTY(src))
69: return NULL;
70: olen = AIT_LEN(src) * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
71: olen += olen / 72; /* LF */
72: olen++; /* \0 */
73: if (olen < AIT_LEN(src)) {
74: www_SetErr(EINVAL, "Integer overflow");
75: return NULL;
76: }
77:
78: AIT_SET_STRSIZ(&v, olen);
79: pos = out = (u_char*) AIT_GET_STR(&v);
80: in = (u_char*) AIT_GET_STR(src);
81: end = in + AIT_LEN(src);
82:
83: while (end - in >= 3) {
84: *pos++ = base64_table[in[0] >> 2];
85: *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
86: *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
87: *pos++ = base64_table[in[2] & 0x3f];
88: in += 3;
89: len += 4;
90: if (len >= 72) {
91: *pos++ = '\n';
92: len = 0;
93: }
94: }
95:
96: if (end - in) {
97: *pos++ = base64_table[in[0] >> 2];
98: if (end - in == 1) {
99: *pos++ = base64_table[(in[0] & 0x03) << 4];
100: *pos++ = '=';
101: } else {
102: *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
103: *pos++ = base64_table[(in[1] & 0x0f) << 2];
104: }
105: *pos++ = '=';
106: len += 4;
107: }
108:
109: if (len)
110: *pos++ = '\n';
111:
112: *pos = 0;
113:
1.3 misho 114: if (!(ret = ait_allocVar())) {
115: www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
1.2 misho 116: return NULL;
117: } else {
118: AIT_INIT_VAL2(ret, string);
119: AIT_SET_STRLCPY(ret, AIT_GET_STR(&v), pos - out);
120: AIT_FREE_VAL(&v);
121: }
122: return ret;
123: }
124:
125: /*
126: * www_b64decode() - Base64 decode function
127: *
128: * @src = source encoded data
1.3 misho 129: * return: NULL error or !=NULL decoded variable, after use call ait_freeVar()
1.2 misho 130: */
131: ait_val_t *
132: www_b64decode(ait_val_t * __restrict src)
133: {
1.4 ! misho 134: ait_val_t v = AIT_VAL_INIT, *ret = NULL;
1.2 misho 135: u_char dtable[256], *s, *pos, *out, in[4], blk[4];
136: register size_t i, olen, cx = 0;
137:
138: if (!src || AIT_ISEMPTY(src))
139: return NULL;
140: else
141: s = (u_char*) AIT_GET_STR(src);
142:
143: memset(dtable, 0x80, sizeof dtable);
144: for (i = 0; i < sizeof base64_table - 1; i++)
145: dtable[base64_table[i]] = (u_char) i;
146: dtable['='] = 0;
147:
148: for (i = 0; i < AIT_LEN(src); i++)
149: if (dtable[s[i]] != 0x80)
150: cx++;
151: if (!cx || cx % 4) {
152: www_SetErr(EINVAL, "Invalid argument");
153: return NULL;
154: }
155:
156: olen = cx / 4 * 3;
157: AIT_SET_STRSIZ(&v, olen);
158: pos = out = (u_char*) AIT_GET_STR(&v);
159:
160: for (cx = i = 0; i < AIT_LEN(src); i++) {
161: if (dtable[s[i]] == 0x80)
162: continue;
163: in[cx] = s[i];
164: blk[cx++] = dtable[s[i]];
165: if (cx == 4) {
166: *pos++ = (blk[0] << 2) | (blk[1] >> 4);
167: *pos++ = (blk[1] << 4) | (blk[2] >> 2);
168: *pos++ = (blk[2] << 6) | blk[3];
169: cx = 0;
170: }
171: }
172:
173: if (pos > out) {
174: if (in[2] == '=')
175: pos -= 2;
176: else if (in[3] == '=')
177: pos--;
178: }
179:
1.3 misho 180: if (!(ret = ait_allocVar())) {
181: www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
1.2 misho 182: return NULL;
183: } else {
184: AIT_INIT_VAL2(ret, string);
185: AIT_SET_STRLCPY(ret, AIT_GET_STR(&v), pos - out);
186: AIT_FREE_VAL(&v);
187: }
188: return ret;
189: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>