File:  [ELWIX - Embedded LightWeight unIX -] / libaitwww / src / base64.c
Revision 1.4: download - view: text, annotated - select for diffs - revision graph
Wed Sep 14 15:12:22 2016 UTC (7 years, 9 months ago) by misho
Branches: MAIN
CVS tags: www3_4, WWW3_3, HEAD
version 3.3

    1: /*************************************************************************
    2: * (C) 2012 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
    3: *  by Michael Pounov <misho@elwix.org>
    4: *
    5: * $Author: misho $
    6: * $Id: base64.c,v 1.4 2016/09/14 15:12:22 misho Exp $
    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: 
   15: Copyright 2004 - 2016
   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
   57:  * return: NULL error or !=NULL encoded variable, after use call ait_freeVar()
   58:  */
   59: ait_val_t *
   60: www_b64encode(ait_val_t * __restrict src)
   61: {
   62: 	ait_val_t v = AIT_VAL_INIT, *ret = NULL;
   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: 
  114: 	if (!(ret = ait_allocVar())) {
  115: 		www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
  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
  129:  * return: NULL error or !=NULL decoded variable, after use call ait_freeVar()
  130:  */
  131: ait_val_t *
  132: www_b64decode(ait_val_t * __restrict src)
  133: {
  134: 	ait_val_t v = AIT_VAL_INIT, *ret = NULL;
  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: 
  180: 	if (!(ret = ait_allocVar())) {
  181: 		www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
  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>