浏览代码

check input of base16_decode()

Steffen Jaeckel 7 年之前
父节点
当前提交
ed5025398b
共有 2 个文件被更改,包括 25 次插入10 次删除
  1. 20 10
      src/misc/base16/base16_decode.c
  2. 5 0
      tests/base16_test.c

+ 20 - 10
src/misc/base16/base16_decode.c

@@ -29,17 +29,17 @@ int base16_decode(const          char *in,  unsigned long  inlen,
                         unsigned char *out, unsigned long *outlen)
 {
    unsigned long pos, out_len;
-   unsigned char idx0;
-   unsigned char idx1;
+   unsigned char idx0, idx1;
+   char in0, in1;
 
    const unsigned char hashmap[] = {
          0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 01234567 */
-         0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 89:;<=>? */
-         0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, /* @ABCDEFG */
-         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* HIJKLMNO */
-         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* PQRSTUVW */
-         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* XYZ[\]^_ */
-         0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, /* `abcdefg */
+         0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 89:;<=>? */
+         0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, /* @ABCDEFG */
+         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* HIJKLMNO */
+         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* PQRSTUVW */
+         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* XYZ[\]^_ */
+         0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, /* `abcdefg */
    };
 
    LTC_ARGCHK(in     != NULL);
@@ -49,8 +49,18 @@ int base16_decode(const          char *in,  unsigned long  inlen,
    if ((inlen % 2) == 1) return CRYPT_INVALID_PACKET;
    out_len = *outlen * 2;
    for (pos = 0; ((pos + 1 < out_len) && (pos + 1 < inlen)); pos += 2) {
-      idx0 = (unsigned char) (in[pos + 0] & 0x1F) ^ 0x10;
-      idx1 = (unsigned char) (in[pos + 1] & 0x1F) ^ 0x10;
+      in0 = in[pos + 0];
+      in1 = in[pos + 1];
+
+      if ((in0 < '0') || (in0 > 'g')) return CRYPT_INVALID_PACKET;
+      if ((in1 < '0') || (in1 > 'g')) return CRYPT_INVALID_PACKET;
+
+      idx0 = (unsigned char) (in0 & 0x1F) ^ 0x10;
+      idx1 = (unsigned char) (in1 & 0x1F) ^ 0x10;
+
+      if (hashmap[idx0] == 0xff) return CRYPT_INVALID_PACKET;
+      if (hashmap[idx1] == 0xff) return CRYPT_INVALID_PACKET;
+
       out[pos / 2] = (unsigned char) (hashmap[idx0] << 4) | hashmap[idx1];
    }
    *outlen = pos / 2;

+ 5 - 0
tests/base16_test.c

@@ -20,6 +20,7 @@ int base16_test(void)
       "0123456789abcdef",
       "0123456789ABCDEF",
    };
+   const char *failing_decode = "test";
    unsigned long x, l1, l2;
    int idx;
 
@@ -45,6 +46,10 @@ int base16_test(void)
       DO(do_compare_testvector(tmp, l2, testin, sizeof(testin), "testin base16", idx));
    }
 
+   l1 = 4;
+   l2 = sizeof(tmp);
+   DO(base16_decode(failing_decode, l1, tmp, &l2) == CRYPT_OK ? CRYPT_FAIL_TESTVECTOR : CRYPT_OK);
+
    return CRYPT_OK;
 }