version 1.1, 2012/09/17 13:05:47
|
version 1.2, 2012/09/20 14:19:45
|
Line 0
|
Line 1
|
|
/************************************************************************* |
|
* (C) 2012 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org> |
|
* by Michael Pounov <misho@elwix.org> |
|
* |
|
* $Author$ |
|
* $Id$ |
|
* |
|
************************************************************************** |
|
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 <info@elwix.org> |
|
|
|
Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 |
|
by Michael Pounov <misho@elwix.org>. 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 <misho@elwix.org> |
|
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; |
|
} |