Imported Upstream version 2.7
[ossec-hids.git] / src / addagent / b64.c
1 /* @(#) $Id: ./src/addagent/b64.c, 2011/09/08 dcid Exp $
2  */
3 /*
4  * Copyright (C), 2000-2004 by the monit project group.
5  * All Rights Reserved.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * 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 Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #define TRUE    1
27 #define FALSE   0
28
29 char *decode_base64(const char *src);
30 char *encode_base64(int size, char *src);
31
32 /* Private prototypes */
33 static int is_base64(char c);
34 static char encode(unsigned char u);
35 static unsigned char decode(char c);
36
37
38 /**
39  *  Implementation of base64 encoding/decoding.
40  *
41  *  @author Jan-Henrik Haukeland, <hauk@tildeslash.com>
42  *
43  *  @version \$Id$
44  *
45  *  @file
46  */
47
48
49
50 /**
51  * Base64 encode and return size data in 'src'. The caller must free the
52  * returned string.
53  * @param size The size of the data in src
54  * @param src The data to be base64 encode
55  * @return encoded string otherwise NULL
56  */
57 char *encode_base64(int size, char *src) {
58
59     int i;
60     char *out, *p;
61
62     if(!src)
63         return NULL;
64
65     if(!size)
66         size= strlen((char *)src);
67
68     out = (char *)calloc(sizeof(char), size*4/3+4);
69     if(!out)
70         return NULL;
71
72     p = out;
73
74     for(i = 0; i < size; i+=3) {
75
76         unsigned char b1=0, b2=0, b3=0, b4=0, b5=0, b6=0, b7=0;
77
78         b1 = src[i];
79
80         if(i+1<size)
81             b2 = src[i+1];
82
83         if(i+2<size)
84             b3 = src[i+2];
85
86         b4= b1>>2;
87         b5= ((b1&0x3)<<4)|(b2>>4);
88         b6= ((b2&0xf)<<2)|(b3>>6);
89         b7= b3&0x3f;
90
91         *p++= encode(b4);
92         *p++= encode(b5);
93
94         if(i+1<size) {
95             *p++= encode(b6);
96         } else {
97             *p++= '=';
98         }
99
100         if(i+2<size) {
101             *p++= encode(b7);
102         } else {
103             *p++= '=';
104         }
105
106     }
107
108     return out;
109
110 }
111
112 /**
113  * Decode the base64 encoded string 'src' into the memory pointed to by
114  * 'dest'. The dest buffer is NUL terminated.
115  * Return NULL in case of error
116  */
117 char *decode_base64(const char *src)
118 {
119     if(src && *src)
120     {
121         char *dest;
122         unsigned char *p;
123         int k, l = strlen(src)+1;
124         unsigned char *buf;
125
126         /* The size of the dest will always be less than
127          * the source
128          */
129         dest = (char *)calloc(sizeof(char), l + 13);
130         if(!dest)
131             return(NULL);
132
133         p = (unsigned char *)dest;
134
135         buf = malloc(l);
136         if(!buf)
137             return(NULL);
138
139         /* Ignore non base64 chars as per the POSIX standard */
140         for(k=0, l=0; src[k]; k++)
141         {
142             if(is_base64(src[k]))
143             {
144                 buf[l++]= src[k];
145             }
146         }
147
148         for(k=0; k<l; k+=4)
149         {
150             char c1='A', c2='A', c3='A', c4='A';
151             unsigned char b1=0, b2=0, b3=0, b4=0;
152
153             c1= buf[k];
154
155             if(k+1<l)
156             {
157                 c2= buf[k+1];
158             }
159
160             if(k+2<l) {
161                 c3= buf[k+2];
162             }
163
164             if(k+3<l) {
165                 c4= buf[k+3];
166             }
167
168             b1= decode(c1);
169             b2= decode(c2);
170             b3= decode(c3);
171             b4= decode(c4);
172
173             *p++=((b1<<2)|(b2>>4) );
174
175             if(c3 != '=') {
176                 *p++=(((b2&0xf)<<4)|(b3>>2) );
177             }
178
179             if(c4 != '=') {
180                 *p++=(((b3&0x3)<<6)|b4 );
181             }
182
183         }
184
185         free(buf);
186
187         /*return(p-dest); */
188         return(dest);
189
190     }
191
192     return(NULL);
193
194 }
195
196
197  /* ----------------------------------------------------------------- Private */
198
199 static char encode(unsigned char u) {
200
201     if(u < 26)  return 'A'+u;
202     if(u < 52)  return 'a'+(u-26);
203     if(u < 62)  return '0'+(u-52);
204     if(u == 62) return '+';
205
206     return '/';
207
208 }
209
210
211 /**
212  * Decode a base64 character
213  */
214 static unsigned char decode(char c) {
215
216     if(c >= 'A' && c <= 'Z') return(c - 'A');
217     if(c >= 'a' && c <= 'z') return(c - 'a' + 26);
218     if(c >= '0' && c <= '9') return(c - '0' + 52);
219     if(c == '+')             return 62;
220
221     return 63;
222
223 }
224
225
226 /**
227  * Return TRUE if 'c' is a valid base64 character, otherwise FALSE
228  */
229 static int is_base64(char c) {
230
231     if((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
232             (c >= '0' && c <= '9') || (c == '+')             ||
233             (c == '/')             || (c == '=')) {
234
235         return TRUE;
236
237     }
238
239     return FALSE;
240
241 }
242
243
244 /*
245 int main(int argc, char **argv)
246 {
247     char *s;
248     char *d;
249
250     if(argc < 2)
251     {
252         printf("%s string\n",argv[0]);
253         exit(1);
254     }
255     s = encode_base64(strlen(argv[1]), argv[1]);
256
257     printf("b64:\n%s\n",s);
258
259
260     d = decode_base64(s);
261     printf("decode:%s\n",d);
262
263     exit(0);
264 }
265
266 */
267
268
269 /* EOF */