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