summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristos Zoulas <christos@zoulas.com>2016-11-07 15:51:23 +0000
committerChristos Zoulas <christos@zoulas.com>2016-11-07 15:51:23 +0000
commita6d1be7348c5decb6bdf1d35b75aed8e2652117f (patch)
tree1b10eddc110407893049ae949343ed09802be0ed
parent570a8e1083317f7452b9f024898e432bde3c124a (diff)
downloadfile-git-a6d1be7348c5decb6bdf1d35b75aed8e2652117f.tar.gz
Fix error checking in the simple case (one digit length) of der magic.
(Jonas Wagner)
-rw-r--r--src/der.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/src/der.c b/src/der.c
index 8ae638fb..40dd1c5e 100644
--- a/src/der.c
+++ b/src/der.c
@@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: der.c,v 1.10 2016/10/24 18:02:17 christos Exp $")
+FILE_RCSID("@(#)$File: der.c,v 1.11 2016/11/07 15:51:23 christos Exp $")
#endif
#endif
@@ -159,31 +159,49 @@ gettag(const uint8_t *c, size_t *p, size_t l)
return tag;
}
+/*
+ * Read the length of a DER tag from the input.
+ *
+ * `c` is the input, `p` is an output parameter that specifies how much of the
+ * input we consumed, and `l` is the maximum input length.
+ *
+ * Returns the length, or DER_BAD if the end of the input is reached or the
+ * length exceeds the remaining input.
+ */
static uint32_t
getlength(const uint8_t *c, size_t *p, size_t l)
{
uint8_t digits, i;
size_t len;
+ int is_onebyte_result;
if (*p >= l)
return DER_BAD;
- digits = c[(*p)++];
+ /*
+ * Digits can either be 0b0 followed by the result, or 0b1
+ * followed by the number of digits of the result. In either case,
+ * we verify that we can read so many bytes from the input.
+ */
+ is_onebyte_result = (c[*p] & 0x80) == 0;
+ digits = c[(*p)++] & 0x7f;
+ if (*p + digits >= l)
+ return DER_BAD;
- if ((digits & 0x80) == 0)
+ if (is_onebyte_result)
return digits;
- digits &= 0x7f;
+ /*
+ * Decode len. We've already verified that we're allowed to read
+ * `digits` bytes.
+ */
len = 0;
-
- if (*p + digits >= l)
- return DER_BAD;
-
for (i = 0; i < digits; i++)
len = (len << 8) | c[(*p)++];
+
if (*p + len >= l)
return DER_BAD;
- return len;
+ return len;
}
static const char *