diff options
author | David Benjamin <davidben@chromium.org> | 2014-08-27 20:19:50 -0400 |
---|---|---|
committer | Adam Langley <agl@google.com> | 2014-08-28 00:45:30 +0000 |
commit | 9b04d657be7daa60864ee0ea81bc493ba07b8ca8 (patch) | |
tree | 180d470a8d4ca26c49316ffc167be014dc40c22b | |
parent | 041b58a6684d2f032f66fa45b0e35f50f9a0fa40 (diff) | |
download | src-9b04d657be7daa60864ee0ea81bc493ba07b8ca8.tar.gz |
Export CBS_get_any_asn1_element.
Useful for parsing things when you don't know what tag to expect (e.g. a
CHOICE). Also allow its operands to be NULL, so that it can be used to skip
arbitrary elements.
Delete CBS_ASN1_ANY which wasn't doing anything.
Change-Id: I56413e68b4f2e13860ea3e55373d5830713d7e5c
Reviewed-on: https://boringssl-review.googlesource.com/1661
Reviewed-by: Adam Langley <agl@google.com>
-rw-r--r-- | crypto/bytestring/cbs.c | 18 | ||||
-rw-r--r-- | crypto/bytestring/internal.h | 9 | ||||
-rw-r--r-- | include/openssl/bytestring.h | 14 |
3 files changed, 27 insertions, 14 deletions
diff --git a/crypto/bytestring/cbs.c b/crypto/bytestring/cbs.c index d6e9442..244daba 100644 --- a/crypto/bytestring/cbs.c +++ b/crypto/bytestring/cbs.c @@ -162,6 +162,12 @@ int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, size_t *out_header_len) { uint8_t tag, length_byte; CBS header = *cbs; + CBS throwaway; + + if (out == NULL) { + out = &throwaway; + } + if (!CBS_get_u8(&header, &tag) || !CBS_get_u8(&header, &length_byte)) { return 0; @@ -172,13 +178,17 @@ int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, return 0; } - *out_tag = tag; + if (out_tag != NULL) { + *out_tag = tag; + } size_t len; if ((length_byte & 0x80) == 0) { /* Short form length. */ len = ((size_t) length_byte) + 2; - *out_header_len = 2; + if (out_header_len != NULL) { + *out_header_len = 2; + } } else { /* Long form length. */ const size_t num_bytes = length_byte & 0x7f; @@ -210,7 +220,9 @@ int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, return 0; } len += 2 + num_bytes; - *out_header_len = 2 + num_bytes; + if (out_header_len != NULL) { + *out_header_len = 2 + num_bytes; + } } return CBS_get_bytes(cbs, out, len); diff --git a/crypto/bytestring/internal.h b/crypto/bytestring/internal.h index fd46aeb..b4ea7e5 100644 --- a/crypto/bytestring/internal.h +++ b/crypto/bytestring/internal.h @@ -22,15 +22,6 @@ extern "C" { #endif -/* 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. If - * the element has indefinite length then |*out| will only contain the header. - * - * Tag numbers greater than 31 are not supported. */ -int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, - size_t *out_header_len); - /* CBS_asn1_ber_to_der reads an ASN.1 structure from |in|. If it finds * indefinite-length elements then it attempts to convert the BER data to DER * and sets |*out| and |*out_length| to describe a malloced buffer containing diff --git a/include/openssl/bytestring.h b/include/openssl/bytestring.h index a7507d8..6e18499 100644 --- a/include/openssl/bytestring.h +++ b/include/openssl/bytestring.h @@ -128,8 +128,6 @@ OPENSSL_EXPORT int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out); #define CBS_ASN1_CONSTRUCTED 0x20 #define CBS_ASN1_CONTEXT_SPECIFIC 0x80 -#define CBS_ASN1_ANY 0x10000 - /* CBS_get_asn1 sets |*out| to the contents of DER-encoded, ASN.1 element (not * including tag and length bytes) and advances |cbs| over it. The ASN.1 * element must match |tag_value|. It returns one on success and zero @@ -142,6 +140,18 @@ OPENSSL_EXPORT int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value); * ASN.1 header bytes too. */ OPENSSL_EXPORT int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value); +/* 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. If + * the element has indefinite length then |*out| will only contain the + * header. Each of |out|, |out_tag|, and |out_header_len| may be NULL to ignore + * the value. + * + * Tag numbers greater than 31 are not supported. */ +OPENSSL_EXPORT int CBS_get_any_asn1_element(CBS *cbs, CBS *out, + unsigned *out_tag, + size_t *out_header_len); + /* CBS_get_asn1_uint64 gets an ASN.1 INTEGER from |cbs| using |CBS_get_asn1| * and sets |*out| to its value. It returns one on success and zero on error, * where error includes the integer being negative, or too large to represent |