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:
parent
4d10f48629
commit
c92c30edbd
60
lib/base64.c
60
lib/base64.c
@ -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;
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user