chiark / gitweb /
62f55259ef3efebd7ab9e1793155a72334582135
[secnet.git] / pubkeys.c
1 /*
2  * This file is part of secnet.
3  * See README for full list of copyright holders.
4  *
5  * secnet is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  * 
10  * secnet is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * version 3 along with secnet; if not, see
17  * https://www.gnu.org/licenses/gpl.html.
18  */
19
20 #include "util.h"
21 #include "base91s/base91.h"
22 #include "pubkeys.h"
23 #include "pubkeys.yy.h"
24
25 void keyset_dispose(struct peer_keyset **ks_io)
26 {
27     struct peer_keyset *ks=*ks_io;
28     if (!ks) return;
29     *ks_io=0;
30     ks->refcount--;
31     assert(ks->refcount>=0);
32     if (ks->refcount) return;
33     for (int ki=0; ki<ks->nkeys; ki++) {
34         struct sigpubkey_if *pk=ks->keys[ki].pubkey;
35         pk->dispose(pk->st);
36     }
37     free(ks);
38 }
39
40 const struct sigscheme_info *sigscheme_lookup(const char *name)
41 {
42     const struct sigscheme_info *scheme;
43     for (scheme=sigschemes; scheme->name; scheme++)
44         if (!strcmp(name,scheme->name))
45             return scheme;
46     return 0;
47 }
48
49 static list_t *makepublic_apply(closure_t *self, struct cloc loc,
50                                 dict_t *context, list_t *args)
51 {
52 #define ARG(ix,vn,what)                                                 \
53     item_t *vn##_i=list_elem(args,ix);                                  \
54     if (!vn##_i) cfgfatal(loc,"make-public","need " what);              \
55     if (vn##_i->type!=t_string) cfgfatal(vn##_i->loc,"make-public",     \
56                                     what "must be string");             \
57     const char *vn=vn##_i->data.string
58
59     ARG(0,algname,"algorithm name");
60     ARG(1,b91d,"base91s-encoded public key");
61
62     const struct sigscheme_info *sch=sigscheme_lookup(algname);
63     if (!sch) cfgfatal(algname_i->loc,"make-public",
64                        "unknown algorithm `%s'",algname);
65
66     size_t b91l=strlen(b91d);
67     if (b91l > INT_MAX/4) cfgfatal(algname_i->loc,"make-public",
68                                       "base91s data unreasonably long");
69
70     struct buffer_if buf;
71     buffer_new(&buf,base91s_decode_maxlen(b91l));
72     BUF_ALLOC(&buf,"make-public data buf");
73     assert(buf.start == buf.base);
74     struct base91s b91;
75     base91s_init(&b91);
76     buf.size= base91s_decode(&b91,b91d,b91l,buf.start);
77     buf.size += base91s_decode_end(&b91,buf.start+buf.size);
78     assert(buf.size <= buf.alloclen);
79
80     struct cfgfile_log log;
81     cfgfile_log_init(&log,loc,"make-public");
82
83     struct sigpubkey_if *pubkey;
84     closure_t *cl;
85     bool_t ok=sch->loadpub(sch,&buf,&pubkey,&cl,&log.log,loc);
86     if (!ok) cfgfatal(loc,"make-public","public key loading failed");
87
88     if (pubkey->sethash) {
89         struct hash_if *defhash=
90             find_cl_if(context,"hash",CL_HASH,True,"make-public",loc);
91         pubkey->sethash(pubkey->st,defhash);
92     }
93
94     BUF_FREE(&buf);
95     buffer_destroy(&buf);
96     return new_closure(cl);
97 }
98
99 void pubkeys_init(dict_t *dict) {
100     add_closure(dict,"make-public",makepublic_apply);
101 }