Re: smtpd: use libtls signer
On Sat, Feb 12, 2022 at 02:49:46PM +0100, Eric Faurot wrote: > On Sun, Jan 30, 2022 at 10:55:40AM +0100, Eric Faurot wrote: > > Hi. > > > > This diff makes use of the new libtls signer api to simplify tls privsep. > > Updated diff after libtls signer api tweak by jsing@ ok tb
Re: smtpd: use libtls signer
On Sun, Jan 30, 2022 at 10:55:40AM +0100, Eric Faurot wrote: > Hi. > > This diff makes use of the new libtls signer api to simplify tls privsep. Updated diff after libtls signer api tweak by jsing@ Eric. Index: ca.c === RCS file: /cvs/src/usr.sbin/smtpd/ca.c,v retrieving revision 1.40 diff -u -p -r1.40 ca.c --- ca.c14 Jun 2021 17:58:15 - 1.40 +++ ca.c12 Feb 2022 12:49:04 - @@ -1,6 +1,7 @@ /* $OpenBSD: ca.c,v 1.40 2021/06/14 17:58:15 eric Exp $*/ /* + * Copyright (c) 2021 Eric Faurot * Copyright (c) 2014 Reyk Floeter * Copyright (c) 2012 Gilles Chehade * @@ -17,45 +18,23 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include +#include #include #include +#include #include +#include #include #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 void ca_imsg(struct mproc *, struct imsg *); +static void ca_init(void); -static struct dict pkeys; -static uint64_t reqid = 0; +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; + struct pki *pki; + void *iter_dict; + + if ((signer = tls_signer_new()) == NULL) + fatal("tls_signer_new"); - log_debug("debug: init private ssl-tree"); - dict_init(); iter_dict = NULL; - while (dict_iter(env->sc_pki_dict, _dict, , (void **))) { + while (dict_iter(env->sc_pki_dict, _dict, NULL, (void **))) { 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(, hash)) - EVP_PKEY_free(pkey); - else - dict_xset(, hash, pkey); - free(hash); + 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"); } } -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
smtpd: use libtls signer
Hi. This diff makes use of the new libtls signer api to simplify tls privsep. Eric. Index: ca.c === RCS file: /cvs/src/usr.sbin/smtpd/ca.c,v retrieving revision 1.40 diff -u -p -r1.40 ca.c --- ca.c14 Jun 2021 17:58:15 - 1.40 +++ ca.c26 Jan 2022 14:01:15 - @@ -1,6 +1,7 @@ /* $OpenBSD: ca.c,v 1.40 2021/06/14 17:58:15 eric Exp $*/ /* + * Copyright (c) 2021 Eric Faurot * Copyright (c) 2014 Reyk Floeter * Copyright (c) 2012 Gilles Chehade * @@ -17,45 +18,23 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include +#include #include #include +#include #include +#include #include #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 void ca_imsg(struct mproc *, struct imsg *); +static void ca_init(void); -static struct dict pkeys; -static uint64_t reqid = 0; +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; + struct pki *pki; + void *iter_dict; + + if ((signer = tls_signer_new()) == NULL) + fatal("tls_signer_new"); - log_debug("debug: init private ssl-tree"); - dict_init(); iter_dict = NULL; - while (dict_iter(env->sc_pki_dict, _dict, , (void **))) { + while (dict_iter(env->sc_pki_dict, _dict, NULL, (void **))) { 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(, hash)) - EVP_PKEY_free(pkey); - else - dict_xset(, hash, pkey); - free(hash); + 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"); } } -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: -
Re: smtpd: use libtls
On Sat, Feb 13, 2021 at 06:26:02PM +0100, Eric Faurot wrote: > Hi. > > The diff seems to work for the few people who tested it (thanks). > Anyone wants to ok this? I read through the diff several times, but I'm not familiar with smtpd so cannot claim a thorough review. Nothing really stood out as odd or wrong. I like the simplification a lot. ok tb I only have these two trivial remarks: > int > -io_start_tls(struct io *io, void *tls) > +io_accept_tls(struct io *io, struct tls *tls) > { > int mode; > > mode = io->flags & IO_RW; > - if (mode == 0 || mode == IO_RW) > - errx(1, "io_start_tls(): full-duplex or unset"); > + if (mode != IO_READ) > + errx(1, "io_connect_tls: expect IO_READ mode"); should be io_accept_tls > > if (io->tls) > errx(1, "io_start_tls(): TLS already started"); dito > io->tls = tls; > + io->state = IO_STATE_ACCEPT_TLS; > + io_reset(io, EV_READ, io_dispatch_accept_tls); > + > + return (0); > +}
Re: smtpd: use libtls
Hi. The diff seems to work for the few people who tested it (thanks). Anyone wants to ok this? Eric. Index: ca.c === RCS file: /cvs/src/usr.sbin/smtpd/ca.c,v retrieving revision 1.37 diff -u -p -r1.37 ca.c --- ca.c31 Dec 2020 08:27:15 - 1.37 +++ ca.c19 Jan 2021 11:09:54 - @@ -69,6 +69,7 @@ static int ecdsae_do_verify(const unsign EC_KEY *); +static struct dict pkeys; static uint64_t reqid = 0; static void @@ -132,26 +133,29 @@ ca_init(void) struct pki *pki; const char *k; void*iter_dict; + char*hash; log_debug("debug: init private ssl-tree"); + dict_init(); iter_dict = NULL; while (dict_iter(env->sc_pki_dict, _dict, , (void **))) { if (pki->pki_key == NULL) continue; - if ((in = BIO_new_mem_buf(pki->pki_key, - pki->pki_key_len)) == NULL) - fatalx("ca_launch: key"); - - if ((pkey = PEM_read_bio_PrivateKey(in, - NULL, NULL, NULL)) == NULL) - fatalx("ca_launch: PEM"); + 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); - pki->pki_pkey = pkey; - - freezero(pki->pki_key, pki->pki_key_len); - pki->pki_key = NULL; + hash = ssl_pubkey_hash(pki->pki_cert, pki->pki_cert_len); + if (dict_check(, hash)) + EVP_PKEY_free(pkey); + else + dict_xset(, hash, pkey); + free(hash); } } @@ -223,15 +227,15 @@ end: 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 *pkiname; + const char *hash; size_t flen, tlen, padding; int buf_len; - struct pki *pki; int ret = 0; uint64_t id; int v; @@ -267,16 +271,15 @@ ca_imsg(struct mproc *p, struct imsg *im case IMSG_CA_RSA_PRIVDEC: m_msg(, imsg); m_get_id(, ); - m_get_string(, ); + m_get_string(, ); m_get_data(, , ); m_get_size(, ); m_get_size(, ); m_end(); - pki = dict_get(env->sc_pki_dict, pkiname); - if (pki == NULL || pki->pki_pkey == NULL || - (rsa = EVP_PKEY_get1_RSA(pki->pki_pkey)) == NULL) - fatalx("ca_imsg: invalid pki"); + pkey = dict_get(, 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"); @@ -306,14 +309,14 @@ ca_imsg(struct mproc *p, struct imsg *im case IMSG_CA_ECDSA_SIGN: m_msg(, imsg); m_get_id(, ); - m_get_string(, ); + m_get_string(, ); m_get_data(, , ); m_end(); - pki = dict_get(env->sc_pki_dict, pkiname); - if (pki == NULL || pki->pki_pkey == NULL || - (ecdsa = EVP_PKEY_get1_EC_KEY(pki->pki_pkey)) == NULL) - fatalx("ca_imsg: invalid pki"); + pkey = dict_get(, 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) @@ -350,12 +353,12 @@ rsae_send_imsg(int flen, const unsigned struct imsg imsg; int n, done = 0; const void *toptr; - char*pkiname; + char*hash; size_t tlen; struct msg m; uint64_t id; - if ((pkiname = RSA_get_ex_data(rsa, 0)) == NULL) + if ((hash = RSA_get_ex_data(rsa, 0)) == NULL) return (0); /* @@ -365,7 +368,7 @@ rsae_send_imsg(int flen, const unsigned m_create(p_ca, cmd, 0, 0, -1); reqid++; m_add_id(p_ca, reqid); -
Re: smtpd: use libtls
Been running it for a few days, no regressions so far > On 5 Feb 2021, at 09:35, Eric Faurot wrote: > > No much report so far. > Anybody had a chance to test this? > Here is the same diff again with manpage update this time. > > Eric. > > Index: ca.c > === > RCS file: /cvs/src/usr.sbin/smtpd/ca.c,v > retrieving revision 1.37 > diff -u -p -r1.37 ca.c > --- ca.c 31 Dec 2020 08:27:15 - 1.37 > +++ ca.c 19 Jan 2021 11:09:54 - > @@ -69,6 +69,7 @@ static int ecdsae_do_verify(const unsign > EC_KEY *); > > > +static struct dict pkeys; > static uint64_treqid = 0; > > static void > @@ -132,26 +133,29 @@ ca_init(void) > struct pki *pki; > const char *k; > void*iter_dict; > + char*hash; > > log_debug("debug: init private ssl-tree"); > + dict_init(); > iter_dict = NULL; > while (dict_iter(env->sc_pki_dict, _dict, , (void **))) { > if (pki->pki_key == NULL) > continue; > > - if ((in = BIO_new_mem_buf(pki->pki_key, > - pki->pki_key_len)) == NULL) > - fatalx("ca_launch: key"); > - > - if ((pkey = PEM_read_bio_PrivateKey(in, > - NULL, NULL, NULL)) == NULL) > - fatalx("ca_launch: PEM"); > + 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); > > - pki->pki_pkey = pkey; > - > - freezero(pki->pki_key, pki->pki_key_len); > - pki->pki_key = NULL; > + hash = ssl_pubkey_hash(pki->pki_cert, pki->pki_cert_len); > + if (dict_check(, hash)) > + EVP_PKEY_free(pkey); > + else > + dict_xset(, hash, pkey); > + free(hash); > } > } > > @@ -223,15 +227,15 @@ end: > 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 *pkiname; > + const char *hash; > size_t flen, tlen, padding; > int buf_len; > - struct pki *pki; > int ret = 0; > uint64_t id; > int v; > @@ -267,16 +271,15 @@ ca_imsg(struct mproc *p, struct imsg *im > case IMSG_CA_RSA_PRIVDEC: > m_msg(, imsg); > m_get_id(, ); > - m_get_string(, ); > + m_get_string(, ); > m_get_data(, , ); > m_get_size(, ); > m_get_size(, ); > m_end(); > > - pki = dict_get(env->sc_pki_dict, pkiname); > - if (pki == NULL || pki->pki_pkey == NULL || > - (rsa = EVP_PKEY_get1_RSA(pki->pki_pkey)) == NULL) > - fatalx("ca_imsg: invalid pki"); > + pkey = dict_get(, 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"); > @@ -306,14 +309,14 @@ ca_imsg(struct mproc *p, struct imsg *im > case IMSG_CA_ECDSA_SIGN: > m_msg(, imsg); > m_get_id(, ); > - m_get_string(, ); > + m_get_string(, ); > m_get_data(, , ); > m_end(); > > - pki = dict_get(env->sc_pki_dict, pkiname); > - if (pki == NULL || pki->pki_pkey == NULL || > - (ecdsa = EVP_PKEY_get1_EC_KEY(pki->pki_pkey)) == NULL) > - fatalx("ca_imsg: invalid pki"); > + pkey = dict_get(, 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) > @@ -350,12 +353,12 @@ rsae_send_imsg(int flen, const unsigned > struct imsg imsg; > int n, done = 0; > const void *toptr; > - char*pkiname; > + char*hash; > size_t tlen; > struct msg m; > uint64_t id; > > - if ((pkiname = RSA_get_ex_data(rsa, 0)) == NULL) > + if ((hash = RSA_get_ex_data(rsa, 0)) == NULL) >
Re: smtpd: use libtls
No much report so far. Anybody had a chance to test this? Here is the same diff again with manpage update this time. Eric. Index: ca.c === RCS file: /cvs/src/usr.sbin/smtpd/ca.c,v retrieving revision 1.37 diff -u -p -r1.37 ca.c --- ca.c31 Dec 2020 08:27:15 - 1.37 +++ ca.c19 Jan 2021 11:09:54 - @@ -69,6 +69,7 @@ static int ecdsae_do_verify(const unsign EC_KEY *); +static struct dict pkeys; static uint64_t reqid = 0; static void @@ -132,26 +133,29 @@ ca_init(void) struct pki *pki; const char *k; void*iter_dict; + char*hash; log_debug("debug: init private ssl-tree"); + dict_init(); iter_dict = NULL; while (dict_iter(env->sc_pki_dict, _dict, , (void **))) { if (pki->pki_key == NULL) continue; - if ((in = BIO_new_mem_buf(pki->pki_key, - pki->pki_key_len)) == NULL) - fatalx("ca_launch: key"); - - if ((pkey = PEM_read_bio_PrivateKey(in, - NULL, NULL, NULL)) == NULL) - fatalx("ca_launch: PEM"); + 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); - pki->pki_pkey = pkey; - - freezero(pki->pki_key, pki->pki_key_len); - pki->pki_key = NULL; + hash = ssl_pubkey_hash(pki->pki_cert, pki->pki_cert_len); + if (dict_check(, hash)) + EVP_PKEY_free(pkey); + else + dict_xset(, hash, pkey); + free(hash); } } @@ -223,15 +227,15 @@ end: 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 *pkiname; + const char *hash; size_t flen, tlen, padding; int buf_len; - struct pki *pki; int ret = 0; uint64_t id; int v; @@ -267,16 +271,15 @@ ca_imsg(struct mproc *p, struct imsg *im case IMSG_CA_RSA_PRIVDEC: m_msg(, imsg); m_get_id(, ); - m_get_string(, ); + m_get_string(, ); m_get_data(, , ); m_get_size(, ); m_get_size(, ); m_end(); - pki = dict_get(env->sc_pki_dict, pkiname); - if (pki == NULL || pki->pki_pkey == NULL || - (rsa = EVP_PKEY_get1_RSA(pki->pki_pkey)) == NULL) - fatalx("ca_imsg: invalid pki"); + pkey = dict_get(, 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"); @@ -306,14 +309,14 @@ ca_imsg(struct mproc *p, struct imsg *im case IMSG_CA_ECDSA_SIGN: m_msg(, imsg); m_get_id(, ); - m_get_string(, ); + m_get_string(, ); m_get_data(, , ); m_end(); - pki = dict_get(env->sc_pki_dict, pkiname); - if (pki == NULL || pki->pki_pkey == NULL || - (ecdsa = EVP_PKEY_get1_EC_KEY(pki->pki_pkey)) == NULL) - fatalx("ca_imsg: invalid pki"); + pkey = dict_get(, 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) @@ -350,12 +353,12 @@ rsae_send_imsg(int flen, const unsigned struct imsg imsg; int n, done = 0; const void *toptr; - char*pkiname; + char*hash; size_t tlen; struct msg m; uint64_t id; - if ((pkiname = RSA_get_ex_data(rsa, 0)) == NULL) + if ((hash = RSA_get_ex_data(rsa, 0)) == NULL) return (0); /* @@ -365,7 +368,7 @@ rsae_send_imsg(int flen, const unsigned m_create(p_ca, cmd, 0, 0, -1); reqid++;
Re: smtpd: use libtls
On 1/27/21 7:29 AM, gil...@poolp.org wrote: > January 27, 2021 9:47 AM, "Lauri Tirkkonen" wrote: > >> On Wed, Jan 27 2021 09:36:31 +0100, Eric Faurot wrote: >> >>> There has been a plan for some time now to make smtpd use libtls >>> instead of openssl. Recent changes in libtls allow to move forward >>> with this. Here is a diff to start the switch. I've tried to keep >>> it as small as possible, sticking to the necessary changes. There is >>> still a lot of code that can be removed but that will be done in a >>> second time. >> >> I'm all for this, and sorry for screaming from the gallery, but I want to >> ask - >> is there a plan relating to libtls for portable OpenSMTPD? As it stands, >> OpenSSL-based systems are largely unable to use libtls (which in itself is a >> shame) - how would this change make it to portable? >> > > TL;DR: > In January 2020, I adapted OpenSMTPD to libtls for the first time and did it > both > for OpenBSD and portable. Since many systems didn't have LibreSSL available, > this > resulted in libtls being brought to the openbsd-compat layer and adapted to > build > with OpenSSL. The plan is to use libtls from LibreSSL if detected, otherwise > take > the openbsd-compat version if OpenSSL is detected. > > More (outdated) details here: > > https://poolp.org/posts/2020-01-22/january-2020-opensmtpd-work-libasr-and-libtls/ > > > As a side note: > > The work eric@ did on the libtls conversion was based on my diff but diverged > and > I will have to adapt my work from last year to make it work again. I'll take > care > of making it work again once his work is committed. > > As of today, there's no one but me working on the portable release so it > would be > nice if people interested in a portable release would step up to help. > Is it not possible to use libretls - https://git.causal.agency/libretls/about/ They plan to maintain such a compatibility layer of libtls with openssl with minimal changes. It might be better to use their effort rather than adding a burden of both a compat libtls and opensmtpd in the portable version. Quite a lot of distributions already have this present so this might be a good idea to use their work. Thoughts? Best, Aisha
Re: smtpd: use libtls
January 27, 2021 9:47 AM, "Lauri Tirkkonen" wrote: > On Wed, Jan 27 2021 09:36:31 +0100, Eric Faurot wrote: > >> There has been a plan for some time now to make smtpd use libtls >> instead of openssl. Recent changes in libtls allow to move forward >> with this. Here is a diff to start the switch. I've tried to keep >> it as small as possible, sticking to the necessary changes. There is >> still a lot of code that can be removed but that will be done in a >> second time. > > I'm all for this, and sorry for screaming from the gallery, but I want to ask > - > is there a plan relating to libtls for portable OpenSMTPD? As it stands, > OpenSSL-based systems are largely unable to use libtls (which in itself is a > shame) - how would this change make it to portable? > TL;DR: In January 2020, I adapted OpenSMTPD to libtls for the first time and did it both for OpenBSD and portable. Since many systems didn't have LibreSSL available, this resulted in libtls being brought to the openbsd-compat layer and adapted to build with OpenSSL. The plan is to use libtls from LibreSSL if detected, otherwise take the openbsd-compat version if OpenSSL is detected. More (outdated) details here: https://poolp.org/posts/2020-01-22/january-2020-opensmtpd-work-libasr-and-libtls/ As a side note: The work eric@ did on the libtls conversion was based on my diff but diverged and I will have to adapt my work from last year to make it work again. I'll take care of making it work again once his work is committed. As of today, there's no one but me working on the portable release so it would be nice if people interested in a portable release would step up to help.
Re: smtpd: use libtls
On Wed, Jan 27 2021 09:36:31 +0100, Eric Faurot wrote: > There has been a plan for some time now to make smtpd use libtls > instead of openssl. Recent changes in libtls allow to move forward > with this. Here is a diff to start the switch. I've tried to keep > it as small as possible, sticking to the necessary changes. There is > still a lot of code that can be removed but that will be done in a > second time. I'm all for this, and sorry for screaming from the gallery, but I want to ask - is there a plan relating to libtls for portable OpenSMTPD? As it stands, OpenSSL-based systems are largely unable to use libtls (which in itself is a shame) - how would this change make it to portable? -- Lauri Tirkkonen | lotheac @ IRCnet
smtpd: use libtls
There has been a plan for some time now to make smtpd use libtls instead of openssl. Recent changes in libtls allow to move forward with this. Here is a diff to start the switch. I've tried to keep it as small as possible, sticking to the necessary changes. There is still a lot of code that can be removed but that will be done in a second time. There are two visible changes that the user must be aware of. First, certificate verification is now delegated to libtls, so peer certificate, if provided, can only be reported as either "valid" or "unverified" (if no-verify is requested). In other words, invalid certificates can no longer (at least for now) be detected but still accepted. Secondly, the way SNI is configured has changed: the "pki" listener option can now be used multiple times to add extra certificates on a listener. Each tls-enabled listener must have at least one certificate explicitly set. The extra ones are used for SNI, and only the specified certificates will be used for this listener. So there is no more fallback or global lookup on configured pki names. Tests and comments would be greatly appreciated. Eric. Index: ca.c === RCS file: /cvs/src/usr.sbin/smtpd/ca.c,v retrieving revision 1.37 diff -u -p -r1.37 ca.c --- ca.c31 Dec 2020 08:27:15 - 1.37 +++ ca.c19 Jan 2021 11:09:54 - @@ -69,6 +69,7 @@ static int ecdsae_do_verify(const unsign EC_KEY *); +static struct dict pkeys; static uint64_t reqid = 0; static void @@ -132,26 +133,29 @@ ca_init(void) struct pki *pki; const char *k; void*iter_dict; + char*hash; log_debug("debug: init private ssl-tree"); + dict_init(); iter_dict = NULL; while (dict_iter(env->sc_pki_dict, _dict, , (void **))) { if (pki->pki_key == NULL) continue; - if ((in = BIO_new_mem_buf(pki->pki_key, - pki->pki_key_len)) == NULL) - fatalx("ca_launch: key"); - - if ((pkey = PEM_read_bio_PrivateKey(in, - NULL, NULL, NULL)) == NULL) - fatalx("ca_launch: PEM"); + 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); - pki->pki_pkey = pkey; - - freezero(pki->pki_key, pki->pki_key_len); - pki->pki_key = NULL; + hash = ssl_pubkey_hash(pki->pki_cert, pki->pki_cert_len); + if (dict_check(, hash)) + EVP_PKEY_free(pkey); + else + dict_xset(, hash, pkey); + free(hash); } } @@ -223,15 +227,15 @@ end: 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 *pkiname; + const char *hash; size_t flen, tlen, padding; int buf_len; - struct pki *pki; int ret = 0; uint64_t id; int v; @@ -267,16 +271,15 @@ ca_imsg(struct mproc *p, struct imsg *im case IMSG_CA_RSA_PRIVDEC: m_msg(, imsg); m_get_id(, ); - m_get_string(, ); + m_get_string(, ); m_get_data(, , ); m_get_size(, ); m_get_size(, ); m_end(); - pki = dict_get(env->sc_pki_dict, pkiname); - if (pki == NULL || pki->pki_pkey == NULL || - (rsa = EVP_PKEY_get1_RSA(pki->pki_pkey)) == NULL) - fatalx("ca_imsg: invalid pki"); + pkey = dict_get(, 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"); @@ -306,14 +309,14 @@ ca_imsg(struct mproc *p, struct imsg *im case IMSG_CA_ECDSA_SIGN: m_msg(, imsg); m_get_id(, ); - m_get_string(, ); + m_get_string(, ); m_get