chiark / gitweb /
rsa: Provide rsa1_loadpub and therefore rsa1 sigscheme
[secnet.git] / rsa.c
diff --git a/rsa.c b/rsa.c
index c2e8e1b8932a9c6ff8651940104dd4391459e4ac..3f2fbd158cc4d07940c598d3fa0629c852ac3ac9 100644 (file)
--- a/rsa.c
+++ b/rsa.c
@@ -328,11 +328,13 @@ static void rsapub_dispose(void *sst) {
 #define RSAPUB_LOADCORE_DEFBN(ix,en,what) \
     const char *en##s, struct cloc en##_loc,
 
-#define LDPUBFATAL(enloc,...) \
-    cfgfatal(enloc, "rsa-public", __VA_ARGS__)
+#define LDPUBFATAL(lc,...) ({                  \
+       load_err(l,(lc),0,0,__VA_ARGS__);       \
+       goto error_out;                         \
+    })
 
 static struct rsapub *rsa_loadpub_core(RSAPUB_BNS(RSAPUB_LOADCORE_DEFBN)
-                                      struct cloc overall_loc)
+                                      struct load_ctx *l)
 {
     struct rsapub *st;
 
@@ -348,16 +350,16 @@ static struct rsapub *rsa_loadpub_core(RSAPUB_BNS(RSAPUB_LOADCORE_DEFBN)
     st->ops.check=rsa_sig_check;
     st->ops.hash=0;
     st->ops.dispose=rsapub_dispose;
-    st->loc=overall_loc;
+    st->loc=l->loc;
     RSAPUB_BNS(RSAPUB_INIT_ST_BN)
 
 #define RSAPUB_LOADCORE_GETBN(ix,en,what)                              \
     if (mpz_init_set_str(&st->en,en##s,10)!=0) {                       \
-       LDPUBFATAL(en##_loc, what " \"%s\" is not a "                   \
+       LDPUBFATAL(&en##_loc, what " \"%s\" is not a "                  \
                 "decimal number string\n",en##s);                      \
     }                                                                  \
     if (mpz_sizeinbase(&st->en, 256) > RSA_MAX_MODBYTES) {             \
-       LDPUBFATAL(en##_loc, "implausibly large " what "\n");           \
+       LDPUBFATAL(&en##_loc, "implausibly large " what "\n");          \
     }
 
     RSAPUB_BNS(RSAPUB_LOADCORE_GETBN)
@@ -372,6 +374,11 @@ static struct rsapub *rsa_loadpub_core(RSAPUB_BNS(RSAPUB_LOADCORE_DEFBN)
 static list_t *rsapub_apply(closure_t *self, struct cloc loc, dict_t *context,
                            list_t *args)
 {
+    struct load_ctx l[1];
+    l->verror=verror_cfgfatal;
+    l->postreadcheck=0;
+    l->what="rsa-public";
+    l->loc=loc;
 
 #define RSAPUB_APPLY_GETBN(ix,en,what)                         \
     item_t *en##i;                                             \
@@ -389,11 +396,51 @@ static list_t *rsapub_apply(closure_t *self, struct cloc loc, dict_t *context,
     RSAPUB_BNS(RSAPUB_APPLY_GETBN)
 
     struct rsapub *st=rsa_loadpub_core(RSAPUB_BNS(RSAPUB_LOADCORE_PASSBN)
-                                      loc);
+                                      l);
 
     return new_closure(&st->cl);
 }
 
+bool_t rsa1_loadpub(const struct sigscheme_info *algo,
+                   struct buffer_if *pubkeydata,
+                   struct sigpubkey_if **sigpub_r,
+                   struct log_if *log, struct cloc loc)
+{
+    struct rsapub *st=0;
+
+    struct load_ctx l[1];
+    l->verror=verror_tryload;
+    l->postreadcheck=0;
+    l->what="rsa1_loadpub";
+    l->loc=loc;
+    l->u.tryload.log=log;
+
+    char *nul=buf_append(pubkeydata,1);
+    if (!nul) LDPUBFATAL(0,"rsa1 public key data too long for extra nul");
+    *nul=0;
+
+    const char *delim=" \t\n";
+    char *saveptr;
+    /*unused*/ strtok_r(pubkeydata->start,delim,&saveptr);
+
+#define RSAPUB_TRYLOAD_GETBN(ix,en,what)                               \
+    struct cloc en##_loc=loc;                                          \
+    const char *en##s=strtok_r(0,delim,&saveptr);                      \
+    if (!en##s) LDPUBFATAL(0,"end of pubkey data looking for " what);
+
+    RSAPUB_BNS(RSAPUB_TRYLOAD_GETBN);
+
+    st=rsa_loadpub_core(RSAPUB_BNS(RSAPUB_LOADCORE_PASSBN) l);
+    if (!st) goto error_out;
+
+    *sigpub_r=&st->ops;
+    return True;
+
+ error_out:
+    rsapub_dispose(st);
+    return False;
+}
+
 #define LDFATAL(...)      ({ load_err(l,0,0,0,__VA_ARGS__); goto error_out; })
 #define LDUNSUP(...)      ({ load_err(l,0,0,1,__VA_ARGS__); goto error_out; })
 #define LDFATAL_FILE(...) ({ load_err(l,0,f,0,__VA_ARGS__); goto error_out; })
@@ -695,7 +742,7 @@ bool_t rsa1_loadpriv(const struct sigscheme_info *algo,
     goto out;
 
  error_out:
-    if (st) { free(st); st=0; }
+    FREE(st);
  out:
     if (f) fclose(f);
     if (!st) return False;