ca.c revision 1.42
1/*	$OpenBSD: ca.c,v 1.42 2022/02/18 16:57:36 millert Exp $	*/
2
3/*
4 * Copyright (c) 2014 Reyk Floeter <reyk@openbsd.org>
5 * Copyright (c) 2012 Gilles Chehade <gilles@poolp.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include <openssl/pem.h>
21#include <openssl/engine.h>
22#include <pwd.h>
23#include <signal.h>
24#include <string.h>
25#include <unistd.h>
26
27#include "smtpd.h"
28#include "log.h"
29#include "ssl.h"
30
31static int	 ca_verify_cb(int, X509_STORE_CTX *);
32
33static int	 rsae_send_imsg(int, const unsigned char *, unsigned char *,
34		    RSA *, int, unsigned int);
35static int	 rsae_pub_enc(int, const unsigned char *, unsigned char *,
36		    RSA *, int);
37static int	 rsae_pub_dec(int,const unsigned char *, unsigned char *,
38		    RSA *, int);
39static int	 rsae_priv_enc(int, const unsigned char *, unsigned char *,
40		    RSA *, int);
41static int	 rsae_priv_dec(int, const unsigned char *, unsigned char *,
42		    RSA *, int);
43static int	 rsae_mod_exp(BIGNUM *, const BIGNUM *, RSA *, BN_CTX *);
44static int	 rsae_bn_mod_exp(BIGNUM *, const BIGNUM *, const BIGNUM *,
45		    const BIGNUM *, BN_CTX *, BN_MONT_CTX *);
46static int	 rsae_init(RSA *);
47static int	 rsae_finish(RSA *);
48static int	 rsae_keygen(RSA *, int, BIGNUM *, BN_GENCB *);
49
50static ECDSA_SIG *ecdsae_do_sign(const unsigned char *, int, const BIGNUM *,
51    const BIGNUM *, EC_KEY *);
52static int ecdsae_sign_setup(EC_KEY *, BN_CTX *, BIGNUM **, BIGNUM **);
53static int ecdsae_do_verify(const unsigned char *, int, const ECDSA_SIG *,
54    EC_KEY *);
55
56
57static struct dict pkeys;
58static uint64_t	 reqid = 0;
59
60static void
61ca_shutdown(void)
62{
63	log_debug("debug: ca agent exiting");
64	_exit(0);
65}
66
67int
68ca(void)
69{
70	struct passwd	*pw;
71
72	purge_config(PURGE_LISTENERS|PURGE_TABLES|PURGE_RULES|PURGE_DISPATCHERS);
73
74	if ((pw = getpwnam(SMTPD_USER)) == NULL)
75		fatalx("unknown user " SMTPD_USER);
76
77	if (chroot(PATH_CHROOT) == -1)
78		fatal("ca: chroot");
79	if (chdir("/") == -1)
80		fatal("ca: chdir(\"/\")");
81
82	config_process(PROC_CA);
83
84	if (setgroups(1, &pw->pw_gid) ||
85	    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
86	    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
87		fatal("ca: cannot drop privileges");
88
89	imsg_callback = ca_imsg;
90	event_init();
91
92	signal(SIGINT, SIG_IGN);
93	signal(SIGTERM, SIG_IGN);
94	signal(SIGPIPE, SIG_IGN);
95	signal(SIGHUP, SIG_IGN);
96
97	config_peer(PROC_CONTROL);
98	config_peer(PROC_PARENT);
99	config_peer(PROC_DISPATCHER);
100
101	/* Ignore them until we get our config */
102	mproc_disable(p_dispatcher);
103
104	if (pledge("stdio", NULL) == -1)
105		fatal("pledge");
106
107	event_dispatch();
108	fatalx("exited event loop");
109
110	return (0);
111}
112
113void
114ca_init(void)
115{
116	BIO		*in = NULL;
117	EVP_PKEY	*pkey = NULL;
118	struct pki	*pki;
119	const char	*k;
120	void		*iter_dict;
121	char		*hash;
122
123	log_debug("debug: init private ssl-tree");
124	dict_init(&pkeys);
125	iter_dict = NULL;
126	while (dict_iter(env->sc_pki_dict, &iter_dict, &k, (void **)&pki)) {
127		if (pki->pki_key == NULL)
128			continue;
129
130		in = BIO_new_mem_buf(pki->pki_key, pki->pki_key_len);
131		if (in == NULL)
132			fatalx("ca_init: key");
133		pkey = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
134		if (pkey == NULL)
135			fatalx("ca_init: PEM");
136		BIO_free(in);
137
138		hash = ssl_pubkey_hash(pki->pki_cert, pki->pki_cert_len);
139		if (dict_check(&pkeys, hash))
140			EVP_PKEY_free(pkey);
141		else
142			dict_xset(&pkeys, hash, pkey);
143		free(hash);
144	}
145}
146
147static int
148ca_verify_cb(int ok, X509_STORE_CTX *ctx)
149{
150	switch (X509_STORE_CTX_get_error(ctx)) {
151	case X509_V_OK:
152		break;
153        case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
154		break;
155        case X509_V_ERR_CERT_NOT_YET_VALID:
156        case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
157		break;
158        case X509_V_ERR_CERT_HAS_EXPIRED:
159        case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
160		break;
161        case X509_V_ERR_NO_EXPLICIT_POLICY:
162		break;
163	}
164	return ok;
165}
166
167int
168ca_X509_verify(void *certificate, void *chain, const char *CAfile,
169    const char *CRLfile, const char **errstr)
170{
171	X509_STORE     *store = NULL;
172	X509_STORE_CTX *xsc = NULL;
173	int		ret = 0;
174	long		error = 0;
175
176	if ((store = X509_STORE_new()) == NULL)
177		goto end;
178
179	if (!X509_STORE_load_locations(store, CAfile, NULL)) {
180		log_warn("warn: unable to load CA file %s", CAfile);
181		goto end;
182	}
183	X509_STORE_set_default_paths(store);
184
185	if ((xsc = X509_STORE_CTX_new()) == NULL)
186		goto end;
187
188	if (X509_STORE_CTX_init(xsc, store, certificate, chain) != 1)
189		goto end;
190
191	X509_STORE_CTX_set_verify_cb(xsc, ca_verify_cb);
192
193	ret = X509_verify_cert(xsc);
194
195end:
196	*errstr = NULL;
197	if (ret != 1) {
198		if (xsc) {
199			error = X509_STORE_CTX_get_error(xsc);
200			*errstr = X509_verify_cert_error_string(error);
201		}
202		else if (ERR_peek_last_error())
203			*errstr = ERR_error_string(ERR_peek_last_error(), NULL);
204	}
205
206	X509_STORE_CTX_free(xsc);
207	X509_STORE_free(store);
208
209	return ret > 0 ? 1 : 0;
210}
211
212void
213ca_imsg(struct mproc *p, struct imsg *imsg)
214{
215	EVP_PKEY		*pkey;
216	RSA			*rsa = NULL;
217	EC_KEY			*ecdsa = NULL;
218	const void		*from = NULL;
219	unsigned char		*to = NULL;
220	struct msg		 m;
221	const char		*hash;
222	size_t			 flen, tlen, padding;
223	int			 buf_len;
224	int			 ret = 0;
225	uint64_t		 id;
226	int			 v;
227
228	if (imsg == NULL)
229		ca_shutdown();
230
231	switch (imsg->hdr.type) {
232	case IMSG_CONF_START:
233		return;
234	case IMSG_CONF_END:
235		ca_init();
236
237		/* Start fulfilling requests */
238		mproc_enable(p_dispatcher);
239		return;
240
241	case IMSG_CTL_VERBOSE:
242		m_msg(&m, imsg);
243		m_get_int(&m, &v);
244		m_end(&m);
245		log_trace_verbose(v);
246		return;
247
248	case IMSG_CTL_PROFILE:
249		m_msg(&m, imsg);
250		m_get_int(&m, &v);
251		m_end(&m);
252		profiling = v;
253		return;
254
255	case IMSG_CA_RSA_PRIVENC:
256	case IMSG_CA_RSA_PRIVDEC:
257		m_msg(&m, imsg);
258		m_get_id(&m, &id);
259		m_get_string(&m, &hash);
260		m_get_data(&m, &from, &flen);
261		m_get_size(&m, &tlen);
262		m_get_size(&m, &padding);
263		m_end(&m);
264
265		pkey = dict_get(&pkeys, hash);
266		if (pkey == NULL || (rsa = EVP_PKEY_get1_RSA(pkey)) == NULL)
267			fatalx("ca_imsg: invalid pkey hash");
268
269		if ((to = calloc(1, tlen)) == NULL)
270			fatalx("ca_imsg: calloc");
271
272		switch (imsg->hdr.type) {
273		case IMSG_CA_RSA_PRIVENC:
274			ret = RSA_private_encrypt(flen, from, to, rsa,
275			    padding);
276			break;
277		case IMSG_CA_RSA_PRIVDEC:
278			ret = RSA_private_decrypt(flen, from, to, rsa,
279			    padding);
280			break;
281		}
282
283		m_create(p, imsg->hdr.type, 0, 0, -1);
284		m_add_id(p, id);
285		m_add_int(p, ret);
286		if (ret > 0)
287			m_add_data(p, to, (size_t)ret);
288		m_close(p);
289
290		free(to);
291		RSA_free(rsa);
292		return;
293
294	case IMSG_CA_ECDSA_SIGN:
295		m_msg(&m, imsg);
296		m_get_id(&m, &id);
297		m_get_string(&m, &hash);
298		m_get_data(&m, &from, &flen);
299		m_end(&m);
300
301		pkey = dict_get(&pkeys, hash);
302		if (pkey == NULL ||
303		    (ecdsa = EVP_PKEY_get1_EC_KEY(pkey)) == NULL)
304			fatalx("ca_imsg: invalid pkey hash");
305
306		buf_len = ECDSA_size(ecdsa);
307		if ((to = calloc(1, buf_len)) == NULL)
308			fatalx("ca_imsg: calloc");
309		ret = ECDSA_sign(0, from, flen, to, &buf_len, ecdsa);
310		m_create(p, imsg->hdr.type, 0, 0, -1);
311		m_add_id(p, id);
312		m_add_int(p, ret);
313		if (ret > 0)
314			m_add_data(p, to, (size_t)buf_len);
315		m_close(p);
316		free(to);
317		EC_KEY_free(ecdsa);
318		return;
319	}
320
321	fatalx("ca_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type));
322}
323
324/*
325 * RSA privsep engine (called from unprivileged processes)
326 */
327
328const RSA_METHOD *rsa_default = NULL;
329
330static RSA_METHOD *rsae_method = NULL;
331
332static int
333rsae_send_imsg(int flen, const unsigned char *from, unsigned char *to,
334    RSA *rsa, int padding, unsigned int cmd)
335{
336	int		 ret = 0;
337	struct imsgbuf	*ibuf;
338	struct imsg	 imsg;
339	int		 n, done = 0;
340	const void	*toptr;
341	char		*hash;
342	size_t		 tlen;
343	struct msg	 m;
344	uint64_t	 id;
345
346	if ((hash = RSA_get_ex_data(rsa, 0)) == NULL)
347		return (0);
348
349	/*
350	 * Send a synchronous imsg because we cannot defer the RSA
351	 * operation in OpenSSL's engine layer.
352	 */
353	m_create(p_ca, cmd, 0, 0, -1);
354	reqid++;
355	m_add_id(p_ca, reqid);
356	m_add_string(p_ca, hash);
357	m_add_data(p_ca, (const void *)from, (size_t)flen);
358	m_add_size(p_ca, (size_t)RSA_size(rsa));
359	m_add_size(p_ca, (size_t)padding);
360	m_flush(p_ca);
361
362	ibuf = &p_ca->imsgbuf;
363
364	while (!done) {
365		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
366			fatalx("imsg_read");
367		if (n == 0)
368			fatalx("pipe closed");
369
370		while (!done) {
371			if ((n = imsg_get(ibuf, &imsg)) == -1)
372				fatalx("imsg_get error");
373			if (n == 0)
374				break;
375
376			log_imsg(PROC_DISPATCHER, PROC_CA, &imsg);
377
378			switch (imsg.hdr.type) {
379			case IMSG_CA_RSA_PRIVENC:
380			case IMSG_CA_RSA_PRIVDEC:
381				break;
382			default:
383				/* Another imsg is queued up in the buffer */
384				dispatcher_imsg(p_ca, &imsg);
385				imsg_free(&imsg);
386				continue;
387			}
388
389			m_msg(&m, &imsg);
390			m_get_id(&m, &id);
391			if (id != reqid)
392				fatalx("invalid response id");
393			m_get_int(&m, &ret);
394			if (ret > 0)
395				m_get_data(&m, &toptr, &tlen);
396			m_end(&m);
397
398			if (ret > 0)
399				memcpy(to, toptr, tlen);
400			done = 1;
401
402			imsg_free(&imsg);
403		}
404	}
405	mproc_event_add(p_ca);
406
407	return (ret);
408}
409
410static int
411rsae_pub_enc(int flen,const unsigned char *from, unsigned char *to, RSA *rsa,
412    int padding)
413{
414	log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
415	return (RSA_meth_get_pub_enc(rsa_default)(flen, from, to, rsa, padding));
416}
417
418static int
419rsae_pub_dec(int flen,const unsigned char *from, unsigned char *to, RSA *rsa,
420    int padding)
421{
422	log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
423	return (RSA_meth_get_pub_dec(rsa_default)(flen, from, to, rsa, padding));
424}
425
426static int
427rsae_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa,
428    int padding)
429{
430	log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
431	if (RSA_get_ex_data(rsa, 0) != NULL)
432		return (rsae_send_imsg(flen, from, to, rsa, padding,
433		    IMSG_CA_RSA_PRIVENC));
434	return (RSA_meth_get_priv_enc(rsa_default)(flen, from, to, rsa, padding));
435}
436
437static int
438rsae_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa,
439    int padding)
440{
441	log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
442	if (RSA_get_ex_data(rsa, 0) != NULL)
443		return (rsae_send_imsg(flen, from, to, rsa, padding,
444		    IMSG_CA_RSA_PRIVDEC));
445
446	return (RSA_meth_get_priv_dec(rsa_default)(flen, from, to, rsa, padding));
447}
448
449static int
450rsae_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
451{
452	log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
453	return (RSA_meth_get_mod_exp(rsa_default)(r0, I, rsa, ctx));
454}
455
456static int
457rsae_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
458    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
459{
460	log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
461	return (RSA_meth_get_bn_mod_exp(rsa_default)(r, a, p, m, ctx, m_ctx));
462}
463
464static int
465rsae_init(RSA *rsa)
466{
467	log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
468	if (RSA_meth_get_init(rsa_default) == NULL)
469		return (1);
470	return (RSA_meth_get_init(rsa_default)(rsa));
471}
472
473static int
474rsae_finish(RSA *rsa)
475{
476	log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
477	if (RSA_meth_get_finish(rsa_default) == NULL)
478		return (1);
479	return (RSA_meth_get_finish(rsa_default)(rsa));
480}
481
482static int
483rsae_keygen(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
484{
485	log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
486	return (RSA_meth_get_keygen(rsa_default)(rsa, bits, e, cb));
487}
488
489
490/*
491 * ECDSA privsep engine (called from unprivileged processes)
492 */
493
494const ECDSA_METHOD *ecdsa_default = NULL;
495
496static ECDSA_METHOD *ecdsae_method = NULL;
497
498ECDSA_METHOD *
499ECDSA_METHOD_new_temporary(const char *name, int);
500
501ECDSA_METHOD *
502ECDSA_METHOD_new_temporary(const char *name, int flags)
503{
504	ECDSA_METHOD	*ecdsa;
505
506	if ((ecdsa = calloc(1, sizeof (*ecdsa))) == NULL)
507		return NULL;
508
509	if ((ecdsa->name = strdup(name)) == NULL) {
510		free(ecdsa);
511		return NULL;
512	}
513
514	ecdsa->flags = flags;
515	return ecdsa;
516}
517
518static ECDSA_SIG *
519ecdsae_send_enc_imsg(const unsigned char *dgst, int dgst_len,
520    const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey)
521{
522	int		 ret = 0;
523	struct imsgbuf	*ibuf;
524	struct imsg	 imsg;
525	int		 n, done = 0;
526	const void	*toptr;
527	char		*hash;
528	size_t		 tlen;
529	struct msg	 m;
530	uint64_t	 id;
531	ECDSA_SIG	*sig = NULL;
532
533	if ((hash = ECDSA_get_ex_data(eckey, 0)) == NULL)
534		return (0);
535
536	/*
537	 * Send a synchronous imsg because we cannot defer the ECDSA
538	 * operation in OpenSSL's engine layer.
539	 */
540	m_create(p_ca, IMSG_CA_ECDSA_SIGN, 0, 0, -1);
541	reqid++;
542	m_add_id(p_ca, reqid);
543	m_add_string(p_ca, hash);
544	m_add_data(p_ca, (const void *)dgst, (size_t)dgst_len);
545	m_flush(p_ca);
546
547	ibuf = &p_ca->imsgbuf;
548
549	while (!done) {
550		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
551			fatalx("imsg_read");
552		if (n == 0)
553			fatalx("pipe closed");
554		while (!done) {
555			if ((n = imsg_get(ibuf, &imsg)) == -1)
556				fatalx("imsg_get error");
557			if (n == 0)
558				break;
559
560			log_imsg(PROC_DISPATCHER, PROC_CA, &imsg);
561
562			switch (imsg.hdr.type) {
563			case IMSG_CA_ECDSA_SIGN:
564				break;
565			default:
566				/* Another imsg is queued up in the buffer */
567				dispatcher_imsg(p_ca, &imsg);
568				imsg_free(&imsg);
569				continue;
570			}
571
572			m_msg(&m, &imsg);
573			m_get_id(&m, &id);
574			if (id != reqid)
575				fatalx("invalid response id");
576			m_get_int(&m, &ret);
577			if (ret > 0)
578				m_get_data(&m, &toptr, &tlen);
579			m_end(&m);
580			done = 1;
581
582			if (ret > 0)
583				d2i_ECDSA_SIG(&sig, (const unsigned char **)&toptr, tlen);
584			imsg_free(&imsg);
585		}
586	}
587	mproc_event_add(p_ca);
588
589	return (sig);
590}
591
592ECDSA_SIG *
593ecdsae_do_sign(const unsigned char *dgst, int dgst_len,
594    const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey)
595{
596	log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
597	if (ECDSA_get_ex_data(eckey, 0) != NULL)
598		return (ecdsae_send_enc_imsg(dgst, dgst_len, inv, rp, eckey));
599	return (ecdsa_default->ecdsa_do_sign(dgst, dgst_len, inv, rp, eckey));
600}
601
602int
603ecdsae_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv,
604    BIGNUM **r)
605{
606	log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
607	return (ecdsa_default->ecdsa_sign_setup(eckey, ctx, kinv, r));
608}
609
610int
611ecdsae_do_verify(const unsigned char *dgst, int dgst_len,
612    const ECDSA_SIG *sig, EC_KEY *eckey)
613{
614	log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
615	return (ecdsa_default->ecdsa_do_verify(dgst, dgst_len, sig, eckey));
616}
617
618
619static void
620rsa_engine_init(void)
621{
622	ENGINE		*e;
623	const char	*errstr, *name;
624
625	if ((rsae_method = RSA_meth_new("RSA privsep engine", 0)) == NULL) {
626		errstr = "RSA_meth_new";
627		goto fail;
628	}
629
630	RSA_meth_set_pub_enc(rsae_method, rsae_pub_enc);
631	RSA_meth_set_pub_dec(rsae_method, rsae_pub_dec);
632	RSA_meth_set_priv_enc(rsae_method, rsae_priv_enc);
633	RSA_meth_set_priv_dec(rsae_method, rsae_priv_dec);
634	RSA_meth_set_mod_exp(rsae_method, rsae_mod_exp);
635	RSA_meth_set_bn_mod_exp(rsae_method, rsae_bn_mod_exp);
636	RSA_meth_set_init(rsae_method, rsae_init);
637	RSA_meth_set_finish(rsae_method, rsae_finish);
638	RSA_meth_set_keygen(rsae_method, rsae_keygen);
639
640	if ((e = ENGINE_get_default_RSA()) == NULL) {
641		if ((e = ENGINE_new()) == NULL) {
642			errstr = "ENGINE_new";
643			goto fail;
644		}
645		if (!ENGINE_set_name(e, RSA_meth_get0_name(rsae_method))) {
646			errstr = "ENGINE_set_name";
647			goto fail;
648		}
649		if ((rsa_default = RSA_get_default_method()) == NULL) {
650			errstr = "RSA_get_default_method";
651			goto fail;
652		}
653	} else if ((rsa_default = ENGINE_get_RSA(e)) == NULL) {
654		errstr = "ENGINE_get_RSA";
655		goto fail;
656	}
657
658	if ((name = ENGINE_get_name(e)) == NULL)
659		name = "unknown RSA engine";
660
661	log_debug("debug: %s: using %s", __func__, name);
662
663	if (RSA_meth_get_mod_exp(rsa_default) == NULL)
664		RSA_meth_set_mod_exp(rsae_method, NULL);
665	if (RSA_meth_get_bn_mod_exp(rsa_default) == NULL)
666		RSA_meth_set_bn_mod_exp(rsae_method, NULL);
667	if (RSA_meth_get_keygen(rsa_default) == NULL)
668		RSA_meth_set_keygen(rsae_method, NULL);
669	RSA_meth_set_flags(rsae_method,
670		RSA_meth_get_flags(rsa_default) | RSA_METHOD_FLAG_NO_CHECK);
671	RSA_meth_set0_app_data(rsae_method,
672		RSA_meth_get0_app_data(rsa_default));
673
674	if (!ENGINE_set_RSA(e, rsae_method)) {
675		errstr = "ENGINE_set_RSA";
676		goto fail;
677	}
678	if (!ENGINE_set_default_RSA(e)) {
679		errstr = "ENGINE_set_default_RSA";
680		goto fail;
681	}
682
683	return;
684
685 fail:
686	ssl_error(errstr);
687	fatalx("%s", errstr);
688}
689
690static void
691ecdsa_engine_init(void)
692{
693	ENGINE		*e;
694	const char	*errstr, *name;
695
696	if ((ecdsae_method = ECDSA_METHOD_new_temporary("ECDSA privsep engine", 0)) == NULL) {
697		errstr = "ECDSA_METHOD_new_temporary";
698		goto fail;
699	}
700
701	ecdsae_method->ecdsa_do_sign = ecdsae_do_sign;
702	ecdsae_method->ecdsa_sign_setup = ecdsae_sign_setup;
703	ecdsae_method->ecdsa_do_verify = ecdsae_do_verify;
704
705	if ((e = ENGINE_get_default_ECDSA()) == NULL) {
706		if ((e = ENGINE_new()) == NULL) {
707			errstr = "ENGINE_new";
708			goto fail;
709		}
710		if (!ENGINE_set_name(e, ecdsae_method->name)) {
711			errstr = "ENGINE_set_name";
712			goto fail;
713		}
714		if ((ecdsa_default = ECDSA_get_default_method()) == NULL) {
715			errstr = "ECDSA_get_default_method";
716			goto fail;
717		}
718	} else if ((ecdsa_default = ENGINE_get_ECDSA(e)) == NULL) {
719		errstr = "ENGINE_get_ECDSA";
720		goto fail;
721	}
722
723	if ((name = ENGINE_get_name(e)) == NULL)
724		name = "unknown ECDSA engine";
725
726	log_debug("debug: %s: using %s", __func__, name);
727
728	if (!ENGINE_set_ECDSA(e, ecdsae_method)) {
729		errstr = "ENGINE_set_ECDSA";
730		goto fail;
731	}
732	if (!ENGINE_set_default_ECDSA(e)) {
733		errstr = "ENGINE_set_default_ECDSA";
734		goto fail;
735	}
736
737	return;
738
739 fail:
740	ssl_error(errstr);
741	fatalx("%s", errstr);
742}
743
744void
745ca_engine_init(void)
746{
747	rsa_engine_init();
748	ecdsa_engine_init();
749}
750