chiark / gitweb /
secnet: Provide `make-public' verb
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 3 Dec 2019 22:57:25 +0000 (22:57 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 15 Feb 2020 21:56:51 +0000 (21:56 +0000)
This allows the config file to specify the use of the scheme loadpub
call without having to put public keys in separate files.  That will
be useful for testing and perhaps in installations that just want
fixed keys.

There is a bug here: we use system_log for reporting errors, but that
is not set up until after the configuration is read.  So errors turn
into segfaults.  We will fix that in a moment.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
README
modules.c
pubkeys.c
secnet.h

diff --git a/README b/README
index 1d29c551c4e5b78bdeaf47b36e5185e582466bab..e23701c9151dc4d946523914dbbf81b2a69251fa 100644 (file)
--- a/README
+++ b/README
@@ -577,6 +577,15 @@ priv-cache: dict argument
   privkey-max (integer): optional, maximum size of private key
     file in bytes. [4095]
 
+** pubkeys
+
+Defines:
+  make-public (closure => sigpubkey closure)
+
+make-public: (
+  arg1: sigscheme name
+  arg2: base91s encoded public key data, according to algorithm
+
 ** rsa
 
 Defines:
index de3e69933ca076f4ac44ade62708229f35fc9987..38f1d0fdd1fce7e434543a36c6d49a6f193dfd8d 100644 (file)
--- a/modules.c
+++ b/modules.c
@@ -21,6 +21,7 @@
 
 void init_builtin_modules(dict_t *dict)
 {
+    pubkeys_init(dict);
     resolver_module(dict);
     random_module(dict);
     udp_module(dict);
index 7ba948200f14d9f97b366184837ba632e0b0f2dc..903103f8399ae487f4f31ef92a6f26f5d9d30658 100644 (file)
--- a/pubkeys.c
+++ b/pubkeys.c
@@ -17,6 +17,8 @@
  * https://www.gnu.org/licenses/gpl.html.
  */
 
+#include "util.h"
+#include "base91s/base91.h"
 #include "pubkeys.h"
 #include "pubkeys.yy.h"
 
@@ -43,3 +45,54 @@ const struct sigscheme_info *sigscheme_lookup(const char *name)
            return scheme;
     return 0;
 }
+
+static list_t *makepublic_apply(closure_t *self, struct cloc loc,
+                               dict_t *context, list_t *args)
+{
+#define ARG(ix,vn,what)                                                        \
+    item_t *vn##_i=list_elem(args,ix);                                 \
+    if (!vn##_i) cfgfatal(loc,"make-public","need " what);             \
+    if (vn##_i->type!=t_string) cfgfatal(vn##_i->loc,"make-public",    \
+                                   what "must be string");             \
+    const char *vn=vn##_i->data.string
+
+    ARG(0,algname,"algorithm name");
+    ARG(1,b91d,"base91s-encoded public key");
+
+    const struct sigscheme_info *sch=sigscheme_lookup(algname);
+    if (!sch) cfgfatal(algname_i->loc,"make-public",
+                      "unknown algorithm `%s'",algname);
+
+    size_t b91l=strlen(b91d);
+    if (b91l > INT_MAX/4) cfgfatal(algname_i->loc,"make-public",
+                                     "base91s data unreasonably long");
+
+    struct buffer_if buf;
+    buffer_new(&buf,base91s_decode_maxlen(b91l));
+    BUF_ALLOC(&buf,"make-public data buf");
+    assert(buf.start == buf.base);
+    struct base91s b91;
+    base91s_init(&b91);
+    buf.size= base91s_decode(&b91,b91d,b91l,buf.start);
+    buf.size += base91s_decode_end(&b91,buf.start+buf.size);
+    assert(buf.size <= buf.alloclen);
+
+    struct sigpubkey_if *pubkey;
+    closure_t *cl;
+    bool_t ok=sch->loadpub(sch,&buf,&pubkey,&cl,system_log,loc);
+    if (!ok) cfgfatal(loc,"make-public","public key loading failed");
+
+    if (pubkey->sethash) {
+       struct hash_if *defhash=
+           find_cl_if(context,"hash",CL_HASH,True,"make-public",loc);
+       pubkey->sethash(pubkey->st,defhash);
+    }
+
+    BUF_FREE(&buf);
+    buffer_destroy(&buf);
+    return new_closure(cl);
+}
+
+void pubkeys_init(dict_t *dict) {
+    add_closure(dict,"make-public",makepublic_apply);
+}
index 057d399cfe1bf144d763637da43635a4ae0a132a..dbf33414e1220c6d1721c2c17ac35f025ea3f355 100644 (file)
--- a/secnet.h
+++ b/secnet.h
@@ -377,6 +377,7 @@ typedef void init_module(dict_t *dict);
 
 extern void init_builtin_modules(dict_t *dict);
 
+extern init_module pubkeys_init;
 extern init_module resolver_module;
 extern init_module random_module;
 extern init_module udp_module;