3 * Request a key over UDP, or respond to such a request
5 * (c) 2012 Mark Wooding
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of udpkey.
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.
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.
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.
27 /*----- Header files ------------------------------------------------------*/
36 #include <sys/types.h>
43 #include <sys/socket.h>
44 #include <arpa/inet.h>
45 #include <netinet/in.h>
48 #include <mLib/alloc.h>
50 #include <mLib/daemonize.h>
51 #include <mLib/dstr.h>
52 #include <mLib/fdflags.h>
53 #include <mLib/fwatch.h>
55 #include <mLib/mdwopt.h>
56 #include <mLib/quis.h>
57 #include <mLib/report.h>
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>
75 #include <catacomb/rijndael-counter.h>
76 #include <catacomb/sha256.h>
84 /*---- Static variables ---------------------------------------------------*/
86 static unsigned flags
= 0;
93 static unsigned char ibuf
[BUFSZ
], obuf
[BUFSZ
];
96 static const char *kfname
= "keyring";
97 static const char *pidfile
;
98 static fwatch kfwatch
;
101 /*----- Miscellaneous utilities -------------------------------------------*/
103 /* Resolve NAME, storing the address in *ADDR. Exit on error. */
104 static void resolve(const char *name
, struct in_addr
*addr
)
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
));
115 /* Convert PORT to a port number (in host byte order). Exit on error. */
116 static unsigned short getport(const char *port
)
123 if (!isdigit(*port
) ||
124 (i
= strtoul(port
, &q
, 0)) == 0 ||
125 i
>= 65536 || *q
|| errno
)
126 die(1, "invalid port number `%s'", port
);
128 return ((unsigned short)i
);
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
136 static int snarf(const char *name
, void **p
, size_t *sz
)
141 if ((fd
= open(name
, O_RDONLY
)) < 0) return (-1);
142 n
= read(fd
, ibuf
, sizeof(ibuf
));
144 if (n
< 0) return (-1);
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
153 static void PRINTF_LIKE(2, 3) complain(int sev
, const char *msg
, ...)
158 if (flags
& f_syslog
)
159 vsyslog(sev
, msg
, ap
);
161 fprintf(stderr
, "%s: ", QUIS
);
162 vfprintf(stderr
, msg
, ap
);
167 /*----- Reading key data --------------------------------------------------*/
174 const gcmac
*mc
; size_t tagsz
;
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; }
181 /* Free a kinfo structure. This is safe on any initialized kinfo
184 static void k_free(struct kinfo
*k
)
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; }
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...
198 /* Table of key types. Entries have the form
200 * _(name, NAME, SETGROUP, SETPRIV, SETPUB)
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.)
208 #define KEYTYPES(_) \
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); \
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); \
225 k->g = group_ec(&ei); \
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); \
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.
237 #define KLOAD(ty, TY, which, WHICH, setgroup, setpriv, setpub) \
238 static int load_##ty##which(key_data *kd, struct kinfo *k, dstr *t) \
240 key_packstruct kps[TY##_##WHICH##FETCHSZ]; \
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)); \
253 /* Extract the components as abstract group elements. */ \
256 k->X = G_CREATE(k->g); \
259 /* Dispose of stuff we don't need. */ \
263 /* Tidy up after mishaps. */ \
270 /* Map over the KEYTYPES to declare the load_tywhich functions using KLOAD
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
)
279 /* Define a table of group key-loading operations. */
282 int (*loadpriv
)(key_data
*, struct kinfo
*, dstr
*);
283 int (*loadpub
)(key_data
*, struct kinfo
*, dstr
*);
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
)
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
297 static int loadkey(const char *tag
, struct kinfo
*k
, int privp
)
299 const struct kload_ops
*ops
;
300 dstr d
= DSTR_INIT
, dd
= DSTR_INIT
;
308 /* Find the key data. */
309 if (key_qtag(kf
, tag
, &d
, &ky
, &kd
)) {
310 complain(LOG_ERR
, "unknown key tag `%s'", tag
);
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;
318 complain(LOG_ERR
, "no group type for key %s", d
.buf
);
321 for (ops
= kload_ops
; ops
->name
; ops
++) {
322 if (strcmp(ty
, ops
->name
) == 0)
325 complain(LOG_ERR
, "unknown group type `%s' in key %s", ty
, d
.buf
);
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)
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
);
342 /* And the chosen hash function. */
343 if ((p
= key_getattr(kf
, ky
, "hash")) == 0)
345 else if ((k
->hc
= ghash_byname(p
)) == 0) {
346 complain(LOG_ERR
, "unknown hash `%s' in key %s", p
, d
.buf
);
350 /* And finally a MAC. This is more fiddly because we must handle (a)
351 * truncation and (b) defaulting based on the hash.
353 if ((p
= key_getattr(kf
, ky
, "mac")) == 0)
354 dstr_putf(&dd
, "%s-hmac", k
->hc
->name
);
357 if ((q
= strchr(dd
.buf
, '/')) != 0) *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
);
364 k
->tagsz
= k
->mc
->hashsz
/2;
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
);
387 static void keymoan(const char *file
, int line
, const char *err
, void *p
)
388 { complain(LOG_ERR
, "%s:%d: %s", file
, line
, err
); }
390 /* Update the keyring `kf' if the file has been changed since we last looked.
392 static void kfupdate(void)
396 if (!fwatch_update(&kfwatch
, kfname
)) return;
397 kfnew
= CREATE(key_file
);
398 if (key_open(kfnew
, kfname
, KOPEN_READ
, keymoan
, 0)) {
407 /*----- Low-level crypto operations ---------------------------------------*/
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.
417 * Basically all we do is compute H(what || U || Z).
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
)
427 /* Find a suitable key size. */
428 if ((*n
= keysz(k
->hc
->hashsz
, ksz
)) == 0) {
430 "failed to find suitable key size for %s `%s' and hash `%s'",
431 what
, name
, k
->hc
->name
);
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
);
442 complain(LOG_ERR
, "overflow while deriving key (prepare preimage)!");
446 /* Derive the output key. */
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)!");
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
)
466 fprintf(stderr
, "%s: *** %s = ", QUIS
, what
);
467 group_writefile(g
, X
, stderr
);
472 /*----- Protocol summary --------------------------------------------------*
474 * There are two protocol versions. The original version works as follows.
477 * memz KEYTAG tag of wanted secret
481 * ge V public vector: V = v P
482 * ge W encrypted clue: W = R - Y = r P - v U
483 * mem[TAGSZ] TAG MAC tag on ciphertext
484 * mem[KSZ] CT secret, encrypted with Z = r X
486 * The new version provides forward secrecy, which involves additional flows.
489 * u8 0 marker byte for new protocol
491 * mem8 KEYTAG wanted secret tag
495 * u32 REF server's reference
496 * ge R public DLIES vector: R = r P
497 * ge W masked DH vector: W = V - Y = v P - r X
500 * u8 0 marker byte for new protocol
502 * mem8 KEYTAG wanted secret tag
503 * u32 REF reference from challenge
504 * ge U public DH vector
505 * mem[HASHSZ] H0 hash; H0||H1 = H(U, V, Z), where Z = v U
509 * mem[TAGSZ] TAG MAC tag on ciphertext
510 * mem[KSZ] CT secret, encrypted with H1
513 #define FWS_GREET 0x01
514 #define FWS_CHALL 0x11
515 #define FWS_RESP 0x02
516 #define FWS_REPLY 0x12
518 /*----- Listening for requests --------------------------------------------*/
520 /* Rate limiting parameters.
522 * There's a probabilistic rate-limiting mechanism. A counter starts at 0.
523 * Every time we process a request, we increment the counter. The counter
524 * drops by RATE_REFILL every second. If the counter is below RATE_CREDIT
525 * then the request is processed; otherwise it is processed with probability
526 * 1/(counter - RATE_CREDIT).
528 #define RATE_REFILL 10 /* Credits per second. */
529 #define RATE_CREDIT 1000 /* Initial credit. */
535 * The server doesn't want to maintain state for each client. Instead, we
536 * generate a global secret, and derive per-client secrets from it. A secret
537 * needs to have an expiry time (at which point we won't use it for new
538 * requests) and a deletion time (at which point we just forget that it ever
539 * existed). This lets us roll over to a new secret without leaving existing
540 * clients completely in the lurch.
542 * Secrets are kept in a linked list, ordered by expiry time. At any given
543 * time there is at most one unexpired secret (because we only make a new one
544 * when the old one expires).
553 static struct secret
*secrets
= 0, *live_secret
= 0;
554 static uint32 next_secret_seq
= 0;
558 static void kill_dead_secrets(void)
560 struct secret
*s
= secrets
, *ss
;
562 for (s
= secrets
; s
&& s
->t_del
<= now
; s
= ss
) {
567 if (!s
) live_secret
= 0;
570 static struct secret
*find_secret(uint32 seq
)
575 for (s
= secrets
; s
; s
= s
->next
)
576 if (s
->seq
== seq
) return (s
);
580 static struct secret
*fresh_secret(void)
584 if (live_secret
&& live_secret
->t_exp
> now
) return (live_secret
);
587 s
= CREATE(struct secret
);
588 s
->seq
= next_secret_seq
++;
590 rand_get(RAND_GLOBAL
, s
->x
, sizeof(s
->x
));
591 s
->t_exp
= now
+ T_SECEXP
; s
->t_del
= now
+ T_SECDEL
;
592 if (live_secret
) live_secret
->next
= s
;
598 static int fetch_key(const char *tag
, struct sockaddr_in
*sin
,
599 key
**ky
, struct kinfo
*k
)
601 dstr d
= DSTR_INIT
, dd
= DSTR_INIT
;
606 int ch
, mlen
, rc
= -1;
610 if (key_qtag(kf
, tag
, &d
, ky
, &kkd
)) {
611 complain(LOG_WARNING
, "unknown key tag `%s' from %s:%d",
612 tag
, inet_ntoa(sin
->sin_addr
), ntohs(sin
->sin_port
));
616 /* And make sure that it has the right shape. */
617 if (((*ky
)->k
->e
& KF_ENCMASK
) != KENC_BINARY
) {
618 complain(LOG_ERR
, "key %s is not plain binary data", d
.buf
);
622 /* Find the list of clients, and look up the caller's address in the
623 * list. Entries have the form ADDRESS[/LEN][=TAG] and are separated by
626 if ((pp
= key_getattr(kf
, *ky
, "clients")) == 0) {
627 complain(LOG_WARNING
,
628 "key %s requested from %s:%d has no `clients' attribute",
629 d
.buf
, inet_ntoa(sin
->sin_addr
), ntohs(sin
->sin_port
));
636 while (isdigit((unsigned char)*q
) || *q
== '.') q
++;
638 if (!inet_aton(p
, &in
)) goto skip
;
643 while (isdigit((unsigned char)*q
)) q
++;
647 if (((sin
->sin_addr
.s_addr
^ in
.s_addr
) &
648 htonl(0xffffffff << (32 - mlen
))) == 0)
653 while (*p
&& *p
!= ';') p
++;
656 complain(LOG_WARNING
, "access to key %s denied to %s:%d",
657 d
.buf
, inet_ntoa(sin
->sin_addr
), ntohs(sin
->sin_port
));
661 /* Build a tag name for the caller's KEM key, either from the client
662 * match or the source address.
666 dstr_puts(&dd
, "client-");
667 dstr_puts(&dd
, inet_ntoa(sin
->sin_addr
));
671 while (*q
&& *q
!= ';') q
++;
672 if (*q
== ';') *q
++ = 0;
675 /* Report the match. */
676 complain(LOG_NOTICE
, "client %s:%d (`%s') requests key %s",
677 inet_ntoa(sin
->sin_addr
), ntohs(sin
->sin_port
), p
, d
.buf
);
679 /* Load the KEM key. */
680 if (loadkey(p
, k
, 0)) goto done
;
681 D( debug_ge("X", k
.g
, k
.X
); )
687 /* Clean everything up. */
694 static int respond_v0(buf
*bin
, buf
*bout
, struct sockaddr_in
*sin
)
696 ge
*R
= 0, *U
= 0, *V
= 0, *W
= 0, *Y
= 0, *Z
= 0;
697 mp
*r
= MP_NEW
, *v
= MP_NEW
;
709 /* Clear out the key state. */
712 /* Extract the key tag name. */
713 if ((p
= buf_getmemz(bin
, &sz
)) == 0) {
714 complain(LOG_WARNING
, "invalid key tag from %s:%d",
715 inet_ntoa(sin
->sin_addr
), ntohs(sin
->sin_port
));
719 /* Find the client's key and check that it's allowed. */
720 if (fetch_key(p
, sin
, &ky
, &k
)) goto done
;
722 /* Read the caller's ephemeral key. */
723 R
= G_CREATE(k
.g
); W
= G_CREATE(k
.g
);
724 U
= G_CREATE(k
.g
); V
= G_CREATE(k
.g
);
725 Y
= G_CREATE(k
.g
); Z
= G_CREATE(k
.g
);
726 if (G_FROMBUF(k
.g
, bin
, U
)) {
727 complain(LOG_WARNING
, "failed to read ephemeral vector from %s:%d",
728 inet_ntoa(sin
->sin_addr
), ntohs(sin
->sin_port
));
731 D( debug_ge("U", k
.g
, U
); )
733 complain(LOG_WARNING
, "trailing junk in request from %s:%d",
734 inet_ntoa(sin
->sin_addr
), ntohs(sin
->sin_port
));
738 /* Ephemeral Diffie--Hellman. Choose v in GF(q) at random; compute
739 * V = v P and -Y = (-v) U.
741 v
= mprand_range(v
, k
.g
->r
, &rand_global
, 0);
742 G_EXP(k
.g
, V
, k
.g
->g
, v
);
743 D( debug_mp("v", v
); debug_ge("V", k
.g
, V
); )
744 v
= mp_sub(v
, k
.g
->r
, v
);
746 D( debug_ge("-Y", k
.g
, Y
); )
748 /* DLIES. Choose r in GF(q) at random; compute R = r P and Z = r X. Mask
749 * the clue R as W = R - Y. (Doing the subtraction here makes life easier
750 * at the other end, since we can determine -Y by negating v whereas the
751 * recipient must subtract vectors which may be less efficient.)
753 r
= mprand_range(r
, k
.g
->r
, &rand_global
, 0);
754 G_EXP(k
.g
, R
, k
.g
->g
, r
);
755 D( debug_mp("r", r
); debug_ge("R", k
.g
, R
); )
756 G_EXP(k
.g
, Z
, k
.X
, r
);
758 D( debug_ge("Z", k
.g
, Z
); debug_ge("W", k
.g
, W
); )
760 /* Derive encryption and integrity keys. */
761 derive(&k
, R
, Z
, "cipher", k
.cc
->name
, k
.cc
->keysz
, &kk
, &ksz
);
762 c
= GC_INIT(k
.cc
, kk
, ksz
);
763 derive(&k
, R
, Z
, "mac", k
.mc
->name
, k
.mc
->keysz
, &kk
, &ksz
);
764 m
= GM_KEY(k
.mc
, kk
, ksz
);
766 /* Build the ciphertext and compute a MAC tag over it. */
768 if (G_TOBUF(k
.g
, bout
, V
) ||
769 G_TOBUF(k
.g
, bout
, W
))
771 if ((t
= buf_get(bout
, k
.tagsz
)) == 0) goto done
;
773 if (BENSURE(bout
, sz
)) goto done
;
774 GC_ENCRYPT(c
, ky
->k
->u
.k
.k
, BCUR(bout
), sz
);
776 GH_HASH(h
, BCUR(bout
), sz
);
777 tt
= GH_DONE(h
, 0); memcpy(t
, tt
, k
.tagsz
);
781 /* Clear everything up and go home. */
782 if (R
) G_DESTROY(k
.g
, R
);
783 if (U
) G_DESTROY(k
.g
, U
);
784 if (V
) G_DESTROY(k
.g
, V
);
785 if (W
) G_DESTROY(k
.g
, W
);
786 if (Y
) G_DESTROY(k
.g
, Y
);
787 if (Z
) G_DESTROY(k
.g
, Z
);
788 if (c
) GC_DESTROY(c
);
789 if (m
) GM_DESTROY(m
);
790 if (h
) GH_DESTROY(h
);
797 static int dolisten(int argc
, char *argv
[])
804 struct sockaddr_in sin
;
808 unsigned bucket
= 0, toks
;
811 /* Set up the socket address. */
812 sin
.sin_family
= AF_INET
;
813 aspec
= xstrdup(argv
[0]);
814 if ((p
= strchr(aspec
, ':')) == 0) {
816 sin
.sin_addr
.s_addr
= INADDR_ANY
;
819 resolve(aspec
, &sin
.sin_addr
);
821 sin
.sin_port
= htons(getport(p
));
823 /* Create and set up the socket itself. */
824 if ((sk
= socket(PF_INET
, SOCK_DGRAM
, 0)) < 0 ||
825 fdflags(sk
, O_NONBLOCK
, O_NONBLOCK
, FD_CLOEXEC
, FD_CLOEXEC
) ||
826 bind(sk
, (struct sockaddr
*)&sin
, sizeof(sin
)))
827 die(1, "failed to create socket: %s", strerror(errno
));
829 /* That's enough initialization. If we should fork, then do that. */
830 if (flags
& f_daemon
) {
831 if (pidfile
&& (fp
= fopen(pidfile
, "w")) == 0)
832 die(1, "failed to open pidfile `%s': %s", pidfile
, strerror(errno
));
833 openlog(QUIS
, LOG_PID
, LOG_DAEMON
);
835 die(1, "failed to become background process: %s", strerror(errno
));
836 if (pidfile
) { fprintf(fp
, "%ld\n", (long)getpid()); fclose(fp
); }
842 /* Wait for something to happen. */
845 if (select(sk
+ 1, &fdin
, 0, 0, 0) < 0)
846 die(1, "select failed: %s", strerror(errno
));
847 noise_timer(RAND_GLOBAL
);
849 /* Fetch a packet. */
851 n
= recvfrom(sk
, ibuf
, sizeof(ibuf
), 0, (struct sockaddr
*)&sin
, &len
);
853 if (errno
!= EAGAIN
&& errno
!= EINTR
)
854 complain(LOG_ERR
, "unexpected receive error: %s", strerror(errno
));
858 /* Refill the bucket, and see whether we should reject this packet. */
860 if (bucket
&& now
!= last
) {
861 toks
= (now
- last
)*RATE_REFILL
;
862 bucket
= bucket
< toks ?
0 : bucket
- toks
;
865 if (bucket
> RATE_CREDIT
&&
866 grand_range(&rand_global
, bucket
- RATE_CREDIT
))
870 /* Set up the input buffer for parsing the request. */
871 buf_init(&bin
, ibuf
, n
);
872 buf_init(&bout
, obuf
, sizeof(obuf
));
874 /* Handle the client's message. */
875 if (respond_v0(&bin
, &bout
, &sin
)) continue;
877 /* Send the reply packet back to the caller. */
878 if (!BOK(&bout
)) goto bad
;
879 if (sendto(sk
, BBASE(&bout
), BLEN(&bout
), 0,
880 (struct sockaddr
*)&sin
, len
) < 0) {
881 complain(LOG_ERR
, "failed to send response to %s:%d: %s",
882 inet_ntoa(sin
.sin_addr
), ntohs(sin
.sin_port
),
890 /* Report a problem building the reply. */
891 complain(LOG_ERR
, "failed to construct response to %s:%d",
892 inet_ntoa(sin
.sin_addr
), ntohs(sin
.sin_port
));
898 /*----- Sending requests and processing responses -------------------------*/
910 struct sockaddr_in sin
;
912 const struct client_protocol
*proto
;
918 struct client_protocol
{
920 int (*setup
)(struct query
*, struct server
*);
921 int (*receive
)(struct query
*, struct server
*, buf
*, buf
*);
922 int (*retransmit
)(struct query
*, struct server
*, buf
*);
925 /* Record a successful fetch of key material for a query Q. The data starts
926 * at K and is SZ bytes long. The data is copied: it's safe to overwrite it.
928 static int donequery(struct query
*q
, struct server
*s
,
929 const void *k
, size_t sz
)
935 /* If we have a hash, check that the fragment matches it. */
937 h
= GH_INIT(s
->k
.hc
);
940 diffp
= memcmp(tt
, s
->h
, h
->ops
->c
->hashsz
);
943 moan("response from %s:%d doesn't match hash",
944 inet_ntoa(s
->sin
.sin_addr
), ntohs(s
->sin
.sin_port
));
949 /* Stash a copy of the key fragment for later. */
958 static int setup_v0(struct query
*q
, struct server
*s
)
960 /* Choose an ephemeral private key u. Let x be our private key. We
961 * compute U = u P and transmit this.
963 s
->u
= mprand_range(MP_NEW
, s
->k
.g
->r
, &rand_global
, 0);
964 s
->U
= G_CREATE(s
->k
.g
);
965 G_EXP(s
->k
.g
, s
->U
, s
->k
.g
->g
, s
->u
);
966 D( debug_mp("u", s
->u
); debug_ge("U", s
->k
.g
, s
->U
); )
971 static int retransmit_v0(struct query
*q
, struct server
*s
, buf
*bout
)
973 buf_putstrz(bout
, q
->tag
);
974 G_TOBUF(s
->k
.g
, bout
, s
->U
);
978 static int receive_v0(struct query
*q
, struct server
*s
, buf
*bin
, buf
*bout
)
980 ge
*R
, *V
= 0, *W
= 0, *Y
= 0, *Z
= 0;
989 R
= G_CREATE(s
->k
.g
);
990 V
= G_CREATE(s
->k
.g
); W
= G_CREATE(s
->k
.g
);
991 Y
= G_CREATE(s
->k
.g
); Z
= G_CREATE(s
->k
.g
);
992 if (G_FROMBUF(s
->k
.g
, bin
, V
)) {
993 moan("invalid Diffie--Hellman vector from %s:%d",
994 inet_ntoa(s
->sin
.sin_addr
), ntohs(s
->sin
.sin_port
));
997 if (G_FROMBUF(s
->k
.g
, bin
, W
)) {
998 moan("invalid clue vector from %s:%d",
999 inet_ntoa(s
->sin
.sin_addr
), ntohs(s
->sin
.sin_port
));
1002 D( debug_ge("V", s
->k
.g
, V
); debug_ge("W", s
->k
.g
, W
); )
1004 /* We have V and W from the server; determine Y = u V, R = W + Y and
1005 * Z = x R, and then derive the symmetric keys.
1007 G_EXP(s
->k
.g
, Y
, V
, s
->u
);
1008 G_MUL(s
->k
.g
, R
, W
, Y
);
1009 G_EXP(s
->k
.g
, Z
, R
, s
->k
.x
);
1010 D( debug_ge("R", s
->k
.g
, R
);
1011 debug_ge("Y", s
->k
.g
, Y
);
1012 debug_ge("Z", s
->k
.g
, Z
); )
1013 derive(&s
->k
, R
, Z
, "cipher", s
->k
.cc
->name
, s
->k
.cc
->keysz
, &kk
, &ksz
);
1014 c
= GC_INIT(s
->k
.cc
, kk
, ksz
);
1015 derive(&s
->k
, R
, Z
, "mac", s
->k
.cc
->name
, s
->k
.cc
->keysz
, &kk
, &ksz
);
1016 m
= GM_KEY(s
->k
.mc
, kk
, ksz
);
1018 /* Find where the MAC tag is. */
1019 if ((t
= buf_get(bin
, s
->k
.tagsz
)) == 0) {
1020 moan("missing tag from %s:%d",
1021 inet_ntoa(s
->sin
.sin_addr
), ntohs(s
->sin
.sin_port
));
1025 /* Check the integrity of the ciphertext against the tag. */
1026 p
= BCUR(bin
); n
= BLEFT(bin
);
1030 if (!ct_memeq(t
, tt
, s
->k
.tagsz
)) {
1031 moan("incorrect tag from %s:%d",
1032 inet_ntoa(s
->sin
.sin_addr
), ntohs(s
->sin
.sin_port
));
1036 /* Decrypt the result and declare this server done. */
1037 GC_DECRYPT(c
, p
, p
, n
);
1038 rc
= donequery(q
, s
, p
, n
);
1041 /* Clear up and go home. */
1042 if (R
) G_DESTROY(s
->k
.g
, R
);
1043 if (V
) G_DESTROY(s
->k
.g
, V
);
1044 if (W
) G_DESTROY(s
->k
.g
, W
);
1045 if (Y
) G_DESTROY(s
->k
.g
, Y
);
1046 if (Z
) G_DESTROY(s
->k
.g
, Z
);
1047 if (c
) GC_DESTROY(c
);
1048 if (m
) GM_DESTROY(m
);
1049 if (h
) GH_DESTROY(h
);
1053 static const struct client_protocol prototab
[] = {
1054 { "v0", setup_v0
, receive_v0
, retransmit_v0
},
1058 /* Initialize a query to a remote server. */
1059 static struct query
*qinit_net(const char *tag
, const char *spec
)
1062 struct server
*s
, **stail
;
1063 dstr d
= DSTR_INIT
, dd
= DSTR_INIT
;
1064 const struct client_protocol
*proto
;
1068 /* Allocate the query block. */
1069 q
= CREATE(struct query
);
1073 /* Put the spec somewhere we can hack at it. */
1074 dstr_puts(&d
, spec
);
1077 /* Parse the query spec. Entries have the form ADDRESS:PORT[=TAG][#HASH]
1078 * and are separated by `;'.
1082 /* Allocate a new server node. */
1083 s
= CREATE(struct server
);
1084 s
->sin
.sin_family
= AF_INET
;
1086 /* Extract the server address. */
1087 if ((pp
= strchr(p
, ':')) == 0)
1088 die(1, "invalid syntax: missing `:PORT'");
1090 resolve(p
, &s
->sin
.sin_addr
);
1092 /* Extract the port number. */
1094 while (isdigit((unsigned char)*pp
)) pp
++;
1095 ch
= *pp
; *pp
++ = 0;
1096 s
->sin
.sin_port
= htons(getport(p
));
1098 /* See if there's a protocol name. */
1103 pp
+= strcspn(pp
, ";#=");
1104 ch
= *pp
; *pp
++ = 0;
1106 for (proto
= prototab
; proto
->name
; proto
++)
1107 if (strcmp(proto
->name
, p
) == 0) goto found_proto
;
1108 die(1, "unknown protocol name `%s'", p
);
1112 /* If there's a key tag then extract that; otherwise use a default. */
1117 pp
+= strcspn(pp
, ";#");
1118 ch
= *pp
; *pp
++ = 0;
1120 if (loadkey(p
, &s
->k
, 1)) exit(1);
1121 D( debug_mp("x", s
->k
.x
); debug_ge("X", s
->k
.g
, s
->k
.X
); )
1123 /* Link the server on. */
1124 *stail
= s
; stail
= &s
->next
;
1126 /* If there's a trailing hash then extract it. */
1131 while (*pp
== '-' || isxdigit((unsigned char)*pp
)) pp
++;
1134 hex_decode(&hc
, p
, pp
- p
, &dd
);
1135 if (dd
.len
!= s
->k
.hc
->hashsz
) die(1, "incorrect hash length");
1136 s
->h
= xmalloc(dd
.len
);
1137 memcpy(s
->h
, dd
.buf
, dd
.len
);
1141 /* Initialize the protocol. */
1142 if (s
->proto
->setup(q
, s
)) die(1, "failed to initialize protocol");
1144 /* If there are more servers, then continue parsing. */
1146 else if (ch
!= ';') die(1, "invalid syntax: expected `;'");
1150 /* Terminate the server list and return. */
1158 /* Handle a `query' to a local file. */
1159 static struct query
*qinit_file(const char *tag
, const char *file
)
1165 /* Snarf the file. */
1166 q
= CREATE(struct query
);
1167 if (snarf(file
, &k
, &sz
))
1168 die(1, "failed to read `%s': %s", file
, strerror(errno
));
1170 donequery(q
, 0, k
, sz
);
1174 /* Retransmission and timeout parameters. */
1175 #define TO_NEXT(t) (((t) + 2)*4/3) /* Timeout growth function */
1176 #define TO_MAX 30 /* When to give up */
1178 static int doquery(int argc
, char *argv
[])
1180 struct query
*q
= 0, *qq
, **qtail
= &qq
;
1181 struct server
*s
= 0;
1182 const char *tag
= argv
[0];
1187 struct timeval now
, when
, tv
;
1188 struct sockaddr_in sin
;
1195 /* Create a socket. We just use the one socket for everything. We don't
1196 * care which port we get allocated.
1198 if ((sk
= socket(PF_INET
, SOCK_DGRAM
, 0)) < 0 ||
1199 fdflags(sk
, O_NONBLOCK
, O_NONBLOCK
, FD_CLOEXEC
, FD_CLOEXEC
))
1200 die(1, "failed to create socket: %s", strerror(errno
));
1202 /* Parse the query target specifications. The adjustments of `nq' aren't
1203 * in the right order but that doesn't matter.
1205 for (i
= 1; i
< argc
; i
++) {
1206 if (*argv
[i
] == '.' || *argv
[i
] == '/') q
= qinit_file(tag
, argv
[i
]);
1207 else if (strchr(argv
[i
], ':')) q
= qinit_net(tag
, argv
[i
]);
1208 else die(1, "unrecognized query target `%s'", argv
[i
]);
1209 *qtail
= q
; qtail
= &q
->next
; nq
++;
1213 /* Find the current time so we can compute retransmission times properly.
1215 gettimeofday(&now
, 0);
1218 /* Continue retransmitting until we have all the answers. */
1221 /* Work out when we next want to wake up. */
1222 if (TV_CMP(&now
, >=, &when
)) {
1224 if (next
>= TO_MAX
) die(1, "no responses: giving up");
1225 next
= TO_NEXT(next
);
1226 TV_ADDL(&when
, &when
, next
, 0);
1227 } while (TV_CMP(&when
, <=, &now
));
1228 for (q
= qq
; q
; q
= q
->next
) {
1230 for (s
= q
->s
; s
; s
= s
->next
) {
1231 buf_init(&bout
, obuf
, sizeof(obuf
));
1232 if (s
->proto
->retransmit(q
, s
, &bout
)) continue;
1234 moan("overflow while constructing request!");
1237 sendto(sk
, BBASE(&bout
), BLEN(&bout
), 0,
1238 (struct sockaddr
*)&s
->sin
, sizeof(s
->sin
));
1243 /* Wait until something interesting happens. */
1246 TV_SUB(&tv
, &when
, &now
);
1247 if (select(sk
+ 1, &fdin
, 0, 0, &tv
) < 0)
1248 die(1, "select failed: %s", strerror(errno
));
1249 gettimeofday(&now
, 0);
1251 /* If we have an input event, process incoming packets. */
1252 if (FD_ISSET(sk
, &fdin
)) {
1255 /* Read a packet and capture its address. */
1257 nn
= recvfrom(sk
, ibuf
, sizeof(ibuf
), 0,
1258 (struct sockaddr
*)&sin
, &len
);
1260 if (errno
== EAGAIN
) break;
1261 else if (errno
== EINTR
) continue;
1263 moan("error receiving reply: %s", strerror(errno
));
1268 /* See whether this corresponds to any of our servers. Don't just
1269 * check the active servers, since this may be late a reply caused by
1270 * retransmissions or similar.
1272 for (q
= qq
; q
; q
= q
->next
) {
1273 for (s
= q
->s
; s
; s
= s
->next
) {
1274 if (s
->sin
.sin_addr
.s_addr
== sin
.sin_addr
.s_addr
&&
1275 s
->sin
.sin_port
== sin
.sin_port
)
1279 moan("received reply from unexpected source %s:%d",
1280 inet_ntoa(sin
.sin_addr
), ntohs(sin
.sin_port
));
1284 /* If the query we found has now been satisfied, ignore this packet.
1288 /* Parse the reply, and either finish the job or get a message to
1289 * send back to the server.
1291 buf_init(&bin
, ibuf
, nn
);
1292 buf_init(&bout
, obuf
, sizeof(obuf
));
1293 if (s
->proto
->receive(q
, s
, &bin
, &bout
)) continue;
1295 if (!BLEN(&bout
) && s
->proto
->retransmit(q
, s
, &bout
)) continue;
1297 moan("overflow while constructing request!");
1300 sendto(sk
, BBASE(&bout
), BLEN(&bout
), 0,
1301 (struct sockaddr
*)&s
->sin
, sizeof(s
->sin
));
1306 /* Check that all of the responses match up and XOR them together. */
1308 if (n
> BUFSZ
) die(1, "response too large");
1310 for (q
= qq
; q
; q
= q
->next
) {
1311 if (!q
->k
) die(1, "INTERNAL: query not complete");
1312 if (q
->sz
!= n
) die(1, "inconsistent response sizes");
1313 for (j
= 0; j
< n
; j
++) obuf
[j
] ^= q
->k
[j
];
1316 /* Write out the completed answer. */
1319 if ((nn
= write(STDOUT_FILENO
, p
, n
)) < 0)
1320 die(1, "error writing response: %s", strerror(errno
));
1326 /*----- Main program ------------------------------------------------------*/
1328 static void usage(FILE *fp
)
1330 pquis(fp
, "Usage: \n\
1331 $ [-OPTS] LABEL {ADDR:PORT[=TAG][#HASH];... | FILE} ...\n\
1332 $ [-OPTS] -l [ADDR:]PORT\n\
1336 static void version(FILE *fp
)
1337 { pquis(fp
, "$, version " VERSION
"\n"); }
1339 static void help(FILE *fp
)
1347 -d, --daemon Run in the background while listening.\n\
1348 -k, --keyring=FILE Read keys from FILE. [default = `keyring']\n\
1349 -l, --listen Listen for incoming requests and serve keys.\n\
1350 -p, --pidfile=FILE Write process id to FILE if in daemon mode.\n\
1351 -r, --random=FILE Key random number generator with contents of FILE.\n\
1355 int main(int argc
, char *argv
[])
1363 static const struct option opts
[] = {
1364 { "help", 0, 0, 'h' },
1365 { "version", 0, 0, 'v' },
1366 { "usage", 0, 0, 'u' },
1367 { "daemon", 0, 0, 'd' },
1368 { "keyfile", OPTF_ARGREQ
, 0, 'k' },
1369 { "listen", 0, 0, 'l' },
1370 { "pidfile", OPTF_ARGREQ
, 0, 'p' },
1371 { "random", OPTF_ARGREQ
, 0, 'r' },
1375 int i
= mdwopt(argc
, argv
, "hvu" "dk:lp:r:", opts
, 0, 0, 0);
1379 case 'h': help(stdout
); exit(0);
1380 case 'v': version(stdout
); exit(0);
1381 case 'u': usage(stdout
); exit(0);
1383 case 'd': flags
|= f_daemon
; break;
1384 case 'k': kfname
= optarg
; break;
1385 case 'l': flags
|= f_listen
; break;
1386 case 'p': pidfile
= optarg
; break;
1388 if (snarf(optarg
, &k
, &sz
))
1389 die(1, "failed to read `%s': %s", optarg
, strerror(errno
));
1390 rand_key(RAND_GLOBAL
, k
, sz
);
1393 default: flags
|= f_bogus
; break;
1397 argv
+= optind
; argc
-= optind
;
1398 if (flags
& f_listen
) argmin
= argmax
= 1;
1399 else argmin
= 2, argmax
= -1;
1400 if ((flags
& f_bogus
) || argc
< argmin
|| (argmax
>= 0 && argc
> argmax
))
1401 { usage(stderr
); exit(1); }
1403 fwatch_init(&kfwatch
, kfname
);
1404 kf
= CREATE(key_file
);
1405 if (key_open(kf
, kfname
, KOPEN_READ
, keymoan
, 0))
1406 die(1, "failed to open keyring file `%s'", kfname
);
1408 rand_noisesrc(RAND_GLOBAL
, &noise_source
);
1409 rand_seed(RAND_GLOBAL
, 512);
1411 if (flags
& f_listen
) return dolisten(argc
, argv
);
1412 else return doquery(argc
, argv
);
1415 /*----- That's all, folks -------------------------------------------------*/