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>
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.
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.
23 #include <openssl/err.h>
24 #include <openssl/pem.h>
30 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
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 },
42 struct imsg_crypto_req {
44 char hash[TLS_CERT_HASH_SIZE];
48 /* followed by flen bytes of `from'. */
51 struct imsg_crypto_res {
55 /* followed by len bytes of reply */
58 static uint64_t reqid;
59 static struct conf *conf;
62 crypto(struct privsep *ps, struct privsep_proc *p)
64 proc_run(ps, p, procs, nitems(procs), crypto_init, NULL);
68 crypto_init(struct privsep *ps, struct privsep_proc *p, void *arg)
71 static volatile int attached;
72 while (!attached) sleep(1);
77 sandbox_crypto_process();
81 crypto_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
83 switch (imsg_get_type(imsg)) {
84 case IMSG_RECONF_START:
85 case IMSG_RECONF_CERT:
88 if (config_recv(conf, imsg) == -1)
99 get_pkey(const char *hash)
103 TAILQ_FOREACH(pki, &conf->pkis, pkis) {
104 if (!strcmp(pki->hash, hash))
112 crypto_dispatch_server(int fd, struct privsep_proc *p, struct imsg *imsg)
114 struct privsep *ps = p->p_ps;
116 EC_KEY *ecdsa = NULL;
118 struct imsg_crypto_req req;
119 struct imsg_crypto_res res;
128 if (imsg_get_ibuf(imsg, &ibuf) == -1)
129 fatalx("%s: couldn't get an ibuf", __func__);
131 pid = imsg_get_pid(imsg);
132 switch (type = imsg_get_type(imsg)) {
133 case IMSG_CRYPTO_RSA_PRIVENC:
134 case IMSG_CRYPTO_RSA_PRIVDEC:
135 if (ibuf_get(&ibuf, &req, sizeof(req)) == -1 ||
136 ibuf_size(&ibuf) != req.flen)
137 fatalx("size mismatch for imsg %d", type);
138 from = ibuf_data(&ibuf);
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)
147 if (type == IMSG_CRYPTO_RSA_PRIVENC)
148 ret = RSA_private_encrypt(req.flen, from,
149 to, rsa, req.padding);
151 ret = RSA_private_decrypt(req.flen, from,
152 to, rsa, req.padding);
154 memset(&res, 0, sizeof(res));
158 memset(&iov, 0, sizeof(iov));
160 iov[n].iov_base = &res;
161 iov[n].iov_len = sizeof(res);
166 iov[n].iov_base = to;
167 iov[n].iov_len = ret;
171 log_debug("replying to server #%d", pid);
172 if (proc_composev_imsg(ps, PROC_SERVER, pid - 1,
173 type, 0, -1, iov, n) == -1)
174 fatal("proc_composev_imsg");
176 if (proc_flush_imsg(ps, PROC_SERVER, pid - 1) == -1)
177 fatal("proc_flush_imsg");
183 case IMSG_CRYPTO_ECDSA_SIGN:
184 if (ibuf_get(&ibuf, &req, sizeof(req)) == -1 ||
185 ibuf_size(&ibuf) != req.flen)
186 fatalx("size mismatch for imsg %d", type);
187 from = ibuf_data(&ibuf);
189 if ((pkey = get_pkey(req.hash)) == NULL ||
190 (ecdsa = EVP_PKEY_get1_EC_KEY(pkey)) == NULL)
191 fatalx("invalid pkey hash");
193 len = ECDSA_size(ecdsa);
194 if ((to = calloc(1, len)) == NULL)
196 ret = ECDSA_sign(0, from, req.flen, to, &len, ecdsa);
198 memset(&res, 0, sizeof(res));
202 memset(&iov, 0, sizeof(iov));
204 iov[0].iov_base = &res;
205 iov[0].iov_len = sizeof(res);
210 iov[n].iov_base = to;
211 iov[n].iov_len = len;
215 log_debug("replying to server #%d", pid);
216 if (proc_composev_imsg(ps, PROC_SERVER, pid - 1,
217 type, 0, -1, iov, n) == -1)
218 fatal("proc_composev_imsg");
220 if (proc_flush_imsg(ps, PROC_SERVER, pid - 1) == -1)
221 fatal("proc_flush_imsg");
236 * RSA privsep engine (called from unprivileged processes)
239 static const RSA_METHOD *rsa_default;
240 static RSA_METHOD *rsae_method;
243 rsae_send_imsg(int flen, const unsigned char *from, unsigned char *to,
244 RSA *rsa, int padding, unsigned int cmd)
246 struct imsg_crypto_req req;
248 struct imsg_crypto_res res;
250 struct privsep_proc *p;
251 struct privsep *ps = conf->ps;
252 struct imsgbuf *imsgbuf;
260 if ((hash = RSA_get_ex_data(rsa, 0)) == NULL)
264 * Send a synchronous imsg because we cannot defer the RSA
265 * operation in OpenSSL's engine layer.
267 memset(&req, 0, sizeof(req));
269 if (strlcpy(req.hash, hash, sizeof(req.hash)) >= sizeof(req.hash))
270 fatalx("%s: hash too long (%zu)", __func__, strlen(hash));
272 req.tlen = RSA_size(rsa);
273 req.padding = padding;
275 memset(&iov, 0, sizeof(iov));
276 iov[0].iov_base = &req;
277 iov[0].iov_len = sizeof(req);
278 iov[1].iov_base = (void *)from;
279 iov[1].iov_len = flen;
281 if (proc_composev(ps, PROC_CRYPTO, cmd, iov, 2) == -1)
282 fatal("proc_composev");
284 if (proc_flush_imsg(ps, PROC_CRYPTO, -1) == -1)
285 fatal("proc_flush_imsg");
287 iev = ps->ps_ievs[PROC_CRYPTO];
289 imsgbuf = &iev->ibuf;
292 if ((n = imsg_read(imsgbuf)) == -1 && errno != EAGAIN)
295 fatalx("pipe closed");
298 if ((n = imsg_get(imsgbuf, &imsg)) == -1)
299 fatalx("imsg_get error");
305 "%s: %s %d got imsg %d id %d from %s %d",
306 __func__, title, 1, imsg_get_type(&imsg),
307 imsg_get_id(&imsg), "crypto", imsg_get_pid(&imsg));
310 if ((p->p_cb)(imsgbuf->fd, p, &imsg) == 0) {
311 /* Message was handled by the callback */
316 switch (imsg_get_type(&imsg)) {
317 case IMSG_CRYPTO_RSA_PRIVENC:
318 case IMSG_CRYPTO_RSA_PRIVDEC:
321 fatalx("%s: %s %d got invalid imsg %d"
323 __func__, "server", ps->ps_instance + 1,
324 imsg_get_type(&imsg), imsg_get_id(&imsg),
325 "crypto", imsg_get_pid(&imsg));
328 if (imsg_get_ibuf(&imsg, &ibuf) == -1 ||
329 ibuf_get(&ibuf, &res, sizeof(res)) == -1 ||
330 (int)ibuf_size(&ibuf) != res.ret)
331 fatalx("size mismatch for imsg %d",
334 toptr = ibuf_data(&ibuf);
337 fatalx("invalid id; got %llu, want %llu",
338 (unsigned long long)res.id,
339 (unsigned long long)reqid);
341 memcpy(to, toptr, res.len);
354 rsae_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa,
357 log_debug("debug: %s", __func__);
358 if (RSA_get_ex_data(rsa, 0) != NULL)
359 return (rsae_send_imsg(flen, from, to, rsa, padding,
360 IMSG_CRYPTO_RSA_PRIVENC));
361 return (RSA_meth_get_priv_enc(rsa_default)(flen, from, to, rsa, padding));
365 rsae_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa,
368 log_debug("debug: %s", __func__);
369 if (RSA_get_ex_data(rsa, 0) != NULL)
370 return (rsae_send_imsg(flen, from, to, rsa, padding,
371 IMSG_CRYPTO_RSA_PRIVDEC));
373 return (RSA_meth_get_priv_dec(rsa_default)(flen, from, to, rsa, padding));
378 * ECDSA privsep engine (called from unprivileged processes)
381 static const EC_KEY_METHOD *ecdsa_default;
382 static EC_KEY_METHOD *ecdsae_method;
385 ecdsae_send_enc_imsg(const unsigned char *dgst, int dgst_len,
386 const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey)
388 ECDSA_SIG *sig = NULL;
389 struct imsg_crypto_req req;
391 struct imsg_crypto_res res;
393 struct privsep_proc *p;
394 struct privsep *ps = conf->ps;
395 struct imsgbuf *imsgbuf;
402 if ((hash = EC_KEY_get_ex_data(eckey, 0)) == NULL)
406 * Send a synchronous imsg because we cannot defer the RSA
407 * operation in OpenSSL's engine layer.
409 memset(&req, 0, sizeof(req));
411 if (strlcpy(req.hash, hash, sizeof(req.hash)) >= sizeof(req.hash))
412 fatalx("%s: hash too long (%zu)", __func__, strlen(hash));
415 memset(&iov, 0, sizeof(iov));
416 iov[0].iov_base = &req;
417 iov[0].iov_len = sizeof(req);
418 iov[1].iov_base = (void *)dgst;
419 iov[1].iov_len = dgst_len;
421 if (proc_composev(ps, PROC_CRYPTO, IMSG_CRYPTO_ECDSA_SIGN, iov, 2) == -1)
422 fatal("proc_composev");
424 if (proc_flush_imsg(ps, PROC_CRYPTO, -1) == -1)
425 fatal("proc_flush_imsg");
427 iev = ps->ps_ievs[PROC_CRYPTO];
429 imsgbuf = &iev->ibuf;
432 if ((n = imsg_read(imsgbuf)) == -1 && errno != EAGAIN)
435 fatalx("pipe closed");
438 if ((n = imsg_get(imsgbuf, &imsg)) == -1)
439 fatalx("imsg_get error");
445 "%s: %s %d got imsg %d peerid %d from %s %d",
446 __func__, title, 1, imsg.hdr.type,
447 imsg.hdr.peerid, "crypto", imsg.hdr.pid);
450 if (imsg.hdr.type != IMSG_CRYPTO_ECDSA_SIGN &&
451 crypto_dispatch_server(imsgbuf->fd, p, &imsg)
453 /* Message was handled by the callback */
458 if (imsg.hdr.type != IMSG_CRYPTO_ECDSA_SIGN)
459 fatalx("%s: %s %d got invalid imsg %d"
460 " peerid %d from %s %d",
461 __func__, "server", ps->ps_instance + 1,
462 imsg.hdr.type, imsg.hdr.peerid,
463 "crypto", imsg.hdr.pid);
465 if (imsg_get_ibuf(&imsg, &ibuf) == -1 ||
466 ibuf_get(&ibuf, &res, sizeof(res)) == -1 ||
467 ibuf_size(&ibuf) != res.len)
468 fatalx("size mismatch for imsg %d",
471 toptr = ibuf_data(&ibuf);
474 fatalx("invalid response id");
477 (const unsigned char **)&toptr, res.len);
491 ecdsae_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
492 const BIGNUM *rp, EC_KEY *eckey)
494 ECDSA_SIG *(*psign_sig)(const unsigned char *, int, const BIGNUM *,
495 const BIGNUM *, EC_KEY *);
497 log_debug("debug: %s", __func__);
498 if (EC_KEY_get_ex_data(eckey, 0) != NULL)
499 return (ecdsae_send_enc_imsg(dgst, dgst_len, inv, rp, eckey));
500 EC_KEY_METHOD_get_sign(ecdsa_default, NULL, NULL, &psign_sig);
501 return (psign_sig(dgst, dgst_len, inv, rp, eckey));
506 * Initialize the two engines.
510 rsa_engine_init(void)
514 if ((rsa_default = RSA_get_default_method()) == NULL) {
515 errstr = "RSA_get_default_method";
519 if ((rsae_method = RSA_meth_dup(rsa_default)) == NULL) {
520 errstr = "RSA_meth_dup";
524 RSA_meth_set_priv_enc(rsae_method, rsae_priv_enc);
525 RSA_meth_set_priv_dec(rsae_method, rsae_priv_dec);
527 RSA_meth_set_flags(rsae_method,
528 RSA_meth_get_flags(rsa_default) | RSA_METHOD_FLAG_NO_CHECK);
529 RSA_meth_set0_app_data(rsae_method,
530 RSA_meth_get0_app_data(rsa_default));
532 RSA_set_default_method(rsae_method);
538 fatalx("%s", errstr);
542 ecdsa_engine_init(void)
544 int (*sign)(int, const unsigned char *, int, unsigned char *,
545 unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *);
546 int (*sign_setup)(EC_KEY *, BN_CTX *, BIGNUM **, BIGNUM **);
549 if ((ecdsa_default = EC_KEY_get_default_method()) == NULL) {
550 errstr = "EC_KEY_get_default_method";
554 if ((ecdsae_method = EC_KEY_METHOD_new(ecdsa_default)) == NULL) {
555 errstr = "EC_KEY_METHOD_new";
559 EC_KEY_METHOD_get_sign(ecdsa_default, &sign, &sign_setup, NULL);
560 EC_KEY_METHOD_set_sign(ecdsae_method, sign, sign_setup,
563 EC_KEY_set_default_method(ecdsae_method);
569 fatalx("%s", errstr);
573 crypto_engine_init(struct conf *c)