chiark / gitweb /
sig: Move marshalling responsibility into sign function
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 27 Sep 2019 17:37:40 +0000 (18:37 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 29 Sep 2019 14:58:48 +0000 (15:58 +0100)
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@chiark.greenend.org.uk>
rsa.c
secnet.h
site.c

diff --git a/rsa.c b/rsa.c
index f17c256..dfbc237 100644 (file)
--- 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;
index 99662a4..bd4362e 100644 (file)
--- 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 (file)
--- 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)