-/* $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.
*
-/* $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.
*
-/* $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.
*
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)
{
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)
{
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)
-/* $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.
*
*/
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.
*/
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 */