From b4dfbc2e00231ea37707b0594bc9d565fd25f368 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Niels=20M=C3=B6ller?= Date: Mon, 13 Oct 2025 19:53:49 +0200 Subject: [PATCH] sexp-conv: Delete use of nettle_armor for output. --- ChangeLog | 9 +++ tools/output.c | 143 ++++++++++++++++++++++++++-------------------- tools/output.h | 21 ++++--- tools/sexp-conv.c | 4 +- 4 files changed, 105 insertions(+), 72 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8b49111f..7f690932 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2025-10-13 Niels Möller + + * tools/output.h (struct sexp_output): Replace use of struct + nettle_armor, instead use just a put_char function pointer. + * tools/output.c (sexp_put_base16_start, sexp_put_base16_end) + (sexp_put_base64_start, sexp_put_base64_end): New functions, + replacing... + (sexp_put_code_start, sexp_put_code_end): Deleted functions. + 2025-10-08 Niels Möller * tools/sexp-conv.c (list_hashes): New function. diff --git a/tools/output.c b/tools/output.c index afc36481..8697b996 100644 --- a/tools/output.c +++ b/tools/output.c @@ -41,9 +41,17 @@ #include "output.h" +#include "base16.h" + /* For TMP_ALLOC */ #include "nettle-internal.h" +static void +sexp_put_hash_char(struct sexp_output *output, uint8_t c) +{ + output->hash->update (output->ctx, 1, &c); +} + void sexp_output_init(struct sexp_output *output, FILE *f, const struct nettle_hash *hash, @@ -51,17 +59,19 @@ sexp_output_init(struct sexp_output *output, FILE *f, { output->f = f; output->line_width = width; - output->coding = NULL; output->prefer_hex = prefer_hex; output->hash = hash; if (output->hash) { output->ctx = xalloc (output->hash->context_size); output->hash->init (output->ctx); + output->put_char = sexp_put_hash_char; } else - output->ctx = NULL; - + { + output->ctx = NULL; + output->put_char = NULL; + } output->pos = 0; output->soft_newline = 0; } @@ -109,30 +119,14 @@ sexp_put_soft_newline(struct sexp_output *output, void sexp_put_char(struct sexp_output *output, uint8_t c) { - if (output->coding) + if (output->put_char) { - /* Two is enough for both base16 and base64. */ - char encoded[2]; - unsigned done; - - unsigned i; - - done = output->coding->encode_update(&output->base64, encoded, - 1, &c); - assert(done <= sizeof(encoded)); - - for (i = 0; iline_width - && output->pos >= output->line_width - && output->pos >= (output->coding_indent + 10)) - sexp_put_newline(output, output->coding_indent); - - sexp_put_raw_char(output, encoded[i]); - } + if (output->line_width + && output->pos >= output->line_width + && output->pos >= (output->coding_indent + 10)) + sexp_put_newline(output, output->coding_indent); + output->put_char (output, c); } - else if (output->hash) - output->hash->update(output->ctx, 1, &c); else sexp_put_raw_char(output, c); } @@ -165,34 +159,59 @@ sexp_put_length(struct sexp_output *output, sexp_put_char(output, '0' + length / digit); } +static void +sexp_put_base16 (struct sexp_output *output, uint8_t c) +{ + char encoded[2]; + base16_encode_single (encoded, c); + sexp_put_raw_char (output, encoded[0]); + sexp_put_raw_char (output, encoded[1]); +} + void -sexp_put_code_start(struct sexp_output *output, - const struct nettle_armor *coding) +sexp_put_base16_start (struct sexp_output *output) { - assert(!output->coding); - + assert (!output->put_char); output->coding_indent = output->pos; - - output->coding = coding; - output->coding->encode_init(&output->base64); + output->put_char = sexp_put_base16; } void -sexp_put_code_end(struct sexp_output *output) +sexp_put_base16_end (struct sexp_output *output) { - /* Enough for both hex and base64 */ - char encoded[BASE64_ENCODE_FINAL_LENGTH]; + output->put_char = NULL; +} + +static void +sexp_put_base64 (struct sexp_output *output, uint8_t c) +{ + char encoded[2]; unsigned done; - assert(output->coding); + done = base64_encode_single (&output->base64, encoded, c); + sexp_put_raw_char (output, encoded[0]); + if (done > 1) + sexp_put_raw_char (output, encoded[1]); +} - done = output->coding->encode_final(&output->base64, encoded); +void +sexp_put_base64_start (struct sexp_output *output) +{ + assert (!output->put_char); + output->coding_indent = output->pos; + base64_encode_init (&output->base64); + output->put_char = sexp_put_base64; +} - assert(done <= sizeof(encoded)); - - output->coding = NULL; +void +sexp_put_base64_end(struct sexp_output *output) +{ + char encoded[BASE64_ENCODE_FINAL_LENGTH]; + unsigned done; - sexp_put_data(output, done, (const uint8_t*) encoded); + done = base64_encode_final (&output->base64, encoded); + output->put_char = NULL; + sexp_put_data (output, done, (const uint8_t*) encoded); } void @@ -261,27 +280,21 @@ sexp_put_string(struct sexp_output *output, enum sexp_mode mode, sexp_put_char(output, '"'); } - else + else if (output->prefer_hex) { - uint8_t delimiter; - const struct nettle_armor *coding; - - if (output->prefer_hex) - { - delimiter = '#'; - coding = &nettle_base16; - } - else - { - delimiter = '|'; - coding = &nettle_base64; - } - - sexp_put_char(output, delimiter); - sexp_put_code_start(output, coding); + sexp_put_char(output, '#'); + sexp_put_base16_start (output); sexp_put_data(output, string->size, string->contents); - sexp_put_code_end(output); - sexp_put_char(output, delimiter); + sexp_put_base16_end (output); + sexp_put_char(output, '#'); + } + else + { + sexp_put_char(output, '|'); + sexp_put_base64_start (output); + sexp_put_data(output, string->size, string->contents); + sexp_put_base64_end (output); + sexp_put_char(output, '|'); } #undef CONTROL_SIZE } @@ -303,8 +316,12 @@ sexp_put_digest(struct sexp_output *output) output->hash->digest(output->ctx, digest); - sexp_put_code_start(output, &nettle_base16); - sexp_put_data(output, output->hash->digest_size, digest); - sexp_put_code_end(output); + output->put_char = NULL; + + sexp_put_base16_start (output); + sexp_put_data (output, output->hash->digest_size, digest); + sexp_put_base16_end (output); + + output->put_char = sexp_put_hash_char; } diff --git a/tools/output.h b/tools/output.h index 66472377..2242232f 100644 --- a/tools/output.h +++ b/tools/output.h @@ -40,13 +40,16 @@ #include +struct sexp_output; +typedef void put_char_func (struct sexp_output *output, uint8_t c); + struct sexp_output { FILE *f; unsigned line_width; - const struct nettle_armor *coding; + put_char_func *put_char; unsigned coding_indent; int prefer_hex; @@ -54,9 +57,8 @@ struct sexp_output const struct nettle_hash *hash; void *ctx; - /* NOTE: There's no context for hex encoding, the state argument to - encode_update is ignored */ - struct base64_decode_ctx base64; + /* NOTE: There's no context needed for hex encoding. */ + struct base64_encode_ctx base64; unsigned pos; int soft_newline; @@ -83,11 +85,16 @@ sexp_put_data(struct sexp_output *output, unsigned length, const uint8_t *data); void -sexp_put_code_start(struct sexp_output *output, - const struct nettle_armor *coding); +sexp_put_base16_start(struct sexp_output *output); + +void +sexp_put_base16_end(struct sexp_output *output); + +void +sexp_put_base64_start(struct sexp_output *output); void -sexp_put_code_end(struct sexp_output *output); +sexp_put_base64_end(struct sexp_output *output); void sexp_put_string(struct sexp_output *output, enum sexp_mode mode, diff --git a/tools/sexp-conv.c b/tools/sexp-conv.c index 3062f013..3001d6b5 100644 --- a/tools/sexp-conv.c +++ b/tools/sexp-conv.c @@ -77,9 +77,9 @@ sexp_convert_item(struct sexp_parser *parser, if (mode_out == SEXP_TRANSPORT) { sexp_put_char(output, '{'); - sexp_put_code_start(output, &nettle_base64); + sexp_put_base64_start(output); sexp_convert_item(parser, token, output, SEXP_CANONICAL, 0); - sexp_put_code_end(output); + sexp_put_base64_end(output); sexp_put_char(output, '}'); } else switch(token->type) -- 2.47.3