chiark / gitweb /
rsa: Provide rsa1_loadpub and therefore rsa1 sigscheme
[secnet.git] / rsa.c
diff --git a/rsa.c b/rsa.c
index 7d5024922c4829e9dd94361fd4d6b0ec81a53ad5..3f2fbd158cc4d07940c598d3fa0629c852ac3ac9 100644 (file)
--- a/rsa.c
+++ b/rsa.c
@@ -328,7 +328,10 @@ static void rsapub_dispose(void *sst) {
 #define RSAPUB_LOADCORE_DEFBN(ix,en,what) \
     const char *en##s, struct cloc en##_loc,
 
-#define LDPUBFATAL(lc,...) ({load_err(l,&lc,0,0,__VA_ARGS__); goto error_out;})
+#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 load_ctx *l)
@@ -352,11 +355,11 @@ static struct rsapub *rsa_loadpub_core(RSAPUB_BNS(RSAPUB_LOADCORE_DEFBN)
 
 #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)
@@ -398,6 +401,46 @@ static list_t *rsapub_apply(closure_t *self, struct cloc loc, dict_t *context,
     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; })
@@ -699,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;