Provide various CBS_peek_* functions.
authorjsing <jsing@openbsd.org>
Wed, 15 Dec 2021 17:36:49 +0000 (17:36 +0000)
committerjsing <jsing@openbsd.org>
Wed, 15 Dec 2021 17:36:49 +0000 (17:36 +0000)
These will be used in libcrypto.

With input from and ok tb@

lib/libssl/bs_cbs.c
lib/libssl/bytestring.h

index 97b0163..63c078c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bs_cbs.c,v 1.23 2021/12/15 17:30:20 jsing Exp $       */
+/*     $OpenBSD: bs_cbs.c,v 1.24 2021/12/15 17:36:49 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)
 {
@@ -259,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)
index fa5e05f..ce933f3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bytestring.h,v 1.21 2021/12/15 17:30:20 jsing Exp $   */
+/*     $OpenBSD: bytestring.h,v 1.22 2021/12/15 17:36:49 jsing Exp $   */
 /*
  * Copyright (c) 2014, Google Inc.
  *
@@ -172,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 */