[SECNET RFC PATCH 2/4] sig: Move marshalling responsibility into sign function

Ian Jackson ijackson at chiark.greenend.org.uk
Fri Sep 27 19:19:11 BST 2019


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 <ijackson at chiark.greenend.org.uk>
---
 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 <gmp.h>
 #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 4f96113..fdffbf4 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 d308f4c..2715828 100644
--- a/site.c
+++ b/site.c
@@ -614,7 +614,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;
 
     st->retries=st->setup_retries;
     BUF_ALLOC(&st->buffer,what);
@@ -652,11 +652,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.11.0




More information about the sgo-software-discuss mailing list