mirror of
https://github.com/AntelopeIO/boringssl.git
synced 2026-07-21 14:43:53 +00:00
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>
This commit is contained in:
committed by
Boringssl LUCI CQ
parent
7ac94aa279
commit
a1dffbfed9
@@ -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;
|
||||
|
||||
+10
-9
@@ -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);
|
||||
}
|
||||
|
||||
+19
-19
@@ -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(©, &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.
|
||||
|
||||
+16
-13
@@ -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) ||
|
||||
|
||||
+2
-1
@@ -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
|
||||
|
||||
+37
-34
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user