2 * The code in this file was taken from openssh-5.2p1, Copyright (c) 1996 by
3 * Internet Software Consortium. Portions Copyright (c) 1995 by International
4 * Business Machines, Inc.
7 /** \file base64.c Uudecode and base64decode implementation. */
16 static const char Base64[] =
17 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
18 static const char Pad64 = '=';
21 * base64-decode a buffer.
23 * \param src The buffer to decode.
24 * \param target Result is stored here.
25 * \param targsize Number of bytes of \a target.
27 * Skips all whitespace anywhere. Converts characters, four at a time, starting
28 * at (or after) src from base - 64 numbers into three 8 bit bytes in the
31 * \return The number of data bytes stored at the target, -E_BASE64 on errors.
33 int base64_decode(char const *src, unsigned char *target, size_t targsize)
35 unsigned int tarindex, state;
42 while ((ch = *src++) != '\0') {
43 if (para_isspace(ch)) /* Skip whitespace anywhere. */
49 pos = strchr(Base64, ch);
50 if (pos == NULL) /* A non-base64 character. */
55 if (tarindex >= targsize)
57 target[tarindex] = (pos - Base64) << 2;
61 if (tarindex + 1 >= targsize)
63 target[tarindex] |= (pos - Base64) >> 4;
64 target[tarindex + 1] = ((pos - Base64) & 0x0f) << 4;
69 if (tarindex + 1 >= targsize)
71 target[tarindex] |= (pos - Base64) >> 2;
72 target[tarindex + 1] = ((pos - Base64) & 0x03) << 6;
77 if (tarindex >= targsize)
79 target[tarindex] |= pos - Base64;
87 * We are done decoding Base-64 chars. Let's see if we ended
88 * on a byte boundary, and/or with erroneous trailing characters.
91 if (ch == Pad64) { /* We got a pad char. */
92 ch = *src++; /* Skip it, get next. */
94 case 0: /* Invalid = in first position */
95 case 1: /* Invalid = in second position */
98 case 2: /* Valid, means one byte of info */
99 /* Skip any number of spaces. */
100 for (; ch != '\0'; ch = *src++)
103 /* Make sure there is another trailing = sign. */
106 ch = *src++; /* Skip the = */
107 /* Fall through to "single trailing =" case. */
110 case 3: /* Valid, means two bytes of info */
112 * We know this char is an =. Is there anything but
113 * whitespace after it?
115 for (; ch != '\0'; ch = *src++)
120 * Now make sure for cases 2 and 3 that the "extra"
121 * bits that slopped past the last full byte were
122 * zeros. If we don't check them, they become a
123 * subliminal channel.
125 if (target[tarindex] != 0)
130 * We ended by seeing the end of the string. Make sure we
131 * have no partial bytes lying around.
142 * \param src The buffer to decode.
143 * \param target Result buffer.
144 * \param targsize The length of \a target in bytes.
146 * This is just a simple wrapper for base64_decode() which strips whitespace.
148 * \return The return value of the underlying call to base64_decode().
150 int uudecode(const char *src, unsigned char *target, size_t targsize)
155 /* copy the 'readonly' source */
156 encoded = para_strdup(src);
157 /* skip whitespace and data */
158 for (p = encoded; *p == ' ' || *p == '\t'; p++)
160 for (; *p != '\0' && *p != ' ' && *p != '\t'; p++)
162 /* and remove trailing whitespace because base64_decode needs this */
164 len = base64_decode(encoded, target, targsize);