From 403cdd364693a05c700f04085fc05dbf575d97ef Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Fri, 27 Sep 2019 18:37:40 +0100 Subject: [PATCH] sig: Move marshalling responsibility into sign function This is the first part of making the pk algorithm responsible for understanding its signature format. The sign function is expected to produce some bytes which (in a moment) its companion functions will be able to parse. Signed-off-by: Ian Jackson --- rsa.c | 22 +++++++++++++++++++--- secnet.h | 5 ++++- site.c | 12 ++++++++---- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/rsa.c b/rsa.c index f17c256..dfbc237 100644 --- a/rsa.c +++ b/rsa.c @@ -35,6 +35,7 @@ #include #include "secnet.h" #include "util.h" +#include "unaligned.h" #define AUTHFILE_ID_STRING "SSH PRIVATE KEY FILE FORMAT 1.1\n" @@ -114,11 +115,13 @@ static void emsa_pkcs1(MP_INT *n, MP_INT *m, mpz_set_str(m, buff, 16); } -static string_t rsa_sign(void *sst, uint8_t *data, int32_t datalen) +static bool_t rsa_sign(void *sst, uint8_t *data, int32_t datalen, + struct buffer_if *msg) { struct rsapriv *st=sst; MP_INT a, b, u, v, tmp, tmp2; - string_t signature; + string_t signature = 0; + bool_t ok; mpz_init(&a); mpz_init(&b); @@ -162,9 +165,22 @@ static string_t rsa_sign(void *sst, uint8_t *data, int32_t datalen) signature=write_mpstring(&b); + uint8_t *op = buf_append(msg,2); + if (!op) { ok=False; goto out; } + size_t l = strlen(signature); + assert(l < 65536); + put_uint16(op, l); + op = buf_append(msg,l); + if (!op) { ok=False; goto out; } + memcpy(op, signature, l); + + ok = True; + + out: + free(signature); mpz_clear(&b); mpz_clear(&a); - return signature; + return ok; } static sig_checksig_fn rsa_sig_check; diff --git a/secnet.h b/secnet.h index 99662a4..bd4362e 100644 --- a/secnet.h +++ b/secnet.h @@ -422,7 +422,10 @@ struct sigpubkey_if { /* SIGPRIVKEY interface */ -typedef string_t sig_makesig_fn(void *st, uint8_t *data, int32_t datalen); +/* Appends the signature to msg. + * Can fail and returnn False, eg if the buffer is too small. */ +typedef bool_t sig_makesig_fn(void *st, uint8_t *data, int32_t datalen, + struct buffer_if *msg); struct sigprivkey_if { void *st; sig_makesig_fn *sign; diff --git a/site.c b/site.c index 9e93ef1..6e5c5a6 100644 --- a/site.c +++ b/site.c @@ -617,7 +617,7 @@ static bool_t generate_msg(struct site *st, uint32_t type, cstring_t what) { void *hst; uint8_t *hash; - string_t dhpub, sig; + string_t dhpub; unsigned minor; st->retries=st->setup_retries; @@ -660,11 +660,15 @@ static bool_t generate_msg(struct site *st, uint32_t type, cstring_t what) hst=st->hash->init(); st->hash->update(hst,st->buffer.start,st->buffer.size); st->hash->final(hst,hash); - sig=st->privkey->sign(st->privkey->st,hash,st->hash->len); - buf_append_string(&st->buffer,sig); - free(sig); + bool_t ok=st->privkey->sign(st->privkey->st,hash,st->hash->len, + &st->buffer); + if (!ok) goto fail; free(hash); return True; + + fail: + free(hash); + return False; } static bool_t unpick_name(struct buffer_if *msg, struct parsedname *nm) -- 2.30.2