chiark / gitweb /
sig: Move unmarshalling responsibility into algorithm
[secnet.git] / site.c
diff --git a/site.c b/site.c
index 67227e63cbc9aba15cc88f5649dda90af8190deb..73d5b64aae560f9b244a333e78d564ed5cc2aa58 100644 (file)
--- a/site.c
+++ b/site.c
@@ -312,8 +312,8 @@ struct site {
     struct resolver_if *resolver;
     struct log_if *log;
     struct random_if *random;
-    struct rsaprivkey_if *privkey;
-    struct rsapubkey_if *pubkey;
+    struct sigprivkey_if *privkey;
+    struct sigpubkey_if *pubkey;
     struct transform_if **transforms;
     int ntransforms;
     struct dh_if *dh;
@@ -534,8 +534,7 @@ struct msg {
     int32_t pklen;
     char *pk;
     int32_t hashlen;
-    int32_t siglen;
-    char *sig;
+    struct alg_msg_data sig;
 };
 
 static int32_t wait_timeout(struct site *st) {
@@ -617,7 +616,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 +659,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)
@@ -741,17 +744,12 @@ static bool_t unpick_msg(struct site *st, uint32_t type,
     CHECK_AVAIL(msg,m->pklen);
     m->pk=buf_unprepend(msg,m->pklen);
     m->hashlen=msg->start-m->hashstart;
-    CHECK_AVAIL(msg,2);
-    m->siglen=buf_unprepend_uint16(msg);
-    CHECK_AVAIL(msg,m->siglen);
-    m->sig=buf_unprepend(msg,m->siglen);
-    CHECK_EMPTY(msg);
 
-    /* In `process_msg3_msg4' below, we assume that we can write a nul
-     * terminator following the signature.  Make sure there's enough space.
-     */
-    if (msg->start >= msg->base + msg->alloclen)
+    if (!st->pubkey->unpick(st->pubkey->st,msg,&m->sig)) {
        return False;
+    }
+
+    CHECK_EMPTY(msg);
 
     return True;
 }
@@ -894,9 +892,9 @@ static bool_t process_msg3_msg4(struct site *st, struct msg *m)
     hst=st->hash->init();
     st->hash->update(hst,m->hashstart,m->hashlen);
     st->hash->final(hst,hash);
-    /* Terminate signature with a '0' - already checked that this will fit */
-    m->sig[m->siglen]=0;
-    if (!st->pubkey->check(st->pubkey->st,hash,st->hash->len,m->sig)) {
+    if (!st->pubkey->check(st->pubkey->st,
+                          hash,st->hash->len,
+                          &m->sig)) {
        slog(st,LOG_SEC,"msg3/msg4 signature failed check!");
        free(hash);
        return False;
@@ -2189,12 +2187,12 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
     st->log=find_cl_if(dict,"log",CL_LOG,True,"site",loc);
     st->random=find_cl_if(dict,"random",CL_RANDOMSRC,True,"site",loc);
 
-    st->privkey=find_cl_if(dict,"local-key",CL_RSAPRIVKEY,True,"site",loc);
+    st->privkey=find_cl_if(dict,"local-key",CL_SIGPRIVKEY,True,"site",loc);
     st->addresses=dict_read_string_array(dict,"address",False,"site",loc,0);
     if (st->addresses)
        st->remoteport=dict_read_number(dict,"port",True,"site",loc,0);
     else st->remoteport=0;
-    st->pubkey=find_cl_if(dict,"key",CL_RSAPUBKEY,True,"site",loc);
+    st->pubkey=find_cl_if(dict,"key",CL_SIGPUBKEY,True,"site",loc);
 
     GET_CLOSURE_LIST("transform",transforms,ntransforms,CL_TRANSFORM);