diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2018-10-29 12:53:15 +0000 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2018-11-07 16:46:09 +0000 |
commit | 6656d5c5e61c9fc1d80216cb65d54bf23dbab73b (patch) | |
tree | 13cbc9b2c25efe911e8dd49bcd3920d241734c5d | |
parent | f82b04f0cec7fe6af7841f73765a1d882ec41098 (diff) | |
download | aports-6656d5c5e61c9fc1d80216cb65d54bf23dbab73b.tar.bz2 aports-6656d5c5e61c9fc1d80216cb65d54bf23dbab73b.tar.xz |
main/opensmtpd: rebuild against openssl-1.1
-rw-r--r-- | main/opensmtpd/APKBUILD | 8 | ||||
-rw-r--r-- | main/opensmtpd/openssl-1.1.patch | 737 |
2 files changed, 742 insertions, 3 deletions
diff --git a/main/opensmtpd/APKBUILD b/main/opensmtpd/APKBUILD index 781b02e946..b3e6e0a709 100644 --- a/main/opensmtpd/APKBUILD +++ b/main/opensmtpd/APKBUILD @@ -4,14 +4,14 @@ # Maintainer: Jonathan Curran <jonathan@curran.in> pkgname=opensmtpd pkgver=6.0.3p1 -pkgrel=1 +pkgrel=2 pkgdesc="secure, reliable, lean, and easy-to configure SMTP server" url="http://www.opensmtpd.org" arch="all" license="ISC" depends="!postfix" makedepends="automake autoconf libtool mdocml db-dev libasr-dev libevent-dev - fts-dev zlib-dev libressl-dev bison flex-dev" + fts-dev zlib-dev openssl-dev bison flex-dev" install="$pkgname.pre-install" subpackages="$pkgname-doc" source="https://www.opensmtpd.org/archives/$pkgname-$pkgver.tar.gz @@ -19,6 +19,7 @@ source="https://www.opensmtpd.org/archives/$pkgname-$pkgver.tar.gz aliases autoconf-decl-checks.patch fix-segfault-in-crypt_checkpass.patch + openssl-1.1.patch " options="suid !check" @@ -62,4 +63,5 @@ sha512sums="e579818a0ddbe637deb5a4e40f43eaf797783903ceac18fd89a57581b135b9e407d4 8d3b27c760df84804baadc90c23b34f3e99980fae97c685f98ab096c3e84ab293316cd7c49317fa3cffac7ab5e63217ada6a2c5b245f352bafe880b087e7705e smtpd.initd 51d47b34eb3d728daa45f29d6434cc75db28dfa69b6fb3ecd873121df85b296a2d2c81016d765a07778aa26a496e4b29c09a30b82678cf42596a536734b5deca aliases 37104cc605569f142ceffa902f200e8a7e9e1114ebe5394ed1eac0ed6ce25454e1610270921c45246de8396eee04b7c8ab5a112a231036a6ef14e7e229b264e3 autoconf-decl-checks.patch -cd6b60e478703890af1112d93c2d2ac0c87c5ad394d91a7903ca11532c4d2c8763330a8c20ef9b8d5a79632760faee5ee1437a43d37d1727aef2e1431d1d030c fix-segfault-in-crypt_checkpass.patch" +cd6b60e478703890af1112d93c2d2ac0c87c5ad394d91a7903ca11532c4d2c8763330a8c20ef9b8d5a79632760faee5ee1437a43d37d1727aef2e1431d1d030c fix-segfault-in-crypt_checkpass.patch +fb5a07cac0b07806d9fa2b5ac87e004da9f0d894cd00526b703fdfd23c94499d2464ae383ba65891232e9a4f2a582af1d6285c5ceb2cca61bbfbec6344cdc46b openssl-1.1.patch" diff --git a/main/opensmtpd/openssl-1.1.patch b/main/opensmtpd/openssl-1.1.patch new file mode 100644 index 0000000000..2eafa7f34b --- /dev/null +++ b/main/opensmtpd/openssl-1.1.patch @@ -0,0 +1,737 @@ +From 32d77702a7c76e462b4f2b6bc88f9101c9839d54 Mon Sep 17 00:00:00 2001 +From: Ryan Kavanagh <rak@debian.org> +Date: Fri, 19 Jan 2018 15:35:49 -0500 +Subject: [PATCH] Update to use SSL_F_SSL_CTX_USE_CERTIFICATE_FILE and + SSL_CTX_clear_extra_chain_certs + +Patch updated by Sebastian Andrzej Siewior <sebastian@breakpoint.cc>, +with description: + + SSL_F_SSL_CTX_USE_CERTIFICATE_FILE and + SSL_CTX_clear_extra_chain_certs was around in openssl since before + they forked it. So with this patch it should work with their + libressl, libssl 1.0.2 and 1.1. + +Source: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=859544#72 +Source: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=859544#96 +--- + openbsd-compat/libressl.c | 17 +-- + smtpd/ca.c | 290 ++++++++++++++++++++++++++++++++------ + smtpd/crypto.c | 64 +++++---- + smtpd/libressl.c | 17 +-- + smtpd/ssl.c | 2 +- + smtpd/ssl.h | 14 ++ + 6 files changed, 312 insertions(+), 92 deletions(-) + +diff --git a/openbsd-compat/libressl.c b/openbsd-compat/libressl.c +index f4f2b52e..d06e006f 100644 +--- a/openbsd-compat/libressl.c ++++ b/openbsd-compat/libressl.c +@@ -81,14 +81,14 @@ SSL_CTX_use_certificate_chain(SSL_CTX *ctx, char *buf, off_t len) + 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 @@ SSL_CTX_use_certificate_chain(SSL_CTX *ctx, char *buf, off_t len) + * 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; +diff --git a/smtpd/ca.c b/smtpd/ca.c +index e383c6a1..29a44b9b 100644 +--- a/smtpd/ca.c ++++ b/smtpd/ca.c +@@ -170,6 +170,190 @@ ca_verify_cb(int ok, X509_STORE_CTX *ctx) + 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 @@ ca_X509_verify(void *certificate, void *chain, const char *CAfile, + *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 @@ ca_imsg(struct mproc *p, struct imsg *imsg) + * RSA privsep engine (called from unprivileged processes) + */ + +-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 RSA_METHOD *rsa_default = NULL; ++ ++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 @@ 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_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 @@ 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_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 @@ rsae_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, + 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 @@ rsae_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, + 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 @@ 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_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 @@ ca_engine_init(void) + 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 @@ ca_engine_init(void) + 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; +- +- if (!ENGINE_set_RSA(e, &rsae_method)) { ++ 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)) { + errstr = "ENGINE_set_RSA"; + goto fail; + } +diff --git a/smtpd/crypto.c b/smtpd/crypto.c +index 76f98807..01452851 100644 +--- a/smtpd/crypto.c ++++ b/smtpd/crypto.c +@@ -64,7 +64,7 @@ crypto_setup(const char *key, size_t len) + 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 @@ crypto_encrypt_file(FILE * in, FILE * out) + 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 @@ crypto_encrypt_file(FILE * in, FILE * out) + 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 @@ crypto_encrypt_file(FILE * in, FILE * out) + 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 @@ crypto_decrypt_file(FILE * in, FILE * out) + 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 @@ crypto_decrypt_file(FILE * in, FILE * out) + 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 @@ crypto_decrypt_file(FILE * in, FILE * out) + 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 @@ crypto_decrypt_file(FILE * in, FILE * out) + 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 @@ crypto_encrypt_buffer(const char *in, size_t inlen, char *out, size_t outlen) + 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 @@ crypto_decrypt_buffer(const char *in, size_t inlen, char *out, size_t outlen) + 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; + } + +diff --git a/smtpd/libressl.c b/smtpd/libressl.c +index 57d74389..db78d943 100644 +--- a/smtpd/libressl.c ++++ b/smtpd/libressl.c +@@ -94,10 +94,10 @@ ssl_ctx_use_certificate_chain_bio(SSL_CTX *ctx, BIO *in) + + 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 @@ ssl_ctx_use_certificate_chain_bio(SSL_CTX *ctx, BIO *in) + 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 @@ SSL_CTX_use_certificate_chain_mem(SSL_CTX *ctx, void *buf, int len) + + 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; + } + +diff --git a/smtpd/ssl.c b/smtpd/ssl.c +index b88360eb..0c93d87e 100644 +--- a/smtpd/ssl.c ++++ b/smtpd/ssl.c +@@ -425,7 +425,7 @@ ssl_ctx_fake_private_key(SSL_CTX *ctx, const void *data, size_t datalen, + */ + 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; +diff --git a/smtpd/ssl.h b/smtpd/ssl.h +index 90f018d0..553120d4 100644 +--- a/smtpd/ssl.h ++++ b/smtpd/ssl.h +@@ -73,3 +73,17 @@ void SSL_CTX_set_ecdh_auto(SSL_CTX *, int); + void SSL_CTX_set_dh_auto(SSL_CTX *, int); + #endif + 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 |