2 * Copyright (c) 2013 Todd C. Miller <Todd.Miller@courtesan.com>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
16 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 #include <sys/types.h>
30 #endif /* STDC_HEADERS */
33 #endif /* HAVE_STRING_H */
36 #endif /* HAVE_STRINGS_H */
39 #include "sudo_debug.h"
42 * Decode a NUL-terminated string in base64 format and store the
46 base64_decode(const char *str, unsigned char *dst, size_t dsize)
48 static const char b64[] =
49 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
50 const unsigned char *dst0 = dst;
51 const unsigned char *dend = dst + dsize;
55 debug_decl(base64_decode, SUDO_DEBUG_MATCH)
58 * Convert from base64 to binary. Each base64 char holds 6 bits of data
59 * so 4 base64 chars equals 3 chars of data.
60 * Padding (with the '=' char) may or may not be present.
62 while (*str != '\0') {
63 for (i = 0; i < 4; i++) {
72 if ((pos = strchr(b64, *str++)) == NULL)
73 debug_return_size_t((size_t)-1);
74 ch[i] = (unsigned char)(pos - b64);
78 if (ch[0] == '=' || ch[1] == '=' || dst == dend)
80 *dst++ = (ch[0] << 2) | ((ch[1] & 0x30) >> 4);
81 if (ch[2] == '=' || dst == dend)
83 *dst++ = ((ch[1] & 0x0f) << 4) | ((ch[2] & 0x3c) >> 2);
84 if (ch[3] == '=' || dst == dend)
86 *dst++ = ((ch[2] & 0x03) << 6) | ch[3];
88 debug_return_size_t((size_t)(dst - dst0));