Start
[exim.git] / src / src / auths / b64decode.c
1 /* $Cambridge: exim/src/src/auths/b64decode.c,v 1.1 2004/10/07 13:10:00 ph10 Exp $ */
2
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
6
7 /* Copyright (c) University of Cambridge 1995 - 2004 */
8 /* See the file NOTICE for conditions of use and distribution. */
9
10 #include "../exim.h"
11
12
13 /*************************************************
14 * Decode byte-string in base 64 *
15 *************************************************/
16
17 /* This function decodes a string in base 64 format as defined in RFC 2045
18 (MIME) and required by the SMTP AUTH extension (RFC 2554). The decoding
19 algorithm is written out in a straightforward way. Turning it into some kind of
20 compact loop is messy and would probably run more slowly.
21
22 Arguments:
23 code points to the coded string, zero-terminated
24 ptr where to put the pointer to the result, which is in
25 dynamic store
26
27 Returns: the number of bytes in the result,
28 or -1 if the input was malformed
29
30 A zero is added on to the end to make it easy in cases where the result is to
31 be interpreted as text. This is not included in the count. */
32
33 static uschar dec64table[] = {
34 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, /* 0-15 */
35 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, /* 16-31 */
36 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63, /* 32-47 */
37 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255,255,255,255, /* 48-63 */
38 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 64-79 */
39 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255, /* 80-95 */
40 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 96-111 */
41 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255 /* 112-127*/
42 };
43
44 int
45 auth_b64decode(uschar *code, uschar **ptr)
46 {
47 register int x, y;
48 uschar *result = store_get(3*(Ustrlen(code)/4) + 1);
49
50 *ptr = result;
51
52 /* Each cycle of the loop handles a quantum of 4 input bytes. For the last
53 quantum this may decode to 1, 2, or 3 output bytes. */
54
55 while ((x = (*code++)) != 0)
56 {
57 if (x > 127 || (x = dec64table[x]) == 255) return -1;
58 if ((y = (*code++)) == 0 || (y = dec64table[y]) == 255)
59 return -1;
60 *result++ = (x << 2) | (y >> 4);
61
62 if ((x = (*code++)) == '=')
63 {
64 if (*code++ != '=' || *code != 0) return -1;
65 }
66 else
67 {
68 if (x > 127 || (x = dec64table[x]) == 255) return -1;
69 *result++ = (y << 4) | (x >> 2);
70 if ((y = (*code++)) == '=')
71 {
72 if (*code != 0) return -1;
73 }
74 else
75 {
76 if (y > 127 || (y = dec64table[y]) == 255) return -1;
77 *result++ = (x << 6) | y;
78 }
79 }
80 }
81
82 *result = 0;
83 return result - *ptr;
84 }
85
86 /* End of b64decode.c */