Add CBS_get_any_asn1.

We have CBS_get_asn1 / CBS_get_asn1_element, but not the "any" variants
of them. Without this, a consumer walking a DER structure must manually
CBS_skip the header, which is a little annoying.

Change-Id: I7735c37eb9e5aaad2bde8407669bce5492e1ccf6
Reviewed-on: https://boringssl-review.googlesource.com/11404
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
This commit is contained in:
David Benjamin 2016-09-30 15:05:32 -04:00 committed by CQ bot account: commit-bot@chromium.org
parent 1f53747baa
commit 455919dda2
3 changed files with 41 additions and 0 deletions

View File

@ -231,6 +231,25 @@ static bool TestGetASN1() {
return false;
}
unsigned tag;
CBS_init(&data, kData1, sizeof(kData1));
if (!CBS_get_any_asn1(&data, &contents, &tag) ||
tag != CBS_ASN1_SEQUENCE ||
CBS_len(&contents) != 2 ||
memcmp(CBS_data(&contents), "\x01\x02", 2) != 0) {
return false;
}
size_t header_len;
CBS_init(&data, kData1, sizeof(kData1));
if (!CBS_get_any_asn1_element(&data, &contents, &tag, &header_len) ||
tag != CBS_ASN1_SEQUENCE ||
header_len != 2 ||
CBS_len(&contents) != 4 ||
memcmp(CBS_data(&contents), "\x30\x02\x01\x02", 2) != 0) {
return false;
}
return true;
}

View File

@ -262,6 +262,20 @@ static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
return CBS_get_bytes(cbs, out, len);
}
int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag) {
size_t header_len;
if (!CBS_get_any_asn1_element(cbs, out, out_tag, &header_len)) {
return 0;
}
if (!CBS_skip(out, header_len)) {
assert(0);
return 0;
}
return 1;
}
int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
size_t *out_header_len) {
return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len,

View File

@ -190,6 +190,14 @@ OPENSSL_EXPORT int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value);
* element is malformed. */
OPENSSL_EXPORT int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value);
/* CBS_get_any_asn1 sets |*out| to contain the next ASN.1 element from |*cbs|
* (not including tag and length bytes), sets |*out_tag| to the tag number, and
* advances |*cbs|. It returns one on success and zero on error. Either of |out|
* and |out_tag| may be NULL to ignore the value.
*
* Tag numbers greater than 30 are not supported (i.e. short form only). */
OPENSSL_EXPORT int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag);
/* CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from
* |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to
* the tag number and |*out_header_len| to the length of the ASN.1 header. Each