base64: Extended validation to look for invalid characters

Extended the basic validation in commit e17c1b25bc33eb to return a
failure when invalid base64 characters are included.
This commit is contained in:
Steve Holme 2013-12-01 11:05:11 +00:00
parent 4d10f48629
commit c92c30edbd
2 changed files with 52 additions and 25 deletions

View File

@ -40,22 +40,32 @@
static const char table64[]= static const char table64[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static void decodeQuantum(unsigned char *dest, const char *src) static size_t decodeQuantum(unsigned char *dest, const char *src)
{ {
size_t padding = 0;
const char *s, *p; const char *s, *p;
unsigned long i, v, x = 0; unsigned long i, v, x = 0;
for(i = 0, s = src; i < 4; i++, s++) { for(i = 0, s = src; i < 4; i++, s++) {
v = 0; v = 0;
p = table64;
while(*p && (*p != *s)) { if(*s == '=') {
v++;
p++;
}
if(*p == *s)
x = (x << 6) + v;
else if(*s == '=')
x = (x << 6); x = (x << 6);
padding++;
}
else {
p = table64;
while(*p && (*p != *s)) {
v++;
p++;
}
if(*p == *s)
x = (x << 6) + v;
else
return 0;
}
} }
dest[2] = curlx_ultouc(x & 0xFFUL); dest[2] = curlx_ultouc(x & 0xFFUL);
@ -63,6 +73,8 @@ static void decodeQuantum(unsigned char *dest, const char *src)
dest[1] = curlx_ultouc(x & 0xFFUL); dest[1] = curlx_ultouc(x & 0xFFUL);
x >>= 8; x >>= 8;
dest[0] = curlx_ultouc(x & 0xFFUL); dest[0] = curlx_ultouc(x & 0xFFUL);
return 3 - padding;
} }
/* /*
@ -86,9 +98,11 @@ CURLcode Curl_base64_decode(const char *src,
size_t length = 0; size_t length = 0;
size_t equalsTerm = 0; size_t equalsTerm = 0;
size_t i; size_t i;
size_t result;
size_t numQuantums; size_t numQuantums;
unsigned char lastQuantum[3]; unsigned char lastQuantum[3];
size_t rawlen = 0; size_t rawlen = 0;
unsigned char *pos;
unsigned char *newstr; unsigned char *newstr;
*outptr = NULL; *outptr = NULL;
@ -125,24 +139,38 @@ CURLcode Curl_base64_decode(const char *src,
if(!newstr) if(!newstr)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
*outptr = newstr; pos = newstr;
/* Decode all but the last quantum (which may not decode to a /* Decode all but the last quantum (which may not decode to a
multiple of 3 bytes) */ multiple of 3 bytes) */
for(i = 0; i < numQuantums - 1; i++) { for(i = 0; i < numQuantums - 1; i++) {
decodeQuantum(newstr, src); result = decodeQuantum(pos, src);
newstr += 3; src += 4; if(!result) {
Curl_safefree(newstr);
return CURLE_BAD_CONTENT_ENCODING;
}
pos += result;
src += 4;
} }
/* Decode the last quantum */ /* Decode the last quantum */
decodeQuantum(lastQuantum, src); result = decodeQuantum(lastQuantum, src);
if(!result) {
Curl_safefree(newstr);
return CURLE_BAD_CONTENT_ENCODING;
}
for(i = 0; i < 3 - equalsTerm; i++) for(i = 0; i < 3 - equalsTerm; i++)
newstr[i] = lastQuantum[i]; pos[i] = lastQuantum[i];
/* Zero terminate */ /* Zero terminate */
newstr[i] = '\0'; pos[i] = '\0';
/* Return the size of decoded data */ /* Return the decoded data */
*outptr = newstr;
*outlen = rawlen; *outlen = rawlen;
return CURLE_OK; return CURLE_OK;

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -31,7 +31,7 @@ static struct SessionHandle *data;
static CURLcode unit_setup( void ) static CURLcode unit_setup( void )
{ {
data = curl_easy_init(); data = curl_easy_init();
if (!data) if(!data)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
return CURLE_OK; return CURLE_OK;
} }
@ -128,13 +128,12 @@ fail_unless(rc == CURLE_BAD_CONTENT_ENCODING, "return code should be CURLE_BAD_C
fail_unless(size == 0, "size should be 0"); fail_unless(size == 0, "size should be 0");
fail_if(decoded, "returned pointer should be NULL"); fail_if(decoded, "returned pointer should be NULL");
/* this is garbage input that libcurl decodes as far as possible */ /* This is garbage input as it contains an illegal base64 character */
size = 0; size = 1; /* not zero */
decoded = NULL; decoded = &anychar; /* not NULL */
rc = Curl_base64_decode("a\x1f==", &decoded, &size); rc = Curl_base64_decode("a\x1f==", &decoded, &size);
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK"); fail_unless(rc == CURLE_BAD_CONTENT_ENCODING, "return code should be CURLE_BAD_CONTENT_ENCODING");
fail_unless(size == 1, "size should be 1"); fail_unless(size == 0, "size should be 0");
fail_if(!decoded, "returned pointer should not be NULL"); fail_if(decoded, "returned pointer should be NULL");
Curl_safefree(decoded);
UNITTEST_STOP UNITTEST_STOP