Blob


1 /*
2 * Copyright (c) 2023 Omar Polo <op@omarpolo.com>
3 * Copyright (c) 2014 Reyk Floeter <reyk@openbsd.org>
4 * Copyright (c) 2012 Gilles Chehade <gilles@poolp.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
19 #include "gmid.h"
21 #include <string.h>
23 #include <openssl/err.h>
24 #include <openssl/pem.h>
26 #include "log.h"
27 #include "proc.h"
29 #ifndef nitems
30 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
31 #endif
33 static void crypto_init(struct privsep *, struct privsep_proc *, void *);
34 static int crypto_dispatch_parent(int, struct privsep_proc *, struct imsg *);
35 static int crypto_dispatch_server(int, struct privsep_proc *, struct imsg *);
37 static struct privsep_proc procs[] = {
38 { "parent", PROC_PARENT, crypto_dispatch_parent },
39 { "server", PROC_SERVER, crypto_dispatch_server },
40 };
42 struct imsg_crypto_req {
43 uint64_t id;
44 char hash[TLS_CERT_HASH_SIZE];
45 size_t flen;
46 size_t tlen;
47 int padding;
48 /* followed by flen bytes of `from'. */
49 };
51 struct imsg_crypto_res {
52 uint64_t id;
53 int ret;
54 size_t len;
55 /* followed by len bytes of reply */
56 };
58 static uint64_t reqid;
59 static struct conf *conf;
61 void
62 crypto(struct privsep *ps, struct privsep_proc *p)
63 {
64 proc_run(ps, p, procs, nitems(procs), crypto_init, NULL);
65 }
67 static void
68 crypto_init(struct privsep *ps, struct privsep_proc *p, void *arg)
69 {
70 #if 0
71 static volatile int attached;
72 while (!attached) sleep(1);
73 #endif
75 conf = ps->ps_env;
77 sandbox_crypto_process();
78 }
80 static int
81 crypto_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
82 {
83 switch (imsg->hdr.type) {
84 case IMSG_RECONF_START:
85 case IMSG_RECONF_CERT:
86 case IMSG_RECONF_KEY:
87 case IMSG_RECONF_END:
88 if (config_recv(conf, imsg) == -1)
89 return -1;
90 break;
91 default:
92 return -1;
93 }
95 return 0;
96 }
98 static EVP_PKEY *
99 get_pkey(const char *hash)
101 struct pki *pki;
103 TAILQ_FOREACH(pki, &conf->pkis, pkis) {
104 if (!strcmp(pki->hash, hash))
105 return pki->pkey;
108 return NULL;
111 static int
112 crypto_dispatch_server(int fd, struct privsep_proc *p, struct imsg *imsg)
114 struct privsep *ps = p->p_ps;
115 RSA *rsa = NULL;
116 EC_KEY *ecdsa = NULL;
117 EVP_PKEY *pkey;
118 struct imsg_crypto_req req;
119 struct imsg_crypto_res res;
120 struct iovec iov[2];
121 const void *from;
122 unsigned char *data, *to;
123 size_t datalen;
124 int n, ret;
125 unsigned int len;
127 data = imsg->data;
128 datalen = IMSG_DATA_SIZE(imsg);
130 switch (imsg->hdr.type) {
131 case IMSG_CRYPTO_RSA_PRIVENC:
132 case IMSG_CRYPTO_RSA_PRIVDEC:
133 if (datalen < sizeof(req))
134 fatalx("size mismatch for imsg %d", imsg->hdr.type);
135 memcpy(&req, data, sizeof(req));
136 if (datalen != sizeof(req) + req.flen)
137 fatalx("size mismatch for imsg %d", imsg->hdr.type);
138 from = data + sizeof(req);
140 if ((pkey = get_pkey(req.hash)) == NULL ||
141 (rsa = EVP_PKEY_get1_RSA(pkey)) == NULL)
142 fatalx("invalid pkey hash");
144 if ((to = calloc(1, req.tlen)) == NULL)
145 fatal("calloc");
147 if (imsg->hdr.type == IMSG_CRYPTO_RSA_PRIVENC)
148 ret = RSA_private_encrypt(req.flen, from,
149 to, rsa, req.padding);
150 else
151 ret = RSA_private_decrypt(req.flen, from,
152 to, rsa, req.padding);
154 memset(&res, 0, sizeof(res));
155 res.id = req.id;
156 res.ret = ret;
158 memset(&iov, 0, sizeof(iov));
159 n = 0;
160 iov[n].iov_base = &res;
161 iov[n].iov_len = sizeof(res);
162 n++;
164 if (ret > 0) {
165 res.len = ret;
166 iov[n].iov_base = to;
167 iov[n].iov_len = ret;
168 n++;
171 log_debug("replying to server #%d", imsg->hdr.pid);
172 if (proc_composev_imsg(ps, PROC_SERVER, imsg->hdr.pid - 1,
173 imsg->hdr.type, 0, -1, iov, n) == -1)
174 fatal("proc_composev_imsg");
176 if (proc_flush_imsg(ps, PROC_SERVER, imsg->hdr.pid - 1) == -1)
177 fatal("proc_flush_imsg");
179 free(to);
180 RSA_free(rsa);
181 break;
183 case IMSG_CRYPTO_ECDSA_SIGN:
184 if (datalen < sizeof(req))
185 fatalx("size mismatch for imsg %d", imsg->hdr.type);
186 memcpy(&req, data, sizeof(req));
187 if (datalen != sizeof(req) + req.flen)
188 fatalx("size mismatch for imsg %d", imsg->hdr.type);
189 from = data + sizeof(req);
191 if ((pkey = get_pkey(req.hash)) == NULL ||
192 (ecdsa = EVP_PKEY_get1_EC_KEY(pkey)) == NULL)
193 fatalx("invalid pkey hash");
195 len = ECDSA_size(ecdsa);
196 if ((to = calloc(1, len)) == NULL)
197 fatal("calloc");
198 ret = ECDSA_sign(0, from, req.flen, to, &len, ecdsa);
200 memset(&res, 0, sizeof(res));
201 res.id = req.id;
202 res.ret = ret;
204 memset(&iov, 0, sizeof(iov));
205 n = 0;
206 iov[0].iov_base = &res;
207 iov[0].iov_len = sizeof(res);
208 n++;
210 if (ret > 0) {
211 res.len = len;
212 iov[n].iov_base = to;
213 iov[n].iov_len = len;
214 n++;
217 log_debug("replying to server #%d", imsg->hdr.pid);
218 if (proc_composev_imsg(ps, PROC_SERVER, imsg->hdr.pid - 1,
219 imsg->hdr.type, 0, -1, iov, n) == -1)
220 fatal("proc_composev_imsg");
222 if (proc_flush_imsg(ps, PROC_SERVER, imsg->hdr.pid - 1) == -1)
223 fatal("proc_flush_imsg");
225 free(to);
226 EC_KEY_free(ecdsa);
227 break;
229 default:
230 return -1;
233 return 0;
237 /*
238 * RSA privsep engine (called from unprivileged processes)
239 */
241 static const RSA_METHOD *rsa_default;
242 static RSA_METHOD *rsae_method;
244 static int
245 rsae_send_imsg(int flen, const unsigned char *from, unsigned char *to,
246 RSA *rsa, int padding, unsigned int cmd)
248 struct imsg_crypto_req req;
249 struct iovec iov[2];
250 struct imsg_crypto_res res;
251 struct imsgev *iev;
252 struct privsep_proc *p;
253 struct privsep *ps = conf->ps;
254 struct imsgbuf *ibuf;
255 struct imsg imsg;
256 int ret = 0;
257 int n, done = 0;
258 const void *toptr;
259 char *hash;
260 unsigned char *data;
261 size_t datalen;
263 if ((hash = RSA_get_ex_data(rsa, 0)) == NULL)
264 return (0);
266 /*
267 * Send a synchronous imsg because we cannot defer the RSA
268 * operation in OpenSSL's engine layer.
269 */
270 memset(&req, 0, sizeof(req));
271 req.id = ++reqid;
272 if (strlcpy(req.hash, hash, sizeof(req.hash)) >= sizeof(req.hash))
273 fatalx("%s: hash too long (%zu)", __func__, strlen(hash));
274 req.flen = flen;
275 req.tlen = RSA_size(rsa);
276 req.padding = padding;
278 memset(&iov, 0, sizeof(iov));
279 iov[0].iov_base = &req;
280 iov[0].iov_len = sizeof(req);
281 iov[1].iov_base = (void *)from;
282 iov[1].iov_len = flen;
284 if (proc_composev(ps, PROC_CRYPTO, cmd, iov, 2) == -1)
285 fatal("proc_composev");
287 if (proc_flush_imsg(ps, PROC_CRYPTO, -1) == -1)
288 fatal("proc_flush_imsg");
290 iev = ps->ps_ievs[PROC_CRYPTO];
291 p = iev->proc;
292 ibuf = &iev->ibuf;
294 while (!done) {
295 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
296 fatalx("imsg_read");
297 if (n == 0)
298 fatalx("pipe closed");
300 while (!done) {
301 if ((n = imsg_get(ibuf, &imsg)) == -1)
302 fatalx("imsg_get error");
303 if (n == 0)
304 break;
306 #if DEBUG > 1
307 log_debug(
308 "%s: %s %d got imsg %d peerid %d from %s %d",
309 __func__, title, 1, imsg.hdr.type,
310 imsg.hdr.peerid, "crypto", imsg.hdr.pid);
311 #endif
313 if ((p->p_cb)(ibuf->fd, p, &imsg) == 0) {
314 /* Message was handled by the callback */
315 imsg_free(&imsg);
316 continue;
319 switch (imsg.hdr.type) {
320 case IMSG_CRYPTO_RSA_PRIVENC:
321 case IMSG_CRYPTO_RSA_PRIVDEC:
322 break;
323 default:
324 fatalx("%s: %s %d got invalid imsg %d"
325 " peerid %d from %s %d",
326 __func__, "server", ps->ps_instance + 1,
327 imsg.hdr.type, imsg.hdr.peerid,
328 "crypto", imsg.hdr.pid);
331 data = imsg.data;
332 datalen = IMSG_DATA_SIZE(&imsg);
333 if (datalen < sizeof(res))
334 fatalx("size mismatch for imsg %d",
335 imsg.hdr.type);
336 memcpy(&res, data, sizeof(res));
337 if (datalen != sizeof(res) + res.ret)
338 fatalx("size mismatch for imsg %d",
339 imsg.hdr.type);
340 ret = res.ret;
341 toptr = data + sizeof(res);
343 if (res.id != reqid)
344 fatalx("invalid id; got %llu, want %llu",
345 (unsigned long long)res.id,
346 (unsigned long long)reqid);
347 if (res.ret > 0)
348 memcpy(to, toptr, res.len);
350 done = 1;
352 imsg_free(&imsg);
355 imsg_event_add(iev);
357 return (ret);
360 static int
361 rsae_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa,
362 int padding)
364 log_debug("debug: %s", __func__);
365 if (RSA_get_ex_data(rsa, 0) != NULL)
366 return (rsae_send_imsg(flen, from, to, rsa, padding,
367 IMSG_CRYPTO_RSA_PRIVENC));
368 return (RSA_meth_get_priv_enc(rsa_default)(flen, from, to, rsa, padding));
371 static int
372 rsae_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa,
373 int padding)
375 log_debug("debug: %s", __func__);
376 if (RSA_get_ex_data(rsa, 0) != NULL)
377 return (rsae_send_imsg(flen, from, to, rsa, padding,
378 IMSG_CRYPTO_RSA_PRIVDEC));
380 return (RSA_meth_get_priv_dec(rsa_default)(flen, from, to, rsa, padding));
384 /*
385 * ECDSA privsep engine (called from unprivileged processes)
386 */
388 static const EC_KEY_METHOD *ecdsa_default;
389 static EC_KEY_METHOD *ecdsae_method;
391 static ECDSA_SIG *
392 ecdsae_send_enc_imsg(const unsigned char *dgst, int dgst_len,
393 const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey)
395 ECDSA_SIG *sig = NULL;
396 struct imsg_crypto_req req;
397 struct iovec iov[2];
398 struct imsg_crypto_res res;
399 struct imsgev *iev;
400 struct privsep_proc *p;
401 struct privsep *ps = conf->ps;
402 struct imsgbuf *ibuf;
403 struct imsg imsg;
404 int n, done = 0;
405 const void *toptr;
406 char *hash;
407 unsigned char *data;
408 size_t datalen;
410 if ((hash = EC_KEY_get_ex_data(eckey, 0)) == NULL)
411 return (0);
413 /*
414 * Send a synchronous imsg because we cannot defer the RSA
415 * operation in OpenSSL's engine layer.
416 */
417 memset(&req, 0, sizeof(req));
418 req.id = ++reqid;
419 if (strlcpy(req.hash, hash, sizeof(req.hash)) >= sizeof(req.hash))
420 fatalx("%s: hash too long (%zu)", __func__, strlen(hash));
421 req.flen = dgst_len;
423 memset(&iov, 0, sizeof(iov));
424 iov[0].iov_base = &req;
425 iov[0].iov_len = sizeof(req);
426 iov[1].iov_base = (void *)dgst;
427 iov[1].iov_len = dgst_len;
429 if (proc_composev(ps, PROC_CRYPTO, IMSG_CRYPTO_ECDSA_SIGN, iov, 2) == -1)
430 fatal("proc_composev");
432 if (proc_flush_imsg(ps, PROC_CRYPTO, -1) == -1)
433 fatal("proc_flush_imsg");
435 iev = ps->ps_ievs[PROC_CRYPTO];
436 p = iev->proc;
437 ibuf = &iev->ibuf;
439 while (!done) {
440 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
441 fatalx("imsg_read");
442 if (n == 0)
443 fatalx("pipe closed");
445 while (!done) {
446 if ((n = imsg_get(ibuf, &imsg)) == -1)
447 fatalx("imsg_get error");
448 if (n == 0)
449 break;
451 #if DEBUG > 1
452 log_debug(
453 "%s: %s %d got imsg %d peerid %d from %s %d",
454 __func__, title, 1, imsg.hdr.type,
455 imsg.hdr.peerid, "crypto", imsg.hdr.pid);
456 #endif
458 if (imsg.hdr.type != IMSG_CRYPTO_ECDSA_SIGN &&
459 crypto_dispatch_server(ibuf->fd, p, &imsg) == 0) {
460 /* Message was handled by the callback */
461 imsg_free(&imsg);
462 continue;
465 if (imsg.hdr.type != IMSG_CRYPTO_ECDSA_SIGN)
466 fatalx("%s: %s %d got invalid imsg %d"
467 " peerid %d from %s %d",
468 __func__, "server", ps->ps_instance + 1,
469 imsg.hdr.type, imsg.hdr.peerid,
470 "crypto", imsg.hdr.pid);
472 data = imsg.data;
473 datalen = IMSG_DATA_SIZE(&imsg);
474 if (datalen < sizeof(res))
475 fatalx("size mismatch for imsg %d",
476 imsg.hdr.type);
477 memcpy(&res, data, sizeof(res));
478 if (datalen != sizeof(res) + res.len)
479 fatalx("size mismatch for imsg %d",
480 imsg.hdr.type);
481 toptr = data + sizeof(res);
483 if (res.id != reqid)
484 fatalx("invalid response id");
485 if (res.ret > 0) {
486 d2i_ECDSA_SIG(&sig,
487 (const unsigned char **)&toptr, res.len);
490 done = 1;
492 imsg_free(&imsg);
495 imsg_event_add(iev);
497 return (sig);
500 static ECDSA_SIG *
501 ecdsae_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
502 const BIGNUM *rp, EC_KEY *eckey)
504 ECDSA_SIG *(*psign_sig)(const unsigned char *, int, const BIGNUM *,
505 const BIGNUM *, EC_KEY *);
507 log_debug("debug: %s", __func__);
508 if (EC_KEY_get_ex_data(eckey, 0) != NULL)
509 return (ecdsae_send_enc_imsg(dgst, dgst_len, inv, rp, eckey));
510 EC_KEY_METHOD_get_sign(ecdsa_default, NULL, NULL, &psign_sig);
511 return (psign_sig(dgst, dgst_len, inv, rp, eckey));
515 /*
516 * Initialize the two engines.
517 */
519 static void
520 rsa_engine_init(void)
522 const char *errstr;
524 if ((rsa_default = RSA_get_default_method()) == NULL) {
525 errstr = "RSA_get_default_method";
526 goto fail;
529 if ((rsae_method = RSA_meth_dup(rsa_default)) == NULL) {
530 errstr = "RSA_meth_dup";
531 goto fail;
534 RSA_meth_set_priv_enc(rsae_method, rsae_priv_enc);
535 RSA_meth_set_priv_dec(rsae_method, rsae_priv_dec);
537 RSA_meth_set_flags(rsae_method,
538 RSA_meth_get_flags(rsa_default) | RSA_METHOD_FLAG_NO_CHECK);
539 RSA_meth_set0_app_data(rsae_method,
540 RSA_meth_get0_app_data(rsa_default));
542 RSA_set_default_method(rsae_method);
544 return;
546 fail:
547 ssl_error(errstr);
548 fatalx("%s", errstr);
551 static void
552 ecdsa_engine_init(void)
554 int (*sign)(int, const unsigned char *, int, unsigned char *,
555 unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *);
556 int (*sign_setup)(EC_KEY *, BN_CTX *, BIGNUM **, BIGNUM **);
557 const char *errstr;
559 if ((ecdsa_default = EC_KEY_get_default_method()) == NULL) {
560 errstr = "EC_KEY_get_default_method";
561 goto fail;
564 if ((ecdsae_method = EC_KEY_METHOD_new(ecdsa_default)) == NULL) {
565 errstr = "EC_KEY_METHOD_new";
566 goto fail;
569 EC_KEY_METHOD_get_sign(ecdsa_default, &sign, &sign_setup, NULL);
570 EC_KEY_METHOD_set_sign(ecdsae_method, sign, sign_setup,
571 ecdsae_do_sign);
573 EC_KEY_set_default_method(ecdsae_method);
575 return;
577 fail:
578 ssl_error(errstr);
579 fatalx("%s", errstr);
582 void
583 crypto_engine_init(struct conf *c)
585 conf = c;
587 rsa_engine_init();
588 ecdsa_engine_init();