From 7a35bab8c8a08e42ff8f5d3b5befe2cdc67a35b2 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Wed, 1 Jun 2016 12:43:02 -0600 Subject: [PATCH] Make base64 decoding table-driven. --- plugins/sudoers/base64.c | 75 ++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/plugins/sudoers/base64.c b/plugins/sudoers/base64.c index d85bfbf59..c8f9273c1 100644 --- a/plugins/sudoers/base64.c +++ b/plugins/sudoers/base64.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015 Todd C. Miller + * Copyright (c) 2013-2016 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -30,44 +30,59 @@ #include "sudoers.h" +/* + * Derived from code with the following declaration: + * PUBLIC DOMAIN - Jon Mayo - November 13, 2003 + */ + +static const unsigned char base64dec_tab[256]= { + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255, + 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255, + 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +}; + /* * Decode a NUL-terminated string in base64 format and store the * result in dst. */ size_t -base64_decode(const char *str, unsigned char *dst, size_t dsize) +base64_decode(const char *in, unsigned char *out, size_t out_size) { - static const char b64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - const unsigned char *dst0 = dst; - const unsigned char *dend = dst + dsize; - unsigned char ch[4]; - char *pos; - int i; + unsigned char *out_end = out + out_size; + const unsigned char *out0 = out; + unsigned int rem, v; debug_decl(base64_decode, SUDOERS_DEBUG_MATCH) - /* - * Convert from base64 to binary. Each base64 char holds 6 bits of data - * so 4 base64 chars equals 3 chars of data. - * Padding (with the '=' char) may or may not be present. - */ - while (*str != '\0') { - for (i = 0; i < 4; i++) { - if (*str == '=' || *str == '\0') - break; - if ((pos = strchr(b64, *str++)) == NULL) + for (v = 0, rem = 0; *in != '\0' && *in != '='; in++) { + unsigned char ch = base64dec_tab[(unsigned char)*in]; + if (ch == 255) + debug_return_size_t((size_t)-1); + v = (v << 6) | ch; + rem += 6; + if (rem >= 8) { + rem -= 8; + if (out >= out_end) debug_return_size_t((size_t)-1); - ch[i] = (unsigned char)(pos - b64); + *out++ = (v >> rem) & 0xff; } - if (i == 0 || i == 1 || dst == dend) - break; - *dst++ = (ch[0] << 2) | ((ch[1] & 0x30) >> 4); - if (i == 2 || dst == dend) - break; - *dst++ = ((ch[1] & 0x0f) << 4) | ((ch[2] & 0x3c) >> 2); - if (i == 3 || dst == dend) - break; - *dst++ = ((ch[2] & 0x03) << 6) | ch[3]; } - debug_return_size_t((size_t)(dst - dst0)); + if (rem >= 8) { + if (out >= out_end) + debug_return_size_t((size_t)-1); + *out++ = (v >> rem) & 0xff; + } + debug_return_size_t((size_t)(out - out0)); } -- 2.40.0