base64: Added basic validation to base64 input string when decoding
authorSteve Holme <steve_holme@hotmail.com>
Wed, 30 Oct 2013 07:31:22 +0000 (07:31 +0000)
committerSteve Holme <steve_holme@hotmail.com>
Wed, 30 Oct 2013 07:31:22 +0000 (07:31 +0000)
A base64 string should be a multiple of 4 characters in length, not
contain any more than 2 padding characters and only contain padding
characters at the end of string. For example: Y3VybA==

Strings such as the following are considered invalid:

Y=   - Invalid length
Y==  - Invalid length
Y=== - More than two padding characters
Y=x= - Padding character contained within string

lib/base64.c
tests/unit/unit1302.c

index 3f3f0f9..2a7add1 100644 (file)
@@ -82,6 +82,7 @@ static void decodeQuantum(unsigned char *dest, const char *src)
 CURLcode Curl_base64_decode(const char *src,
                             unsigned char **outptr, size_t *outlen)
 {
+  size_t srcLen = 0;
   size_t length = 0;
   size_t equalsTerm = 0;
   size_t i;
@@ -92,21 +93,31 @@ CURLcode Curl_base64_decode(const char *src,
 
   *outptr = NULL;
   *outlen = 0;
+  srcLen = strlen(src);
 
+  /* Check the length of the input string is valid */
+  if(!srcLen || srcLen % 4)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  /* Find the position of any = padding characters */
   while((src[length] != '=') && src[length])
     length++;
+
   /* A maximum of two = padding characters is allowed */
   if(src[length] == '=') {
     equalsTerm++;
     if(src[length+equalsTerm] == '=')
       equalsTerm++;
   }
-  numQuantums = (length + equalsTerm) / 4;
+  
+  /* Check the = padding characters weren't part way through the input */
+  if(length + equalsTerm != srcLen)
+    return CURLE_BAD_CONTENT_ENCODING;
 
-  /* Don't allocate a buffer if the decoded length is 0 */
-  if(numQuantums == 0)
-    return CURLE_OK;
+  /* Calculate the number of quantums */
+  numQuantums = (length + equalsTerm) / 4;
 
+  /* Calculate the size of the decoded string */
   rawlen = (numQuantums * 3) - equalsTerm;
 
   /* The buffer must be large enough to make room for the last quantum
index fc50c88..b5688f0 100644 (file)
@@ -104,11 +104,27 @@ fail_unless(size == 1, "size should be 1");
 verify_memory(decoded, "i", 2);
 Curl_safefree(decoded);
 
-/* this is an illegal input */
+/* This is illegal input as the data is too short */
 size = 1; /* not zero */
 decoded = &anychar; /* not NULL */
 rc = Curl_base64_decode("aQ", &decoded, &size);
-/* return code indiferent, but output shall be as follows */
+fail_unless(rc == CURLE_BAD_CONTENT_ENCODING, "return code should be CURLE_BAD_CONTENT_ENCODING");
+fail_unless(size == 0, "size should be 0");
+fail_if(decoded, "returned pointer should be NULL");
+
+/* This is illegal input as it contains three padding characters */
+size = 1; /* not zero */
+decoded = &anychar; /* not NULL */
+rc = Curl_base64_decode("a===", &decoded, &size);
+fail_unless(rc == CURLE_BAD_CONTENT_ENCODING, "return code should be CURLE_BAD_CONTENT_ENCODING");
+fail_unless(size == 0, "size should be 0");
+fail_if(decoded, "returned pointer should be NULL");
+
+/* This is illegal input as it contains a padding character mid input */
+size = 1; /* not zero */
+decoded = &anychar; /* not NULL */
+rc = Curl_base64_decode("a=Q=", &decoded, &size);
+fail_unless(rc == CURLE_BAD_CONTENT_ENCODING, "return code should be CURLE_BAD_CONTENT_ENCODING");
 fail_unless(size == 0, "size should be 0");
 fail_if(decoded, "returned pointer should be NULL");