Merge documentation from chromium's net/der into cbs.c
Change-Id: Icfd959a168e3fce423b10dd0dcb1312ec03f0623
Reviewed-on: https://boringssl-review.googlesource.com/7800
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/crypto/bytestring/cbs.c b/crypto/bytestring/cbs.c
index 5e0c538..ed54b49 100644
--- a/crypto/bytestring/cbs.c
+++ b/crypto/bytestring/cbs.c
@@ -181,8 +181,14 @@
return 0;
}
+ /* ITU-T X.690 section 8.1.2.3 specifies the format for identifiers with a tag
+ * number no greater than 30.
+ *
+ * If the number portion is 31 (0x1f, the largest value that fits in the
+ * allotted bits), then the tag is more than one byte long and the
+ * continuation bytes contain the tag number. This parser only supports tag
+ * numbers less than 31 (and thus single-byte tags). */
if ((tag & 0x1f) == 0x1f) {
- /* Long form tags are not supported. */
return 0;
}
@@ -191,6 +197,8 @@
}
size_t len;
+ /* The format for the length encoding is specified in ITU-T X.690 section
+ * 8.1.3. */
if ((length_byte & 0x80) == 0) {
/* Short form length. */
len = ((size_t) length_byte) + 2;
@@ -198,7 +206,9 @@
*out_header_len = 2;
}
} else {
- /* Long form length. */
+ /* The high bit indicate that this is the long form, while the next 7 bits
+ * encode the number of subsequent octets used to encode the length (ITU-T
+ * X.690 clause 8.1.3.5.b). */
const size_t num_bytes = length_byte & 0x7f;
uint32_t len32;
@@ -210,12 +220,18 @@
return CBS_get_bytes(cbs, out, 2);
}
+ /* ITU-T X.690 clause 8.1.3.5.c specifies that the value 0xff shall not be
+ * used as the first byte of the length. If this parser encounters that
+ * value, num_bytes will be parsed as 127, which will fail the check below.
+ */
if (num_bytes == 0 || num_bytes > 4) {
return 0;
}
if (!cbs_get_u(&header, &len32, num_bytes)) {
return 0;
}
+ /* ITU-T X.690 section 10.1 (DER length forms) requires encoding the length
+ * with the minimum number of octets. */
if (len32 < 128) {
/* Length should have used short-form encoding. */
return 0;