tags 920489 + patch
thanks

For convenience, I've attached the updated patch series + files which
should be replaced in debian/patches.

I'll leave it up to the maintainer to decide what to do with this;
uploading to experimental might be fine (considering we really should be
using LibreSSL instead), although I've been rocking on with these
patches for over a month now with no issues at all.
Description: Enable support for OpenSSL 1.1
Author: Sebastian Andrzej Siewior <sebast...@breakpoint.cc>
        Ryan Kavanagh <r...@debian.org>
	Linda Lapinlampi <li...@lindalap.fi>
Origin: Debian
Bug: https://github.com/OpenSMTPD/OpenSMTPD/issues/738
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=859544
Forwarded: https://github.com/OpenSMTPD/OpenSMTPD/pull/825
Last-Update: 2019-01-06
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
--- a/openbsd-compat/libressl.c
+++ b/openbsd-compat/libressl.c
@@ -81,14 +81,14 @@
 	x = ca = NULL;
 
 	if ((in = BIO_new_mem_buf(buf, len)) == NULL) {
-		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB);
+		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB);
 		goto end;
 	}
 
 	if ((x = PEM_read_bio_X509(in, NULL,
-		    ctx->default_passwd_callback,
-		    ctx->default_passwd_callback_userdata)) == NULL) {
-		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
+		    SSL_CTX_get_default_passwd_cb(ctx),
+		    SSL_CTX_get_default_passwd_cb_userdata(ctx))) == NULL) {
+		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_PEM_LIB);
 		goto end;
 	}
 
@@ -99,14 +99,11 @@
 	 * the CA certificates.
 	 */
 
-	if (ctx->extra_certs != NULL) {
-		sk_X509_pop_free(ctx->extra_certs, X509_free);
-		ctx->extra_certs = NULL;
-	}
+	SSL_CTX_clear_extra_chain_certs(ctx);
 
 	while ((ca = PEM_read_bio_X509(in, NULL,
-		    ctx->default_passwd_callback,
-		    ctx->default_passwd_callback_userdata)) != NULL) {
+		    SSL_CTX_get_default_passwd_cb(ctx),
+		    SSL_CTX_get_default_passwd_cb_userdata(ctx))) != NULL) {
 
 		if (!SSL_CTX_add_extra_chain_cert(ctx, ca))
 			goto end;
--- a/smtpd/ca.c
+++ b/smtpd/ca.c
@@ -170,6 +170,190 @@
 	return ok;
 }
 
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
+
+static int RSA_meth_get_flags(RSA_METHOD *meth)
+{
+	return meth->flags;
+}
+
+static int RSA_meth_set_flags(RSA_METHOD *meth, int flags)
+{
+	meth->flags = flags;
+	return 1;
+}
+
+static void *RSA_meth_get0_app_data(const RSA_METHOD *meth)
+{
+	return meth->app_data;
+}
+
+static int RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data)
+{
+	meth->app_data = app_data;
+	return 1;
+}
+
+static int (*RSA_meth_get_pub_enc(const RSA_METHOD *meth))
+(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
+{
+	return meth->rsa_pub_enc;
+}
+
+static int RSA_meth_set_pub_enc(RSA_METHOD *meth,
+	int (*pub_enc) (int flen, const unsigned char *from,
+			unsigned char *to, RSA *rsa,
+			int padding))
+{
+	meth->rsa_pub_enc = pub_enc;
+	return 1;
+}
+
+static int (*RSA_meth_get_pub_dec(const RSA_METHOD *meth))
+(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
+{
+	return meth->rsa_pub_dec;
+}
+
+static int (*RSA_meth_get_priv_enc(const RSA_METHOD *meth))
+(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
+{
+	return meth->rsa_priv_enc;
+}
+
+int RSA_meth_set_priv_enc(RSA_METHOD *meth,
+  int (*priv_enc) (int flen, const unsigned char *from,
+  unsigned char *to, RSA *rsa, int padding))
+{
+	meth->rsa_priv_enc = priv_enc;
+	return 1;
+}
+
+static int (*RSA_meth_get_priv_dec(const RSA_METHOD *meth))
+(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
+{
+	return meth->rsa_priv_dec;
+}
+
+static int RSA_meth_set_priv_dec(RSA_METHOD *meth,
+  int (*priv_dec) (int flen, const unsigned char *from,
+  unsigned char *to, RSA *rsa, int padding))
+{
+	meth->rsa_priv_dec = priv_dec;
+	return 1;
+}
+
+static int (*RSA_meth_get_mod_exp(const RSA_METHOD *meth))
+  (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+{
+	return meth->rsa_mod_exp;
+}
+
+static int RSA_meth_set_mod_exp(RSA_METHOD *meth,
+  int (*mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx))
+{
+	meth->rsa_mod_exp = mod_exp;
+	return 1;
+}
+
+static int (*RSA_meth_get_bn_mod_exp(const RSA_METHOD *meth))
+(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+{
+	return meth->bn_mod_exp;
+}
+
+static int RSA_meth_set_bn_mod_exp(RSA_METHOD *meth, int (*bn_mod_exp)
+  (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
+   BN_CTX *ctx, BN_MONT_CTX *m_ctx))
+{
+	meth->bn_mod_exp = bn_mod_exp;
+	return 1;
+}
+
+static int (*RSA_meth_get_init(const RSA_METHOD *meth)) (RSA *rsa)
+{
+	return meth->init;
+}
+
+static int RSA_meth_set_init(RSA_METHOD *meth, int (*init) (RSA *rsa))
+{
+	meth->init = init;
+	return 1;
+}
+
+static int (*RSA_meth_get_finish(const RSA_METHOD *meth)) (RSA *rsa)
+{
+	return meth->finish;
+}
+
+static int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa))
+{
+	meth->finish = finish;
+	return 1;
+}
+
+static int (*RSA_meth_get_keygen(const RSA_METHOD *meth))
+  (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
+{
+	return meth->rsa_keygen;
+}
+
+static int RSA_meth_set_keygen(RSA_METHOD *meth, int (*keygen)
+  (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb))
+{
+	meth->rsa_keygen = keygen;
+	return 1;
+}
+
+static int (*RSA_meth_get_verify(const RSA_METHOD *meth))
+  (int dtype, const unsigned char *m,
+   unsigned int m_length, const unsigned char *sigbuf,
+   unsigned int siglen, const RSA *rsa)
+{
+	if (meth->flags & RSA_FLAG_SIGN_VER)
+		return meth->rsa_verify;
+	return NULL;
+}
+
+static int (*RSA_meth_get_sign(const RSA_METHOD *meth))
+  (int type,
+   const unsigned char *m, unsigned int m_length,
+   unsigned char *sigret, unsigned int *siglen,
+   const RSA *rsa)
+{
+	if (meth->flags & RSA_FLAG_SIGN_VER)
+		return meth->rsa_sign;
+	return NULL;
+}
+
+static int RSA_meth_set_pub_dec(RSA_METHOD *meth,
+ int (*pub_dec) (int flen, const unsigned char *from,
+   unsigned char *to, RSA *rsa, int padding))
+{
+	meth->rsa_pub_dec = pub_dec;
+	return 1;
+}
+
+static RSA_METHOD *RSA_meth_new(const char *name, int flags)
+{
+	RSA_METHOD *meth = malloc(sizeof(*meth));
+
+	if (meth != NULL) {
+		memset(meth, 0, sizeof(*meth));
+		meth->flags = flags;
+
+		meth->name = strdup(name);
+		if (meth->name != NULL)
+			return meth;
+
+		free(meth);
+	}
+
+	return NULL;
+}
+
+#endif
+
 int
 ca_X509_verify(void *certificate, void *chain, const char *CAfile,
     const char *CRLfile, const char **errstr)
@@ -201,7 +385,7 @@
 	*errstr = NULL;
 	if (ret != 1) {
 		if (xsc)
-			*errstr = X509_verify_cert_error_string(xsc->error);
+			*errstr = X509_verify_cert_error_string(X509_STORE_CTX_get_error(xsc));
 		else if (ERR_peek_last_error())
 			*errstr = ERR_error_string(ERR_peek_last_error(), NULL);
 	}
@@ -302,24 +486,9 @@
  * RSA privsep engine (called from unprivileged processes)
  */
 
-const RSA_METHOD *rsa_default = NULL;
+static const RSA_METHOD *rsa_default = NULL;
 
-static RSA_METHOD rsae_method = {
-	"RSA privsep engine",
-	rsae_pub_enc,
-	rsae_pub_dec,
-	rsae_priv_enc,
-	rsae_priv_dec,
-	rsae_mod_exp,
-	rsae_bn_mod_exp,
-	rsae_init,
-	rsae_finish,
-	0,
-	NULL,
-	NULL,
-	NULL,
-	rsae_keygen
-};
+static const char *rsae_method_name = "RSA privsep engine";
 
 static int
 rsae_send_imsg(int flen, const unsigned char *from, unsigned char *to,
@@ -404,7 +573,7 @@
     int padding)
 {
 	log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
-	return (rsa_default->rsa_pub_enc(flen, from, to, rsa, padding));
+	return (RSA_meth_get_pub_enc(rsa_default)(flen, from, to, rsa, padding));
 }
 
 static int
@@ -412,7 +581,7 @@
     int padding)
 {
 	log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
-	return (rsa_default->rsa_pub_dec(flen, from, to, rsa, padding));
+	return (RSA_meth_get_pub_dec(rsa_default)(flen, from, to, rsa, padding));
 }
 
 static int
@@ -424,7 +593,7 @@
 		return (rsae_send_imsg(flen, from, to, rsa, padding,
 		    IMSG_CA_PRIVENC));
 	}
-	return (rsa_default->rsa_priv_enc(flen, from, to, rsa, padding));
+	return (RSA_meth_get_priv_enc(rsa_default)(flen, from, to, rsa, padding));
 }
 
 static int
@@ -436,14 +605,14 @@
 		return (rsae_send_imsg(flen, from, to, rsa, padding,
 		    IMSG_CA_PRIVDEC));
 	}
-	return (rsa_default->rsa_priv_dec(flen, from, to, rsa, padding));
+	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_default->rsa_mod_exp(r0, I, rsa, ctx));
+	return (RSA_meth_get_mod_exp(rsa_default)(r0, I, rsa, ctx));
 }
 
 static int
@@ -451,34 +620,36 @@
     const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
 {
 	log_debug("debug: %s: %s", proc_name(smtpd_process), __func__);
-	return (rsa_default->bn_mod_exp(r, a, p, m, ctx, m_ctx));
+	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_default->init == NULL)
+	if (RSA_meth_get_init(rsa_default) == NULL)
 		return (1);
-	return (rsa_default->init(rsa));
+	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_default->finish == NULL)
+	if (RSA_meth_get_finish(rsa_default) == NULL)
 		return (1);
-	return (rsa_default->finish(rsa));
+	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_default->rsa_keygen(rsa, bits, e, cb));
+	return (RSA_meth_get_keygen(rsa_default)(rsa, bits, e, cb));
 }
 
+static RSA_METHOD *rsae_method;
+
 void
 ca_engine_init(void)
 {
@@ -490,7 +661,7 @@
 			errstr = "ENGINE_new";
 			goto fail;
 		}
-		if (!ENGINE_set_name(e, rsae_method.name)) {
+		if (!ENGINE_set_name(e, rsae_method_name)) {
 			errstr = "ENGINE_set_name";
 			goto fail;
 		}
@@ -503,25 +674,58 @@
 		goto fail;
 	}
 
+	rsae_method = RSA_meth_new(rsae_method_name, 0);
+	if (!rsae_method) {
+		errstr = "RSA_meth_new";
+		goto fail;
+	}
+
 	if ((name = ENGINE_get_name(e)) == NULL)
 		name = "unknown RSA engine";
 
 	log_debug("debug: %s: using %s", __func__, name);
 
-	if (rsa_default->flags & RSA_FLAG_SIGN_VER)
+	if (RSA_meth_get_sign(rsa_default) ||
+	    RSA_meth_get_verify(rsa_default))
 		fatalx("unsupported RSA engine");
 
-	if (rsa_default->rsa_mod_exp == NULL)
-		rsae_method.rsa_mod_exp = NULL;
-	if (rsa_default->bn_mod_exp == NULL)
-		rsae_method.bn_mod_exp = NULL;
-	if (rsa_default->rsa_keygen == NULL)
-		rsae_method.rsa_keygen = NULL;
-	rsae_method.flags = rsa_default->flags |
-	    RSA_METHOD_FLAG_NO_CHECK;
-	rsae_method.app_data = rsa_default->app_data;
+	errstr = "Setting callback";
+	if (!RSA_meth_set_pub_enc(rsae_method, rsae_pub_enc))
+		goto fail;
+        if (!RSA_meth_set_pub_dec(rsae_method, rsae_pub_dec))
+		goto fail;
+        if (!RSA_meth_set_priv_enc(rsae_method, rsae_priv_enc))
+		goto fail;
+        if (!RSA_meth_set_priv_dec(rsae_method, rsae_priv_dec))
+		goto fail;
+
+	if (RSA_meth_get_mod_exp(rsa_default)) {
+		if (!RSA_meth_set_mod_exp(rsae_method, rsae_mod_exp))
+			goto fail;
+	}
+
+	if (RSA_meth_get_bn_mod_exp(rsa_default))
+		if (!RSA_meth_set_bn_mod_exp(rsae_method, rsae_bn_mod_exp))
+			goto fail;
+        if (!RSA_meth_set_init(rsae_method, rsae_init))
+		goto fail;
+        if (!RSA_meth_set_finish(rsae_method, rsae_finish))
+		goto fail;
+
+	if (RSA_meth_get_keygen(rsa_default)) {
+		if (!RSA_meth_set_keygen(rsae_method, rsae_keygen))
+			goto fail;
+	}
+
+	if (!RSA_meth_set_flags(rsae_method,
+			   RSA_meth_get_flags(rsa_default) |
+			   RSA_METHOD_FLAG_NO_CHECK))
+		goto fail;
+
+	if (!RSA_meth_set0_app_data(rsae_method, RSA_meth_get0_app_data(rsa_default)))
+		goto fail;
 
-	if (!ENGINE_set_RSA(e, &rsae_method)) {
+	if (!ENGINE_set_RSA(e, rsae_method)) {
 		errstr = "ENGINE_set_RSA";
 		goto fail;
 	}
--- a/smtpd/crypto.c
+++ b/smtpd/crypto.c
@@ -64,7 +64,7 @@
 int
 crypto_encrypt_file(FILE * in, FILE * out)
 {
-	EVP_CIPHER_CTX	ctx;
+	EVP_CIPHER_CTX	*ctx;
 	uint8_t		ibuf[CRYPTO_BUFFER_SIZE];
 	uint8_t		obuf[CRYPTO_BUFFER_SIZE];
 	uint8_t		iv[IV_SIZE];
@@ -91,12 +91,14 @@
 	if ((w = fwrite(iv, 1, sizeof iv, out)) != sizeof iv)
 		return 0;
 
-	EVP_CIPHER_CTX_init(&ctx);
-	EVP_EncryptInit_ex(&ctx, EVP_aes_256_gcm(), NULL, cp.key, iv);
+        ctx = EVP_CIPHER_CTX_new();
+        if (!ctx)
+                return 0;
+	EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, cp.key, iv);
 
 	/* encrypt until end of file */
 	while ((r = fread(ibuf, 1, CRYPTO_BUFFER_SIZE, in)) != 0) {
-		if (!EVP_EncryptUpdate(&ctx, obuf, &len, ibuf, r))
+		if (!EVP_EncryptUpdate(ctx, obuf, &len, ibuf, r))
 			goto end;
 		if (len && (w = fwrite(obuf, len, 1, out)) != 1)
 			goto end;
@@ -105,13 +107,13 @@
 		goto end;
 
 	/* finalize and write last chunk if any */
-	if (!EVP_EncryptFinal_ex(&ctx, obuf, &len))
+	if (!EVP_EncryptFinal_ex(ctx, obuf, &len))
 		goto end;
 	if (len && (w = fwrite(obuf, len, 1, out)) != 1)
 		goto end;
 
 	/* get and append tag */
-	EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, sizeof tag, tag);
+	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, sizeof tag, tag);
 	if ((w = fwrite(tag, sizeof tag, 1, out)) != 1)
 		goto end;
 
@@ -119,14 +121,14 @@
 	ret = 1;
 
 end:
-	EVP_CIPHER_CTX_cleanup(&ctx);
+	EVP_CIPHER_CTX_free(ctx);
 	return ret;
 }
 
 int
 crypto_decrypt_file(FILE * in, FILE * out)
 {
-	EVP_CIPHER_CTX	ctx;
+	EVP_CIPHER_CTX	*ctx;
 	uint8_t		ibuf[CRYPTO_BUFFER_SIZE];
 	uint8_t		obuf[CRYPTO_BUFFER_SIZE];
 	uint8_t		iv[IV_SIZE];
@@ -171,11 +173,13 @@
 	sz -= sizeof tag;
 
 
-	EVP_CIPHER_CTX_init(&ctx);
-	EVP_DecryptInit_ex(&ctx, EVP_aes_256_gcm(), NULL, cp.key, iv);
+        ctx = EVP_CIPHER_CTX_new();
+        if (!ctx)
+                return 0;
+	EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, cp.key, iv);
 
 	/* set expected tag */
-	EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, sizeof tag, tag);
+	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, sizeof tag, tag);
 
 	/* decrypt until end of ciphertext */
 	while (sz) {
@@ -185,7 +189,7 @@
 			r = fread(ibuf, 1, sz, in);
 		if (!r)
 			break;
-		if (!EVP_DecryptUpdate(&ctx, obuf, &len, ibuf, r))
+		if (!EVP_DecryptUpdate(ctx, obuf, &len, ibuf, r))
 			goto end;
 		if (len && (w = fwrite(obuf, len, 1, out)) != 1)
 			goto end;
@@ -195,7 +199,7 @@
 		goto end;
 
 	/* finalize, write last chunk if any and perform authentication check */
-	if (!EVP_DecryptFinal_ex(&ctx, obuf, &len))
+	if (!EVP_DecryptFinal_ex(ctx, obuf, &len))
 		goto end;
 	if (len && (w = fwrite(obuf, len, 1, out)) != 1)
 		goto end;
@@ -204,14 +208,14 @@
 	ret = 1;
 
 end:
-	EVP_CIPHER_CTX_cleanup(&ctx);
+	EVP_CIPHER_CTX_free(ctx);
 	return ret;
 }
 
 size_t
 crypto_encrypt_buffer(const char *in, size_t inlen, char *out, size_t outlen)
 {
-	EVP_CIPHER_CTX	ctx;
+	EVP_CIPHER_CTX	*ctx;
 	uint8_t		iv[IV_SIZE];
 	uint8_t		tag[GCM_TAG_SIZE];
 	uint8_t		version = API_VERSION;
@@ -239,33 +243,35 @@
 	memcpy(out + len, iv, sizeof iv);
 	len += sizeof iv;
 
-	EVP_CIPHER_CTX_init(&ctx);
-	EVP_EncryptInit_ex(&ctx, EVP_aes_256_gcm(), NULL, cp.key, iv);
+        ctx = EVP_CIPHER_CTX_new();
+        if (!ctx)
+                return 0;
+	EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, cp.key, iv);
 
 	/* encrypt buffer */
-	if (!EVP_EncryptUpdate(&ctx, out + len, &olen, in, inlen))
+	if (!EVP_EncryptUpdate(ctx, out + len, &olen, in, inlen))
 		goto end;
 	len += olen;
 
 	/* finalize and write last chunk if any */
-	if (!EVP_EncryptFinal_ex(&ctx, out + len, &olen))
+	if (!EVP_EncryptFinal_ex(ctx, out + len, &olen))
 		goto end;
 	len += olen;
 
 	/* get and append tag */
-	EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, sizeof tag, tag);
+	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, sizeof tag, tag);
 	memcpy(out + len, tag, sizeof tag);
 	ret = len + sizeof tag;
 
 end:
-	EVP_CIPHER_CTX_cleanup(&ctx);
+	EVP_CIPHER_CTX_cleanup(ctx);
 	return ret;
 }
 
 size_t
 crypto_decrypt_buffer(const char *in, size_t inlen, char *out, size_t outlen)
 {
-	EVP_CIPHER_CTX	ctx;
+	EVP_CIPHER_CTX	*ctx;
 	uint8_t		iv[IV_SIZE];
 	uint8_t		tag[GCM_TAG_SIZE];
 	int		olen;
@@ -292,24 +298,26 @@
 	inlen -= sizeof iv;
 	in += sizeof iv;
 
-	EVP_CIPHER_CTX_init(&ctx);
-	EVP_DecryptInit_ex(&ctx, EVP_aes_256_gcm(), NULL, cp.key, iv);
+        ctx = EVP_CIPHER_CTX_new();
+        if (!ctx)
+                return 0;
+	EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, cp.key, iv);
 
 	/* set expected tag */
-	EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, sizeof tag, tag);
+	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, sizeof tag, tag);
 
 	/* decrypt buffer */
-	if (!EVP_DecryptUpdate(&ctx, out, &olen, in, inlen))
+	if (!EVP_DecryptUpdate(ctx, out, &olen, in, inlen))
 		goto end;
 	len += olen;
 
 	/* finalize, write last chunk if any and perform authentication check */
-	if (!EVP_DecryptFinal_ex(&ctx, out + len, &olen))
+	if (!EVP_DecryptFinal_ex(ctx, out + len, &olen))
 		goto end;
 	ret = len + olen;
 
 end:
-	EVP_CIPHER_CTX_cleanup(&ctx);
+	EVP_CIPHER_CTX_cleanup(ctx);
 	return ret;
 }
 
--- a/smtpd/libressl.c
+++ b/smtpd/libressl.c
@@ -94,10 +94,10 @@
 
 	ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */
 
-	x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback,
-	    ctx->default_passwd_callback_userdata);
+	x = PEM_read_bio_X509_AUX(in, NULL, SSL_CTX_get_default_passwd_cb(ctx),
+	    SSL_CTX_get_default_passwd_cb_userdata(ctx));
 	if (x == NULL) {
-		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
+		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_PEM_LIB);
 		goto end;
 	}
 
@@ -115,14 +115,11 @@
 		int r;
 		unsigned long err;
 
-		if (ctx->extra_certs != NULL) {
-			sk_X509_pop_free(ctx->extra_certs, X509_free);
-			ctx->extra_certs = NULL;
-		}
+		SSL_CTX_clear_extra_chain_certs(ctx);
 
 		while ((ca = PEM_read_bio_X509(in, NULL,
-		    ctx->default_passwd_callback,
-		    ctx->default_passwd_callback_userdata)) != NULL) {
+		    SSL_CTX_get_default_passwd_cb(ctx),
+		    SSL_CTX_get_default_passwd_cb_userdata(ctx))) != NULL) {
 			r = SSL_CTX_add_extra_chain_cert(ctx, ca);
 			if (!r) {
 				X509_free(ca);
@@ -160,7 +157,7 @@
 
 	in = BIO_new_mem_buf(buf, len);
 	if (in == NULL) {
-		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB);
+		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB);
 		goto end;
 	}
 
--- a/smtpd/ssl.c
+++ b/smtpd/ssl.c
@@ -425,7 +425,7 @@
 	 */
 	ret = SSL_CTX_use_PrivateKey(ctx, pkey);
 	if (!ret)
-		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_SSL_LIB);
+		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_SYS_LIB);
 
 	if (pkeyptr != NULL)
 		*pkeyptr = pkey;
--- a/smtpd/ssl.h
+++ b/smtpd/ssl.h
@@ -66,3 +66,17 @@
 /* ssl_privsep.c */
 int		ssl_by_mem_ctrl(X509_LOOKUP *, int, const char *, long, char **);
 int SSL_CTX_use_certificate_chain_mem(SSL_CTX *, void *, int);
+
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
+
+static inline pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx)
+{
+	return ctx->default_passwd_callback;
+}
+
+static inline void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx)
+{
+	return ctx->default_passwd_callback_userdata;
+}
+
+#endif
--- a/configure.ac
+++ b/configure.ac
@@ -1133,6 +1133,10 @@
 
 ##gilles
 
+AC_CHECK_DECLS([SSL_OP_NO_CLIENT_RENEGOTIATION], [], [], [
+#include <openssl/ssl.h>
+])
+
 SMTPD_USER=_smtpd
 AC_ARG_WITH([user-smtpd],
 	[  --with-user-smtpd=user	Specify non-privileged user for smtpd (default=_smtpd)],
@@ -1922,6 +1926,43 @@
 )
 #l2371
 
+##gilles
+OPENSSL_SUPPORTS_ECDH_AUTO=no
+AC_MSG_CHECKING([if programs using SSL_CTX_set_ecdh_auto will link])
+AC_LINK_IFELSE(
+	[AC_LANG_PROGRAM([[ #include <openssl/ssl.h> ]],
+	[[ SSL_CTX_set_ecdh_auto(NULL, 1); ]])],
+	[
+		AC_MSG_RESULT([yes])
+		AC_DEFINE([HAVE_SSL_CTX_SET_ECDH_AUTO], [1],
+			[Define if SSL library support SSL_CTX_set_ecdh_auto])
+		OPENSSL_SUPPORTS_ECDH_AUTO=yes
+	],
+	[
+		AC_MSG_RESULT([no])
+	]
+)
+AM_CONDITIONAL([HAVE_SSL_CTX_SET_ECDH_AUTO], [test $OPENSSL_SUPPORTS_ECDH_AUTO = yes])
+##gilles
+
+##gilles
+OPENSSL_SUPPORTS_DH_AUTO=no
+AC_MSG_CHECKING([if programs using SSL_CTX_set_dh_auto will link])
+AC_LINK_IFELSE(
+	[AC_LANG_PROGRAM([[ #include <openssl/ssl.h> ]],
+	[[ SSL_CTX_set_dh_auto(NULL, 1); ]])],
+	[
+		AC_MSG_RESULT([yes])
+		AC_DEFINE([HAVE_SSL_CTX_SET_DH_AUTO], [1],
+			[Define if SSL library support SSL_CTX_set_dh_auto])
+		OPENSSL_SUPPORTS_DH_AUTO=yes
+	],
+	[
+		AC_MSG_RESULT([no])
+	]
+)
+AM_CONDITIONAL([HAVE_SSL_CTX_SET_DH_AUTO], [test $OPENSSL_SUPPORTS_DH_AUTO = yes])
+##gilles
 
 dnl zlib is required
 AC_ARG_WITH([libz],
--- a/mk/smtpd/Makefile.am
+++ b/mk/smtpd/Makefile.am
@@ -28,7 +28,7 @@
 smtpd_SOURCES+=		$(smtpd_srcdir)/forward.c
 smtpd_SOURCES+=		$(smtpd_srcdir)/iobuf.c
 smtpd_SOURCES+=		$(smtpd_srcdir)/ioev.c
-#smtpd_SOURCES+=		$(smtpd_srcdir)/libressl.c
+smtpd_SOURCES+=		$(smtpd_srcdir)/libressl.c
 smtpd_SOURCES+=		$(smtpd_srcdir)/limit.c
 smtpd_SOURCES+=		$(smtpd_srcdir)/lka.c
 smtpd_SOURCES+=		$(smtpd_srcdir)/lka_session.c
--- a/openbsd-compat/Makefile.am
+++ b/openbsd-compat/Makefile.am
@@ -1,7 +1,7 @@
 noinst_LIBRARIES = libopenbsd-compat.a
 
-#libopenbsd_compat_a_SOURCES =	arc4random.c
-libopenbsd_compat_a_SOURCES =	base64.c
+libopenbsd_compat_a_SOURCES =	arc4random.c
+libopenbsd_compat_a_SOURCES +=	base64.c
 libopenbsd_compat_a_SOURCES +=	bsd-getpeereid.c
 libopenbsd_compat_a_SOURCES +=	bsd-misc.c
 libopenbsd_compat_a_SOURCES +=	bsd-waitpid.c
@@ -12,7 +12,7 @@
 libopenbsd_compat_a_SOURCES +=	getopt.c
 libopenbsd_compat_a_SOURCES +=	imsg.c
 libopenbsd_compat_a_SOURCES +=	imsg-buffer.c
-#libopenbsd_compat_a_SOURCES +=	libressl.c
+libopenbsd_compat_a_SOURCES +=	libressl.c
 libopenbsd_compat_a_SOURCES +=	pidfile.c
 libopenbsd_compat_a_SOURCES +=	pw_dup.c
 libopenbsd_compat_a_SOURCES +=	reallocarray.c
--- a/openbsd-compat/defines.h
+++ b/openbsd-compat/defines.h
@@ -503,4 +503,8 @@
 #define LOG_PERROR 0
 #endif
 
+#if !HAVE_DECL_SSL_OP_NO_CLIENT_RENEGOTIATION
+#define SSL_OP_NO_CLIENT_RENEGOTIATION 0
+#endif
+
 #endif /* _DEFINES_H */
Description: Revert "GCM is available in all LibreSSL versions" (d74dbd3)
  GCM is not available on OpenSSL versions < 1.0.2. Restores old OpenSSL
  compatibility. (This patch is safe to remove on OpenSSL 1.1.1a.)
Origin: other, https://github.com/OpenSMTPD/OpenSMTPD/commit/d74dbd3
Author: Linda Lapinlampi <li...@lindalap.fi>
Last-Update: 2019-01-06
--- a/configure.ac
+++ b/configure.ac
@@ -1131,6 +1131,25 @@
 #l2816
 
 
+##chl
+EXPERIMENTAL_GCM_CRYPTO=no
+AC_MSG_CHECKING([if programs using LibreSSL EVP_aes_256_gcm() will link])
+AC_LINK_IFELSE(
+	[AC_LANG_PROGRAM([[ #include <openssl/evp.h> ]],
+	[[ EVP_aes_256_gcm(); ]])],
+	[
+		AC_MSG_RESULT([yes])
+		AC_DEFINE([HAVE_GCM_CRYPTO], [1],
+			[Define if you want to use GCM crypto support])
+		EXPERIMENTAL_GCM_CRYPTO=yes
+	],
+	[
+		AC_MSG_RESULT([no])
+	]
+)
+AM_CONDITIONAL([HAVE_GCM_CRYPTO], [test $EXPERIMENTAL_GCM_CRYPTO = yes])
+##chl
+
 ##gilles
 
 AC_CHECK_DECLS([SSL_OP_NO_CLIENT_RENEGOTIATION], [], [], [
--- a/mk/smtpctl/Makefile.am
+++ b/mk/smtpctl/Makefile.am
@@ -32,7 +32,9 @@
 smtpctl_SOURCES+=	$(smtpd_srcdir)/makemap.c
 endif
 
+if HAVE_GCM_CRYPTO
 smtpctl_SOURCES+=	$(smtpd_srcdir)/crypto.c
+endif
 
 smtpctl_CFLAGS=		-DNO_IO -DCONFIG_MINIMUM
 smtpctl_CFLAGS+=	-DPATH_GZCAT=\"$(ZCAT)\" \
--- a/mk/smtpd/Makefile.am
+++ b/mk/smtpd/Makefile.am
@@ -65,7 +65,9 @@
 smtpd_SOURCES+=		$(smtpd_srcdir)/waitq.c
 
 # backends
+if HAVE_GCM_CRYPTO
 smtpd_SOURCES+=		$(smtpd_srcdir)/crypto.c
+endif
 smtpd_SOURCES+=		$(smtpd_srcdir)/compress_gzip.c
 if HAVE_DB_API
 smtpd_SOURCES+=		$(smtpd_srcdir)/table_db.c
--- a/smtpd/queue.c
+++ b/smtpd/queue.c
@@ -647,11 +647,13 @@
 	if (env->sc_queue_flags & QUEUE_COMPRESSION)
 		log_info("queue: queue compression enabled");
 
+#ifdef HAVE_GCM_CRYPTO
 	if (env->sc_queue_key) {
 		if (!crypto_setup(env->sc_queue_key, strlen(env->sc_queue_key)))
 			fatalx("crypto_setup: invalid key for queue encryption");
 		log_info("queue: queue encryption enabled");
 	}
+#endif
 
 	if (setgroups(1, &pw->pw_gid) ||
 	    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
--- a/smtpd/queue_backend.c
+++ b/smtpd/queue_backend.c
@@ -254,6 +254,7 @@
 		}
 	}
 
+#ifdef HAVE_GCM_CRYPTO
 	if (env->sc_queue_flags & QUEUE_ENCRYPTION) {
 		bsnprintf(tmppath, sizeof tmppath, "%s.enc", msgpath);
 		ifp = fopen(msgpath, "r");
@@ -275,6 +276,7 @@
 			return (0);
 		}
 	}
+#endif
 
 	r = handler_message_commit(msgid, msgpath);
 	profile_leave();
@@ -313,6 +315,7 @@
 	if (fdin == -1)
 		return (-1);
 
+#ifdef HAVE_GCM_CRYPTO
 	if (env->sc_queue_flags & QUEUE_ENCRYPTION) {
 		if ((fdout = mktmpfile()) == -1)
 			goto err;
@@ -334,6 +337,7 @@
 		ofp = NULL;
 		lseek(fdin, SEEK_SET, 0);
 	}
+#endif
 
 	if (env->sc_queue_flags & QUEUE_COMPRESSION) {
 		if ((fdout = mktmpfile()) == -1)
@@ -390,8 +394,10 @@
 	size_t	evplen;
 	size_t	complen;
 	char	compbuf[sizeof(struct envelope)];
+#ifdef HAVE_GCM_CRYPTO
 	size_t	enclen;
 	char	encbuf[sizeof(struct envelope)];
+#endif
 
 	evp = evpbuf;
 	evplen = envelope_dump_buffer(ep, evpbuf, evpbufsize);
@@ -406,6 +412,7 @@
 		evplen = complen;
 	}
 
+#ifdef HAVE_GCM_CRYPTO
 	if (env->sc_queue_flags & QUEUE_ENCRYPTION) {
 		enclen = crypto_encrypt_buffer(evp, evplen, encbuf, sizeof encbuf);
 		if (enclen == 0)
@@ -413,6 +420,7 @@
 		evp = encbuf;
 		evplen = enclen;
 	}
+#endif
 
 	memmove(evpbuf, evp, evplen);
 
@@ -426,12 +434,15 @@
 	size_t		 evplen;
 	char		 compbuf[sizeof(struct envelope)];
 	size_t		 complen;
+#ifdef HAVE_GCM_CRYPTO
 	char		 encbuf[sizeof(struct envelope)];
 	size_t		 enclen;
+#endif
 
 	evp = evpbuf;
 	evplen = evpbufsize;
 
+#ifdef HAVE_GCM_CRYPTO
 	if (env->sc_queue_flags & QUEUE_ENCRYPTION) {
 		enclen = crypto_decrypt_buffer(evp, evplen, encbuf, sizeof encbuf);
 		if (enclen == 0)
@@ -439,6 +450,7 @@
 		evp = encbuf;
 		evplen = enclen;
 	}
+#endif
 
 	if (env->sc_queue_flags & QUEUE_COMPRESSION) {
 		complen = uncompress_chunk(evp, evplen, compbuf, sizeof compbuf);
--- a/smtpd/smtpctl.c
+++ b/smtpd/smtpctl.c
@@ -1302,7 +1302,9 @@
 display(const char *s)
 {
 	FILE   *fp;
+#ifdef HAVE_GCM_CRYPTO
 	char   *key;
+#endif
 	int	gzipped;
 	char   *gzcat_argv0 = strrchr(PATH_GZCAT, '/') + 1;
 
@@ -1310,6 +1312,7 @@
 		err(1, "fopen");
 
 	if (is_encrypted_fp(fp)) {
+#ifdef HAVE_GCM_CRYPTO
 		int	i;
 		int	fd;
 		FILE   *ofp = NULL;
@@ -1342,6 +1345,10 @@
 		fclose(fp);
 		fp = ofp;
 		fseek(fp, 0, SEEK_SET);
+#else
+	       	printf("GCM crypto not supported!\n");
+       		exit(1);
+#endif
 	}
 	gzipped = is_gzip_fp(fp);
 
--- a/smtpd/smtpd.c
+++ b/smtpd/smtpd.c
@@ -650,12 +650,14 @@
 		errx(1, "config file exceeds PATH_MAX");
 
 	if (env->sc_opts & SMTPD_OPT_NOACTION) {
+#ifdef HAVE_GCM_CRYPTO
 		if (env->sc_queue_key &&
 		    crypto_setup(env->sc_queue_key,
 		    strlen(env->sc_queue_key)) == 0) {
 			fatalx("crypto_setup:"
 			    "invalid key for queue encryption");
 		}
+#endif
 		load_pki_tree();
 		load_pki_keys();
 		fprintf(stderr, "configuration OK\n");
Description: Revert "SNI is available in all LibreSSL versions" (b6cfe5b)
  SNI is not available on OpenSSL versions < 1.1.1. Restores old OpenSSL
  compatibility. (This patch is safe to remove on OpenSSL 1.1.1a.)
Origin: other, https://github.com/OpenSMTPD/OpenSMTPD/commit/b6cfe5b
Author: Linda Lapinlampi <li...@lindalap.fi>
Last-Update: 2019-01-06
--- a/configure.ac
+++ b/configure.ac
@@ -1151,6 +1151,25 @@
 ##chl
 
 ##gilles
+OPENSSL_SUPPORTS_SNI=no
+AC_MSG_CHECKING([if programs using TLSEXT_NAMETYPE_host_name will link])
+AC_LINK_IFELSE(
+	[AC_LANG_PROGRAM([[ #include <openssl/ssl.h> ]],
+	[[ SSL_CTX_set_tlsext_servername_callback(NULL, NULL); ]])],
+	[
+		AC_MSG_RESULT([yes])
+		AC_DEFINE([HAVE_TLSEXT_SERVERNAME], [1],
+			[Define if you want to enable TLS extension SERVERNAME])
+		OPENSSL_SUPPORTS_SNI=yes
+	],
+	[
+		AC_MSG_RESULT([no])
+	]
+)
+AM_CONDITIONAL([HAVE_TLSEXT_SERVERNAME], [test $OPENSSL_SUPPORTS_SNI = yes])
+##gilles
+
+##gilles
 
 AC_CHECK_DECLS([SSL_OP_NO_CLIENT_RENEGOTIATION], [], [], [
 #include <openssl/ssl.h>
--- a/smtpd/smtp.c
+++ b/smtpd/smtp.c
@@ -324,6 +324,7 @@
 static int
 smtp_sni_callback(SSL *ssl, int *ad, void *arg)
 {
+#if defined(HAVE_TLSEXT_SERVERNAME)
 	const char		*sn;
 	void			*ssl_ctx;
 
@@ -335,6 +336,10 @@
 		return SSL_TLSEXT_ERR_NOACK;
 	SSL_set_SSL_CTX(ssl, ssl_ctx);
 	return SSL_TLSEXT_ERR_OK;
+#else
+	/* ssl_smtp_init should have ignored the callback if SNI is not supported */
+	fatalx("unxepected call to smtp_sni_callback()");
+#endif /* defined(HAVE_TLSEXT_SERVERNAME) */
 }
 
 static void
07_automake_missing_options.diff
10_smtpd.conf.diff
11_ssl_1.1.diff
12_revert_gcm_removal_d74dbd3.diff
13_revert_sni_removal_b6cfe5b.diff

Reply via email to