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>
25 #include <openssl/engine.h>
27 #include "log.h"
28 #include "proc.h"
30 #ifndef nitems
31 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
32 #endif
34 static void crypto_init(struct privsep *, struct privsep_proc *, void *);
35 static int crypto_dispatch_parent(int, struct privsep_proc *, struct imsg *);
36 static int crypto_dispatch_server(int, struct privsep_proc *, struct imsg *);
38 static struct privsep_proc procs[] = {
39 { "parent", PROC_PARENT, crypto_dispatch_parent },
40 { "server", PROC_SERVER, crypto_dispatch_server },
41 };
43 struct imsg_crypto_req {
44 uint64_t id;
45 char hash[TLS_CERT_HASH_SIZE];
46 size_t flen;
47 size_t tlen;
48 int padding;
49 /* followed by flen bytes of `from'. */
50 };
52 struct imsg_crypto_res {
53 uint64_t id;
54 int ret;
55 size_t len;
56 /* followed by len bytes of reply */
57 };
59 static uint64_t reqid;
60 static struct conf *conf;
62 void
63 crypto(struct privsep *ps, struct privsep_proc *p)
64 {
65 proc_run(ps, p, procs, nitems(procs), crypto_init, NULL);
66 }
68 static void
69 crypto_init(struct privsep *ps, struct privsep_proc *p, void *arg)
70 {
71 #if 0
72 static volatile int attached;
73 while (!attached) sleep(1);
74 #endif
76 conf = ps->ps_env;
78 sandbox_crypto_process();
79 }
81 static int
82 crypto_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
83 {
84 switch (imsg->hdr.type) {
85 case IMSG_RECONF_START:
86 case IMSG_RECONF_CERT:
87 case IMSG_RECONF_KEY:
88 case IMSG_RECONF_END:
89 if (config_recv(conf, imsg) == -1)
90 return -1;
91 break;
92 default:
93 return -1;
94 }
96 return 0;
97 }
99 static EVP_PKEY *
100 get_pkey(const char *hash)
102 struct pki *pki;
104 TAILQ_FOREACH(pki, &conf->pkis, pkis) {
105 if (!strcmp(pki->hash, hash))
106 return pki->pkey;
109 return NULL;
112 static int
113 crypto_dispatch_server(int fd, struct privsep_proc *p, struct imsg *imsg)
115 struct privsep *ps = p->p_ps;
116 RSA *rsa;
117 EC_KEY *ecdsa;
118 EVP_PKEY *pkey;
119 struct imsg_crypto_req req;
120 struct imsg_crypto_res res;
121 struct iovec iov[2];
122 const void *from;
123 unsigned char *to;
124 size_t datalen;
125 int n, len, ret;
127 datalen = IMSG_DATA_SIZE(imsg);
129 switch (imsg->hdr.type) {
130 case IMSG_CRYPTO_RSA_PRIVENC:
131 case IMSG_CRYPTO_RSA_PRIVDEC:
132 if (datalen < sizeof(req))
133 fatalx("size mismatch for imsg %d", imsg->hdr.type);
134 memcpy(&req, imsg->data, sizeof(req));
135 if (datalen != sizeof(req) + req.flen)
136 fatalx("size mismatch for imsg %d", imsg->hdr.type);
137 from = imsg->data + sizeof(req);
139 if ((pkey = get_pkey(req.hash)) == NULL ||
140 (rsa = EVP_PKEY_get1_RSA(pkey)) == NULL)
141 fatalx("invalid pkey hash");
143 if ((to = calloc(1, req.tlen)) == NULL)
144 fatal("calloc");
146 switch (imsg->hdr.type) {
147 case IMSG_CRYPTO_RSA_PRIVENC:
148 ret = RSA_private_encrypt(req.flen, from,
149 to, rsa, req.padding);
150 break;
151 case IMSG_CRYPTO_RSA_PRIVDEC:
152 ret = RSA_private_decrypt(req.flen, from,
153 to, rsa, req.padding);
154 break;
157 memset(&res, 0, sizeof(res));
158 res.id = req.id;
159 res.ret = ret;
161 memset(&iov, 0, sizeof(iov));
162 n = 0;
163 iov[n].iov_base = &res;
164 iov[n].iov_len = sizeof(res);
165 n++;
167 if (ret > 0) {
168 res.len = ret;
169 iov[n].iov_base = to;
170 iov[n].iov_len = ret;
171 n++;
174 log_debug("replying to server #%d", imsg->hdr.pid);
175 if (proc_composev_imsg(ps, PROC_SERVER, imsg->hdr.pid - 1,
176 imsg->hdr.type, 0, -1, iov, n) == -1)
177 fatal("proc_composev_imsg");
179 if (proc_flush_imsg(ps, PROC_SERVER, imsg->hdr.pid - 1) == -1)
180 fatal("proc_flush_imsg");
182 free(to);
183 RSA_free(rsa);
184 break;
186 case IMSG_CRYPTO_ECDSA_SIGN:
187 if (datalen < sizeof(req))
188 fatalx("size mismatch for imsg %d", imsg->hdr.type);
189 memcpy(&req, imsg->data, sizeof(req));
190 if (datalen != sizeof(req) + req.flen)
191 fatalx("size mismatch for imsg %d", imsg->hdr.type);
192 from = imsg->data + sizeof(req);
194 if ((pkey = get_pkey(req.hash)) == NULL ||
195 (ecdsa = EVP_PKEY_get1_EC_KEY(pkey)) == NULL)
196 fatalx("invalid pkey hash");
198 len = ECDSA_size(ecdsa);
199 if ((to = calloc(1, len)) == NULL)
200 fatal("calloc");
201 ret = ECDSA_sign(0, from, req.flen, to, &len, ecdsa);
203 memset(&res, 0, sizeof(res));
204 res.id = req.id;
205 res.ret = ret;
207 memset(&iov, 0, sizeof(iov));
208 n = 0;
209 iov[0].iov_base = &res;
210 iov[1].iov_len = sizeof(res);
211 n++;
213 if (ret > 0) {
214 res.len = len;
215 iov[n].iov_base = to;
216 iov[n].iov_len = len;
217 n++;
220 log_debug("replying to server #%d", imsg->hdr.pid);
221 if (proc_composev_imsg(ps, PROC_SERVER, imsg->hdr.pid - 1,
222 imsg->hdr.type, 0, -1, iov, n) == -1)
223 fatal("proc_composev_imsg");
225 if (proc_flush_imsg(ps, PROC_SERVER, imsg->hdr.pid - 1) == -1)
226 fatal("proc_flush_imsg");
228 free(to);
229 EC_KEY_free(ecdsa);
230 break;
232 default:
233 return -1;
236 return 0;
240 /*
241 * RSA privsep engine (called from unprivileged processes)
242 */
244 static const RSA_METHOD *rsa_default;
245 static RSA_METHOD *rsae_method;
247 static int
248 rsae_send_imsg(int flen, const unsigned char *from, unsigned char *to,
249 RSA *rsa, int padding, unsigned int cmd)
251 struct imsg_crypto_req req;
252 struct iovec iov[2];
253 struct imsg_crypto_res res;
254 struct imsgev *iev;
255 struct privsep_proc *p;
256 struct privsep *ps = conf->ps;
257 struct imsgbuf *ibuf;
258 struct imsg imsg;
259 int ret = 0;
260 int n, done = 0;
261 const void *toptr;
262 char *hash;
263 size_t datalen;
265 if ((hash = RSA_get_ex_data(rsa, 0)) == NULL)
266 return (0);
268 /*
269 * Send a synchronous imsg because we cannot defer the RSA
270 * operation in OpenSSL's engine layer.
271 */
272 memset(&req, 0, sizeof(req));
273 req.id = ++reqid;
274 if (strlcpy(req.hash, hash, sizeof(req.hash)) >= sizeof(req.hash))
275 fatalx("%s: hash too long (%zu)", __func__, strlen(hash));
276 req.flen = flen;
277 req.tlen = RSA_size(rsa);
278 req.padding = padding;
280 memset(&iov, 0, sizeof(iov));
281 iov[0].iov_base = &req;
282 iov[0].iov_len = sizeof(req);
283 iov[1].iov_base = (void *)from;
284 iov[1].iov_len = flen;
286 if (proc_composev(ps, PROC_CRYPTO, cmd, iov, 2) == -1)
287 fatal("proc_composev");
289 if (proc_flush_imsg(ps, PROC_CRYPTO, -1) == -1)
290 fatal("proc_flush_imsg");
292 iev = ps->ps_ievs[PROC_CRYPTO];
293 p = iev->proc;
294 ibuf = &iev->ibuf;
296 while (!done) {
297 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
298 fatalx("imsg_read");
299 if (n == 0)
300 fatalx("pipe closed");
302 while (!done) {
303 if ((n = imsg_get(ibuf, &imsg)) == -1)
304 fatalx("imsg_get error");
305 if (n == 0)
306 break;
308 #if DEBUG > 1
309 log_debug(
310 "%s: %s %d got imsg %d peerid %d from %s %d",
311 __func__, title, 1, imsg.hdr.type,
312 imsg.hdr.peerid, "crypto", imsg.hdr.pid);
313 #endif
315 if ((p->p_cb)(ibuf->fd, p, &imsg) == 0) {
316 /* Message was handled by the callback */
317 imsg_free(&imsg);
318 continue;
321 switch (imsg.hdr.type) {
322 case IMSG_CRYPTO_RSA_PRIVENC:
323 case IMSG_CRYPTO_RSA_PRIVDEC:
324 break;
325 default:
326 fatalx("%s: %s %d got invalid imsg %d"
327 " peerid %d from %s %d",
328 __func__, "server", ps->ps_instance + 1,
329 imsg.hdr.type, imsg.hdr.peerid,
330 "crypto", imsg.hdr.pid);
333 datalen = IMSG_DATA_SIZE(&imsg);
334 if (datalen < sizeof(res))
335 fatalx("size mismatch for imsg %d",
336 imsg.hdr.type);
337 memcpy(&res, imsg.data, sizeof(res));
338 if (datalen != sizeof(res) + res.ret)
339 fatalx("size mismatch for imsg %d",
340 imsg.hdr.type);
341 ret = res.ret;
342 toptr = imsg.data + sizeof(res);
344 if (res.id != reqid)
345 fatalx("invalid response id"
346 " got %llu, want %llu", res.id, reqid);
347 if (res.ret > 0)
348 memcpy(to, toptr, res.len);
350 log_warnx("the return is %d", ret);
352 done = 1;
354 imsg_free(&imsg);
357 imsg_event_add(iev);
359 return (ret);
362 static int
363 rsae_pub_enc(int flen,const unsigned char *from, unsigned char *to, RSA *rsa,
364 int padding)
366 log_debug("debug: %s", __func__);
367 return (RSA_meth_get_pub_enc(rsa_default)(flen, from, to, rsa, padding));
370 static int
371 rsae_pub_dec(int flen,const unsigned char *from, unsigned char *to, RSA *rsa,
372 int padding)
374 log_debug("debug: %s", __func__);
375 return (RSA_meth_get_pub_dec(rsa_default)(flen, from, to, rsa, padding));
378 static int
379 rsae_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa,
380 int padding)
382 log_debug("debug: %s", __func__);
383 if (RSA_get_ex_data(rsa, 0) != NULL)
384 return (rsae_send_imsg(flen, from, to, rsa, padding,
385 IMSG_CRYPTO_RSA_PRIVENC));
386 return (RSA_meth_get_priv_enc(rsa_default)(flen, from, to, rsa, padding));
389 static int
390 rsae_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa,
391 int padding)
393 log_debug("debug: %s", __func__);
394 if (RSA_get_ex_data(rsa, 0) != NULL)
395 return (rsae_send_imsg(flen, from, to, rsa, padding,
396 IMSG_CRYPTO_RSA_PRIVDEC));
398 return (RSA_meth_get_priv_dec(rsa_default)(flen, from, to, rsa, padding));
401 static int
402 rsae_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
404 log_debug("debug: %s", __func__);
405 return (RSA_meth_get_mod_exp(rsa_default)(r0, I, rsa, ctx));
408 static int
409 rsae_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
410 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
412 log_debug("debug: %s", __func__);
413 return (RSA_meth_get_bn_mod_exp(rsa_default)(r, a, p, m, ctx, m_ctx));
416 static int
417 rsae_init(RSA *rsa)
419 log_debug("debug: %s", __func__);
420 if (RSA_meth_get_init(rsa_default) == NULL)
421 return (1);
422 return (RSA_meth_get_init(rsa_default)(rsa));
425 static int
426 rsae_finish(RSA *rsa)
428 log_debug("debug: %s", __func__);
429 if (RSA_meth_get_finish(rsa_default) == NULL)
430 return (1);
431 return (RSA_meth_get_finish(rsa_default)(rsa));
434 static int
435 rsae_keygen(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
437 log_debug("debug: %s", __func__);
438 return (RSA_meth_get_keygen(rsa_default)(rsa, bits, e, cb));
442 /*
443 * ECDSA privsep engine (called from unprivileged processes)
444 */
446 static const EC_KEY_METHOD *ecdsa_default;
447 static EC_KEY_METHOD *ecdsae_method;
449 static ECDSA_SIG *
450 ecdsae_send_enc_imsg(const unsigned char *dgst, int dgst_len,
451 const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey)
453 ECDSA_SIG *sig = NULL;
454 struct imsg_crypto_req req;
455 struct iovec iov[2];
456 struct imsg_crypto_res res;
457 struct imsgev *iev;
458 struct privsep_proc *p;
459 struct privsep *ps = conf->ps;
460 struct imsgbuf *ibuf;
461 struct imsg imsg;
462 int n, done = 0;
463 const void *toptr;
464 char *hash;
465 size_t datalen;
467 if ((hash = EC_KEY_get_ex_data(eckey, 0)) == NULL)
468 return (0);
470 /*
471 * Send a synchronous imsg because we cannot defer the RSA
472 * operation in OpenSSL's engine layer.
473 */
474 memset(&req, 0, sizeof(req));
475 req.id = reqid++;
476 if (strlcpy(req.hash, hash, sizeof(req.hash)) >= sizeof(req.hash))
477 fatalx("%s: hash too long (%zu)", __func__, strlen(hash));
478 req.flen = dgst_len;
480 memset(&iov, 0, sizeof(iov));
481 iov[0].iov_base = &req;
482 iov[0].iov_len = sizeof(req);
483 iov[1].iov_base = (void *)dgst;
484 iov[1].iov_len = dgst_len;
486 if (proc_composev(ps, PROC_CRYPTO, IMSG_CRYPTO_ECDSA_SIGN, iov, 2) == -1)
487 fatal("proc_composev");
489 if (proc_flush_imsg(ps, PROC_CRYPTO, -1) == -1)
490 fatal("proc_flush_imsg");
492 iev = ps->ps_ievs[PROC_CRYPTO];
493 p = iev->proc;
494 ibuf = &iev->ibuf;
496 while (!done) {
497 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
498 fatalx("imsg_read");
499 if (n == 0)
500 fatalx("pipe closed");
502 while (!done) {
503 if ((n = imsg_get(ibuf, &imsg)) == -1)
504 fatalx("imsg_get error");
505 if (n == 0)
506 break;
508 #if DEBUG > 1
509 log_debug(
510 "%s: %s %d got imsg %d peerid %d from %s %d",
511 __func__, title, 1, imsg.hdr.type,
512 imsg.hdr.peerid, "crypto", imsg.hdr.pid);
513 #endif
515 if (crypto_dispatch_server(ibuf->fd, p, &imsg) == 0) {
516 /* Message was handled by the callback */
517 imsg_free(&imsg);
518 continue;
521 if (imsg.hdr.type != IMSG_CRYPTO_ECDSA_SIGN)
522 fatalx("%s: %s %d got invalid imsg %d"
523 " peerid %d from %s %d",
524 __func__, "server", ps->ps_instance + 1,
525 imsg.hdr.type, imsg.hdr.peerid,
526 "crypto", imsg.hdr.pid);
528 datalen = IMSG_DATA_SIZE(&imsg);
529 if (datalen < sizeof(res))
530 fatalx("size mismatch for imsg %d",
531 imsg.hdr.type);
532 memcpy(&res, imsg.data, sizeof(res));
533 if (datalen != sizeof(res) + res.ret)
534 fatalx("size mismatch for imsg %d",
535 imsg.hdr.type);
536 toptr = imsg.data + sizeof(res);
538 if (res.id != reqid)
539 fatalx("invalid response id");
540 if (res.ret > 0) {
541 d2i_ECDSA_SIG(&sig,
542 (const unsigned char **)&toptr, res.len);
545 done = 1;
547 imsg_free(&imsg);
550 imsg_event_add(iev);
552 return (sig);
555 static int
556 ecdsae_keygen(EC_KEY *eckey)
558 int (*keygen)(EC_KEY *);
560 log_debug("debug: %s", __func__);
561 EC_KEY_METHOD_get_keygen(ecdsa_default, &keygen);
562 return (keygen(eckey));
565 static int
566 ecdsae_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
567 EC_KEY *ecdh, void *(*kdf)(const void *, size_t, void *, size_t *))
569 int (*ckey)(void *, size_t, const EC_POINT *, EC_KEY *,
570 void *(*)(const void *, size_t, void *, size_t *));
572 log_debug("debug: %s", __func__);
573 EC_KEY_METHOD_get_compute_key(ecdsa_default, &ckey);
574 return (ckey(out, outlen, pub_key, ecdh, kdf));
577 static int
578 ecdsae_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
579 unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey)
581 int (*sign)(int, const unsigned char *, int, unsigned char *,
582 unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *);
584 log_debug("debug: %s", __func__);
585 EC_KEY_METHOD_get_sign(ecdsa_default, &sign, NULL, NULL);
586 return (sign(type, dgst, dlen, sig, siglen, kinv, r, eckey));
589 static ECDSA_SIG *
590 ecdsae_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
591 const BIGNUM *rp, EC_KEY *eckey)
593 ECDSA_SIG *(*psign_sig)(const unsigned char *, int, const BIGNUM *,
594 const BIGNUM *, EC_KEY *);
596 log_debug("debug: %s", __func__);
597 if (EC_KEY_get_ex_data(eckey, 0) != NULL)
598 return (ecdsae_send_enc_imsg(dgst, dgst_len, inv, rp, eckey));
599 EC_KEY_METHOD_get_sign(ecdsa_default, NULL, NULL, &psign_sig);
600 return (psign_sig(dgst, dgst_len, inv, rp, eckey));
603 static int
604 ecdsae_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, BIGNUM **r)
606 int (*psign_setup)(EC_KEY *, BN_CTX *, BIGNUM **, BIGNUM **);
608 log_debug("debug: %s", __func__);
609 EC_KEY_METHOD_get_sign(ecdsa_default, NULL, &psign_setup, NULL);
610 return (psign_setup(eckey, ctx, kinv, r));
613 static int
614 ecdsae_verify(int type, const unsigned char *dgst, int dgst_len,
615 const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
617 int (*verify)(int, const unsigned char *, int, const unsigned char *,
618 int, EC_KEY *);
620 log_debug("debug: %s", __func__);
621 EC_KEY_METHOD_get_verify(ecdsa_default, &verify, NULL);
622 return (verify(type, dgst, dgst_len, sigbuf, sig_len, eckey));
625 static int
626 ecdsae_do_verify(const unsigned char *dgst, int dgst_len,
627 const ECDSA_SIG *sig, EC_KEY *eckey)
629 int (*pverify_sig)(const unsigned char *, int, const ECDSA_SIG *,
630 EC_KEY *);
632 log_debug("debug: %s", __func__);
633 EC_KEY_METHOD_get_verify(ecdsa_default, NULL, &pverify_sig);
634 return (pverify_sig(dgst, dgst_len, sig, eckey));
638 /*
639 * Initialize the two engines.
640 */
642 static void
643 rsa_engine_init(void)
645 ENGINE *e;
646 const char *errstr, *name;
648 if ((rsae_method = RSA_meth_new("RSA privsep engine", 0)) == NULL) {
649 errstr = "RSA_meth_new";
650 goto fail;
653 RSA_meth_set_pub_enc(rsae_method, rsae_pub_enc);
654 RSA_meth_set_pub_dec(rsae_method, rsae_pub_dec);
655 RSA_meth_set_priv_enc(rsae_method, rsae_priv_enc);
656 RSA_meth_set_priv_dec(rsae_method, rsae_priv_dec);
657 RSA_meth_set_mod_exp(rsae_method, rsae_mod_exp);
658 RSA_meth_set_bn_mod_exp(rsae_method, rsae_bn_mod_exp);
659 RSA_meth_set_init(rsae_method, rsae_init);
660 RSA_meth_set_finish(rsae_method, rsae_finish);
661 RSA_meth_set_keygen(rsae_method, rsae_keygen);
663 if ((e = ENGINE_get_default_RSA()) == NULL) {
664 if ((e = ENGINE_new()) == NULL) {
665 errstr = "ENGINE_new";
666 goto fail;
668 if (!ENGINE_set_name(e, RSA_meth_get0_name(rsae_method))) {
669 errstr = "ENGINE_set_name";
670 goto fail;
672 if ((rsa_default = RSA_get_default_method()) == NULL) {
673 errstr = "RSA_get_default_method";
674 goto fail;
676 } else if ((rsa_default = ENGINE_get_RSA(e)) == NULL) {
677 errstr = "ENGINE_get_RSA";
678 goto fail;
681 if ((name = ENGINE_get_name(e)) == NULL)
682 name = "unknown RSA engine";
684 log_debug("debug: %s: using %s", __func__, name);
686 if (RSA_meth_get_mod_exp(rsa_default) == NULL)
687 RSA_meth_set_mod_exp(rsae_method, NULL);
688 if (RSA_meth_get_bn_mod_exp(rsa_default) == NULL)
689 RSA_meth_set_bn_mod_exp(rsae_method, NULL);
690 if (RSA_meth_get_keygen(rsa_default) == NULL)
691 RSA_meth_set_keygen(rsae_method, NULL);
692 RSA_meth_set_flags(rsae_method,
693 RSA_meth_get_flags(rsa_default) | RSA_METHOD_FLAG_NO_CHECK);
694 RSA_meth_set0_app_data(rsae_method,
695 RSA_meth_get0_app_data(rsa_default));
697 if (!ENGINE_set_RSA(e, rsae_method)) {
698 errstr = "ENGINE_set_RSA";
699 goto fail;
701 if (!ENGINE_set_default_RSA(e)) {
702 errstr = "ENGINE_set_default_RSA";
703 goto fail;
706 return;
708 fail:
709 ssl_error(errstr);
710 fatalx("%s", errstr);
713 static void
714 ecdsa_engine_init(void)
716 ENGINE *e;
717 const char *errstr, *name;
719 if ((ecdsae_method = EC_KEY_METHOD_new(NULL)) == NULL) {
720 errstr = "EC_KEY_METHOD_new";
721 goto fail;
724 EC_KEY_METHOD_set_keygen(ecdsae_method, ecdsae_keygen);
725 EC_KEY_METHOD_set_compute_key(ecdsae_method, ecdsae_compute_key);
726 EC_KEY_METHOD_set_sign(ecdsae_method, ecdsae_sign, ecdsae_sign_setup,
727 ecdsae_do_sign);
728 EC_KEY_METHOD_set_verify(ecdsae_method, ecdsae_verify,
729 ecdsae_do_verify);
731 if ((e = ENGINE_get_default_EC()) == NULL) {
732 if ((e = ENGINE_new()) == NULL) {
733 errstr = "ENGINE_new";
734 goto fail;
736 if (!ENGINE_set_name(e, "ECDSA privsep engine")) {
737 errstr = "ENGINE_set_name";
738 goto fail;
740 if ((ecdsa_default = EC_KEY_get_default_method()) == NULL) {
741 errstr = "EC_KEY_get_default_method";
742 goto fail;
744 } else if ((ecdsa_default = ENGINE_get_EC(e)) == NULL) {
745 errstr = "ENGINE_get_EC";
746 goto fail;
749 if ((name = ENGINE_get_name(e)) == NULL)
750 name = "unknown ECDSA engine";
752 log_debug("debug: %s: using %s", __func__, name);
754 if (!ENGINE_set_EC(e, ecdsae_method)) {
755 errstr = "ENGINE_set_EC";
756 goto fail;
758 if (!ENGINE_set_default_EC(e)) {
759 errstr = "ENGINE_set_default_EC";
760 goto fail;
763 return;
765 fail:
766 ssl_error(errstr);
767 fatalx("%s", errstr);
770 void
771 crypto_engine_init(struct conf *c)
773 conf = c;
775 rsa_engine_init();
776 ecdsa_engine_init();