1 /*
2  *	base64.c
3  *	Release $Name: MATRIXSSL-3-3-0-OPEN $
4  *
5  *	Base64 operations
6  */
7 /*
8  *	Copyright (c) AuthenTec, Inc. 2011-2012
9  *	Copyright (c) PeerSec Networks, 2002-2011
10  *	All Rights Reserved
11  *
12  *	The latest version of this code is available at http://www.matrixssl.org
13  *
14  *	This software is open source; you can redistribute it and/or modify
15  *	it under the terms of the GNU General Public License as published by
16  *	the Free Software Foundation; either version 2 of the License, or
17  *	(at your option) any later version.
18  *
19  *	This General Public License does NOT permit incorporating this software
20  *	into proprietary programs.  If you are unable to comply with the GPL, a
21  *	commercial license for this software may be purchased from AuthenTec at
22  *	http://www.authentec.com/Products/EmbeddedSecurity/SecurityToolkits.aspx
23  *
24  *	This program is distributed in WITHOUT ANY WARRANTY; without even the
25  *	implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26  *	See the GNU General Public License for more details.
27  *
28  *	You should have received a copy of the GNU General Public License
29  *	along with this program; if not, write to the Free Software
30  *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
31  *	http://www.gnu.org/copyleft/gpl.html
32  */
33 /******************************************************************************/
34 
35 #include "../cryptoApi.h"
36 
37 #ifdef USE_BASE64_DECODE
38 
39 static const unsigned char map[256] = {
40 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
41 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
42 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
43 255, 255, 255, 255, 255, 255, 255,  62, 255, 255, 255,  63,
44  52,  53,  54,  55,  56,  57,  58,  59,  60,  61, 255, 255,
45 255, 254, 255, 255, 255,   0,   1,   2,   3,   4,   5,   6,
46   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,
47  19,  20,  21,  22,  23,  24,  25, 255, 255, 255, 255, 255,
48 255,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,
49  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
50  49,  50,  51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
51 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
52 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
53 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
54 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
55 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
56 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
57 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
58 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
59 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
60 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
61 255, 255, 255, 255 };
62 
psBase64decode(const unsigned char * in,uint32 len,unsigned char * out,uint32 * outlen)63 int32 psBase64decode(const unsigned char *in, uint32 len,
64 					unsigned char *out, uint32 *outlen)
65 {
66 	unsigned long	t, x, y, z;
67 	unsigned char	c;
68 	int32			g;
69 
70 	if (in == NULL || out == NULL || outlen == NULL) {
71 		psTraceCrypto("Arg failure to psBase64decode\n");
72 		return PS_ARG_FAIL;
73 	}
74 	g = 3;
75 	for (x = y = z = t = 0; x < len; x++) {
76 		c = map[in[x]&0xFF];
77 		if (c == 255) {
78 			continue;
79 		}
80 /*
81 	the final = symbols are read and used to trim the remaining bytes
82  */
83 	if (c == 254) {
84 		c = 0;
85 /*
86 		prevent g < 0 which would potentially allow an overflow later
87  */
88 		if (--g < 0) {
89 			psTraceCrypto("Negative g failure in psBase64decode\n");
90 			return PS_LIMIT_FAIL;
91 		}
92 	} else if (g != 3) {
93 /*
94 		we only allow = to be at the end
95  */
96 		psTraceCrypto("g failure in psBase64decode\n");
97 		return PS_PARSE_FAIL;
98 	}
99 
100 		t = (t<<6)|c;
101 
102 		if (++y == 4) {
103 			if (z + g > *outlen) {
104 				psTraceCrypto("outlen too small for psBase64decode\n");
105 				return PS_LIMIT_FAIL;
106 			}
107 			out[z++] = (unsigned char)((t>>16)&255);
108 			if (g > 1) {
109 				out[z++] = (unsigned char)((t>>8)&255);
110 			}
111 			if (g > 2) {
112 				out[z++] = (unsigned char)(t&255);
113 			}
114 			y = t = 0;
115 		}
116 	}
117 	if (y != 0) {
118 		psTraceCrypto("y failure in psBase64decode\n");
119 		return PS_PARSE_FAIL;
120 	}
121 	*outlen = z;
122 	return PS_SUCCESS;
123 }
124 
125 #endif /* USE_BASE64_DECODE */
126 
127 /******************************************************************************/
128 
129