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