summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/smtpd/ca.c647
-rw-r--r--usr.sbin/smtpd/dispatcher.c4
-rw-r--r--usr.sbin/smtpd/mta.c10
-rw-r--r--usr.sbin/smtpd/smtp.c10
-rw-r--r--usr.sbin/smtpd/smtpd.c6
-rw-r--r--usr.sbin/smtpd/smtpd.h14
-rw-r--r--usr.sbin/smtpd/ssl.c59
-rw-r--r--usr.sbin/smtpd/ssl.h3
8 files changed, 81 insertions, 672 deletions
diff --git a/usr.sbin/smtpd/ca.c b/usr.sbin/smtpd/ca.c
index e7b4201d5cd..03304e95c4e 100644
--- a/usr.sbin/smtpd/ca.c
+++ b/usr.sbin/smtpd/ca.c
@@ -1,6 +1,7 @@
-/* $OpenBSD: ca.c,v 1.40 2021/06/14 17:58:15 eric Exp $ */
+/* $OpenBSD: ca.c,v 1.41 2022/02/12 18:22:04 eric Exp $ */
/*
+ * Copyright (c) 2021 Eric Faurot <eric@openbsd.org>
* Copyright (c) 2014 Reyk Floeter <reyk@openbsd.org>
* Copyright (c) 2012 Gilles Chehade <gilles@poolp.org>
*
@@ -17,45 +18,23 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <openssl/pem.h>
-#include <openssl/engine.h>
+#include <errno.h>
#include <pwd.h>
#include <signal.h>
+#include <stdlib.h>
#include <string.h>
+#include <tls.h>
#include <unistd.h>
#include "smtpd.h"
-#include "log.h"
#include "ssl.h"
+#include "log.h"
-static int ca_verify_cb(int, X509_STORE_CTX *);
-
-static int rsae_send_imsg(int, const unsigned char *, unsigned char *,
- RSA *, int, unsigned int);
-static int rsae_pub_enc(int, const unsigned char *, unsigned char *,
- RSA *, int);
-static int rsae_pub_dec(int,const unsigned char *, unsigned char *,
- RSA *, int);
-static int rsae_priv_enc(int, const unsigned char *, unsigned char *,
- RSA *, int);
-static int rsae_priv_dec(int, const unsigned char *, unsigned char *,
- RSA *, int);
-static int rsae_mod_exp(BIGNUM *, const BIGNUM *, RSA *, BN_CTX *);
-static int rsae_bn_mod_exp(BIGNUM *, const BIGNUM *, const BIGNUM *,
- const BIGNUM *, BN_CTX *, BN_MONT_CTX *);
-static int rsae_init(RSA *);
-static int rsae_finish(RSA *);
-static int rsae_keygen(RSA *, int, BIGNUM *, BN_GENCB *);
-
-static ECDSA_SIG *ecdsae_do_sign(const unsigned char *, int, const BIGNUM *,
- const BIGNUM *, EC_KEY *);
-static int ecdsae_sign_setup(EC_KEY *, BN_CTX *, BIGNUM **, BIGNUM **);
-static int ecdsae_do_verify(const unsigned char *, int, const ECDSA_SIG *,
- EC_KEY *);
-
-
-static struct dict pkeys;
-static uint64_t reqid = 0;
+static void ca_imsg(struct mproc *, struct imsg *);
+static void ca_init(void);
+
+static struct tls_signer *signer;
+static uint64_t reqid = 0;
static void
ca_shutdown(void)
@@ -69,7 +48,9 @@ ca(void)
{
struct passwd *pw;
- purge_config(PURGE_LISTENERS|PURGE_TABLES|PURGE_RULES|PURGE_DISPATCHERS);
+ ca_init();
+
+ purge_config(PURGE_EVERYTHING);
if ((pw = getpwnam(SMTPD_USER)) == NULL)
fatalx("unknown user " SMTPD_USER);
@@ -98,9 +79,6 @@ ca(void)
config_peer(PROC_PARENT);
config_peer(PROC_DISPATCHER);
- /* Ignore them until we get our config */
- mproc_disable(p_dispatcher);
-
if (pledge("stdio", NULL) == -1)
fatal("pledge");
@@ -110,120 +88,35 @@ ca(void)
return (0);
}
-void
+static void
ca_init(void)
{
- BIO *in = NULL;
- EVP_PKEY *pkey = NULL;
- struct pki *pki;
- const char *k;
- void *iter_dict;
- char *hash;
-
- log_debug("debug: init private ssl-tree");
- dict_init(&pkeys);
+ struct pki *pki;
+ void *iter_dict;
+
+ if ((signer = tls_signer_new()) == NULL)
+ fatal("tls_signer_new");
+
iter_dict = NULL;
- while (dict_iter(env->sc_pki_dict, &iter_dict, &k, (void **)&pki)) {
+ while (dict_iter(env->sc_pki_dict, &iter_dict, NULL, (void **)&pki)) {
if (pki->pki_key == NULL)
continue;
-
- in = BIO_new_mem_buf(pki->pki_key, pki->pki_key_len);
- if (in == NULL)
- fatalx("ca_init: key");
- pkey = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
- if (pkey == NULL)
- fatalx("ca_init: PEM");
- BIO_free(in);
-
- hash = ssl_pubkey_hash(pki->pki_cert, pki->pki_cert_len);
- if (dict_check(&pkeys, hash))
- EVP_PKEY_free(pkey);
- else
- dict_xset(&pkeys, hash, pkey);
- free(hash);
- }
-}
-
-static int
-ca_verify_cb(int ok, X509_STORE_CTX *ctx)
-{
- switch (X509_STORE_CTX_get_error(ctx)) {
- case X509_V_OK:
- break;
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
- break;
- case X509_V_ERR_CERT_NOT_YET_VALID:
- case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
- break;
- case X509_V_ERR_CERT_HAS_EXPIRED:
- case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
- break;
- case X509_V_ERR_NO_EXPLICIT_POLICY:
- break;
- }
- return ok;
-}
-
-int
-ca_X509_verify(void *certificate, void *chain, const char *CAfile,
- const char *CRLfile, const char **errstr)
-{
- X509_STORE *store = NULL;
- X509_STORE_CTX *xsc = NULL;
- int ret = 0;
- long error = 0;
-
- if ((store = X509_STORE_new()) == NULL)
- goto end;
-
- if (!X509_STORE_load_locations(store, CAfile, NULL)) {
- log_warn("warn: unable to load CA file %s", CAfile);
- goto end;
- }
- X509_STORE_set_default_paths(store);
-
- if ((xsc = X509_STORE_CTX_new()) == NULL)
- goto end;
-
- if (X509_STORE_CTX_init(xsc, store, certificate, chain) != 1)
- goto end;
-
- X509_STORE_CTX_set_verify_cb(xsc, ca_verify_cb);
-
- ret = X509_verify_cert(xsc);
-
-end:
- *errstr = NULL;
- if (ret != 1) {
- if (xsc) {
- error = X509_STORE_CTX_get_error(xsc);
- *errstr = X509_verify_cert_error_string(error);
- }
- else if (ERR_peek_last_error())
- *errstr = ERR_error_string(ERR_peek_last_error(), NULL);
+ if (tls_signer_add_keypair_mem(signer, pki->pki_cert,
+ pki->pki_cert_len, pki->pki_key, pki->pki_key_len) == -1)
+ fatalx("ca_init: tls_signer_add_keypair_mem");
}
-
- X509_STORE_CTX_free(xsc);
- X509_STORE_free(store);
-
- return ret > 0 ? 1 : 0;
}
-void
+static void
ca_imsg(struct mproc *p, struct imsg *imsg)
{
- EVP_PKEY *pkey;
- RSA *rsa = NULL;
- EC_KEY *ecdsa = NULL;
- const void *from = NULL;
- unsigned char *to = NULL;
- struct msg m;
- const char *hash;
- size_t flen, tlen, padding;
- int buf_len;
- int ret = 0;
- uint64_t id;
- int v;
+ const void *input = NULL;
+ uint8_t *sig = NULL;
+ struct msg m;
+ const char *hash;
+ size_t input_len, siglen;
+ int padding_type, ret, v;
+ uint64_t id;
if (imsg == NULL)
ca_shutdown();
@@ -232,10 +125,6 @@ ca_imsg(struct mproc *p, struct imsg *imsg)
case IMSG_CONF_START:
return;
case IMSG_CONF_END:
- ca_init();
-
- /* Start fulfilling requests */
- mproc_enable(p_dispatcher);
return;
case IMSG_CTL_VERBOSE:
@@ -252,112 +141,39 @@ ca_imsg(struct mproc *p, struct imsg *imsg)
profiling = v;
return;
- case IMSG_CA_RSA_PRIVENC:
- case IMSG_CA_RSA_PRIVDEC:
+ case IMSG_CA_SIGN:
m_msg(&m, imsg);
m_get_id(&m, &id);
m_get_string(&m, &hash);
- m_get_data(&m, &from, &flen);
- m_get_size(&m, &tlen);
- m_get_size(&m, &padding);
+ m_get_data(&m, &input, &input_len);
+ m_get_int(&m, &padding_type);
m_end(&m);
- pkey = dict_get(&pkeys, hash);
- if (pkey == NULL || (rsa = EVP_PKEY_get1_RSA(pkey)) == NULL)
- fatalx("ca_imsg: invalid pkey hash");
-
- if ((to = calloc(1, tlen)) == NULL)
- fatalx("ca_imsg: calloc");
-
- switch (imsg->hdr.type) {
- case IMSG_CA_RSA_PRIVENC:
- ret = RSA_private_encrypt(flen, from, to, rsa,
- padding);
- break;
- case IMSG_CA_RSA_PRIVDEC:
- ret = RSA_private_decrypt(flen, from, to, rsa,
- padding);
- break;
- }
+ ret = tls_signer_sign(signer, hash, input, input_len,
+ padding_type, &sig, &siglen);
m_create(p, imsg->hdr.type, 0, 0, -1);
m_add_id(p, id);
m_add_int(p, ret);
- if (ret > 0)
- m_add_data(p, to, (size_t)ret);
+ if (ret != -1)
+ m_add_data(p, sig, siglen);
m_close(p);
-
- free(to);
- RSA_free(rsa);
- return;
-
- case IMSG_CA_ECDSA_SIGN:
- m_msg(&m, imsg);
- m_get_id(&m, &id);
- m_get_string(&m, &hash);
- m_get_data(&m, &from, &flen);
- m_end(&m);
-
- pkey = dict_get(&pkeys, hash);
- if (pkey == NULL ||
- (ecdsa = EVP_PKEY_get1_EC_KEY(pkey)) == NULL)
- fatalx("ca_imsg: invalid pkey hash");
-
- buf_len = ECDSA_size(ecdsa);
- if ((to = calloc(1, buf_len)) == NULL)
- fatalx("ca_imsg: calloc");
- ret = ECDSA_sign(0, from, flen, to, &buf_len, ecdsa);
- m_create(p, imsg->hdr.type, 0, 0, -1);
- m_add_id(p, id);
- m_add_int(p, ret);
- if (ret > 0)
- m_add_data(p, to, (size_t)buf_len);
- m_close(p);
- free(to);
- EC_KEY_free(ecdsa);
+ free(sig);
return;
}
fatalx("ca_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type));
}
-/*
- * RSA privsep engine (called from unprivileged processes)
- */
-
-const RSA_METHOD *rsa_default = NULL;
-
-static RSA_METHOD *rsae_method = NULL;
-
static int
-rsae_send_imsg(int flen, const unsigned char *from, unsigned char *to,
- RSA *rsa, int padding, unsigned int cmd)
+ca_imsg_get_sync(uint32_t type, uint8_t **output, size_t *output_len)
{
- int ret = 0;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- int n, done = 0;
- const void *toptr;
- char *hash;
- size_t tlen;
- struct msg m;
- uint64_t id;
-
- if ((hash = RSA_get_ex_data(rsa, 0)) == NULL)
- return (0);
-
- /*
- * Send a synchronous imsg because we cannot defer the RSA
- * operation in OpenSSL's engine layer.
- */
- m_create(p_ca, cmd, 0, 0, -1);
- reqid++;
- m_add_id(p_ca, reqid);
- m_add_string(p_ca, hash);
- m_add_data(p_ca, (const void *)from, (size_t)flen);
- m_add_size(p_ca, (size_t)RSA_size(rsa));
- m_add_size(p_ca, (size_t)padding);
- m_flush(p_ca);
+ struct imsgbuf *ibuf;
+ struct imsg imsg;
+ struct msg m;
+ const void *data;
+ uint64_t id;
+ int ret, n, done = 0;
ibuf = &p_ca->imsgbuf;
@@ -375,11 +191,7 @@ rsae_send_imsg(int flen, const unsigned char *from, unsigned char *to,
log_imsg(PROC_DISPATCHER, PROC_CA, &imsg);
- switch (imsg.hdr.type) {
- case IMSG_CA_RSA_PRIVENC:
- case IMSG_CA_RSA_PRIVDEC:
- break;
- default:
+ if (imsg.hdr.type != type) {
/* Another imsg is queued up in the buffer */
dispatcher_imsg(p_ca, &imsg);
imsg_free(&imsg);
@@ -391,359 +203,36 @@ rsae_send_imsg(int flen, const unsigned char *from, unsigned char *to,
if (id != reqid)
fatalx("invalid response id");
m_get_int(&m, &ret);
- if (ret > 0)
- m_get_data(&m, &toptr, &tlen);
+ if (ret != -1) {
+ m_get_data(&m, &data, output_len);
+ if ((*output = malloc(*output_len)) == NULL) {
+ *output_len = 0;
+ ret = -1;
+ }
+ else
+ memcpy(*output, data, *output_len);
+ }
m_end(&m);
-
- if (ret > 0)
- memcpy(to, toptr, tlen);
- done = 1;
-
imsg_free(&imsg);
+ done = 1;
}
}
+
mproc_event_add(p_ca);
return (ret);
}
-static int
-rsae_pub_enc(int flen,const unsigned char *from, unsigned char *to, RSA *rsa,
- int padding)
-{
- log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
- return (RSA_meth_get_pub_enc(rsa_default)(flen, from, to, rsa, padding));
-}
-
-static int
-rsae_pub_dec(int flen,const unsigned char *from, unsigned char *to, RSA *rsa,
- int padding)
-{
- log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
- return (RSA_meth_get_pub_dec(rsa_default)(flen, from, to, rsa, padding));
-}
-
-static int
-rsae_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa,
- int padding)
-{
- log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
- if (RSA_get_ex_data(rsa, 0) != NULL)
- return (rsae_send_imsg(flen, from, to, rsa, padding,
- IMSG_CA_RSA_PRIVENC));
- return (RSA_meth_get_priv_enc(rsa_default)(flen, from, to, rsa, padding));
-}
-
-static int
-rsae_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa,
- int padding)
-{
- log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
- if (RSA_get_ex_data(rsa, 0) != NULL)
- return (rsae_send_imsg(flen, from, to, rsa, padding,
- IMSG_CA_RSA_PRIVDEC));
-
- return (RSA_meth_get_priv_dec(rsa_default)(flen, from, to, rsa, padding));
-}
-
-static int
-rsae_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
-{
- log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
- return (RSA_meth_get_mod_exp(rsa_default)(r0, I, rsa, ctx));
-}
-
-static int
-rsae_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
- const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
-{
- log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
- return (RSA_meth_get_bn_mod_exp(rsa_default)(r, a, p, m, ctx, m_ctx));
-}
-
-static int
-rsae_init(RSA *rsa)
-{
- log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
- if (RSA_meth_get_init(rsa_default) == NULL)
- return (1);
- return (RSA_meth_get_init(rsa_default)(rsa));
-}
-
-static int
-rsae_finish(RSA *rsa)
-{
- log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
- if (RSA_meth_get_finish(rsa_default) == NULL)
- return (1);
- return (RSA_meth_get_finish(rsa_default)(rsa));
-}
-
-static int
-rsae_keygen(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
-{
- log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
- return (RSA_meth_get_keygen(rsa_default)(rsa, bits, e, cb));
-}
-
-
-/*
- * ECDSA privsep engine (called from unprivileged processes)
- */
-
-const ECDSA_METHOD *ecdsa_default = NULL;
-
-static ECDSA_METHOD *ecdsae_method = NULL;
-
-ECDSA_METHOD *
-ECDSA_METHOD_new_temporary(const char *name, int);
-
-ECDSA_METHOD *
-ECDSA_METHOD_new_temporary(const char *name, int flags)
-{
- ECDSA_METHOD *ecdsa;
-
- if ((ecdsa = calloc(1, sizeof (*ecdsa))) == NULL)
- return NULL;
-
- if ((ecdsa->name = strdup(name)) == NULL) {
- free(ecdsa);
- return NULL;
- }
-
- ecdsa->flags = flags;
- return ecdsa;
-}
-
-static ECDSA_SIG *
-ecdsae_send_enc_imsg(const unsigned char *dgst, int dgst_len,
- const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey)
+int
+ca_sign(void *arg, const char *hash, const uint8_t *input, size_t input_len,
+ int padding_type, uint8_t **output, size_t *output_len)
{
- int ret = 0;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- int n, done = 0;
- const void *toptr;
- char *hash;
- size_t tlen;
- struct msg m;
- uint64_t id;
- ECDSA_SIG *sig = NULL;
-
- if ((hash = ECDSA_get_ex_data(eckey, 0)) == NULL)
- return (0);
-
- /*
- * Send a synchronous imsg because we cannot defer the ECDSA
- * operation in OpenSSL's engine layer.
- */
- m_create(p_ca, IMSG_CA_ECDSA_SIGN, 0, 0, -1);
- reqid++;
- m_add_id(p_ca, reqid);
+ m_create(p_ca, IMSG_CA_SIGN, 0, 0, -1);
+ m_add_id(p_ca, ++reqid);
m_add_string(p_ca, hash);
- m_add_data(p_ca, (const void *)dgst, (size_t)dgst_len);
+ m_add_data(p_ca, input, input_len);
+ m_add_int(p_ca, padding_type);
m_flush(p_ca);
- ibuf = &p_ca->imsgbuf;
-
- while (!done) {
- if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
- fatalx("imsg_read");
- if (n == 0)
- fatalx("pipe closed");
- while (!done) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatalx("imsg_get error");
- if (n == 0)
- break;
-
- log_imsg(PROC_DISPATCHER, PROC_CA, &imsg);
-
- switch (imsg.hdr.type) {
- case IMSG_CA_ECDSA_SIGN:
- break;
- default:
- /* Another imsg is queued up in the buffer */
- dispatcher_imsg(p_ca, &imsg);
- imsg_free(&imsg);
- continue;
- }
-
- m_msg(&m, &imsg);
- m_get_id(&m, &id);
- if (id != reqid)
- fatalx("invalid response id");
- m_get_int(&m, &ret);
- if (ret > 0)
- m_get_data(&m, &toptr, &tlen);
- m_end(&m);
- done = 1;
-
- if (ret > 0)
- d2i_ECDSA_SIG(&sig, (const unsigned char **)&toptr, tlen);
- imsg_free(&imsg);
- }
- }
- mproc_event_add(p_ca);
-
- return (sig);
-}
-
-ECDSA_SIG *
-ecdsae_do_sign(const unsigned char *dgst, int dgst_len,
- const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey)
-{
- log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
- if (ECDSA_get_ex_data(eckey, 0) != NULL)
- return (ecdsae_send_enc_imsg(dgst, dgst_len, inv, rp, eckey));
- return (ecdsa_default->ecdsa_do_sign(dgst, dgst_len, inv, rp, eckey));
-}
-
-int
-ecdsae_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv,
- BIGNUM **r)
-{
- log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
- return (ecdsa_default->ecdsa_sign_setup(eckey, ctx, kinv, r));
-}
-
-int
-ecdsae_do_verify(const unsigned char *dgst, int dgst_len,
- const ECDSA_SIG *sig, EC_KEY *eckey)
-{
- log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
- return (ecdsa_default->ecdsa_do_verify(dgst, dgst_len, sig, eckey));
-}
-
-
-static void
-rsa_engine_init(void)
-{
- ENGINE *e;
- const char *errstr, *name;
-
- if ((rsae_method = RSA_meth_new("RSA privsep engine", 0)) == NULL) {
- errstr = "RSA_meth_new";
- goto fail;
- }
-
- RSA_meth_set_pub_enc(rsae_method, rsae_pub_enc);
- RSA_meth_set_pub_dec(rsae_method, rsae_pub_dec);
- RSA_meth_set_priv_enc(rsae_method, rsae_priv_enc);
- RSA_meth_set_priv_dec(rsae_method, rsae_priv_dec);
- RSA_meth_set_mod_exp(rsae_method, rsae_mod_exp);
- RSA_meth_set_bn_mod_exp(rsae_method, rsae_bn_mod_exp);
- RSA_meth_set_init(rsae_method, rsae_init);
- RSA_meth_set_finish(rsae_method, rsae_finish);
- RSA_meth_set_keygen(rsae_method, rsae_keygen);
-
- if ((e = ENGINE_get_default_RSA()) == NULL) {
- if ((e = ENGINE_new()) == NULL) {
- errstr = "ENGINE_new";
- goto fail;
- }
- if (!ENGINE_set_name(e, RSA_meth_get0_name(rsae_method))) {
- errstr = "ENGINE_set_name";
- goto fail;
- }
- if ((rsa_default = RSA_get_default_method()) == NULL) {
- errstr = "RSA_get_default_method";
- goto fail;
- }
- } else if ((rsa_default = ENGINE_get_RSA(e)) == NULL) {
- errstr = "ENGINE_get_RSA";
- goto fail;
- }
-
- if ((name = ENGINE_get_name(e)) == NULL)
- name = "unknown RSA engine";
-
- log_debug("debug: %s: using %s", __func__, name);
-
- if (RSA_meth_get_mod_exp(rsa_default) == NULL)
- RSA_meth_set_mod_exp(rsae_method, NULL);
- if (RSA_meth_get_bn_mod_exp(rsa_default) == NULL)
- RSA_meth_set_bn_mod_exp(rsae_method, NULL);
- if (RSA_meth_get_keygen(rsa_default) == NULL)
- RSA_meth_set_keygen(rsae_method, NULL);
- RSA_meth_set_flags(rsae_method,
- RSA_meth_get_flags(rsa_default) | RSA_METHOD_FLAG_NO_CHECK);
- RSA_meth_set0_app_data(rsae_method,
- RSA_meth_get0_app_data(rsa_default));
-
- if (!ENGINE_set_RSA(e, rsae_method)) {
- errstr = "ENGINE_set_RSA";
- goto fail;
- }
- if (!ENGINE_set_default_RSA(e)) {
- errstr = "ENGINE_set_default_RSA";
- goto fail;
- }
-
- return;
-
- fail:
- ssl_error(errstr);
- fatalx("%s", errstr);
-}
-
-static void
-ecdsa_engine_init(void)
-{
- ENGINE *e;
- const char *errstr, *name;
-
- if ((ecdsae_method = ECDSA_METHOD_new_temporary("ECDSA privsep engine", 0)) == NULL) {
- errstr = "ECDSA_METHOD_new_temporary";
- goto fail;
- }
-
- ecdsae_method->ecdsa_do_sign = ecdsae_do_sign;
- ecdsae_method->ecdsa_sign_setup = ecdsae_sign_setup;
- ecdsae_method->ecdsa_do_verify = ecdsae_do_verify;
-
- if ((e = ENGINE_get_default_ECDSA()) == NULL) {
- if ((e = ENGINE_new()) == NULL) {
- errstr = "ENGINE_new";
- goto fail;
- }
- if (!ENGINE_set_name(e, ecdsae_method->name)) {
- errstr = "ENGINE_set_name";
- goto fail;
- }
- if ((ecdsa_default = ECDSA_get_default_method()) == NULL) {
- errstr = "ECDSA_get_default_method";
- goto fail;
- }
- } else if ((ecdsa_default = ENGINE_get_ECDSA(e)) == NULL) {
- errstr = "ENGINE_get_ECDSA";
- goto fail;
- }
-
- if ((name = ENGINE_get_name(e)) == NULL)
- name = "unknown ECDSA engine";
-
- log_debug("debug: %s: using %s", __func__, name);
-
- if (!ENGINE_set_ECDSA(e, ecdsae_method)) {
- errstr = "ENGINE_set_ECDSA";
- goto fail;
- }
- if (!ENGINE_set_default_ECDSA(e)) {
- errstr = "ENGINE_set_default_ECDSA";
- goto fail;
- }
-
- return;
-
- fail:
- ssl_error(errstr);
- fatalx("%s", errstr);
-}
-
-void
-ca_engine_init(void)
-{
- rsa_engine_init();
- ecdsa_engine_init();
+ return (ca_imsg_get_sync(IMSG_CA_SIGN, output, output_len));
}
diff --git a/usr.sbin/smtpd/dispatcher.c b/usr.sbin/smtpd/dispatcher.c
index d294fceda19..f1d061da5d3 100644
--- a/usr.sbin/smtpd/dispatcher.c
+++ b/usr.sbin/smtpd/dispatcher.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dispatcher.c,v 1.5 2021/06/14 17:58:15 eric Exp $ */
+/* $OpenBSD: dispatcher.c,v 1.6 2022/02/12 18:22:04 eric Exp $ */
/*
* Copyright (c) 2014 Gilles Chehade <gilles@poolp.org>
@@ -132,8 +132,6 @@ dispatcher(void)
{
struct passwd *pw;
- ca_engine_init();
-
mda_postfork();
mta_postfork();
smtp_postfork();
diff --git a/usr.sbin/smtpd/mta.c b/usr.sbin/smtpd/mta.c
index 1d48fe69673..080c562c8c4 100644
--- a/usr.sbin/smtpd/mta.c
+++ b/usr.sbin/smtpd/mta.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mta.c,v 1.241 2022/02/10 14:59:35 millert Exp $ */
+/* $OpenBSD: mta.c,v 1.242 2022/02/12 18:22:04 eric Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -124,12 +124,6 @@ int mta_is_blocked(struct mta_source *, char *);
static int mta_block_cmp(const struct mta_block *, const struct mta_block *);
SPLAY_PROTOTYPE(mta_block_tree, mta_block, entry, mta_block_cmp);
-/*
- * This function is not publicy exported because it is a hack until libtls
- * has a proper privsep setup
- */
-void tls_config_use_fake_private_key(struct tls_config *config);
-
static struct mta_relay_tree relays;
static struct mta_domain_tree domains;
static struct mta_host_tree hosts;
@@ -506,7 +500,7 @@ mta_setup_dispatcher(struct dispatcher *dispatcher)
fatal("client pki \"%s\" not found ", remote->pki);
tls_config_set_dheparams(config, dheparams[pki->pki_dhe]);
- tls_config_use_fake_private_key(config);
+ tls_config_set_sign_cb(config, ca_sign, NULL);
if (tls_config_set_keypair_mem(config, pki->pki_cert,
pki->pki_cert_len, NULL, 0) == -1)
fatal("tls_config_set_keypair_mem");
diff --git a/usr.sbin/smtpd/smtp.c b/usr.sbin/smtpd/smtp.c
index b02a9aef757..00bda472ddd 100644
--- a/usr.sbin/smtpd/smtp.c
+++ b/usr.sbin/smtpd/smtp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtp.c,v 1.171 2021/06/14 17:58:16 eric Exp $ */
+/* $OpenBSD: smtp.c,v 1.172 2022/02/12 18:22:04 eric Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -47,12 +47,6 @@ proxy_session(struct listener *listener, int sock,
static void smtp_accepted(struct listener *, int, const struct sockaddr_storage *, struct io *);
-/*
- * This function are not publicy exported because it is a hack until libtls
- * has a proper privsep setup
- */
-void tls_config_use_fake_private_key(struct tls_config *config);
-
#define SMTP_FD_RESERVE 5
static size_t sessions;
static size_t maxsessions;
@@ -183,7 +177,7 @@ smtp_setup_listener_tls(struct listener *l)
if (tls_config_set_dheparams(config, dheparams[pki->pki_dhe]) == -1)
fatal("tls_config_set_dheparams");
- tls_config_use_fake_private_key(config);
+ tls_config_set_sign_cb(config, ca_sign, NULL);
for (i = 0; i < l->pkicount; i++) {
pki = l->pki[i];
if (i == 0) {
diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c
index dd3a7de8ebe..08f76233c00 100644
--- a/usr.sbin/smtpd/smtpd.c
+++ b/usr.sbin/smtpd/smtpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.c,v 1.341 2021/07/14 13:33:57 kn Exp $ */
+/* $OpenBSD: smtpd.c,v 1.342 2022/02/12 18:22:04 eric Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -2100,9 +2100,7 @@ imsg_to_str(int type)
CASE(IMSG_FILTER_SMTP_DATA_BEGIN);
CASE(IMSG_FILTER_SMTP_DATA_END);
- CASE(IMSG_CA_RSA_PRIVENC);
- CASE(IMSG_CA_RSA_PRIVDEC);
- CASE(IMSG_CA_ECDSA_SIGN);
+ CASE(IMSG_CA_SIGN);
default:
(void)snprintf(buf, sizeof(buf), "IMSG_??? (%d)", type);
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index 7e80dcc2abc..df86eb05212 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.672 2022/02/10 14:59:35 millert Exp $ */
+/* $OpenBSD: smtpd.h,v 1.673 2022/02/12 18:22:04 eric Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -329,9 +329,7 @@ enum imsg_type {
IMSG_FILTER_SMTP_DATA_BEGIN,
IMSG_FILTER_SMTP_DATA_END,
- IMSG_CA_RSA_PRIVENC,
- IMSG_CA_RSA_PRIVDEC,
- IMSG_CA_ECDSA_SIGN,
+ IMSG_CA_SIGN,
};
enum smtp_proc_type {
@@ -1271,12 +1269,8 @@ void bounce_fd(int);
/* ca.c */
-int ca(void);
-int ca_X509_verify(void *, void *, const char *, const char *, const char **);
-void ca_imsg(struct mproc *, struct imsg *);
-void ca_init(void);
-void ca_engine_init(void);
-
+int ca(void);
+int ca_sign(void *, const char *, const uint8_t *, size_t, int, uint8_t **, size_t *);
/* compress_backend.c */
struct compress_backend *compress_backend_lookup(const char *);
diff --git a/usr.sbin/smtpd/ssl.c b/usr.sbin/smtpd/ssl.c
index cbb3574a049..65b259073d7 100644
--- a/usr.sbin/smtpd/ssl.c
+++ b/usr.sbin/smtpd/ssl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl.c,v 1.96 2021/06/14 17:58:16 eric Exp $ */
+/* $OpenBSD: ssl.c,v 1.97 2022/02/12 18:22:04 eric Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -23,7 +23,6 @@
#include <fcntl.h>
#include <limits.h>
#include <openssl/engine.h>
-#include <openssl/err.h>
#include <openssl/ssl.h>
#include <string.h>
#include <unistd.h>
@@ -244,59 +243,3 @@ ssl_error(const char *where)
log_debug("debug: SSL library error: %s: %s", where, errbuf);
}
}
-
-static void
-hash_x509(X509 *cert, char *hash, size_t hashlen)
-{
- static const char hex[] = "0123456789abcdef";
- size_t off;
- char digest[EVP_MAX_MD_SIZE];
- int dlen, i;
-
- if (X509_pubkey_digest(cert, EVP_sha256(), digest, &dlen) != 1)
- fatalx("%s: X509_pubkey_digest failed", __func__);
-
- if (hashlen < 2 * dlen + sizeof("SHA256:"))
- fatalx("%s: hash buffer to small", __func__);
-
- off = strlcpy(hash, "SHA256:", hashlen);
-
- for (i = 0; i < dlen; i++) {
- hash[off++] = hex[(digest[i] >> 4) & 0x0f];
- hash[off++] = hex[digest[i] & 0x0f];
- }
- hash[off] = 0;
-}
-
-char *
-ssl_pubkey_hash(const char *buf, off_t len)
-{
-#define TLS_CERT_HASH_SIZE 128
- BIO *in;
- X509 *x509 = NULL;
- char *hash = NULL;
-
- if ((in = BIO_new_mem_buf(buf, len)) == NULL) {
- log_warnx("%s: BIO_new_mem_buf failed", __func__);
- return NULL;
- }
-
- if ((x509 = PEM_read_bio_X509(in, NULL, NULL, NULL)) == NULL) {
- log_warnx("%s: PEM_read_bio_X509 failed", __func__);
- goto fail;
- }
-
- if ((hash = malloc(TLS_CERT_HASH_SIZE)) == NULL) {
- log_warn("%s: malloc", __func__);
- goto fail;
- }
- hash_x509(x509, hash, TLS_CERT_HASH_SIZE);
-
-fail:
- BIO_free(in);
-
- if (x509)
- X509_free(x509);
-
- return hash;
-}
diff --git a/usr.sbin/smtpd/ssl.h b/usr.sbin/smtpd/ssl.h
index 0bbe5cb8034..1144038a653 100644
--- a/usr.sbin/smtpd/ssl.h
+++ b/usr.sbin/smtpd/ssl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl.h,v 1.24 2021/05/26 07:05:50 eric Exp $ */
+/* $OpenBSD: ssl.h,v 1.25 2022/02/12 18:22:04 eric Exp $ */
/*
* Copyright (c) 2013 Gilles Chehade <gilles@poolp.org>
*
@@ -44,4 +44,3 @@ void ssl_error(const char *);
int ssl_load_certificate(struct pki *, const char *);
int ssl_load_keyfile(struct pki *, const char *, const char *);
int ssl_load_cafile(struct ca *, const char *);
-char *ssl_pubkey_hash(const char *, off_t);