1 /* $OpenBSD: ca.c,v 1.49 2024/11/21 13:22:21 claudio 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 = imsgbuf_read(ibuf)) == -1)
327 fatalx("imsgbuf_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 = imsgbuf_read(ibuf)) == -1)
435 fatalx("imsgbuf_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