chiark / gitweb /
17c6ed32426fa87a33eb5bdafcfc77b622346464
[udpkey] / udpkey.c
1 /* -*-c-*-
2  *
3  * Request a key over UDP, or respond to such a request
4  *
5  * (c) 2012 Mark Wooding
6  */
7
8 /*----- Licensing notice --------------------------------------------------*
9  *
10  * This file is part of udpkey.
11  *
12  * The udpkey program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * The udpkey program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with udpkey; if not, write to the Free Software Foundation,
24  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25  */
26
27 /*----- Header files ------------------------------------------------------*/
28
29 #include <ctype.h>
30 #include <errno.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <time.h>
35
36 #include <sys/types.h>
37 #include <sys/time.h>
38 #include <unistd.h>
39 #include <fcntl.h>
40
41 #include <syslog.h>
42
43 #include <sys/socket.h>
44 #include <arpa/inet.h>
45 #include <netinet/in.h>
46 #include <netdb.h>
47
48 #include <mLib/alloc.h>
49 #include <mLib/buf.h>
50 #include <mLib/daemonize.h>
51 #include <mLib/dstr.h>
52 #include <mLib/fdflags.h>
53 #include <mLib/fwatch.h>
54 #include <mLib/hex.h>
55 #include <mLib/mdwopt.h>
56 #include <mLib/quis.h>
57 #include <mLib/report.h>
58 #include <mLib/sub.h>
59 #include <mLib/tv.h>
60
61 #include <catacomb/buf.h>
62 #include <catacomb/ct.h>
63 #include <catacomb/dh.h>
64 #include <catacomb/ec.h>
65 #include <catacomb/ec-keys.h>
66 #include <catacomb/gcipher.h>
67 #include <catacomb/gmac.h>
68 #include <catacomb/group.h>
69 #include <catacomb/key.h>
70 #include <catacomb/mp.h>
71 #include <catacomb/mprand.h>
72 #include <catacomb/noise.h>
73 #include <catacomb/rand.h>
74
75 #include <catacomb/rijndael-counter.h>
76 #include <catacomb/sha256.h>
77
78 #ifdef DEBUG
79 #  define D(x) x
80 #else
81 #  define D(x)
82 #endif
83
84 /*---- Static variables ---------------------------------------------------*/
85
86 static unsigned flags = 0;
87 #define f_bogus 1u
88 #define f_listen 2u
89 #define f_daemon 4u
90 #define f_syslog 8u
91
92 #define BUFSZ 65536
93 static unsigned char ibuf[BUFSZ], obuf[BUFSZ];
94
95 static key_file *kf;
96 static const char *kfname = "keyring";
97 static const char *pidfile;
98 static fwatch kfwatch;
99 static unsigned nq;
100
101 /*----- Miscellaneous utilities -------------------------------------------*/
102
103 /* Resolve NAME, storing the address in *ADDR.  Exit on error. */
104 static void resolve(const char *name, struct in_addr *addr)
105 {
106   struct hostent *h;
107
108   if ((h = gethostbyname(name)) == 0)
109     die(1, "failed to resolve `%s': %s", name, hstrerror(h_errno));
110   if (h->h_addrtype != AF_INET)
111     die(1, "unexpected address type %d", h->h_addrtype);
112   memcpy(addr, h->h_addr, sizeof(struct in_addr));
113 }
114
115 /* Convert PORT to a port number (in host byte order).  Exit on error. */
116 static unsigned short getport(const char *port)
117 {
118   unsigned long i = 0;
119   char *q;
120   int e = errno;
121
122   errno = 0;
123   if (!isdigit(*port) ||
124       (i = strtoul(port, &q, 0)) == 0 ||
125       i >= 65536 || *q || errno)
126     die(1, "invalid port number `%s'", port);
127   errno = e;
128   return ((unsigned short)i);
129 }
130
131 /* Read the file named by NAME into a buffer -- or at least an initial
132  * portion of it; set *P to the start and *SZ to the length.  Return -1 if it
133  * didn't work.  The buffer doesn't need to be freed: the data is stashed in
134  * ibuf.
135  */
136 static int snarf(const char *name, void **p, size_t *sz)
137 {
138   ssize_t n;
139   int fd;
140
141   if ((fd = open(name, O_RDONLY)) < 0) return (-1);
142   n = read(fd, ibuf, sizeof(ibuf));
143   close(fd);
144   if (n < 0) return (-1);
145   *p = ibuf; *sz = n;
146   return (0);
147 }
148
149 /* Complain about something.  If f_syslog is set then complain to that;
150  * otherwise write to stderr.  Don't use `%m' because that won't work when
151  * writing to stderr.
152  */
153 static void complain(int sev, const char *msg, ...)
154 {
155   va_list ap;
156
157   va_start(ap, msg);
158   if (flags & f_syslog)
159     vsyslog(sev, msg, ap);
160   else {
161     fprintf(stderr, "%s: ", QUIS);
162     vfprintf(stderr, msg, ap);
163     fputc('\n', stderr);
164   }
165 }
166
167 /*----- Reading key data --------------------------------------------------*/
168
169 struct kinfo {
170   group *g;
171   ge *X;
172   mp *x;
173   const gccipher *cc;
174   const gcmac *mc; size_t tagsz;
175   const gchash *hc;
176 };
177
178 /* Clear a kinfo structure so it can be freed without trouble. */
179 static void k_init(struct kinfo *k) { k->g = 0; k->x = 0; k->X = 0; }
180
181 /* Free a kinfo structure. This is safe on any initialized kinfo
182  * structure.
183  */
184 static void k_free(struct kinfo *k)
185 {
186   if (k->X) { G_DESTROY(k->g, k->X); k->X = 0; }
187   if (k->x) { MP_DROP(k->x); k->x = 0; }
188   if (k->g) { G_DESTROYGROUP(k->g); k->g = 0; }
189 }
190
191 /* Empty macro arguments are forbidden.  But arguments are expended during
192  * replacement, not while the call is being processed, so this hack is OK.
193  * Unfortunately, if a potentially empty argument is passed on to another
194  * macro then it needs to be guarded with a use of EMPTY too...
195  */
196 #define EMPTY
197
198 /* Table of key types.  Entries have the form
199  *
200  *      _(name, NAME, SETGROUP, SETPRIV, SETPUB)
201  *
202  * The name and NAME are lower- and uppercase names for the type used for
203  * constructing various type name constant names.  The code fragment SETGROUP
204  * initializes k->g given the name_{pub,priv} structure in p; SETPRIV and
205  * SETPUB set up k->x and k->X respectively.  (In this last case, k->X will
206  * have been created as a group element already.)
207  */
208 #define KEYTYPES(_)                                                     \
209                                                                         \
210   _(dh, DH,                                                             \
211     { k->g = group_prime(&p.dp); },                                     \
212     { k->x = MP_COPY(p.x); },                                           \
213     { if (G_FROMINT(k->g, k->X, p.y)) {                                 \
214         complain(LOG_ERR, "bad public key in `%s'", t->buf);            \
215         goto fail;                                                      \
216       }                                                                 \
217     })                                                                  \
218                                                                         \
219   _(ec, EC,                                                             \
220     { ec_info ei; const char *e;                                        \
221       if ((e = ec_getinfo(&ei, p.cstr)) != 0) {                         \
222         complain(LOG_ERR, "bad elliptic curve in `%s': %s", t->buf, e); \
223         goto fail;                                                      \
224       }                                                                 \
225       k->g = group_ec(&ei);                                             \
226     },                                                                  \
227     { k->x = MP_COPY(p.x); },                                           \
228     { if (G_FROMEC(k->g, k->X, &p.p)) {                                 \
229         complain(LOG_ERR, "bad public point in `%s'", t->buf);          \
230         goto fail;                                                      \
231       }                                                                 \
232     })
233
234 /* Define load_tywhich, where which is `pub' or `priv', to load a public or
235  * private key.  Other parameters are as for the KEYTYPES list above.
236  */
237 #define KLOAD(ty, TY, which, WHICH, setgroup, setpriv, setpub)          \
238 static int load_##ty##which(key_data *kd, struct kinfo *k, dstr *t)     \
239 {                                                                       \
240   key_packstruct kps[TY##_##WHICH##FETCHSZ];                            \
241   key_packdef *kp;                                                      \
242   ty##_##which p;                                                       \
243   int rc;                                                               \
244                                                                         \
245   /* Extract the key data from the keydata. */                          \
246   kp = key_fetchinit(ty##_##which##fetch, kps, &p);                     \
247   if ((rc = key_unpack(kp, kd, t)) != 0) {                              \
248     complain(LOG_ERR, "failed to unpack key `%s': %s",                  \
249              t->buf, key_strerror(rc));                                 \
250     goto fail;                                                          \
251   }                                                                     \
252                                                                         \
253   /* Extract the components as abstract group elements. */              \
254   setgroup;                                                             \
255   setpriv;                                                              \
256   k->X = G_CREATE(k->g);                                                \
257   setpub;                                                               \
258                                                                         \
259   /* Dispose of stuff we don't need. */                                 \
260   key_fetchdone(kp);                                                    \
261   return (0);                                                           \
262                                                                         \
263   /* Tidy up after mishaps. */                                          \
264 fail:                                                                   \
265   k_free(k);                                                            \
266   key_fetchdone(kp);                                                    \
267   return (-1);                                                          \
268 }
269
270 /* Map over the KEYTYPES to declare the load_tywhich functions using KLOAD
271  * above.
272  */
273 #define KEYTYPE_KLOAD(ty, TY, setgroup, setpriv, setpub)                \
274   KLOAD(ty, TY, priv, PRIV, setgroup, setpriv,                          \
275         { G_EXP(k->g, k->X, k->g->g, k->x); })                          \
276   KLOAD(ty, TY, pub, PUB, setgroup, { }, setpub)
277 KEYTYPES(KEYTYPE_KLOAD)
278
279 /* Define a table of group key-loading operations. */
280 struct kload_ops {
281   const char *name;
282   int (*loadpriv)(key_data *, struct kinfo *, dstr *);
283   int (*loadpub)(key_data *, struct kinfo *, dstr *);
284 };
285
286 static const struct kload_ops kload_ops[] = {
287 #define KEYTYPE_OPS(ty, TY, setgroup, setpriv, setpub)                  \
288   { #ty, load_##ty##priv, load_##ty##pub },
289 KEYTYPES(KEYTYPE_OPS)
290   { 0 }
291 };
292
293 /* Load a private or public (indicated by PRIVP) key named TAG into a kinfo
294  * structure K.  Also fill in the cipher suite selections extracted from the
295  * key attributes.
296  */
297 static int loadkey(const char *tag, struct kinfo *k, int privp)
298 {
299   const struct kload_ops *ops;
300   dstr d = DSTR_INIT, dd = DSTR_INIT;
301   key *ky;
302   key_data **kd;
303   const char *ty, *p;
304   char *q;
305   int tsz;
306   int rc;
307
308   /* Find the key data. */
309   if (key_qtag(kf, tag, &d, &ky, &kd)) {
310     complain(LOG_ERR, "unknown key tag `%s'", tag);
311     goto fail;
312   }
313
314   /* Find the key's group type and locate the group operations. */
315   ty = key_getattr(kf, ky, "group");
316   if (!ty && strncmp(ky->type, "udpkey-", 7) == 0) ty = ky->type + 7;
317   if (!ty) {
318     complain(LOG_ERR, "no group type for key %s", d.buf);
319     goto fail;
320   }
321   for (ops = kload_ops; ops->name; ops++) {
322     if (strcmp(ty, ops->name) == 0)
323       goto found;
324   }
325   complain(LOG_ERR, "unknown group type `%s' in key %s", ty, d.buf);
326   goto fail;
327
328 found:
329   /* Extract the key data into an appropriately abstract form. */
330   k->g = 0; k->x = 0; k->X = 0;
331   if ((rc = (privp ? ops->loadpriv : ops->loadpub)(*kd, k, &d)) != 0)
332     goto fail;
333
334   /* Extract the chosen symmetric cipher. */
335   if ((p = key_getattr(kf, ky, "cipher")) == 0)
336     k->cc = &rijndael_counter;
337   else if ((k->cc = gcipher_byname(p)) == 0) {
338     complain(LOG_ERR, "unknown cipher `%s' in key %s", p, d.buf);
339     goto fail;
340   }
341
342   /* And the chosen hash function. */
343   if ((p = key_getattr(kf, ky, "hash")) == 0)
344     k->hc = &sha256;
345   else if ((k->hc = ghash_byname(p)) == 0) {
346     complain(LOG_ERR, "unknown hash `%s' in key %s", p, d.buf);
347     goto fail;
348   }
349
350   /* And finally a MAC.  This is more fiddly because we must handle (a)
351    * truncation and (b) defaulting based on the hash.
352    */
353   if ((p = key_getattr(kf, ky, "mac")) == 0)
354     dstr_putf(&dd, "%s-hmac", k->hc->name);
355   else
356     dstr_puts(&dd, p);
357   if ((q = strchr(dd.buf, '/')) != 0) *q++ = 0;
358   else q = 0;
359   if ((k->mc = gmac_byname(dd.buf)) == 0) {
360     complain(LOG_ERR, "unknown mac `%s' in key %s", dd.buf, d.buf);
361     goto fail;
362   }
363   if (!q)
364     k->tagsz = k->mc->hashsz/2;
365   else {
366     tsz = atoi(q);
367     if (tsz <= 0 || tsz%8 || tsz/8 > k->mc->hashsz) {
368       complain(LOG_ERR, "bad tag size `%s' for mac `%s' in key %s",
369                q, k->mc->name, d.buf);
370       goto fail;
371     }
372     k->tagsz = tsz/8;
373   }
374
375   /* Done. */
376   rc = 0;
377   goto done;
378
379 fail:
380   rc = -1;
381 done:
382   dstr_destroy(&d);
383   dstr_destroy(&dd);
384   return (rc);
385 }
386
387 static void keymoan(const char *file, int line, const char *err, void *p)
388   { complain(LOG_ERR, "%s:%d: %s", file, line, err); }
389
390 /* Update the keyring `kf' if the file has been changed since we last looked.
391  */
392 static void kfupdate(void)
393 {
394   key_file *kfnew;
395
396   if (!fwatch_update(&kfwatch, kfname)) return;
397   kfnew = CREATE(key_file);
398   if (key_open(kfnew, kfname, KOPEN_READ, keymoan, 0)) {
399     DESTROY(kfnew);
400     return;
401   }
402   key_close(kf);
403   DESTROY(kf);
404   kf = kfnew;
405 }
406
407 /*----- Low-level crypto operations ---------------------------------------*/
408
409 /* Derive a key, writing its address to *KK and size to *N.  The size is
410  * compatible with the keysz rules KSZ.  It is generated for the purpose of
411  * keying a WHAT (used for key separation and in error messages), and NAME is
412  * the name of the specific instance (e.g., `twofish-counter') from the class
413  * name.  The kinfo structure K tells us which algorithms to use for the
414  * derivation.  The group elements U and Z are the cryptographic inputs
415  * for the derivation.
416  *
417  * Basically all we do is compute H(what || U || Z).
418  */
419 static int derive(struct kinfo *k, ge *U, ge *Z,
420                   const char *what, const char *name, const octet *ksz,
421                   octet **kk, size_t *n)
422 {
423   buf b;
424   ghash *h;
425   octet *p;
426
427   /* Find a suitable key size. */
428   if ((*n = keysz(k->hc->hashsz, ksz)) == 0) {
429     complain(LOG_ERR,
430              "failed to find suitable key size for %s `%s' and hash `%s'",
431              what, name, k->hc->name);
432     return (-1);
433   }
434
435   /* Build the hash preimage. */
436   buf_init(&b, obuf, sizeof(obuf));
437   buf_put(&b, "udpkey-", 7);
438   buf_putstrz(&b, what);
439   G_TORAW(k->g, &b, U);
440   G_TORAW(k->g, &b, Z);
441   if (BBAD(&b)) {
442     complain(LOG_ERR, "overflow while deriving key (prepare preimage)!");
443     return (-1);
444   }
445
446   /* Derive the output key. */
447   h = GH_INIT(k->hc);
448   GH_HASH(h, BBASE(&b), BLEN(&b));
449   buf_init(&b, obuf, sizeof(obuf));
450   if ((p = buf_get(&b, h->ops->c->hashsz)) == 0) {
451     complain(LOG_ERR, "overflow while deriving key (output hash)!");
452     GH_DESTROY(h);
453     return (-1);
454   }
455   GH_DONE(h, p);
456   GH_DESTROY(h);
457   *kk = p;
458   return (0);
459 }
460
461 #ifdef DEBUG
462 static void debug_mp(const char *what, mp *x)
463   { fprintf(stderr, "%s: *** ", QUIS); MP_EPRINT(what, x); }
464 static void debug_ge(const char *what, group *g, ge *X)
465 {
466   fprintf(stderr, "%s: *** %s = ", QUIS, what);
467   group_writefile(g, X, stderr);
468   fputc('\n', stderr);
469 }
470 #endif
471
472 /*----- Listening for requests --------------------------------------------*/
473
474 /* Rate limiting parameters.
475  *
476  * There's a probabilistic rate-limiting mechanism.  A counter starts at 0.
477  * Every time we oricess a request, we increment the counter.  The counter
478  * drops by RATE_REFILL every second.  If the counter is below RATE_CREDIT
479  * then the request is processed; otherwise it is processed with probability
480  * 1/(counter - RATE_CREDIT).
481  */
482 #define RATE_REFILL 10                  /* Credits per second. */
483 #define RATE_CREDIT 1000                /* Initial credit. */
484
485 static int dolisten(int argc, char *argv[])
486 {
487   int sk;
488   char *p, *q, ch;
489   const char *pp;
490   char *aspec;
491   ssize_t n;
492   size_t sz;
493   fd_set fdin;
494   struct sockaddr_in sin;
495   struct in_addr in;
496   int mlen;
497   socklen_t len;
498   buf bin, bout;
499   dstr d = DSTR_INIT, dd = DSTR_INIT;
500   FILE *fp = 0;
501   key *ky;
502   key_data **kkd;
503   mp *r = MP_NEW, *v = MP_NEW;
504   ge *R = 0, *U = 0, *V = 0, *W = 0, *Y = 0, *Z = 0;
505   ghash *h = 0;
506   gmac *m = 0;
507   gcipher *c = 0;
508   octet *kk, *t, *tt;
509   size_t ksz;
510   struct kinfo k;
511   unsigned bucket = 0, toks;
512   time_t last = 0, now;
513
514   /* Set up the socket address. */
515   sin.sin_family = AF_INET;
516   aspec = xstrdup(argv[0]);
517   if ((p = strchr(aspec, ':')) == 0) {
518     p = aspec;
519     sin.sin_addr.s_addr = INADDR_ANY;
520   } else {
521     *p++ = 0;
522     resolve(aspec, &sin.sin_addr);
523   }
524   sin.sin_port = htons(getport(p));
525
526   /* Create and set up the socket itself. */
527   if ((sk = socket(PF_INET, SOCK_DGRAM, 0)) < 0 ||
528       fdflags(sk, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC) ||
529       bind(sk, (struct sockaddr *)&sin, sizeof(sin)))
530     die(1, "failed to create socket: %s", strerror(errno));
531
532   /* That's enough initialization.  If we should fork, then do that. */
533   if (flags & f_daemon) {
534     if (pidfile && (fp = fopen(pidfile, "w")) == 0)
535       die(1, "failed to open pidfile `%s': %s", pidfile, strerror(errno));
536     openlog(QUIS, LOG_PID, LOG_DAEMON);
537     if (daemonize())
538       die(1, "failed to become background process: %s", strerror(errno));
539     if (pidfile) { fprintf(fp, "%ld\n", (long)getpid()); fclose(fp); }
540     flags |= f_syslog;
541   }
542
543   for (;;) {
544
545     /* Clear out the key state. */
546     k_init(&k);
547
548     /* Wait for something to happen. */
549     FD_ZERO(&fdin);
550     FD_SET(sk, &fdin);
551     if (select(sk + 1, &fdin, 0, 0, 0) < 0)
552       die(1, "select failed: %s", strerror(errno));
553     noise_timer(RAND_GLOBAL);
554
555     /* Fetch a packet. */
556     len = sizeof(sin);
557     n = recvfrom(sk, ibuf, sizeof(ibuf), 0, (struct sockaddr *)&sin, &len);
558     if (n < 0) {
559       if (errno != EAGAIN && errno != EINTR)
560         complain(LOG_ERR, "unexpected receive error: %s", strerror(errno));
561       goto again;
562     }
563
564     /* Refill the bucket, and see whether we should reject this packet. */
565     now = time(0);
566     if (bucket && now != last) {
567       toks = (now - last)*RATE_REFILL;
568       bucket = bucket < toks ? 0 : bucket - toks;
569     }
570     last = now;
571     if (bucket > RATE_CREDIT &&
572         grand_range(&rand_global, bucket - RATE_CREDIT))
573       goto again;
574     bucket++;
575
576     /* Set up the input buffer for parsing the request. */
577     buf_init(&bin, ibuf, n);
578
579     /* Extract the key tag name. */
580     if ((p = buf_getmemz(&bin, &sz)) == 0) {
581       complain(LOG_WARNING, "invalid key tag from %s:%d",
582                inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
583       goto again;
584     }
585
586     /* Find the key. */
587     kfupdate();
588     if (key_qtag(kf, p, &d, &ky, &kkd)) {
589       complain(LOG_WARNING, "unknown key tag `%s' from %s:%d",
590                p, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
591       goto again;
592     }
593
594     /* And make sure that it has the right shape. */
595     if ((ky->k->e & KF_ENCMASK) != KENC_BINARY) {
596       complain(LOG_ERR, "key %s is not plain binary data", d.buf);
597       goto again;
598     }
599
600     /* Find the list of clients, and look up the caller's address in the
601      * list.  Entries have the form ADDRESS[/LEN][=TAG] and are separated by
602      * `;'.
603      */
604     if ((pp = key_getattr(kf, ky, "clients")) == 0) {
605       complain(LOG_WARNING,
606                "key %s requested from %s:%d has no `clients' attribute",
607                d.buf, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
608       goto again;
609     }
610     dstr_puts(&dd, pp);
611     p = dd.buf;
612     while (*p) {
613       q = p;
614       while (isdigit((unsigned char)*q) || *q == '.') q++;
615       ch = *q; *q++ = 0;
616       if (!inet_aton(p, &in)) goto skip;
617       if (ch != '/')
618         mlen = 32;
619       else {
620         p = q;
621         while (isdigit((unsigned char)*q)) q++;
622         ch = *q; *q++ = 0;
623         mlen = atoi(p);
624       }
625       if (((sin.sin_addr.s_addr ^ in.s_addr) &
626            (0xffffffff << (32 - mlen))) == 0)
627         goto match;
628     skip:
629       if (!ch) break;
630       p = q;
631       while (*p && *p != ';') p++;
632       if (*p) p++;
633     }
634     complain(LOG_WARNING, "access to key %s denied to %s:%d",
635              d.buf, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
636     goto again;
637
638   match:
639     /* Build a tag name for the caller's KEM key, either from the client
640      * match or the source address.
641      */
642     if (ch != '=') {
643       DRESET(&dd);
644       dstr_puts(&dd, "client-");
645       dstr_puts(&dd, inet_ntoa(sin.sin_addr));
646       p = dd.buf;
647     } else {
648       p = q;
649       while (*q && *q != ';') q++;
650       if (*q == ';') *q++ = 0;
651     }
652
653     /* Report the match. */
654     complain(LOG_NOTICE, "client %s:%d (`%s') requests key %s",
655              inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), p, d.buf);
656
657     /* Load the KEM key. */
658     if (loadkey(p, &k, 0)) goto again;
659     D( debug_ge("X", k.g, k.X); )
660
661     /* Read the caller's ephemeral key. */
662     R = G_CREATE(k.g); W = G_CREATE(k.g);
663     U = G_CREATE(k.g); V = G_CREATE(k.g);
664     Y = G_CREATE(k.g); Z = G_CREATE(k.g);
665     if (G_FROMBUF(k.g, &bin, U)) {
666       complain(LOG_WARNING, "failed to read ephemeral vector from %s:%d",
667                inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
668       goto again;
669     }
670     D( debug_ge("U", k.g, U); )
671     if (BLEFT(&bin)) {
672       complain(LOG_WARNING, "trailing junk in request from %s:%d",
673                inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
674       goto again;
675     }
676
677     /* Ephemeral Diffie--Hellman.  Choose v in GF(q) at random; compute
678      * V = v P and -Y = (-v) U.
679      */
680     v = mprand_range(v, k.g->r, &rand_global, 0);
681     G_EXP(k.g, V, k.g->g, v);
682     D( debug_mp("v", v); debug_ge("V", k.g, V); )
683     v = mp_sub(v, k.g->r, v);
684     G_EXP(k.g, Y, U, v);
685     D( debug_ge("-Y", k.g, Y); )
686
687     /* DLIES.  Choose r in GF(q) at random; compute R = r P and Z = r X.
688      * Mask the clue R as W = R - Y.  (Doing the subtraction here makes life
689      * easier at the other end, since we can determine -Y by negating v
690      * whereas the recipient must subtract vectors which may be less
691      * efficient.)
692      */
693     r = mprand_range(r, k.g->r, &rand_global, 0);
694     G_EXP(k.g, R, k.g->g, r);
695     D( debug_mp("r", r); debug_ge("R", k.g, R); )
696     G_EXP(k.g, Z, k.X, r);
697     G_MUL(k.g, W, R, Y);
698     D( debug_ge("Z", k.g, Z); debug_ge("W", k.g, W); )
699
700     /* Derive encryption and integrity keys. */
701     derive(&k, R, Z, "cipher", k.cc->name, k.cc->keysz, &kk, &ksz);
702     c = GC_INIT(k.cc, kk, ksz);
703     derive(&k, R, Z, "mac", k.mc->name, k.mc->keysz, &kk, &ksz);
704     m = GM_KEY(k.mc, kk, ksz);
705
706     /* Build the ciphertext and compute a MAC tag over it. */
707     buf_init(&bout, obuf, sizeof(obuf));
708     if (G_TOBUF(k.g, &bout, V) ||
709         G_TOBUF(k.g, &bout, W))
710       goto bad;
711     if ((t = buf_get(&bout, k.tagsz)) == 0) goto bad;
712     sz = ky->k->u.k.sz;
713     if (BENSURE(&bout, sz)) goto bad;
714     GC_ENCRYPT(c, ky->k->u.k.k, BCUR(&bout), sz);
715     h = GM_INIT(m);
716     GH_HASH(h, BCUR(&bout), sz);
717     tt = GH_DONE(h, 0); memcpy(t, tt, k.tagsz);
718     BSTEP(&bout, sz);
719
720     /* Send the reply packet back to the caller. */
721     if (sendto(sk, BBASE(&bout), BLEN(&bout), 0,
722                (struct sockaddr *)&sin, len) < 0) {
723       complain(LOG_ERR, "failed to send response to %s:%d: %s",
724                inet_ntoa(sin.sin_addr), ntohs(sin.sin_port),
725                strerror(errno));
726       goto again;
727     }
728
729     goto again;
730
731   bad:
732     /* Report a problem building the reply. */
733     complain(LOG_ERR, "failed to construct response to %s:%d",
734              inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
735
736   again:
737     /* Free stuff for the next iteration. */
738     DRESET(&d); DRESET(&dd);
739     if (R) { G_DESTROY(k.g, R); R = 0; }
740     if (U) { G_DESTROY(k.g, U); U = 0; }
741     if (V) { G_DESTROY(k.g, V); V = 0; }
742     if (W) { G_DESTROY(k.g, W); W = 0; }
743     if (Y) { G_DESTROY(k.g, Y); Y = 0; }
744     if (Z) { G_DESTROY(k.g, Z); Z = 0; }
745     if (c) { GC_DESTROY(c); c = 0; }
746     if (m) { GM_DESTROY(m); m = 0; }
747     if (h) { GH_DESTROY(h); h = 0; }
748     k_free(&k);
749   }
750
751   return (-1);
752 }
753
754 /*----- Sending requests and processing responses -------------------------*/
755
756 struct query {
757   struct query *next;
758   octet *k;
759   size_t sz;
760   struct server *s;
761 };
762
763 struct server {
764   struct server *next;
765   struct sockaddr_in sin;
766   struct kinfo k;
767   mp *u;
768   ge *U;
769   octet *h;
770 };
771
772 /* Record a successful fetch of key material for a query Q.  The data starts
773  * at K and is SZ bytes long.  The data is copied: it's safe to overwrite it.
774  */
775 static void donequery(struct query *q, const void *k, size_t sz)
776   { q->k = xmalloc(sz); memcpy(q->k, k, sz); q->sz = sz; nq--; }
777
778 /* Initialize a query to a remote server. */
779 static struct query *qinit_net(const char *tag, const char *spec)
780 {
781   struct query *q;
782   struct server *s, **stail;
783   dstr d = DSTR_INIT, dd = DSTR_INIT;
784   hex_ctx hc;
785   char *p, *pp, ch;
786
787   /* Allocate the query block. */
788   q = CREATE(struct query);
789   stail = &q->s;
790
791   /* Put the spec somewhere we can hack at it. */
792   dstr_puts(&d, spec);
793   p = d.buf;
794
795   /* Parse the query spec.  Entries have the form ADDRESS:PORT[=TAG][#HASH]
796    * and are separated by `;'.
797    */
798   while (*p) {
799
800     /* Allocate a new server node. */
801     s = CREATE(struct server);
802     s->sin.sin_family = AF_INET;
803
804     /* Extract the server address. */
805     if ((pp = strchr(p, ':')) == 0)
806       die(1, "invalid syntax: missing `:PORT'");
807     *pp++ = 0;
808     resolve(p, &s->sin.sin_addr);
809
810     /* Extract the port number. */
811     p = pp;
812     while (isdigit((unsigned char)*pp)) pp++;
813     ch = *pp; *pp++ = 0;
814     s->sin.sin_port = htons(getport(p));
815
816     /* If there's a key tag then extract that; otherwise use a default. */
817     if (ch != '=')
818       p = "udpkey-kem";
819     else {
820       p = pp;
821       pp += strcspn(pp, ";#");
822       ch = *pp; *pp++ = 0;
823     }
824     if (loadkey(p, &s->k, 1)) exit(1);
825     D( debug_mp("x", s->k.x); debug_ge("X", s->k.g, s->k.X); )
826
827     /* Choose an ephemeral private key u.  Let x be our private key.  We
828      * compute U = u P and transmit this.
829      */
830     s->u = mprand_range(MP_NEW, s->k.g->r, &rand_global, 0);
831     s->U = G_CREATE(s->k.g);
832     G_EXP(s->k.g, s->U, s->k.g->g, s->u);
833     D( debug_mp("u", s->u); debug_ge("U", s->k.g, s->U); )
834
835     /* Link the server on. */
836     *stail = s; stail = &s->next;
837
838     /* If there's a trailing hash then extract it. */
839     if (ch != '#')
840       s->h = 0;
841     else {
842       p = pp;
843       while (*pp == '-' || isxdigit((unsigned char)*pp)) pp++;
844       hex_init(&hc);
845       DRESET(&dd);
846       hex_decode(&hc, p, pp - p, &dd);
847       if (dd.len != s->k.hc->hashsz) die(1, "incorrect hash length");
848       s->h = xmalloc(dd.len);
849       memcpy(s->h, dd.buf, dd.len);
850       ch = *pp++;
851     }
852
853     /* If there are more servers, then continue parsing. */
854     if (!ch) break;
855     else if (ch != ';') die(1, "invalid syntax: expected `;'");
856     p = pp;
857   }
858
859   /* Terminate the server list and return. */
860   *stail = 0;
861   q->k = 0;
862   dstr_destroy(&d);
863   dstr_destroy(&dd);
864   return (q);
865 }
866
867 /* Handle a `query' to a local file. */
868 static struct query *qinit_file(const char *tag, const char *file)
869 {
870   struct query *q;
871   void *k;
872   size_t sz;
873
874   /* Snarf the file. */
875   q = CREATE(struct query);
876   if (snarf(file, &k, &sz))
877     die(1, "failed to read `%s': %s", file, strerror(errno));
878   q->s = 0;
879   donequery(q, k, sz);
880   return (q);
881 }
882
883 /* Reransmission and timeout parameters. */
884 #define TO_NEXT(t) (((t) + 2)*4/3)      /* Timeout growth function */
885 #define TO_MAX 30                       /* When to give up */
886
887 static int doquery(int argc, char *argv[])
888 {
889   struct query *q = 0, *qq, **qtail = &qq;
890   struct server *s = 0;
891   const char *tag = argv[0];
892   octet *p;
893   int i;
894   int sk;
895   fd_set fdin;
896   struct timeval now, when, tv;
897   struct sockaddr_in sin;
898   ge *R, *V = 0, *W = 0, *Y = 0, *Z = 0;
899   octet *kk, *t, *tt;
900   gcipher *c = 0;
901   gmac *m = 0;
902   ghash *h = 0;
903   socklen_t len;
904   unsigned next = 0;
905   buf bin, bout;
906   size_t n, j, ksz;
907   ssize_t nn;
908
909   /* Create a socket.  We just use the one socket for everything.  We don't
910    * care which port we get allocated.
911    */
912   if ((sk = socket(PF_INET, SOCK_DGRAM, 0)) < 0 ||
913       fdflags(sk, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC))
914     die(1, "failed to create socket: %s", strerror(errno));
915
916   /* Parse the query target specifications.  The adjustments of `nq' aren't
917    * in the right order but that doesn't matter.
918    */
919   for (i = 1; i < argc; i++) {
920     if (*argv[i] == '.' || *argv[i] == '/') q = qinit_file(tag, argv[i]);
921     else if (strchr(argv[i], ':')) q = qinit_net(tag, argv[i]);
922     else die(1, "unrecognized query target `%s'", argv[i]);
923     *qtail = q; qtail = &q->next; nq++;
924   }
925   *qtail = 0;
926
927   /* Find the current time so we can compute retransmission times properly.
928    */
929   gettimeofday(&now, 0);
930   when = now;
931
932   /* Continue retransmitting until we have all the answers. */
933   while (nq) {
934
935     /* Work out when we next want to wake up. */
936     if (TV_CMP(&now, >=, &when)) {
937       do {
938         if (next >= TO_MAX) die(1, "no responses: giving up");
939         next = TO_NEXT(next);
940         TV_ADDL(&when, &when, next, 0);
941       } while (TV_CMP(&when, <=, &now));
942       for (q = qq; q; q = q->next) {
943         if (q->k) continue;
944         for (s = q->s; s; s = s->next) {
945           buf_init(&bout, obuf, sizeof(obuf));
946           buf_putstrz(&bout, tag);
947           G_TOBUF(s->k.g, &bout, s->U);
948           if (BBAD(&bout)) {
949             moan("overflow while constructing request!");
950             continue;
951           }
952           sendto(sk, BBASE(&bout), BLEN(&bout), 0,
953                  (struct sockaddr *)&s->sin, sizeof(s->sin));
954         }
955       }
956     }
957
958     /* Wait until something interesting happens. */
959     FD_ZERO(&fdin);
960     FD_SET(sk, &fdin);
961     TV_SUB(&tv, &when, &now);
962     if (select(sk + 1, &fdin, 0, 0, &tv) < 0)
963       die(1, "select failed: %s", strerror(errno));
964     gettimeofday(&now, 0);
965
966     /* If we have an input event, process incoming packets. */
967     if (FD_ISSET(sk, &fdin)) {
968       for (;;) {
969
970         /* Read a packet and capture its address. */
971         len = sizeof(sin);
972         nn = recvfrom(sk, ibuf, sizeof(ibuf), 0,
973                       (struct sockaddr *)&sin, &len);
974         if (nn < 0) {
975           if (errno == EAGAIN) break;
976           else if (errno == EINTR) continue;
977           else {
978             moan("error receiving reply: %s", strerror(errno));
979             goto again;
980           }
981         }
982
983         /* Wee whether this corresponds to any of our servers.  Don't just
984          * check the active servers, since this may be late replies caused by
985          * retransmissions or similar.
986          */
987         for (q = qq; q; q = q->next) {
988           for (s = q->s; s; s = s->next) {
989             if (s->sin.sin_addr.s_addr == sin.sin_addr.s_addr &&
990                 s->sin.sin_port == sin.sin_port)
991               goto found;
992           }
993         }
994         moan("received reply from unexpected source %s:%d",
995              inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
996         goto again;
997
998       found:
999         /* If the query we found has now been satisfied, ignore this packet.
1000          */
1001         if (q->k) goto again;
1002
1003         /* Start parsing the reply. */
1004         buf_init(&bin, ibuf, nn);
1005         R = G_CREATE(s->k.g);
1006         V = G_CREATE(s->k.g); W = G_CREATE(s->k.g);
1007         Y = G_CREATE(s->k.g); Z = G_CREATE(s->k.g);
1008         if (G_FROMBUF(s->k.g, &bin, V)) {
1009           moan("invalid Diffie--Hellman vector from %s:%d",
1010                inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
1011           goto again;
1012         }
1013         if (G_FROMBUF(s->k.g, &bin, W)) {
1014           moan("invalid clue vector from %s:%d",
1015                inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
1016           goto again;
1017         }
1018         D( debug_ge("V", s->k.g, V); debug_ge("W", s->k.g, W); )
1019
1020         /* We have V and W from the server; determine Y = u V, R = W + Y and
1021          * Z = x R, and then derive the symmetric keys.
1022          */
1023         G_EXP(s->k.g, Y, V, s->u);
1024         G_MUL(s->k.g, R, W, Y);
1025         G_EXP(s->k.g, Z, R, s->k.x);
1026         D( debug_ge("R", s->k.g, R);
1027            debug_ge("Y", s->k.g, Y);
1028            debug_ge("Z", s->k.g, Z); )
1029         derive(&s->k, R, Z, "cipher", s->k.cc->name, s->k.cc->keysz,
1030                &kk, &ksz);
1031         c = GC_INIT(s->k.cc, kk, ksz);
1032         derive(&s->k, R, Z, "mac", s->k.cc->name, s->k.cc->keysz,
1033                &kk, &ksz);
1034         m = GM_KEY(s->k.mc, kk, ksz);
1035
1036         /* Find where the MAC tag is. */
1037         if ((t = buf_get(&bin, s->k.tagsz)) == 0) {
1038           moan("missing tag from %s:%d",
1039                inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
1040           goto again;
1041         }
1042
1043         /* Check the integrity of the ciphertext against the tag. */
1044         p = BCUR(&bin); n = BLEFT(&bin);
1045         h = GM_INIT(m);
1046         GH_HASH(h, p, n);
1047         tt = GH_DONE(h, 0);
1048         if (!ct_memeq(t, tt, s->k.tagsz)) {
1049           moan("incorrect tag from %s:%d",
1050                inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
1051           goto again;
1052         }
1053
1054         /* Decrypt the result and declare this server done. */
1055         GC_DECRYPT(c, p, p, n);
1056         if (s->h) {
1057           GH_DESTROY(h);
1058           h = GH_INIT(s->k.hc);
1059           GH_HASH(h, p, n);
1060           tt = GH_DONE(h, 0);
1061           if (memcmp(tt, s->h, h->ops->c->hashsz) != 0) {
1062             moan("response from %s:%d doesn't match hash",
1063                  inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
1064             goto again;
1065           }
1066         }
1067         donequery(q, p, n);
1068
1069       again:
1070         /* Tidy things up for the next run through. */
1071         if (R) { G_DESTROY(s->k.g, R); R = 0; }
1072         if (V) { G_DESTROY(s->k.g, V); V = 0; }
1073         if (W) { G_DESTROY(s->k.g, W); W = 0; }
1074         if (Y) { G_DESTROY(s->k.g, Y); Y = 0; }
1075         if (Z) { G_DESTROY(s->k.g, Z); Z = 0; }
1076         if (c) { GC_DESTROY(c); c = 0; }
1077         if (m) { GM_DESTROY(m); m = 0; }
1078         if (h) { GH_DESTROY(h); h = 0; }
1079       }
1080     }
1081   }
1082
1083   /* Check that all of the responses match up and XOR them together. */
1084   n = qq->sz;
1085   if (n > BUFSZ) die(1, "response too large");
1086   memset(obuf, 0, n);
1087   for (q = qq; q; q = q->next) {
1088     if (!q->k) die(1, "INTERNAL: query not complete");
1089     if (q->sz != n) die(1, "inconsistent response sizes");
1090     for (j = 0; j < n; j++) obuf[j] ^= q->k[j];
1091   }
1092
1093   /* Write out the completed answer. */
1094   p = obuf;
1095   while (n) {
1096     if ((nn = write(STDOUT_FILENO, p, n)) < 0)
1097       die(1, "error writing response: %s", strerror(errno));
1098     p += nn; n -= nn;
1099   }
1100   return (0);
1101 }
1102
1103 /*----- Main program ------------------------------------------------------*/
1104
1105 static void usage(FILE *fp)
1106 {
1107   pquis(fp, "Usage: \n\
1108         $ [-OPTS] LABEL {ADDR:PORT | FILE} ...\n\
1109         $ [-OPTS] -l [ADDR:]PORT\n\
1110 ");
1111 }
1112
1113 static void version(FILE *fp)
1114   { pquis(fp, "$, version " VERSION "\n"); }
1115
1116 static void help(FILE *fp)
1117 {
1118   version(fp);
1119   putc('\n', fp);
1120   usage(fp);
1121   fputs("\n\
1122 Options:\n\
1123 \n\
1124   -d, --daemon          Run in the background while listening.\n\
1125   -k, --keyring=FILE    Read keys from FILE. [default = `keyring']\n\
1126   -l, --listen          Listen for incoming requests and serve keys.\n\
1127   -p, --pidfile=FILE    Write process id to FILE if in daemon mode.\n\
1128   -r, --random=FILE     Key random number generator with contents of FILE.\n\
1129 ", fp);
1130 }
1131
1132 int main(int argc, char *argv[])
1133 {
1134   int argmin, argmax;
1135   void *k;
1136   size_t sz;
1137
1138   ego(argv[0]);
1139   for (;;) {
1140     static const struct option opts[] = {
1141       { "help",                 0,              0,      'h' },
1142       { "version",              0,              0,      'v' },
1143       { "usage",                0,              0,      'u' },
1144       { "daemon",               0,              0,      'd' },
1145       { "keyfile",              OPTF_ARGREQ,    0,      'k' },
1146       { "listen",               0,              0,      'l' },
1147       { "pidfile",              OPTF_ARGREQ,    0,      'p' },
1148       { "random",               OPTF_ARGREQ,    0,      'r' },
1149       { 0 }
1150     };
1151
1152     int i = mdwopt(argc, argv, "hvu" "dk:lp:r:", opts, 0, 0, 0);
1153     if (i < 0) break;
1154
1155     switch (i) {
1156       case 'h': help(stdout); exit(0);
1157       case 'v': version(stdout); exit(0);
1158       case 'u': usage(stdout); exit(0);
1159
1160       case 'd': flags |= f_daemon; break;
1161       case 'k': kfname = optarg; break;
1162       case 'l': flags |= f_listen; break;
1163       case 'p': pidfile = optarg; break;
1164       case 'r':
1165         if (snarf(optarg, &k, &sz))
1166           die(1, "failed to read `%s': %s", optarg, strerror(errno));
1167         rand_key(RAND_GLOBAL, k, sz);
1168         break;
1169
1170       default: flags |= f_bogus; break;
1171     }
1172   }
1173
1174   argv += optind; argc -= optind;
1175   if (flags & f_listen) argmin = argmax = 1;
1176   else argmin = 2, argmax = -1;
1177   if ((flags & f_bogus) || argc < argmin || (argmax >= 0 && argc > argmax))
1178     { usage(stderr); exit(1); }
1179
1180   fwatch_init(&kfwatch, kfname);
1181   kf = CREATE(key_file);
1182   if (key_open(kf, kfname, KOPEN_READ, keymoan, 0))
1183     die(1, "failed to open keyring file `%s'", kfname);
1184
1185   rand_noisesrc(RAND_GLOBAL, &noise_source);
1186   rand_seed(RAND_GLOBAL, 512);
1187
1188   if (flags & f_listen) return dolisten(argc, argv);
1189   else return doquery(argc, argv);
1190 }
1191
1192 /*----- That's all, folks -------------------------------------------------*/