xref: /openbsd/usr.sbin/smtpd/ca.c (revision ed3431f4)
1 /*	$OpenBSD: ca.c,v 1.47 2023/07/11 16:40:22 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 <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 
31 static int	 rsae_send_imsg(int, const unsigned char *, unsigned char *,
32 		    RSA *, int, unsigned int);
33 static int	 rsae_priv_enc(int, const unsigned char *, unsigned char *,
34 		    RSA *, int);
35 static int	 rsae_priv_dec(int, const unsigned char *, unsigned char *,
36 		    RSA *, int);
37 static ECDSA_SIG *ecdsae_do_sign(const unsigned char *, int, const BIGNUM *,
38     const BIGNUM *, EC_KEY *);
39 
40 static struct dict pkeys;
41 static uint64_t	 reqid = 0;
42 
43 static void
ca_shutdown(void)44 ca_shutdown(void)
45 {
46 	log_debug("debug: ca agent exiting");
47 	_exit(0);
48 }
49 
50 int
ca(void)51 ca(void)
52 {
53 	struct passwd	*pw;
54 
55 	purge_config(PURGE_LISTENERS|PURGE_TABLES|PURGE_RULES|PURGE_DISPATCHERS);
56 
57 	if ((pw = getpwnam(SMTPD_USER)) == NULL)
58 		fatalx("unknown user " SMTPD_USER);
59 
60 	if (chroot(PATH_CHROOT) == -1)
61 		fatal("ca: chroot");
62 	if (chdir("/") == -1)
63 		fatal("ca: chdir(\"/\")");
64 
65 	config_process(PROC_CA);
66 
67 	if (setgroups(1, &pw->pw_gid) ||
68 	    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
69 	    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
70 		fatal("ca: cannot drop privileges");
71 
72 	imsg_callback = ca_imsg;
73 	event_init();
74 
75 	signal(SIGINT, SIG_IGN);
76 	signal(SIGTERM, SIG_IGN);
77 	signal(SIGPIPE, SIG_IGN);
78 	signal(SIGHUP, SIG_IGN);
79 
80 	config_peer(PROC_CONTROL);
81 	config_peer(PROC_PARENT);
82 	config_peer(PROC_DISPATCHER);
83 
84 	/* Ignore them until we get our config */
85 	mproc_disable(p_dispatcher);
86 
87 	if (pledge("stdio", NULL) == -1)
88 		fatal("pledge");
89 
90 	event_dispatch();
91 	fatalx("exited event loop");
92 
93 	return (0);
94 }
95 
96 void
ca_init(void)97 ca_init(void)
98 {
99 	BIO		*in = NULL;
100 	EVP_PKEY	*pkey = NULL;
101 	struct pki	*pki;
102 	const char	*k;
103 	void		*iter_dict;
104 	char		*hash;
105 
106 	log_debug("debug: init private ssl-tree");
107 	dict_init(&pkeys);
108 	iter_dict = NULL;
109 	while (dict_iter(env->sc_pki_dict, &iter_dict, &k, (void **)&pki)) {
110 		if (pki->pki_key == NULL)
111 			continue;
112 
113 		in = BIO_new_mem_buf(pki->pki_key, pki->pki_key_len);
114 		if (in == NULL)
115 			fatalx("ca_init: key");
116 		pkey = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
117 		if (pkey == NULL)
118 			fatalx("ca_init: PEM");
119 		BIO_free(in);
120 
121 		hash = ssl_pubkey_hash(pki->pki_cert, pki->pki_cert_len);
122 		if (dict_check(&pkeys, hash))
123 			EVP_PKEY_free(pkey);
124 		else
125 			dict_xset(&pkeys, hash, pkey);
126 		free(hash);
127 	}
128 }
129 
130 int
ca_X509_verify(void * certificate,void * chain,const char * CAfile,const char * CRLfile,const char ** errstr)131 ca_X509_verify(void *certificate, void *chain, const char *CAfile,
132     const char *CRLfile, const char **errstr)
133 {
134 	X509_STORE     *store = NULL;
135 	X509_STORE_CTX *xsc = NULL;
136 	int		ret = 0;
137 	long		error = 0;
138 
139 	if ((store = X509_STORE_new()) == NULL)
140 		goto end;
141 
142 	if (!X509_STORE_load_locations(store, CAfile, NULL)) {
143 		log_warn("warn: unable to load CA file %s", CAfile);
144 		goto end;
145 	}
146 	X509_STORE_set_default_paths(store);
147 
148 	if ((xsc = X509_STORE_CTX_new()) == NULL)
149 		goto end;
150 
151 	if (X509_STORE_CTX_init(xsc, store, certificate, chain) != 1)
152 		goto end;
153 
154 	ret = X509_verify_cert(xsc);
155 
156 end:
157 	*errstr = NULL;
158 	if (ret != 1) {
159 		if (xsc) {
160 			error = X509_STORE_CTX_get_error(xsc);
161 			*errstr = X509_verify_cert_error_string(error);
162 		}
163 		else if (ERR_peek_last_error())
164 			*errstr = ERR_error_string(ERR_peek_last_error(), NULL);
165 	}
166 
167 	X509_STORE_CTX_free(xsc);
168 	X509_STORE_free(store);
169 
170 	return ret > 0 ? 1 : 0;
171 }
172 
173 void
ca_imsg(struct mproc * p,struct imsg * imsg)174 ca_imsg(struct mproc *p, struct imsg *imsg)
175 {
176 	EVP_PKEY		*pkey;
177 	RSA			*rsa = NULL;
178 	EC_KEY			*ecdsa = NULL;
179 	const void		*from = NULL;
180 	unsigned char		*to = NULL;
181 	struct msg		 m;
182 	const char		*hash;
183 	size_t			 flen, tlen, padding;
184 	int			 buf_len;
185 	int			 ret = 0;
186 	uint64_t		 id;
187 	int			 v;
188 
189 	if (imsg == NULL)
190 		ca_shutdown();
191 
192 	switch (imsg->hdr.type) {
193 	case IMSG_CONF_START:
194 		return;
195 	case IMSG_CONF_END:
196 		ca_init();
197 
198 		/* Start fulfilling requests */
199 		mproc_enable(p_dispatcher);
200 		return;
201 
202 	case IMSG_CTL_VERBOSE:
203 		m_msg(&m, imsg);
204 		m_get_int(&m, &v);
205 		m_end(&m);
206 		log_trace_verbose(v);
207 		return;
208 
209 	case IMSG_CTL_PROFILE:
210 		m_msg(&m, imsg);
211 		m_get_int(&m, &v);
212 		m_end(&m);
213 		profiling = v;
214 		return;
215 
216 	case IMSG_CA_RSA_PRIVENC:
217 	case IMSG_CA_RSA_PRIVDEC:
218 		m_msg(&m, imsg);
219 		m_get_id(&m, &id);
220 		m_get_string(&m, &hash);
221 		m_get_data(&m, &from, &flen);
222 		m_get_size(&m, &tlen);
223 		m_get_size(&m, &padding);
224 		m_end(&m);
225 
226 		pkey = dict_get(&pkeys, hash);
227 		if (pkey == NULL || (rsa = EVP_PKEY_get1_RSA(pkey)) == NULL)
228 			fatalx("ca_imsg: invalid pkey hash");
229 
230 		if ((to = calloc(1, tlen)) == NULL)
231 			fatalx("ca_imsg: calloc");
232 
233 		switch (imsg->hdr.type) {
234 		case IMSG_CA_RSA_PRIVENC:
235 			ret = RSA_private_encrypt(flen, from, to, rsa,
236 			    padding);
237 			break;
238 		case IMSG_CA_RSA_PRIVDEC:
239 			ret = RSA_private_decrypt(flen, from, to, rsa,
240 			    padding);
241 			break;
242 		}
243 
244 		m_create(p, imsg->hdr.type, 0, 0, -1);
245 		m_add_id(p, id);
246 		m_add_int(p, ret);
247 		if (ret > 0)
248 			m_add_data(p, to, (size_t)ret);
249 		m_close(p);
250 
251 		free(to);
252 		RSA_free(rsa);
253 		return;
254 
255 	case IMSG_CA_ECDSA_SIGN:
256 		m_msg(&m, imsg);
257 		m_get_id(&m, &id);
258 		m_get_string(&m, &hash);
259 		m_get_data(&m, &from, &flen);
260 		m_end(&m);
261 
262 		pkey = dict_get(&pkeys, hash);
263 		if (pkey == NULL ||
264 		    (ecdsa = EVP_PKEY_get1_EC_KEY(pkey)) == NULL)
265 			fatalx("ca_imsg: invalid pkey hash");
266 
267 		buf_len = ECDSA_size(ecdsa);
268 		if ((to = calloc(1, buf_len)) == NULL)
269 			fatalx("ca_imsg: calloc");
270 		ret = ECDSA_sign(0, from, flen, to, &buf_len, ecdsa);
271 		m_create(p, imsg->hdr.type, 0, 0, -1);
272 		m_add_id(p, id);
273 		m_add_int(p, ret);
274 		if (ret > 0)
275 			m_add_data(p, to, (size_t)buf_len);
276 		m_close(p);
277 		free(to);
278 		EC_KEY_free(ecdsa);
279 		return;
280 	}
281 
282 	fatalx("ca_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type));
283 }
284 
285 /*
286  * RSA privsep engine (called from unprivileged processes)
287  */
288 
289 const RSA_METHOD *rsa_default = NULL;
290 
291 static RSA_METHOD *rsae_method = NULL;
292 
293 static int
rsae_send_imsg(int flen,const unsigned char * from,unsigned char * to,RSA * rsa,int padding,unsigned int cmd)294 rsae_send_imsg(int flen, const unsigned char *from, unsigned char *to,
295     RSA *rsa, int padding, unsigned int cmd)
296 {
297 	int		 ret = 0;
298 	struct imsgbuf	*ibuf;
299 	struct imsg	 imsg;
300 	int		 n, done = 0;
301 	const void	*toptr;
302 	char		*hash;
303 	size_t		 tlen;
304 	struct msg	 m;
305 	uint64_t	 id;
306 
307 	if ((hash = RSA_get_ex_data(rsa, 0)) == NULL)
308 		return (0);
309 
310 	/*
311 	 * Send a synchronous imsg because we cannot defer the RSA
312 	 * operation in OpenSSL's engine layer.
313 	 */
314 	m_create(p_ca, cmd, 0, 0, -1);
315 	reqid++;
316 	m_add_id(p_ca, reqid);
317 	m_add_string(p_ca, hash);
318 	m_add_data(p_ca, (const void *)from, (size_t)flen);
319 	m_add_size(p_ca, (size_t)RSA_size(rsa));
320 	m_add_size(p_ca, (size_t)padding);
321 	m_flush(p_ca);
322 
323 	ibuf = &p_ca->imsgbuf;
324 
325 	while (!done) {
326 		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
327 			fatalx("imsg_read");
328 		if (n == 0)
329 			fatalx("pipe closed");
330 
331 		while (!done) {
332 			if ((n = imsg_get(ibuf, &imsg)) == -1)
333 				fatalx("imsg_get error");
334 			if (n == 0)
335 				break;
336 
337 			log_imsg(PROC_DISPATCHER, PROC_CA, &imsg);
338 
339 			switch (imsg.hdr.type) {
340 			case IMSG_CA_RSA_PRIVENC:
341 			case IMSG_CA_RSA_PRIVDEC:
342 				break;
343 			default:
344 				/* Another imsg is queued up in the buffer */
345 				dispatcher_imsg(p_ca, &imsg);
346 				imsg_free(&imsg);
347 				continue;
348 			}
349 
350 			m_msg(&m, &imsg);
351 			m_get_id(&m, &id);
352 			if (id != reqid)
353 				fatalx("invalid response id");
354 			m_get_int(&m, &ret);
355 			if (ret > 0)
356 				m_get_data(&m, &toptr, &tlen);
357 			m_end(&m);
358 
359 			if (ret > 0)
360 				memcpy(to, toptr, tlen);
361 			done = 1;
362 
363 			imsg_free(&imsg);
364 		}
365 	}
366 	mproc_event_add(p_ca);
367 
368 	return (ret);
369 }
370 
371 static int
rsae_priv_enc(int flen,const unsigned char * from,unsigned char * to,RSA * rsa,int padding)372 rsae_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa,
373     int padding)
374 {
375 	log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
376 	if (RSA_get_ex_data(rsa, 0) != NULL)
377 		return (rsae_send_imsg(flen, from, to, rsa, padding,
378 		    IMSG_CA_RSA_PRIVENC));
379 	return (RSA_meth_get_priv_enc(rsa_default)(flen, from, to, rsa, padding));
380 }
381 
382 static int
rsae_priv_dec(int flen,const unsigned char * from,unsigned char * to,RSA * rsa,int padding)383 rsae_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa,
384     int padding)
385 {
386 	log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
387 	if (RSA_get_ex_data(rsa, 0) != NULL)
388 		return (rsae_send_imsg(flen, from, to, rsa, padding,
389 		    IMSG_CA_RSA_PRIVDEC));
390 
391 	return (RSA_meth_get_priv_dec(rsa_default)(flen, from, to, rsa, padding));
392 }
393 
394 /*
395  * ECDSA privsep engine (called from unprivileged processes)
396  */
397 
398 const EC_KEY_METHOD *ecdsa_default = NULL;
399 
400 static EC_KEY_METHOD *ecdsae_method = NULL;
401 
402 static ECDSA_SIG *
ecdsae_send_enc_imsg(const unsigned char * dgst,int dgst_len,const BIGNUM * inv,const BIGNUM * rp,EC_KEY * eckey)403 ecdsae_send_enc_imsg(const unsigned char *dgst, int dgst_len,
404     const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey)
405 {
406 	int		 ret = 0;
407 	struct imsgbuf	*ibuf;
408 	struct imsg	 imsg;
409 	int		 n, done = 0;
410 	const void	*toptr;
411 	char		*hash;
412 	size_t		 tlen;
413 	struct msg	 m;
414 	uint64_t	 id;
415 	ECDSA_SIG	*sig = NULL;
416 
417 	if ((hash = EC_KEY_get_ex_data(eckey, 0)) == NULL)
418 		return (0);
419 
420 	/*
421 	 * Send a synchronous imsg because we cannot defer the ECDSA
422 	 * operation in OpenSSL's engine layer.
423 	 */
424 	m_create(p_ca, IMSG_CA_ECDSA_SIGN, 0, 0, -1);
425 	reqid++;
426 	m_add_id(p_ca, reqid);
427 	m_add_string(p_ca, hash);
428 	m_add_data(p_ca, (const void *)dgst, (size_t)dgst_len);
429 	m_flush(p_ca);
430 
431 	ibuf = &p_ca->imsgbuf;
432 
433 	while (!done) {
434 		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
435 			fatalx("imsg_read");
436 		if (n == 0)
437 			fatalx("pipe closed");
438 		while (!done) {
439 			if ((n = imsg_get(ibuf, &imsg)) == -1)
440 				fatalx("imsg_get error");
441 			if (n == 0)
442 				break;
443 
444 			log_imsg(PROC_DISPATCHER, PROC_CA, &imsg);
445 
446 			switch (imsg.hdr.type) {
447 			case IMSG_CA_ECDSA_SIGN:
448 				break;
449 			default:
450 				/* Another imsg is queued up in the buffer */
451 				dispatcher_imsg(p_ca, &imsg);
452 				imsg_free(&imsg);
453 				continue;
454 			}
455 
456 			m_msg(&m, &imsg);
457 			m_get_id(&m, &id);
458 			if (id != reqid)
459 				fatalx("invalid response id");
460 			m_get_int(&m, &ret);
461 			if (ret > 0)
462 				m_get_data(&m, &toptr, &tlen);
463 			m_end(&m);
464 			done = 1;
465 
466 			if (ret > 0)
467 				d2i_ECDSA_SIG(&sig, (const unsigned char **)&toptr, tlen);
468 			imsg_free(&imsg);
469 		}
470 	}
471 	mproc_event_add(p_ca);
472 
473 	return (sig);
474 }
475 
476 static ECDSA_SIG *
ecdsae_do_sign(const unsigned char * dgst,int dgst_len,const BIGNUM * inv,const BIGNUM * rp,EC_KEY * eckey)477 ecdsae_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
478     const BIGNUM *rp, EC_KEY *eckey)
479 {
480 	ECDSA_SIG *(*psign_sig)(const unsigned char *, int, const BIGNUM *,
481 	    const BIGNUM *, EC_KEY *);
482 
483 	log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
484 	if (EC_KEY_get_ex_data(eckey, 0) != NULL)
485 		return (ecdsae_send_enc_imsg(dgst, dgst_len, inv, rp, eckey));
486 	EC_KEY_METHOD_get_sign(ecdsa_default, NULL, NULL, &psign_sig);
487 	return (psign_sig(dgst, dgst_len, inv, rp, eckey));
488 }
489 
490 static void
rsa_engine_init(void)491 rsa_engine_init(void)
492 {
493 	const char	*errstr;
494 
495 	if ((rsa_default = RSA_get_default_method()) == NULL) {
496 		errstr = "RSA_get_default_method";
497 		goto fail;
498 	}
499 
500 	if ((rsae_method = RSA_meth_dup(rsa_default)) == NULL) {
501 		errstr = "RSA_meth_dup";
502 		goto fail;
503 	}
504 
505 	RSA_meth_set_priv_enc(rsae_method, rsae_priv_enc);
506 	RSA_meth_set_priv_dec(rsae_method, rsae_priv_dec);
507 
508 	RSA_meth_set_flags(rsae_method,
509 		RSA_meth_get_flags(rsa_default) | RSA_METHOD_FLAG_NO_CHECK);
510 	RSA_meth_set0_app_data(rsae_method,
511 		RSA_meth_get0_app_data(rsa_default));
512 
513 	RSA_set_default_method(rsae_method);
514 
515 	return;
516 
517  fail:
518 	ssl_error(errstr);
519 	fatalx("%s", errstr);
520 }
521 
522 static void
ecdsa_engine_init(void)523 ecdsa_engine_init(void)
524 {
525 	int (*sign)(int, const unsigned char *, int, unsigned char *,
526 	    unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *);
527 	int (*sign_setup)(EC_KEY *, BN_CTX *, BIGNUM **, BIGNUM **);
528 	const char *errstr;
529 
530 	if ((ecdsa_default = EC_KEY_get_default_method()) == NULL) {
531 		errstr = "EC_KEY_get_default_method";
532 		goto fail;
533 	}
534 
535 	if ((ecdsae_method = EC_KEY_METHOD_new(ecdsa_default)) == NULL) {
536 		errstr = "EC_KEY_METHOD_new";
537 		goto fail;
538 	}
539 
540 	EC_KEY_METHOD_get_sign(ecdsa_default, &sign, &sign_setup, NULL);
541 	EC_KEY_METHOD_set_sign(ecdsae_method, sign, sign_setup,
542 	    ecdsae_do_sign);
543 
544 	EC_KEY_set_default_method(ecdsae_method);
545 
546 	return;
547 
548  fail:
549 	ssl_error(errstr);
550 	fatalx("%s", errstr);
551 }
552 
553 void
ca_engine_init(void)554 ca_engine_init(void)
555 {
556 	rsa_engine_init();
557 	ecdsa_engine_init();
558 }
559