chiark / gitweb /
The beginnings of a malicious proxy for TrIPE.
[tripe] / keymgmt.c
1 /* -*-c-*-
2  *
3  * $Id: keymgmt.c,v 1.2 2001/06/19 22:07:09 mdw Exp $
4  *
5  * Key loading and storing
6  *
7  * (c) 2001 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of Trivial IP Encryption (TrIPE).
13  *
14  * TrIPE is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  * 
19  * TrIPE is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  * 
24  * You should have received a copy of the GNU General Public License
25  * along with TrIPE; if not, write to the Free Software Foundation,
26  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27  */
28
29 /*----- Revision history --------------------------------------------------* 
30  *
31  * $Log: keymgmt.c,v $
32  * Revision 1.2  2001/06/19 22:07:09  mdw
33  * Cosmetic fixes.
34  *
35  * Revision 1.1  2001/02/03 20:26:37  mdw
36  * Initial checkin.
37  *
38  */
39
40 /*----- Header files ------------------------------------------------------*/
41
42 #include "tripe.h"
43
44 /*----- Global variables --------------------------------------------------*/
45
46 mpmont mg;
47 dh_priv kpriv;
48
49 /*----- Static variables --------------------------------------------------*/
50
51 static key_file *kf_pub;
52 static const char *kr_priv, *kr_pub, *tag_priv;
53 static fwatch w_priv, w_pub;
54
55 /*----- Main code ---------------------------------------------------------*/
56
57 /* --- @keymoan@ --- *
58  *
59  * Arguments:   @const char *file@ = name of the file
60  *              @int line@ = line number in file
61  *              @const char *msg@ = error message
62  *              @void *p@ = argument pointer
63  *
64  * Returns:     ---
65  *
66  * Use:         Reports an error message about loading a key file.
67  */
68
69 static void keymoan(const char *file, int line, const char *msg, void *p)
70 {
71   a_warn("%s:%i: error: %s", file, line, msg);
72 }
73
74 /* --- @loadpriv@ --- *
75  *
76  * Arguments:   @dstr *d@ = string to write errors in
77  *              @dh_priv *dh@ = where to store the key
78  *
79  * Returns:     Zero if OK, nonzero on error.
80  *
81  * Use:         Loads the private key from its keyfile.
82  */
83
84 static int loadpriv(dstr *d, dh_priv *dh)
85 {
86   key_file kf;
87   key_packstruct kps[DH_PRIVFETCHSZ];
88   key_packdef *kp;
89   dh_priv mydh;
90   int rc = 0;
91   int e;
92
93   if (key_open(&kf, kr_priv, KOPEN_READ, keymoan, 0)) {
94     dstr_putf(d, "error reading private keyring `%s': %s",
95               kr_priv, strerror(errno));
96     rc = -1;
97   } else {
98     T( trace(T_KEYMGMT, "keymgmt: loaded private keyring `%s'", kr_priv); )
99     kp = key_fetchinit(dh_privfetch, kps, &mydh);
100     if ((e = key_fetchbyname(kp, &kf, tag_priv)) != 0) {
101       dstr_putf(d, "error loading private key `%s': %s",
102                 tag_priv, key_strerror(e));
103       rc = -1;
104     } else {
105       dh->dp.p = MP_COPY(mydh.dp.p);
106       dh->dp.q = MP_COPY(mydh.dp.q);
107       dh->dp.g = MP_COPY(mydh.dp.g);
108       dh->x = MP_COPY(mydh.x);
109       dh->y = MP_COPY(mydh.y);      
110       IF_TRACING(T_KEYMGMT, {
111         trace(T_KEYMGMT, "keymgmt: extracted private key `%s'", tag_priv);
112         IF_TRACING(T_CRYPTO, {
113           trace(T_CRYPTO, "crypto: p = %s", mpstr(kpriv.dp.p));
114           trace(T_CRYPTO, "crypto: q = %s", mpstr(kpriv.dp.q));
115           trace(T_CRYPTO, "crypto: g = %s", mpstr(kpriv.dp.g));
116           trace(T_CRYPTO, "crypto: x = %s", mpstr(kpriv.x));
117           trace(T_CRYPTO, "crypto: g^x = %s", mpstr(kpriv.y));
118         })
119       })
120     }
121     key_fetchdone(kp);
122     key_close(&kf);
123   }
124   return (rc);
125 }
126
127 /* --- @loadpub@ --- *
128  *
129  * Arguments:   @dstr *d@ = string to write errors to
130  *
131  * Returns:     Zero if OK, nonzero on error.
132  *
133  * Use:         Reloads the public keyring.
134  */
135
136 static int loadpub(dstr *d)
137 {
138   key_file *kf = CREATE(key_file);
139
140   if (key_open(kf, kr_pub, KOPEN_READ, keymoan, 0)) {
141     dstr_putf(d, "error reading public keyring `%s': %s",
142               kr_pub, strerror(errno));
143     DESTROY(kf);
144     return (-1);
145   }
146   kf_pub = kf;
147   T( trace(T_KEYMGMT, "keymgmt: loaded public keyring `%s'", kr_pub); )
148   return (0);
149 }
150
151 /* --- @km_interval@ --- *
152  *
153  * Arguments:   ---
154  *
155  * Returns:     Zero if OK, nonzero to force reloading of keys.
156  *
157  * Use:         Called on the interval timer to perform various useful jobs.
158  */
159
160 int km_interval(void)
161 {
162   dstr d = DSTR_INIT;
163   dh_priv dh;
164   key_file *kf;
165   int reload = 0;
166
167   /* --- Check the private key first --- */
168
169   if (fwatch_update(&w_priv, kr_priv)) {
170     T( trace(T_KEYMGMT, "keymgmt: private keyring updated: reloading..."); )
171     DRESET(&d);
172     if (loadpriv(&d, &dh))
173       a_warn("%s -- ignoring changes", d.buf);
174     else {
175       reload = 1;
176       mpmont_destroy(&mg);
177       dh_privfree(&kpriv);
178       kpriv = dh;
179       mpmont_create(&mg, kpriv.dp.p);
180     }
181   }
182
183   /* --- Now check the public keys --- */
184
185   if (fwatch_update(&w_pub, kr_pub)) {
186     T( trace(T_KEYMGMT, "keymgmt: public keyring updated: reloading..."); )
187     kf = kf_pub;
188     DRESET(&d);
189     if (loadpub(&d))
190       a_warn("%s -- ignoring changes", d.buf);
191     else {
192       reload = 1;
193       key_close(kf);
194       DESTROY(kf);
195     }
196   }
197
198   /* --- Done --- */
199
200   return (reload);
201 }
202
203 /* --- @km_init@ --- *
204  *
205  * Arguments:   @const char *priv@ = private keyring file
206  *              @const char *pub@ = public keyring file
207  *              @const char *tag@ = tag to load
208  *
209  * Returns:     ---
210  *
211  * Use:         Initializes, and loads the private key.
212  */
213
214 void km_init(const char *priv, const char *pub, const char *tag)
215 {
216   dstr d = DSTR_INIT;
217
218   kr_priv = priv;
219   kr_pub = pub;
220   tag_priv = tag;
221   fwatch_init(&w_priv, kr_priv);
222   fwatch_init(&w_pub, kr_pub);
223
224   DRESET(&d);
225   if (loadpriv(&d, &kpriv))
226     die(EXIT_FAILURE, "%s", d.buf);
227   mpmont_create(&mg, kpriv.dp.p);
228   if (loadpub(&d))
229     die(EXIT_FAILURE, "%s", d.buf);
230 }
231
232 /* --- @km_getpubkey@ --- *
233  *
234  * Arguments:   @const char *tag@ = public key tag to load
235  *              @dh_pub *kpub@ = where to put the public key
236  *
237  * Returns:     Zero if OK, nonzero if it failed.
238  *
239  * Use:         Fetches a public key from the keyring.
240  */
241
242 int km_getpubkey(const char *tag, dh_pub *kpub)
243 {
244   key_packstruct kps[DH_PUBFETCHSZ];
245   key_packdef *kp;
246   dh_pub dp;
247   int e;
248
249   kp = key_fetchinit(dh_pubfetch, kps, &dp);
250   e = key_fetchbyname(kp, kf_pub, tag);
251   key_fetchdone(kp);
252   if (e) {
253     a_warn("error loading public key `%s': %s", tag, key_strerror(e));
254     return (-1);
255   }
256   IF_TRACING(T_KEYMGMT, {
257     trace(T_KEYMGMT, "keymgmt: extracted public key `%s'", tag);
258     IF_TRACING(T_CRYPTO, {
259       trace(T_CRYPTO, "crypto: p = %s", mpstr(dp.dp.p));
260       trace(T_CRYPTO, "crypto: q = %s", mpstr(dp.dp.q));
261       trace(T_CRYPTO, "crypto: g = %s", mpstr(dp.dp.g));
262       trace(T_CRYPTO, "crypto: g^x = %s", mpstr(dp.y));
263     })
264   })
265   if (!mp_eq(dp.dp.p, kpriv.dp.p) ||
266       !mp_eq(dp.dp.q, kpriv.dp.q) ||
267       !mp_eq(dp.dp.g, kpriv.dp.g)) {
268     a_warn("public key `%s' has different group from private key", tag);
269     return (-1);
270   }
271   kpub->dp.p = MP_COPY(dp.dp.p);
272   kpub->dp.q = MP_COPY(dp.dp.q);
273   kpub->dp.g = MP_COPY(dp.dp.g);
274   kpub->y = MP_COPY(dp.y);
275   return (0);
276 }
277
278 /*----- That's all, folks -------------------------------------------------*/