]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
base64: Stop decoding at the first sequence of pad characters
authorJouni Malinen <j@w1.fi>
Sun, 16 Oct 2011 09:36:21 +0000 (12:36 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 16 Oct 2011 09:36:21 +0000 (12:36 +0300)
The base64 encoded data cannot included pad characters in the middle, so
we can stop the loop at the first sequence of pad characters. If the
sequence includes more than two pad characters, the encoding is invalid
and we can indicate failure.

src/utils/base64.c

index 155bfce83aa574b7f93be8ef1b61fb6a5e71c54b..fb1224b959eac3d9b79a64b286c7bdfcdcf9f963 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Base64 encoding/decoding (RFC1341)
- * Copyright (c) 2005, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -103,8 +103,9 @@ unsigned char * base64_encode(const unsigned char *src, size_t len,
 unsigned char * base64_decode(const unsigned char *src, size_t len,
                              size_t *out_len)
 {
-       unsigned char dtable[256], *out, *pos, in[4], block[4], tmp;
+       unsigned char dtable[256], *out, *pos, block[4], tmp;
        size_t i, count, olen;
+       int pad = 0;
 
        os_memset(dtable, 0x80, 256);
        for (i = 0; i < sizeof(base64_table) - 1; i++)
@@ -131,7 +132,8 @@ unsigned char * base64_decode(const unsigned char *src, size_t len,
                if (tmp == 0x80)
                        continue;
 
-               in[count] = src[i];
+               if (src[i] == '=')
+                       pad++;
                block[count] = tmp;
                count++;
                if (count == 4) {
@@ -139,16 +141,21 @@ unsigned char * base64_decode(const unsigned char *src, size_t len,
                        *pos++ = (block[1] << 4) | (block[2] >> 2);
                        *pos++ = (block[2] << 6) | block[3];
                        count = 0;
+                       if (pad) {
+                               if (pad == 1)
+                                       pos--;
+                               else if (pad == 2)
+                                       pos -= 2;
+                               else {
+                                       /* Invalid padding */
+                                       os_free(out);
+                                       return NULL;
+                               }
+                               break;
+                       }
                }
        }
 
-       if (pos > out) {
-               if (in[2] == '=')
-                       pos -= 2;
-               else if (in[3] == '=')
-                       pos--;
-       }
-
        *out_len = pos - out;
        return out;
 }