From 41c305f6cde8418f9475474d761a3163d973efe6 Mon Sep 17 00:00:00 2001 From: Andrew Kozlik Date: Thu, 30 Nov 2023 20:41:21 +0100 Subject: [PATCH] feat(crypto): Use entire DER encoding in DER_ITEM. --- crypto/buffer.c | 10 ++++++++++ crypto/buffer.h | 1 + crypto/der.c | 17 ++++++++++++----- crypto/der.h | 7 ++++++- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/crypto/buffer.c b/crypto/buffer.c index 829aad1d2..9b6d34eac 100644 --- a/crypto/buffer.c +++ b/crypto/buffer.c @@ -64,6 +64,16 @@ bool buffer_get(BUFFER_READER *buf, uint8_t *byte) { return true; } +bool buffer_seek(BUFFER_READER *buf, size_t pos) { + if ((buf->data == NULL) || (pos > buf->size)) { + return false; + } + + buf->pos = pos; + + return true; +} + bool buffer_read_buffer(BUFFER_READER *src, BUFFER_READER *dest, size_t size) { if ((src->data == NULL) || (src->pos + size > src->size)) { return false; diff --git a/crypto/buffer.h b/crypto/buffer.h index 4c2f4e608..6be46dcf2 100644 --- a/crypto/buffer.h +++ b/crypto/buffer.h @@ -48,6 +48,7 @@ void buffer_writer_init(BUFFER_WRITER *buf, uint8_t *data, size_t size); size_t __wur buffer_remaining(BUFFER_READER *buf); bool __wur buffer_peek(const BUFFER_READER *buf, uint8_t *byte); bool __wur buffer_get(BUFFER_READER *buf, uint8_t *byte); +bool __wur buffer_seek(BUFFER_READER *buf, size_t pos); bool __wur buffer_read_buffer(BUFFER_READER *src, BUFFER_READER *dest, size_t size); void buffer_lstrip(BUFFER_READER *buf, uint8_t byte); diff --git a/crypto/der.c b/crypto/der.c index 2813978ae..e863ef85e 100644 --- a/crypto/der.c +++ b/crypto/der.c @@ -87,6 +87,7 @@ bool der_write_length(BUFFER_WRITER *buf, size_t len) { } bool der_read_item(BUFFER_READER *buf, DER_ITEM *item) { + size_t begin_pos = buf->pos; if (!buffer_get(buf, &item->id) || ((item->id & 0x1f) == 0x1f)) { // Multi-byte identifiers not supported. return false; @@ -97,7 +98,13 @@ bool der_read_item(BUFFER_READER *buf, DER_ITEM *item) { return false; } - return buffer_read_buffer(buf, &item->cont, len); + size_t header_size = buf->pos - begin_pos; + if (!buffer_seek(buf, begin_pos) || + !buffer_read_buffer(buf, &item->buf, header_size + len)) { + return false; + } + + return buffer_seek(&item->buf, header_size); } // Reencode a positive integer which violates the encoding rules in Rec. ITU-T @@ -111,13 +118,13 @@ bool der_reencode_int(BUFFER_READER *reader, BUFFER_WRITER *writer) { } // Strip any leading 0x00 bytes. - buffer_lstrip(&item.cont, 0x00); - size_t len = buffer_remaining(&item.cont); + buffer_lstrip(&item.buf, 0x00); + size_t len = buffer_remaining(&item.buf); // Positive integers should start with one 0x00 byte if and only if the most // significant byte is >= 0x80. uint8_t msb = 0; - bool prepend_null = (!buffer_peek(&item.cont, &msb) || msb >= 0x80); + bool prepend_null = (!buffer_peek(&item.buf, &msb) || msb >= 0x80); if (prepend_null) { len += 1; } @@ -132,5 +139,5 @@ bool der_reencode_int(BUFFER_READER *reader, BUFFER_WRITER *writer) { } } - return buffer_write_buffer(writer, &item.cont); + return buffer_write_buffer(writer, &item.buf); } diff --git a/crypto/der.h b/crypto/der.h index 4d249c287..b6c84033c 100644 --- a/crypto/der.h +++ b/crypto/der.h @@ -33,9 +33,14 @@ #define DER_SEQUENCE 0x30 #define DER_INTEGER 0x02 +// Struct representing a DER-encoded ASN.1 data value. typedef struct { + // Single-octet identifier encoding the ASN.1 class, type and tag number. uint8_t id; - BUFFER_READER cont; + // A buffer containing the entire DER encoding of the data value including the + // tag and length, but with the position indicator initialized to the offset + // of the contents octets. + BUFFER_READER buf; } DER_ITEM; bool __wur der_read_length(BUFFER_READER *buf, size_t *len);