From 470be27da253cd8812cde224519dfe518ee7f1f5 Mon Sep 17 00:00:00 2001 From: jsing Date: Wed, 15 Dec 2021 18:02:39 +0000 Subject: [PATCH] Sync bytestring with libssl. --- lib/libcrypto/bytestring/bs_ber.c | 2 +- lib/libcrypto/bytestring/bs_cbb.c | 2 +- lib/libcrypto/bytestring/bs_cbs.c | 107 +++++++++++++++++++++++++- lib/libcrypto/bytestring/bytestring.h | 44 ++++++++++- 4 files changed, 151 insertions(+), 4 deletions(-) diff --git a/lib/libcrypto/bytestring/bs_ber.c b/lib/libcrypto/bytestring/bs_ber.c index e77c98b2238..c9779c8965c 100644 --- a/lib/libcrypto/bytestring/bs_ber.c +++ b/lib/libcrypto/bytestring/bs_ber.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bs_ber.c,v 1.1 2021/11/20 18:10:52 jsing Exp $ */ +/* $OpenBSD: bs_ber.c,v 1.2 2021/12/15 18:02:39 jsing Exp $ */ /* * Copyright (c) 2014, Google Inc. * diff --git a/lib/libcrypto/bytestring/bs_cbb.c b/lib/libcrypto/bytestring/bs_cbb.c index 2aaee30a068..1fa358d6c42 100644 --- a/lib/libcrypto/bytestring/bs_cbb.c +++ b/lib/libcrypto/bytestring/bs_cbb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bs_cbb.c,v 1.1 2021/11/20 18:10:52 jsing Exp $ */ +/* $OpenBSD: bs_cbb.c,v 1.2 2021/12/15 18:02:39 jsing Exp $ */ /* * Copyright (c) 2014, Google Inc. * diff --git a/lib/libcrypto/bytestring/bs_cbs.c b/lib/libcrypto/bytestring/bs_cbs.c index 06283abd946..e2bb54e4602 100644 --- a/lib/libcrypto/bytestring/bs_cbs.c +++ b/lib/libcrypto/bytestring/bs_cbs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bs_cbs.c,v 1.1 2021/11/20 18:10:52 jsing Exp $ */ +/* $OpenBSD: bs_cbs.c,v 1.2 2021/12/15 18:02:39 jsing Exp $ */ /* * Copyright (c) 2014, Google Inc. * @@ -47,6 +47,16 @@ cbs_get(CBS *cbs, const uint8_t **p, size_t n) return 1; } +static int +cbs_peek(CBS *cbs, const uint8_t **p, size_t n) +{ + if (cbs->len < n) + return 0; + + *p = cbs->data; + return 1; +} + size_t CBS_offset(const CBS *cbs) { @@ -190,6 +200,34 @@ CBS_get_u32(CBS *cbs, uint32_t *out) return cbs_get_u(cbs, out, 4); } +int +CBS_get_u64(CBS *cbs, uint64_t *out) +{ + uint32_t a, b; + + if (cbs->len < 8) + return 0; + + if (!CBS_get_u32(cbs, &a)) + return 0; + if (!CBS_get_u32(cbs, &b)) + return 0; + + *out = (uint64_t)a << 32 | b; + return 1; +} + +int +CBS_get_last_u8(CBS *cbs, uint8_t *out) +{ + if (cbs->len == 0) + return 0; + + *out = cbs->data[cbs->len - 1]; + cbs->len--; + return 1; +} + int CBS_get_bytes(CBS *cbs, CBS *out, size_t len) { @@ -231,6 +269,73 @@ CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) return cbs_get_length_prefixed(cbs, out, 3); } +static int +cbs_peek_u(CBS *cbs, uint32_t *out, size_t len) +{ + uint32_t result = 0; + size_t i; + const uint8_t *data; + + if (len < 1 || len > 4) + return 0; + + if (!cbs_peek(cbs, &data, len)) + return 0; + + for (i = 0; i < len; i++) { + result <<= 8; + result |= data[i]; + } + *out = result; + return 1; +} + +int +CBS_peek_u8(CBS *cbs, uint8_t *out) +{ + const uint8_t *v; + + if (!cbs_peek(cbs, &v, 1)) + return 0; + + *out = *v; + return 1; +} + +int +CBS_peek_u16(CBS *cbs, uint16_t *out) +{ + uint32_t v; + + if (!cbs_peek_u(cbs, &v, 2)) + return 0; + + *out = v; + return 1; +} + +int +CBS_peek_u24(CBS *cbs, uint32_t *out) +{ + return cbs_peek_u(cbs, out, 3); +} + +int +CBS_peek_u32(CBS *cbs, uint32_t *out) +{ + return cbs_peek_u(cbs, out, 4); +} + +int +CBS_peek_last_u8(CBS *cbs, uint8_t *out) +{ + if (cbs->len == 0) + return 0; + + *out = cbs->data[cbs->len - 1]; + return 1; +} + int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag, size_t *out_header_len) diff --git a/lib/libcrypto/bytestring/bytestring.h b/lib/libcrypto/bytestring/bytestring.h index 7728ef8de26..54d8f54ce27 100644 --- a/lib/libcrypto/bytestring/bytestring.h +++ b/lib/libcrypto/bytestring/bytestring.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bytestring.h,v 1.1 2021/11/20 18:10:52 jsing Exp $ */ +/* $OpenBSD: bytestring.h,v 1.2 2021/12/15 18:02:39 jsing Exp $ */ /* * Copyright (c) 2014, Google Inc. * @@ -133,6 +133,18 @@ int CBS_get_u24(CBS *cbs, uint32_t *out); */ int CBS_get_u32(CBS *cbs, uint32_t *out); +/* + * CBS_get_u64 sets |*out| to the next, big-endian uint64_t value from |cbs| + * and advances |cbs|. It returns one on success and zero on error. + */ +int CBS_get_u64(CBS *cbs, uint64_t *out); + +/* + * CBS_get_last_u8 sets |*out| to the last uint8_t from |cbs| and shortens + * |cbs|. It returns one on success and zero on error. + */ +int CBS_get_last_u8(CBS *cbs, uint8_t *out); + /* * CBS_get_bytes sets |*out| to the next |len| bytes from |cbs| and advances * |cbs|. It returns one on success and zero on error. @@ -160,6 +172,36 @@ int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out); */ int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out); +/* + * CBS_peek_u8 sets |*out| to the next uint8_t from |cbs|, but does not advance + * |cbs|. It returns one on success and zero on error. + */ +int CBS_peek_u8(CBS *cbs, uint8_t *out); + +/* + * CBS_peek_u16 sets |*out| to the next, big-endian uint16_t from |cbs|, but + * does not advance |cbs|. It returns one on success and zero on error. + */ +int CBS_peek_u16(CBS *cbs, uint16_t *out); + +/* + * CBS_peek_u24 sets |*out| to the next, big-endian 24-bit value from |cbs|, but + * does not advance |cbs|. It returns one on success and zero on error. + */ +int CBS_peek_u24(CBS *cbs, uint32_t *out); + +/* + * CBS_peek_u32 sets |*out| to the next, big-endian uint32_t value from |cbs|, + * but does not advance |cbs|. It returns one on success and zero on error. + */ +int CBS_peek_u32(CBS *cbs, uint32_t *out); + +/* + * CBS_peek_last_u8 sets |*out| to the last uint8_t from |cbs|, but does not + * shorten |cbs|. It returns one on success and zero on error. + */ +int CBS_peek_last_u8(CBS *cbs, uint8_t *out); + /* Parsing ASN.1 */ -- 2.20.1