1 /*
2 **
3 ** Copyright (C) 1994 Swedish University Network (SUNET)
4 ** Modified by Rami Lehti (C) 1999
5 **
6 **
7 ** This program is free software; you can redistribute it and/or modify
8 ** it under the terms of the GNU General Public License as published by
9 ** the Free Software Foundation; either version 2 of the License, or
10 ** (at your option) any later version.
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITTNESS FOR A PARTICULAR PURPOSE. See the
15 ** GNU General Public License for more details.
16 **
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program; if not, write to the Free Software
19 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 **
21 **
22 ** Martin.Wendel@udac.uu.se
23 ** Torbjorn.Wictorin@udac.uu.se
24 **
25 ** UDAC
26 ** P.O. Box 174
27 ** S-751 04 Uppsala
28 ** Sweden
29 **
30 */
31
32 #include "aide.h"
33 #include <string.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include "base64.h"
37 #include "util.h"
38 #include "log.h"
39 /*for locale support*/
40 #include "locale-aide.h"
41 /*for locale support*/
42
43 char tob64[] =
44 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
45
46
47
48 int fromb64[] = {
49 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
50 FAIL, SKIP, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL,
51 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
52 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
53
54 SKIP, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
55 FAIL, FAIL, FAIL, 0x3e, FAIL, FAIL, FAIL, 0x3f,
56 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
57 0x3c, 0x3d, FAIL, FAIL, FAIL, SKIP, FAIL, FAIL,
58
59 FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
60 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
61 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
62 0x17, 0x18, 0x19, FAIL, FAIL, FAIL, FAIL, FAIL,
63
64 FAIL, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
65 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
66 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
67 0x31, 0x32, 0x33, FAIL, FAIL, FAIL, FAIL, FAIL,
68
69 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
70 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
71 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
72 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
73 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
74 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
75 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
76 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
77 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
78 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
79 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
80 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
81 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
82 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
83 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
84 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL
85 };
86
87 /* Returns NULL on error */
encode_base64(byte * src,size_t ssize)88 char* encode_base64(byte* src,size_t ssize)
89 {
90 char* outbuf;
91 int pos;
92 int i, l, left;
93 unsigned long triple;
94 byte *inb;
95
96 /* Exit on empty input */
97 if (!ssize||src==NULL){
98 log_msg(LOG_LEVEL_DEBUG,"encode base64: empty string");
99 return NULL;
100 }
101
102 /* length of encoded base64 string (padded) */
103 size_t length = sizeof(char)* ((ssize + 2) / 3) * 4;
104 outbuf = (char *)checked_malloc(length + 1);
105
106 /* Initialize working pointers */
107 inb = src;
108 i = 0;
109 triple = 0;
110 pos = 0;
111 left = ssize;
112 log_msg(LOG_LEVEL_TRACE, "encode base64:, data length: %d", left);
113 /*
114 * Process entire inbuf.
115 */
116 while (left != 0)
117 {
118 i++;
119 left--;
120
121 triple = (triple <<8) | *inb;
122 if (i == 3 || left == 0)
123 {
124 switch (i)
125 {
126 case 1:
127 triple = triple<<4;
128 break;
129 case 2:
130 triple = triple<<2;
131 break;
132 default:
133 break;
134 }
135 for (l = i; l >= 0; l--){
136 /* register */
137 int rr;
138 rr = 0x3f & (triple>>(6*l));
139 assert (rr < 64);
140 outbuf[pos]=tob64[rr];
141 pos++;
142 }
143 if (left == 0)
144 switch(i)
145 {
146 case 2:
147 outbuf[pos]='=';
148 pos++;
149 break;
150 case 1:
151 outbuf[pos]='=';
152 pos++;
153 outbuf[pos]='=';
154 pos++;
155 break;
156 default:
157 break;
158 }
159 triple = 0;
160 i = 0;
161 }
162 inb++;
163 }
164
165 outbuf[pos]='\0';
166
167 return outbuf;
168 }
169
decode_base64(char * src,size_t ssize,size_t * ret_len)170 byte* decode_base64(char* src,size_t ssize, size_t *ret_len)
171 {
172 byte* outbuf;
173 char* inb;
174 int i;
175 int l;
176 int left;
177 int pos;
178 unsigned long triple;
179
180 /* Exit on empty input */
181 if (!ssize||src==NULL) {
182 log_msg(LOG_LEVEL_DEBUG, "decode base64: empty string");
183 return NULL;
184 }
185
186 /* exit on unpadded input */
187 if (ssize % 4) {
188 log_msg(LOG_LEVEL_WARNING, "decode_base64: '%s' has invalid length (missing padding characters?)", src);
189 return NULL;
190 }
191
192 /* calculate length of decoded string, substract padding chars if any (ssize is >= 4) */
193 size_t length = sizeof(byte) * ((ssize / 4) * 3)- (src[ssize-1] == '=') - (src[ssize-2] == '=');
194
195 /* Initialize working pointers */
196 inb = src;
197 outbuf = (byte *)checked_malloc(length + 1);
198
199 l = 0;
200 triple = 0;
201 pos=0;
202 left = ssize;
203 /*
204 * Process entire inbuf.
205 */
206 while (left != 0)
207 {
208 left--;
209 i = fromb64[(unsigned char)*inb];
210 switch(i)
211 {
212 case FAIL:
213 log_msg(LOG_LEVEL_WARNING, "decode_base64: illegal character: '%c' in '%s'", *inb, src);
214 free(outbuf);
215 return NULL;
216 break;
217 case SKIP:
218 break;
219 default:
220 triple = triple<<6 | (0x3f & i);
221 l++;
222 break;
223 }
224 if (l == 4 || left == 0)
225 {
226 switch(l)
227 {
228 case 2:
229 triple = triple>>4;
230 break;
231 case 3:
232 triple = triple>>2;
233 break;
234 default:
235 break;
236 }
237 for (l -= 2; l >= 0; l--)
238 {
239 outbuf[pos]=( 0xff & (triple>>(l*8)));
240 pos++;
241 }
242 triple = 0;
243 l = 0;
244 }
245 inb++;
246 }
247
248 outbuf[pos]='\0';
249
250 if (ret_len) *ret_len = pos;
251
252 return outbuf;
253 }
254
length_base64(char * src,size_t ssize)255 size_t length_base64(char* src,size_t ssize)
256 {
257 char* inb;
258 int i;
259 int l;
260 int left;
261 size_t pos;
262 unsigned long triple;
263
264 /* Exit on empty input */
265 if (!ssize||src==NULL) {
266 log_msg(LOG_LEVEL_DEBUG,"length_base64: empty string");
267 return 0;
268 }
269
270
271
272 /* Initialize working pointers */
273 inb = src;
274
275 l = 0;
276 triple = 0;
277 pos=0;
278 left = ssize;
279 /*
280 * Process entire inbuf.
281 */
282 while (left != 0)
283 {
284 left--;
285 i = fromb64[(unsigned char)*inb];
286 switch(i)
287 {
288 case FAIL:
289 log_msg(LOG_LEVEL_DEBUG, "length_base64: illegal string: '%s'", src);
290 return 0;
291 break;
292 case SKIP:
293 break;
294 default:
295 triple = triple<<6 | (0x3f & i);
296 l++;
297 break;
298 }
299 if (l == 4 || left == 0)
300 {
301 switch(l)
302 {
303 case 2:
304 triple = triple>>4;
305 break;
306 case 3:
307 triple = triple>>2;
308 break;
309 default:
310 break;
311 }
312 for (l -= 2; l >= 0; l--)
313 {
314 pos++;
315 }
316 triple = 0;
317 l = 0;
318 }
319 inb++;
320 }
321
322 return pos;
323 }
324
325