--- libaitwww/src/base64.c 2012/09/17 13:05:47 1.1 +++ libaitwww/src/base64.c 2012/09/20 14:19:45 1.2 @@ -0,0 +1,189 @@ +/************************************************************************* +* (C) 2012 AITNET ltd - Sofia/Bulgaria - +* by Michael Pounov +* +* $Author: misho $ +* $Id: base64.c,v 1.2 2012/09/20 14:19:45 misho Exp $ +* +************************************************************************** +The ELWIX and AITNET software is distributed under the following +terms: + +All of the documentation and software included in the ELWIX and AITNET +Releases is copyrighted by ELWIX - Sofia/Bulgaria + +Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 + by Michael Pounov . 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. +3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: +This product includes software developed by Michael Pounov +ELWIX - Embedded LightWeight unIX and its contributors. +4. Neither the name of AITNET nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY AITNET 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. +*/ +#include "global.h" + + +static const unsigned char base64_table[65] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + +/* + * www_b64encode() - Base64 encode function + * + * @src = source data + * return: NULL error or !=NULL encoded variable, after use call io_freeVar() + */ +ait_val_t * +www_b64encode(ait_val_t * __restrict src) +{ + ait_val_t v, *ret = NULL; + size_t olen; + const u_char *in, *end; + u_char *pos, *out; + int len = 0; + + if (!src || AIT_ISEMPTY(src)) + return NULL; + olen = AIT_LEN(src) * 4 / 3 + 4; /* 3-byte blocks to 4-byte */ + olen += olen / 72; /* LF */ + olen++; /* \0 */ + if (olen < AIT_LEN(src)) { + www_SetErr(EINVAL, "Integer overflow"); + return NULL; + } + + AIT_SET_STRSIZ(&v, olen); + pos = out = (u_char*) AIT_GET_STR(&v); + in = (u_char*) AIT_GET_STR(src); + end = in + AIT_LEN(src); + + while (end - in >= 3) { + *pos++ = base64_table[in[0] >> 2]; + *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; + *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; + *pos++ = base64_table[in[2] & 0x3f]; + in += 3; + len += 4; + if (len >= 72) { + *pos++ = '\n'; + len = 0; + } + } + + if (end - in) { + *pos++ = base64_table[in[0] >> 2]; + if (end - in == 1) { + *pos++ = base64_table[(in[0] & 0x03) << 4]; + *pos++ = '='; + } else { + *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; + *pos++ = base64_table[(in[1] & 0x0f) << 2]; + } + *pos++ = '='; + len += 4; + } + + if (len) + *pos++ = '\n'; + + *pos = 0; + + if (!(ret = io_allocVar())) { + www_SetErr(io_GetErrno(), "%s", io_GetError()); + return NULL; + } else { + AIT_INIT_VAL2(ret, string); + AIT_SET_STRLCPY(ret, AIT_GET_STR(&v), pos - out); + AIT_FREE_VAL(&v); + } + return ret; +} + +/* + * www_b64decode() - Base64 decode function + * + * @src = source encoded data + * return: NULL error or !=NULL decoded variable, after use call io_freeVar() + */ +ait_val_t * +www_b64decode(ait_val_t * __restrict src) +{ + ait_val_t v, *ret = NULL; + u_char dtable[256], *s, *pos, *out, in[4], blk[4]; + register size_t i, olen, cx = 0; + + if (!src || AIT_ISEMPTY(src)) + return NULL; + else + s = (u_char*) AIT_GET_STR(src); + + memset(dtable, 0x80, sizeof dtable); + for (i = 0; i < sizeof base64_table - 1; i++) + dtable[base64_table[i]] = (u_char) i; + dtable['='] = 0; + + for (i = 0; i < AIT_LEN(src); i++) + if (dtable[s[i]] != 0x80) + cx++; + if (!cx || cx % 4) { + www_SetErr(EINVAL, "Invalid argument"); + return NULL; + } + + olen = cx / 4 * 3; + AIT_SET_STRSIZ(&v, olen); + pos = out = (u_char*) AIT_GET_STR(&v); + + for (cx = i = 0; i < AIT_LEN(src); i++) { + if (dtable[s[i]] == 0x80) + continue; + in[cx] = s[i]; + blk[cx++] = dtable[s[i]]; + if (cx == 4) { + *pos++ = (blk[0] << 2) | (blk[1] >> 4); + *pos++ = (blk[1] << 4) | (blk[2] >> 2); + *pos++ = (blk[2] << 6) | blk[3]; + cx = 0; + } + } + + if (pos > out) { + if (in[2] == '=') + pos -= 2; + else if (in[3] == '=') + pos--; + } + + if (!(ret = io_allocVar())) { + www_SetErr(io_GetErrno(), "%s", io_GetError()); + return NULL; + } else { + AIT_INIT_VAL2(ret, string); + AIT_SET_STRLCPY(ret, AIT_GET_STR(&v), pos - out); + AIT_FREE_VAL(&v); + } + return ret; +}