Re: smtpd: use libtls signer

2022-02-12 Thread Theo Buehler
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

2022-02-12 Thread Eric Faurot
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

2022-01-30 Thread Eric Faurot
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

2021-03-02 Thread Theo Buehler
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

2021-02-13 Thread Eric Faurot
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

2021-02-05 Thread Gilles CHEHADE
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

2021-02-05 Thread Eric Faurot
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

2021-01-27 Thread Aisha Tammy
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

2021-01-27 Thread gilles
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

2021-01-27 Thread Lauri Tirkkonen
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

2021-01-27 Thread Eric Faurot
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