ze-filter  (ze-filter-0.8.0-develop-180218)
ze-base64.c
Go to the documentation of this file.
1 /*
2  *
3  * ze-filter - Mail Server Filter for sendmail
4  *
5  * Copyright (c) 2001-2018 - Jose-Marcio Martins da Cruz
6  *
7  * Auteur : Jose Marcio Martins da Cruz
8  * jose.marcio.mc@gmail.org
9  *
10  * Historique :
11  * Creation : janvier 2002
12  *
13  * This program is free software, but with restricted license :
14  *
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19  *
20  * More details about ze-filter license can be found at ze-filter
21  * web site : http://foss.jose-marcio.org
22  */
23 
24 #include <ze-sys.h>
25 
26 #include "ze-libjc.h"
27 #include "ze-base64.h"
28 
29 
30 /* ****************************************************************************
31  * *
32  * *
33  **************************************************************************** */
34 static char *B64 =
35  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
36 
37 #define ISB64CHAR(c) ((strchr (B64, (int) c) != NULL ) ? TRUE : FALSE)
38 
39 static char
40 b64index(c)
41  char c;
42 {
43  char *p = strchr(B64, c);
44 
45  if (p != NULL)
46  return (p - B64);
47 
48  return -1;
49 }
50 
51 
52 static int
53 decode_buf64(o, i)
54  char *o;
55  char *i;
56 
57 {
58  int ix[4];
59 
60  if ((i == NULL) || (o == NULL))
61  return 0;
62 
63  o[0] = o[1] = o[2] = o[3] = '\0';
64 
65  if (!ISB64CHAR(i[0]) || !ISB64CHAR(i[1]))
66  return 0;
67 
68  ix[0] = b64index(i[0]);
69  ix[1] = b64index(i[1]);
70  o[0] = (ix[0] << 2) | (ix[1] >> 4);
71 
72  if ((i[2] == '=') || !ISB64CHAR(i[2]))
73  return 1;
74 
75  ix[2] = b64index(i[2]);
76 
77  o[1] = (ix[1] << 4) | (ix[2] >> 2);
78 
79  if ((i[3] == '=') || !ISB64CHAR(i[3]))
80  return 2;
81 
82  ix[3] = b64index(i[3]);
83 
84  o[2] = (ix[2] << 6) | ix[3];
85 
86  return 3;
87 }
88 
89 /* ****************************************************************************
90  * *
91  * *
92  **************************************************************************** */
93 int
94 base64_decode(out, in, nout, nin)
95  char *out;
96  char *in;
97  size_t *nout;
98  size_t *nin;
99 
100 {
101  char *p = in;
102  char *q = out;
103  int res = 0;
104 
105  char ibuf[5];
106  char obuf[4];
107  int di = 0;
108  int nsep = 0;
109 
110  size_t no = 0;
111 
112  if ((in == NULL) || (out == NULL))
113  return 0;
114 
115  memset(ibuf, 0, sizeof (ibuf));
116  memset(obuf, 0, sizeof (obuf));
117  *q = '\0';
118  no = 1;
119 
120  nsep = 0;
121  while ((p != NULL) && (*p != '\0'))
122  {
123 
124  if (*p == '=')
125  {
126  while (di < 4)
127  ibuf[di++] = '=';
128  break;
129  }
130 
131  if (strchr(" \t\r\n", *p))
132  {
133  if (nsep++ == 2)
134  break;
135  p++;
136  continue;
137  }
138  nsep = 0;
139 
140  if (!ISB64CHAR(*p))
141  {
142  res = 1;
143  break;
144  }
145 
146  ibuf[di++] = *p;
147  ibuf[di] = '\0';
148 
149  if (di == 4)
150  {
151  int l;
152 
153  if ((nout != NULL) && (no + 3 > *nout))
154  break;
155  l = decode_buf64(obuf, ibuf);
156 
157  strcat(q, obuf);
158  q += l;
159  no += l;
160  *q = '\0';
161  di = 0;
162  memset(ibuf, 0, sizeof (ibuf));
163  memset(obuf, 0, sizeof (obuf));
164  }
165 
166  p++;
167  continue;
168 
169  }
170 
171  if ((di > 0) && ((nout == NULL) || (no + 3 < *nout)))
172  {
173  int l;
174 
175  while (di < 4)
176  ibuf[di++] = '=';
177 
178  l = decode_buf64(obuf, ibuf);
179  strcat(q, obuf);
180  q += l;
181  no += l;
182  *q = '\0';
183  }
184  *q = '\0';
185 
186  if (nin != NULL)
187  *nin = (size_t) (p - in);
188  if (nout != NULL)
189  *nout = (size_t) (q - out);
190 
191  return res;
192 }
193 
194 
195 /* ****************************************************************************
196  * *
197  * *
198  **************************************************************************** */
199 void *
200 new_base64_decode(bufin, size)
201  char *bufin;
202  size_t *size;
203 
204 {
205  char *p = bufin;
206  char *q = NULL, *bufout;
207  int res = 0;
208 
209  char ibuf[5];
210  char obuf[4];
211  int di = 0;
212  int nsep = 0;
213 
214  size_t sz_in, sz_out;
215  size_t no = 0;
216 
217  if ((bufin == NULL) || (strlen(bufin) == 0))
218  {
219  ZE_LogMsgError(0, "input buffer NULL or empty");
220  return NULL;
221  }
222 
223  sz_in = strlen(bufin);
224  if ((bufout = (char *) malloc(sz_in + 1)) == NULL)
225  {
226  ZE_LogSysError("malloc output buffer");
227  return NULL;
228  }
229  memset(bufout, 0, sz_in + 1);
230 
231  memset(ibuf, 0, sizeof (ibuf));
232  memset(obuf, 0, sizeof (obuf));
233  *q = '\0';
234  no = 1;
235 
236  nsep = 0;
237  while ((p != NULL) && (*p != '\0'))
238  {
239 
240  if (*p == '=')
241  {
242  while (di < 4)
243  ibuf[di++] = '=';
244  break;
245  }
246 
247  if (strchr(" \t\r\n", *p))
248  {
249  if (nsep++ == 2)
250  break;
251  p++;
252  continue;
253  }
254  nsep = 0;
255 
256  if (!ISB64CHAR(*p))
257  {
258  res = 1;
259  break;
260  }
261 
262  ibuf[di++] = *p;
263 
264  if (di == 4)
265  {
266  int l;
267 
268  if (no + 3 > sz_in)
269  break;
270  l = decode_buf64(obuf, ibuf);
271  strcat(q, obuf);
272  q += l;
273  no += l;
274  *q = '\0';
275  di = 0;
276  memset(ibuf, 0, sizeof (ibuf));
277  memset(obuf, 0, sizeof (obuf));
278  }
279 
280  p++;
281  continue;
282 
283  }
284 
285  if ((di > 0) && (no + 3 < sz_in))
286  {
287  int l;
288 
289  while (di < 4)
290  ibuf[di++] = '=';
291 
292  l = decode_buf64(obuf, ibuf);
293  strcat(q, obuf);
294  q += l;
295  no += l;
296  *q = '\0';
297  }
298  *q = '\0';
299 
300  sz_out = (size_t) (q - bufout);
301  if (size != NULL)
302  *size = sz_out;
303 
304  return bufout;
305 }
306 
307 /* ****************************************************************************
308  * *
309  * *
310  **************************************************************************** */
311 bool
312 base64_encode(sout, szout, sin, szin)
313  char *sout;
314  size_t szout;
315  unsigned char *sin;
316  size_t szin;
317 {
318  unsigned char *q = sin;
319  unsigned char bin[3];
320  char cin[5];
321  int sz;
322 
323  ASSERT(sout != NULL);
324  ASSERT(szout > 0);
325 
326  memset(sout, 0, szout);
327 
328  if (3 * szout < 4 * szin)
329  return FALSE;
330 
331  sz = szin;
332  while (sz > 0)
333  {
334  int i;
335 
336  memset(bin, 0, sizeof (bin));
337  bin[0] = (unsigned char) q[0];
338  if (sz > 1)
339  bin[1] = (unsigned char) q[1];
340  if (sz > 2)
341  bin[2] = (unsigned char) q[2];
342 
343  strlcpy(cin, "====", sizeof (cin));
344 
345  i = (bin[0] & 0xFC) >> 2;
346  cin[0] = B64[i];
347 
348  i = ((bin[0] & 0x03) << 4) | ((bin[1] & 0xF0) >> 4);
349  cin[1] = B64[i];
350 
351  if (sz > 1)
352  {
353  i = ((bin[1] & 0x0F) << 2) | ((bin[2] & 0xC0) >> 6);
354  cin[2] = B64[i];
355  }
356 
357  if (sz > 2)
358  {
359  i = (bin[2] & 0x3F);
360  cin[3] = B64[i];
361  }
362  strlcat(sout, cin, szout);
363 
364  sz -= 3;
365  q += 3;
366  }
367 
368  return TRUE;
369 }
#define ISB64CHAR(c)
Definition: ze-base64.c:37
#define ASSERT(a)
Definition: macros.h:27
#define FALSE
Definition: macros.h:160
#define strlcpy
Definition: zeString.h:32
#define ZE_LogMsgError(level,...)
Definition: zeSyslog.h:113
#define strlcat
Definition: zeString.h:28
#define strchr
Definition: ze-sys.h:218
#define TRUE
Definition: macros.h:157
void * new_base64_decode(char *bufin, size_t *size)
Definition: ze-base64.c:200
bool base64_encode(char *sout, size_t szout, unsigned char *sin, size_t szin)
Definition: ze-base64.c:312
#define ZE_LogSysError(...)
Definition: zeSyslog.h:129
int base64_decode(char *out, char *in, size_t *nout, size_t *nin)
Definition: ze-base64.c:94