Define CBS/CBB tags as uint32_t with a typedef.

We use unsigned, but we actually assume it is 32-bit for the bit-packing
strategy. But also introduce a typedef to hint that callers shouldn't
treat it as an arbitrary 32-bit integer. A typedef would also allow us
to extend to uint64_t in the future, if we ever need to.

Update-Note: Some APIs switch from unsigned * to uint32_t * out
pointers. This is only source-compatible if unsigned and uint32_t are
the exact same type. The CQ suggests this is indeed true. If they are
not, replace unsigned with CBS_ASN1_TAG to fix the build.

Bug: 525
Change-Id: I45cbe127c1aa252f5f6a169dca2e44d1e6e1d669
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/54986
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
fips-20230428
David Benjamin 2 years ago committed by Boringssl LUCI CQ
parent 7ac94aa279
commit a1dffbfed9
  1. 2
      crypto/asn1/asn1_lib.c
  2. 19
      crypto/bytestring/ber.c
  3. 14
      crypto/bytestring/bytestring_test.cc
  4. 8
      crypto/bytestring/cbb.c
  5. 38
      crypto/bytestring/cbs.c
  6. 4
      crypto/bytestring/internal.h
  7. 4
      crypto/ec_extra/ec_asn1.c
  8. 2
      fuzz/der_roundtrip.cc
  9. 4
      include/openssl/base.h
  10. 33
      include/openssl/bytestring.h
  11. 29
      ssl/handoff.cc
  12. 3
      ssl/internal.h
  13. 71
      ssl/ssl_asn1.cc

@ -117,7 +117,7 @@ int ASN1_get_object(const unsigned char **inp, long *out_len, int *out_tag,
// signature fields (see b/18228011). Make this only apply to that field,
// while requiring DER elsewhere. Better yet, it should be limited to an
// preprocessing step in that part of Android.
unsigned tag;
CBS_ASN1_TAG tag;
size_t header_len;
int indefinite;
CBS cbs, body;

@ -24,11 +24,11 @@
// kMaxDepth is a just a sanity limit. The code should be such that the length
// of the input being processes always decreases. None the less, a very large
// input could otherwise cause the stack to overflow.
static const unsigned kMaxDepth = 2048;
static const uint32_t kMaxDepth = 2048;
// is_string_type returns one if |tag| is a string type and zero otherwise. It
// ignores the constructed bit.
static int is_string_type(unsigned tag) {
static int is_string_type(CBS_ASN1_TAG tag) {
// While BER supports constructed BIT STRINGS, OpenSSL misparses them. To
// avoid acting on an ambiguous input, we do not support constructed BIT
// STRINGS. See https://github.com/openssl/openssl/issues/12810.
@ -55,7 +55,7 @@ static int is_string_type(unsigned tag) {
// depending on whether an indefinite length element or constructed string was
// found. The value of |orig_in| is not changed. It returns one on success (i.e.
// |*ber_found| was set) and zero on error.
static int cbs_find_ber(const CBS *orig_in, int *ber_found, unsigned depth) {
static int cbs_find_ber(const CBS *orig_in, int *ber_found, uint32_t depth) {
CBS in;
if (depth > kMaxDepth) {
@ -67,7 +67,7 @@ static int cbs_find_ber(const CBS *orig_in, int *ber_found, unsigned depth) {
while (CBS_len(&in) > 0) {
CBS contents;
unsigned tag;
CBS_ASN1_TAG tag;
size_t header_len;
int indefinite;
if (!CBS_get_any_ber_asn1_element(&in, &contents, &tag, &header_len,
@ -110,8 +110,8 @@ static int cbs_get_eoc(CBS *cbs) {
// constructed string. If |looking_for_eoc| is set then any EOC elements found
// will cause the function to return after consuming it. It returns one on
// success and zero on error.
static int cbs_convert_ber(CBS *in, CBB *out, unsigned string_tag,
char looking_for_eoc, unsigned depth) {
static int cbs_convert_ber(CBS *in, CBB *out, CBS_ASN1_TAG string_tag,
int looking_for_eoc, uint32_t depth) {
assert(!(string_tag & CBS_ASN1_CONSTRUCTED));
if (depth > kMaxDepth) {
@ -124,7 +124,7 @@ static int cbs_convert_ber(CBS *in, CBB *out, unsigned string_tag,
}
CBS contents;
unsigned tag, child_string_tag = string_tag;
CBS_ASN1_TAG tag, child_string_tag = string_tag;
size_t header_len;
int indefinite;
CBB *out_contents, out_contents_storage;
@ -142,7 +142,7 @@ static int cbs_convert_ber(CBS *in, CBB *out, unsigned string_tag,
}
out_contents = out;
} else {
unsigned out_tag = tag;
CBS_ASN1_TAG out_tag = tag;
if ((tag & CBS_ASN1_CONSTRUCTED) && is_string_type(tag)) {
// If a constructed string, clear the constructed bit and inform
// children to concatenate bodies.
@ -221,7 +221,8 @@ int CBS_asn1_ber_to_der(CBS *in, CBS *out, uint8_t **out_storage) {
}
int CBS_get_asn1_implicit_string(CBS *in, CBS *out, uint8_t **out_storage,
unsigned outer_tag, unsigned inner_tag) {
CBS_ASN1_TAG outer_tag,
CBS_ASN1_TAG inner_tag) {
assert(!(outer_tag & CBS_ASN1_CONSTRUCTED));
assert(!(inner_tag & CBS_ASN1_CONSTRUCTED));
assert(is_string_type(inner_tag));

@ -249,7 +249,7 @@ TEST(CBSTest, GetASN1) {
EXPECT_FALSE(CBS_get_optional_asn1_uint64(
&data, &value, CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1, 42));
unsigned tag;
CBS_ASN1_TAG tag;
CBS_init(&data, kData1, sizeof(kData1));
ASSERT_TRUE(CBS_get_any_asn1(&data, &contents, &tag));
EXPECT_EQ(CBS_ASN1_SEQUENCE, tag);
@ -267,7 +267,7 @@ TEST(CBSTest, GetASN1) {
TEST(CBSTest, ParseASN1Tag) {
const struct {
bool ok;
unsigned tag;
CBS_ASN1_TAG tag;
std::vector<uint8_t> in;
} kTests[] = {
{true, CBS_ASN1_SEQUENCE, {0x30, 0}},
@ -278,9 +278,9 @@ TEST(CBSTest, ParseASN1Tag) {
{true,
CBS_ASN1_PRIVATE | CBS_ASN1_CONSTRUCTED | 0x1fffffff,
{0xff, 0x81, 0xff, 0xff, 0xff, 0x7f, 0}},
// Tag number fits in unsigned but not |CBS_ASN1_TAG_NUMBER_MASK|.
// Tag number fits in |uint32_t| but not |CBS_ASN1_TAG_NUMBER_MASK|.
{false, 0, {0xff, 0x82, 0xff, 0xff, 0xff, 0x7f, 0}},
// Tag number does not fit in unsigned.
// Tag number does not fit in |uint32_t|.
{false, 0, {0xff, 0x90, 0x80, 0x80, 0x80, 0, 0}},
// Tag number is not minimally-encoded
{false, 0, {0x5f, 0x80, 0x1f, 0}},
@ -289,7 +289,7 @@ TEST(CBSTest, ParseASN1Tag) {
};
for (const auto &t : kTests) {
SCOPED_TRACE(Bytes(t.in));
unsigned tag;
CBS_ASN1_TAG tag;
CBS cbs, child;
CBS_init(&cbs, t.in.data(), t.in.size());
ASSERT_EQ(t.ok, !!CBS_get_any_asn1(&cbs, &child, &tag));
@ -702,7 +702,7 @@ struct BERTest {
bool ok;
bool ber_found;
bool indefinite;
unsigned tag;
CBS_ASN1_TAG tag;
};
static const BERTest kBERTests[] = {
@ -748,7 +748,7 @@ TEST(CBSTest, BERElementTest) {
ASSERT_TRUE(DecodeHex(&in_bytes, test.in_hex));
CBS in(in_bytes);
CBS out;
unsigned tag;
CBS_ASN1_TAG tag;
size_t header_len;
int ber_found;
int indefinite;

@ -333,14 +333,14 @@ static int add_base128_integer(CBB *cbb, uint64_t v) {
return 1;
}
int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag) {
int CBB_add_asn1(CBB *cbb, CBB *out_contents, CBS_ASN1_TAG tag) {
if (!CBB_flush(cbb)) {
return 0;
}
// Split the tag into leading bits and tag number.
uint8_t tag_bits = (tag >> CBS_ASN1_TAG_SHIFT) & 0xe0;
unsigned tag_number = tag & CBS_ASN1_TAG_NUMBER_MASK;
CBS_ASN1_TAG tag_number = tag & CBS_ASN1_TAG_NUMBER_MASK;
if (tag_number >= 0x1f) {
// Set all the bits in the tag number to signal high tag number form.
if (!CBB_add_u8(cbb, tag_bits | 0x1f) ||
@ -470,7 +470,7 @@ int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) {
return CBB_add_asn1_uint64_with_tag(cbb, value, CBS_ASN1_INTEGER);
}
int CBB_add_asn1_uint64_with_tag(CBB *cbb, uint64_t value, unsigned tag) {
int CBB_add_asn1_uint64_with_tag(CBB *cbb, uint64_t value, CBS_ASN1_TAG tag) {
CBB child;
if (!CBB_add_asn1(cbb, &child, tag)) {
return 0;
@ -508,7 +508,7 @@ int CBB_add_asn1_int64(CBB *cbb, int64_t value) {
return CBB_add_asn1_int64_with_tag(cbb, value, CBS_ASN1_INTEGER);
}
int CBB_add_asn1_int64_with_tag(CBB *cbb, int64_t value, unsigned tag) {
int CBB_add_asn1_int64_with_tag(CBB *cbb, int64_t value, CBS_ASN1_TAG tag) {
if (value >= 0) {
return CBB_add_asn1_uint64_with_tag(cbb, (uint64_t)value, tag);
}

@ -254,7 +254,7 @@ static int parse_base128_integer(CBS *cbs, uint64_t *out) {
return 1;
}
static int parse_asn1_tag(CBS *cbs, unsigned *out) {
static int parse_asn1_tag(CBS *cbs, CBS_ASN1_TAG *out) {
uint8_t tag_byte;
if (!CBS_get_u8(cbs, &tag_byte)) {
return 0;
@ -266,8 +266,8 @@ static int parse_asn1_tag(CBS *cbs, unsigned *out) {
// 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.
unsigned tag = ((unsigned)tag_byte & 0xe0) << CBS_ASN1_TAG_SHIFT;
unsigned tag_number = tag_byte & 0x1f;
CBS_ASN1_TAG tag = ((CBS_ASN1_TAG)tag_byte & 0xe0) << CBS_ASN1_TAG_SHIFT;
CBS_ASN1_TAG tag_number = tag_byte & 0x1f;
if (tag_number == 0x1f) {
uint64_t v;
if (!parse_base128_integer(cbs, &v) ||
@ -277,7 +277,7 @@ static int parse_asn1_tag(CBS *cbs, unsigned *out) {
v < 0x1f) {
return 0;
}
tag_number = (unsigned)v;
tag_number = (CBS_ASN1_TAG)v;
}
tag |= tag_number;
@ -293,7 +293,7 @@ static int parse_asn1_tag(CBS *cbs, unsigned *out) {
return 1;
}
static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag,
size_t *out_header_len, int *out_ber_found,
int *out_indefinite, int ber_ok) {
CBS header = *cbs;
@ -310,7 +310,7 @@ static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
assert(out_indefinite == NULL);
}
unsigned tag;
CBS_ASN1_TAG tag;
if (!parse_asn1_tag(&header, &tag)) {
return 0;
}
@ -394,7 +394,7 @@ 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) {
int CBS_get_any_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag) {
size_t header_len;
if (!CBS_get_any_asn1_element(cbs, out, out_tag, &header_len)) {
return 0;
@ -408,13 +408,13 @@ int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag) {
return 1;
}
int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
int CBS_get_any_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag,
size_t *out_header_len) {
return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len, NULL, NULL,
/*ber_ok=*/0);
}
int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag,
size_t *out_header_len, int *out_ber_found,
int *out_indefinite) {
int ber_found_temp;
@ -424,10 +424,10 @@ int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
/*ber_ok=*/1);
}
static int cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value,
static int cbs_get_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value,
int skip_header) {
size_t header_len;
unsigned tag;
CBS_ASN1_TAG tag;
CBS throwaway;
if (out == NULL) {
@ -447,21 +447,21 @@ static int cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value,
return 1;
}
int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value) {
int CBS_get_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value) {
return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */);
}
int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value) {
int CBS_get_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value) {
return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */);
}
int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value) {
int CBS_peek_asn1_tag(const CBS *cbs, CBS_ASN1_TAG tag_value) {
if (CBS_len(cbs) < 1) {
return 0;
}
CBS copy = *cbs;
unsigned actual_tag;
CBS_ASN1_TAG actual_tag;
return parse_asn1_tag(&copy, &actual_tag) && tag_value == actual_tag;
}
@ -524,7 +524,7 @@ int CBS_get_asn1_bool(CBS *cbs, int *out) {
return 1;
}
int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) {
int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, CBS_ASN1_TAG tag) {
int present = 0;
if (CBS_peek_asn1_tag(cbs, tag)) {
@ -542,7 +542,7 @@ int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) {
}
int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
unsigned tag) {
CBS_ASN1_TAG tag) {
CBS child;
int present;
if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
@ -563,7 +563,7 @@ int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
return 1;
}
int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag,
int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, CBS_ASN1_TAG tag,
uint64_t default_value) {
CBS child;
int present;
@ -581,7 +581,7 @@ int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag,
return 1;
}
int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag,
int CBS_get_optional_asn1_bool(CBS *cbs, int *out, CBS_ASN1_TAG tag,
int default_value) {
CBS child, child2;
int present;

@ -54,8 +54,8 @@ OPENSSL_EXPORT int CBS_asn1_ber_to_der(CBS *in, CBS *out,
// It returns one on success and zero otherwise.
OPENSSL_EXPORT int CBS_get_asn1_implicit_string(CBS *in, CBS *out,
uint8_t **out_storage,
unsigned outer_tag,
unsigned inner_tag);
CBS_ASN1_TAG outer_tag,
CBS_ASN1_TAG inner_tag);
// CBB_finish_i2d calls |CBB_finish| on |cbb| which must have been initialized
// with |CBB_init|. If |outp| is not NULL then the result is written to |*outp|

@ -67,9 +67,9 @@
#include "../internal.h"
static const unsigned kParametersTag =
static const CBS_ASN1_TAG kParametersTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0;
static const unsigned kPublicKeyTag =
static const CBS_ASN1_TAG kPublicKeyTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1;
EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) {

@ -22,7 +22,7 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
CBS cbs, body;
unsigned tag;
CBS_ASN1_TAG tag;
CBS_init(&cbs, buf, len);
if (CBS_get_any_asn1(&cbs, &body, &tag)) {
// DER has a unique encoding, so any parsed input should round-trip

@ -335,6 +335,10 @@ enum ssl_verify_result_t BORINGSSL_ENUM_INT;
// are sizes of or indices into C objects, can be converted without overflow.
typedef ptrdiff_t ossl_ssize_t;
// CBS_ASN1_TAG is the type used by |CBS| and |CBB| for ASN.1 tags. See that
// header for details. This type is defined in base.h as a forward declaration.
typedef uint32_t CBS_ASN1_TAG;
// CRYPTO_THREADID is a dummy value.
typedef int CRYPTO_THREADID;

@ -169,8 +169,8 @@ OPENSSL_EXPORT int CBS_get_until_first(CBS *cbs, CBS *out, uint8_t c);
// SEQUENCE, branching on CHOICEs or OPTIONAL fields, checking for trailing
// data, and handling explict vs. implicit tagging.
//
// Tags are represented as |unsigned| values in memory. The upper few bits store
// the class and constructed bit, and the remaining bits store the tag
// Tags are represented as |CBS_ASN1_TAG| values in memory. The upper few bits
// store the class and constructed bit, and the remaining bits store the tag
// number. Note this differs from the DER serialization, to support tag numbers
// beyond 31. Consumers must use the constants defined below to decompose or
// assemble tags.
@ -231,31 +231,33 @@ OPENSSL_EXPORT int CBS_get_until_first(CBS *cbs, CBS *out, uint8_t c);
// 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
// on error.
OPENSSL_EXPORT int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value);
OPENSSL_EXPORT int CBS_get_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value);
// CBS_get_asn1_element acts like |CBS_get_asn1| but |out| will include the
// ASN.1 header bytes too.
OPENSSL_EXPORT int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value);
OPENSSL_EXPORT int CBS_get_asn1_element(CBS *cbs, CBS *out,
CBS_ASN1_TAG tag_value);
// CBS_peek_asn1_tag looks ahead at the next ASN.1 tag and returns one
// if the next ASN.1 element on |cbs| would have tag |tag_value|. If
// |cbs| is empty or the tag does not match, it returns zero. Note: if
// it returns one, CBS_get_asn1 may still fail if the rest of the
// element is malformed.
OPENSSL_EXPORT int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value);
OPENSSL_EXPORT int CBS_peek_asn1_tag(const CBS *cbs, CBS_ASN1_TAG 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.
OPENSSL_EXPORT int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag);
OPENSSL_EXPORT int CBS_get_any_asn1(CBS *cbs, CBS *out,
CBS_ASN1_TAG *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
// of |out|, |out_tag|, and |out_header_len| may be NULL to ignore the value.
OPENSSL_EXPORT int CBS_get_any_asn1_element(CBS *cbs, CBS *out,
unsigned *out_tag,
CBS_ASN1_TAG *out_tag,
size_t *out_header_len);
// CBS_get_any_ber_asn1_element acts the same as |CBS_get_any_asn1_element| but
@ -271,7 +273,7 @@ OPENSSL_EXPORT int CBS_get_any_asn1_element(CBS *cbs, CBS *out,
// element. Callers parsing indefinite-length encoding must check for EOC
// separately.
OPENSSL_EXPORT int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out,
unsigned *out_tag,
CBS_ASN1_TAG *out_tag,
size_t *out_header_len,
int *out_ber_found,
int *out_indefinite);
@ -297,7 +299,7 @@ OPENSSL_EXPORT int CBS_get_asn1_bool(CBS *cbs, int *out);
// one, otherwise zero. It returns one on success, whether or not the element
// was present, and zero on decode failure.
OPENSSL_EXPORT int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present,
unsigned tag);
CBS_ASN1_TAG tag);
// CBS_get_optional_asn1_octet_string gets an optional
// explicitly-tagged OCTET STRING from |cbs|. If present, it sets
@ -307,7 +309,7 @@ OPENSSL_EXPORT int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present,
// present, and zero on decode failure.
OPENSSL_EXPORT int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out,
int *out_present,
unsigned tag);
CBS_ASN1_TAG tag);
// CBS_get_optional_asn1_uint64 gets an optional explicitly-tagged
// INTEGER from |cbs|. If present, it sets |*out| to the
@ -315,7 +317,7 @@ OPENSSL_EXPORT int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out,
// on success, whether or not the element was present, and zero on
// decode failure.
OPENSSL_EXPORT int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out,
unsigned tag,
CBS_ASN1_TAG tag,
uint64_t default_value);
// CBS_get_optional_asn1_bool gets an optional, explicitly-tagged BOOLEAN from
@ -323,7 +325,8 @@ OPENSSL_EXPORT int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out,
// boolean. Otherwise, it sets |*out| to |default_value|. It returns one on
// success, whether or not the element was present, and zero on decode
// failure.
OPENSSL_EXPORT int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag,
OPENSSL_EXPORT int CBS_get_optional_asn1_bool(CBS *cbs, int *out,
CBS_ASN1_TAG tag,
int default_value);
// CBS_is_valid_asn1_bitstring returns one if |cbs| is a valid ASN.1 BIT STRING
@ -502,7 +505,7 @@ OPENSSL_EXPORT int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents);
// CBB_add_asn1 sets |*out_contents| to a |CBB| into which the contents of an
// ASN.1 object can be written. The |tag| argument will be used as the tag for
// the object. It returns one on success or zero on error.
OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag);
OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, CBS_ASN1_TAG tag);
// CBB_add_bytes appends |len| bytes from |data| to |cbb|. It returns one on
// success and zero otherwise.
@ -574,7 +577,7 @@ OPENSSL_EXPORT int CBB_add_asn1_uint64(CBB *cbb, uint64_t value);
// |tag| as the tag instead of INTEGER. This is useful if the INTEGER type uses
// implicit tagging.
OPENSSL_EXPORT int CBB_add_asn1_uint64_with_tag(CBB *cbb, uint64_t value,
unsigned tag);
CBS_ASN1_TAG tag);
// CBB_add_asn1_int64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1|
// and writes |value| in its contents. It returns one on success and zero on
@ -585,7 +588,7 @@ OPENSSL_EXPORT int CBB_add_asn1_int64(CBB *cbb, int64_t value);
// as the tag instead of INTEGER. This is useful if the INTEGER type uses
// implicit tagging.
OPENSSL_EXPORT int CBB_add_asn1_int64_with_tag(CBB *cbb, int64_t value,
unsigned tag);
CBS_ASN1_TAG tag);
// CBB_add_asn1_octet_string writes an ASN.1 OCTET STRING into |cbb| with the
// given contents. It returns one on success and zero on error.

@ -26,7 +26,7 @@ BSSL_NAMESPACE_BEGIN
constexpr int kHandoffVersion = 0;
constexpr int kHandbackVersion = 0;
static const unsigned kHandoffTagALPS = CBS_ASN1_CONTEXT_SPECIFIC | 0;
static const CBS_ASN1_TAG kHandoffTagALPS = CBS_ASN1_CONTEXT_SPECIFIC | 0;
// early_data_t represents the state of early data in a more compact way than
// the 3 bits used by the implementation.
@ -823,19 +823,22 @@ int SSL_request_handshake_hints(SSL *ssl, const uint8_t *client_hello,
// }
// HandshakeHints tags.
static const unsigned kServerRandomTLS13Tag = CBS_ASN1_CONTEXT_SPECIFIC | 0;
static const unsigned kKeyShareHintTag =
static const CBS_ASN1_TAG kServerRandomTLS13Tag =
CBS_ASN1_CONTEXT_SPECIFIC | 0;
static const CBS_ASN1_TAG kKeyShareHintTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1;
static const unsigned kSignatureHintTag =
static const CBS_ASN1_TAG kSignatureHintTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2;
static const unsigned kDecryptedPSKTag = CBS_ASN1_CONTEXT_SPECIFIC | 3;
static const unsigned kIgnorePSKTag = CBS_ASN1_CONTEXT_SPECIFIC | 4;
static const unsigned kCompressCertificateTag = CBS_ASN1_CONTEXT_SPECIFIC | 5;
static const unsigned kServerRandomTLS12Tag = CBS_ASN1_CONTEXT_SPECIFIC | 6;
static const unsigned kECDHEHintTag = CBS_ASN1_CONSTRUCTED | 7;
static const unsigned kDecryptedTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 8;
static const unsigned kRenewTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 9;
static const unsigned kIgnoreTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 10;
static const CBS_ASN1_TAG kDecryptedPSKTag = CBS_ASN1_CONTEXT_SPECIFIC | 3;
static const CBS_ASN1_TAG kIgnorePSKTag = CBS_ASN1_CONTEXT_SPECIFIC | 4;
static const CBS_ASN1_TAG kCompressCertificateTag =
CBS_ASN1_CONTEXT_SPECIFIC | 5;
static const CBS_ASN1_TAG kServerRandomTLS12Tag =
CBS_ASN1_CONTEXT_SPECIFIC | 6;
static const CBS_ASN1_TAG kECDHEHintTag = CBS_ASN1_CONSTRUCTED | 7;
static const CBS_ASN1_TAG kDecryptedTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 8;
static const CBS_ASN1_TAG kRenewTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 9;
static const CBS_ASN1_TAG kIgnoreTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 10;
int SSL_serialize_handshake_hints(const SSL *ssl, CBB *out) {
const SSL_HANDSHAKE *hs = ssl->s3->hs.get();
@ -954,7 +957,7 @@ int SSL_serialize_handshake_hints(const SSL *ssl, CBB *out) {
}
static bool get_optional_implicit_null(CBS *cbs, bool *out_present,
unsigned tag) {
CBS_ASN1_TAG tag) {
CBS value;
int present;
if (!CBS_get_optional_asn1(cbs, &value, &present, tag) ||

@ -1313,7 +1313,8 @@ enum ssl_key_usage_t {
// ssl_cert_check_key_usage parses the DER-encoded, X.509 certificate in |in|
// and returns true if doesn't specify a key usage or, if it does, if it
// includes |bit|. Otherwise it pushes to the error queue and returns false.
bool ssl_cert_check_key_usage(const CBS *in, enum ssl_key_usage_t bit);
OPENSSL_EXPORT bool ssl_cert_check_key_usage(const CBS *in,
enum ssl_key_usage_t bit);
// ssl_cert_parse_pubkey extracts the public key from the DER-encoded, X.509
// certificate in |in|. It returns an allocated |EVP_PKEY| or else returns

@ -150,57 +150,57 @@ BSSL_NAMESPACE_BEGIN
static const unsigned kVersion = 1;
static const unsigned kTimeTag =
static const CBS_ASN1_TAG kTimeTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1;
static const unsigned kTimeoutTag =
static const CBS_ASN1_TAG kTimeoutTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2;
static const unsigned kPeerTag =
static const CBS_ASN1_TAG kPeerTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3;
static const unsigned kSessionIDContextTag =
static const CBS_ASN1_TAG kSessionIDContextTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 4;
static const unsigned kVerifyResultTag =
static const CBS_ASN1_TAG kVerifyResultTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 5;
static const unsigned kHostNameTag =
static const CBS_ASN1_TAG kHostNameTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 6;
static const unsigned kPSKIdentityTag =
static const CBS_ASN1_TAG kPSKIdentityTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 8;
static const unsigned kTicketLifetimeHintTag =
static const CBS_ASN1_TAG kTicketLifetimeHintTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 9;
static const unsigned kTicketTag =
static const CBS_ASN1_TAG kTicketTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 10;
static const unsigned kPeerSHA256Tag =
static const CBS_ASN1_TAG kPeerSHA256Tag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 13;
static const unsigned kOriginalHandshakeHashTag =
static const CBS_ASN1_TAG kOriginalHandshakeHashTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 14;
static const unsigned kSignedCertTimestampListTag =
static const CBS_ASN1_TAG kSignedCertTimestampListTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 15;
static const unsigned kOCSPResponseTag =
static const CBS_ASN1_TAG kOCSPResponseTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 16;
static const unsigned kExtendedMasterSecretTag =
static const CBS_ASN1_TAG kExtendedMasterSecretTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 17;
static const unsigned kGroupIDTag =
static const CBS_ASN1_TAG kGroupIDTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 18;
static const unsigned kCertChainTag =
static const CBS_ASN1_TAG kCertChainTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 19;
static const unsigned kTicketAgeAddTag =
static const CBS_ASN1_TAG kTicketAgeAddTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 21;
static const unsigned kIsServerTag =
static const CBS_ASN1_TAG kIsServerTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 22;
static const unsigned kPeerSignatureAlgorithmTag =
static const CBS_ASN1_TAG kPeerSignatureAlgorithmTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 23;
static const unsigned kTicketMaxEarlyDataTag =
static const CBS_ASN1_TAG kTicketMaxEarlyDataTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 24;
static const unsigned kAuthTimeoutTag =
static const CBS_ASN1_TAG kAuthTimeoutTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 25;
static const unsigned kEarlyALPNTag =
static const CBS_ASN1_TAG kEarlyALPNTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 26;
static const unsigned kIsQuicTag =
static const CBS_ASN1_TAG kIsQuicTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 27;
static const unsigned kQuicEarlyDataContextTag =
static const CBS_ASN1_TAG kQuicEarlyDataContextTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 28;
static const unsigned kLocalALPSTag =
static const CBS_ASN1_TAG kLocalALPSTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 29;
static const unsigned kPeerALPSTag =
static const CBS_ASN1_TAG kPeerALPSTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 30;
static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb,
@ -438,7 +438,8 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb,
// tagged with |tag| from |cbs| and saves it in |*out|. If the element was not
// found, it sets |*out| to NULL. It returns one on success, whether or not the
// element was found, and zero on decode error.
static int SSL_SESSION_parse_string(CBS *cbs, UniquePtr<char> *out, unsigned tag) {
static int SSL_SESSION_parse_string(CBS *cbs, UniquePtr<char> *out,
CBS_ASN1_TAG tag) {
CBS value;
int present;
if (!CBS_get_optional_asn1_octet_string(cbs, &value, &present, tag)) {
@ -466,7 +467,7 @@ static int SSL_SESSION_parse_string(CBS *cbs, UniquePtr<char> *out, unsigned tag
// tagged with |tag| from |cbs| and stows it in |*out|. It returns one on
// success, whether or not the element was found, and zero on decode error.
static bool SSL_SESSION_parse_octet_string(CBS *cbs, Array<uint8_t> *out,
unsigned tag) {
CBS_ASN1_TAG tag) {
CBS value;
if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
@ -477,7 +478,7 @@ static bool SSL_SESSION_parse_octet_string(CBS *cbs, Array<uint8_t> *out,
static int SSL_SESSION_parse_crypto_buffer(CBS *cbs,
UniquePtr<CRYPTO_BUFFER> *out,
unsigned tag,
CBS_ASN1_TAG tag,
CRYPTO_BUFFER_POOL *pool) {
if (!CBS_peek_asn1_tag(cbs, tag)) {
return 1;
@ -500,8 +501,10 @@ static int SSL_SESSION_parse_crypto_buffer(CBS *cbs,
// SSL_SESSION_parse_bounded_octet_string parses an optional ASN.1 OCTET STRING
// explicitly tagged with |tag| of size at most |max_out|.
static int SSL_SESSION_parse_bounded_octet_string(
CBS *cbs, uint8_t *out, uint8_t *out_len, uint8_t max_out, unsigned tag) {
static int SSL_SESSION_parse_bounded_octet_string(CBS *cbs, uint8_t *out,
uint8_t *out_len,
uint8_t max_out,
CBS_ASN1_TAG tag) {
CBS value;
if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag) ||
CBS_len(&value) > max_out) {
@ -513,7 +516,7 @@ static int SSL_SESSION_parse_bounded_octet_string(
return 1;
}
static int SSL_SESSION_parse_long(CBS *cbs, long *out, unsigned tag,
static int SSL_SESSION_parse_long(CBS *cbs, long *out, CBS_ASN1_TAG tag,
long default_value) {
uint64_t value;
if (!CBS_get_optional_asn1_uint64(cbs, &value, tag,
@ -526,7 +529,7 @@ static int SSL_SESSION_parse_long(CBS *cbs, long *out, unsigned tag,
return 1;
}
static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, unsigned tag,
static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, CBS_ASN1_TAG tag,
uint32_t default_value) {
uint64_t value;
if (!CBS_get_optional_asn1_uint64(cbs, &value, tag,
@ -539,7 +542,7 @@ static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, unsigned tag,
return 1;
}
static int SSL_SESSION_parse_u16(CBS *cbs, uint16_t *out, unsigned tag,
static int SSL_SESSION_parse_u16(CBS *cbs, uint16_t *out, CBS_ASN1_TAG tag,
uint16_t default_value) {
uint64_t value;
if (!CBS_get_optional_asn1_uint64(cbs, &value, tag,

Loading…
Cancel
Save