sendmail: Add OpenSSL 1.1 support

First patch is from Debian and enables OpenSSL 1.1 support.

Second patch is a fix for OpenSSL 1.1 ECC curves.

Third patch allows compilation without deprecated APIs.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
This commit is contained in:
Rosen Penev 2018-12-02 17:14:38 -08:00
parent d26f7e5a47
commit 035f7deb2d
4 changed files with 352 additions and 1 deletions

View File

@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=sendmail
PKG_VERSION:=8.15.2
PKG_RELEASE:=2
PKG_RELEASE:=3
PKG_SOURCE:=$(PKG_NAME).$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://artfiles.org/sendmail.org/pub/sendmail/ \

View File

@ -0,0 +1,255 @@
Not needed for 8.16
From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Date: Sat, 10 Sep 2016 19:27:17 +0000
Subject: [PATCH] sendmail: compile against openssl 1.1.0
Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
---
--- a/sendmail/tls.c
+++ b/sendmail/tls.c
@@ -60,18 +60,58 @@ static unsigned char dh512_g[] =
0x02
};
+#if OPENSSL_VERSION_NUMBER < 0x10100000
+
+static inline int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+ /* If the fields p and g in d are NULL, the corresponding input
+ * parameters MUST be non-NULL. q may remain NULL.
+ */
+ if ((dh->p == NULL && p == NULL)
+ || (dh->g == NULL && g == NULL))
+ return 0;
+
+ if (p != NULL) {
+ BN_free(dh->p);
+ dh->p = p;
+ }
+ if (q != NULL) {
+ BN_free(dh->q);
+ dh->q = q;
+ }
+ if (g != NULL) {
+ BN_free(dh->g);
+ dh->g = g;
+ }
+
+ if (q != NULL) {
+ dh->length = BN_num_bits(q);
+ }
+
+ return 1;
+}
+#endif
+
static DH *
get_dh512()
{
DH *dh = NULL;
+ BIGNUM *p;
+ BIGNUM *g;
- if ((dh = DH_new()) == NULL)
- return NULL;
- dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL);
- dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL);
- if ((dh->p == NULL) || (dh->g == NULL))
- return NULL;
+ dh = DH_new();
+ p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL);
+ g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL);
+ if (!dh || !p || !g)
+ goto err;
+ if (!DH_set0_pqg(dh, p, NULL, g))
+ goto err;
return dh;
+err:
+ DH_free(dh);
+ BN_free(p);
+ BN_free(g);
+ return NULL;
}
# if 0
@@ -117,17 +157,22 @@ get_dh2048()
};
static unsigned char dh2048_g[]={ 0x02, };
DH *dh;
+ BIGNUM *p;
+ BIGNUM *g;
- if ((dh=DH_new()) == NULL)
- return(NULL);
- dh->p=BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL);
- dh->g=BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL);
- if ((dh->p == NULL) || (dh->g == NULL))
- {
- DH_free(dh);
- return(NULL);
- }
+ dh = DH_new();
+ p = BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL);
+ g = BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL);
+ if (!dh || !p || !g)
+ goto err;
+ if (!DH_set0_pqg(dh, p, NULL, g))
+ goto err;
return(dh);
+err:
+ DH_free(dh);
+ BN_free(p);
+ BN_free(g);
+ return NULL;
}
# endif /* !NO_DH */
@@ -926,7 +971,7 @@ inittls(ctx, req, options, srv, certfile
{
/* get a pointer to the current certificate validation store */
store = SSL_CTX_get_cert_store(*ctx); /* does not fail */
- crl_file = BIO_new(BIO_s_file_internal());
+ crl_file = BIO_new(BIO_s_file());
if (crl_file != NULL)
{
if (BIO_read_filename(crl_file, CRLFile) >= 0)
@@ -1000,26 +1045,43 @@ inittls(ctx, req, options, srv, certfile
** maybe we should do it only on demand...
*/
- if (bitset(TLS_I_RSA_TMP, req)
# if SM_CONF_SHM
- && ShmId != SM_SHM_NO_ID &&
- (rsa_tmp = RSA_generate_key(RSA_KEYLENGTH, RSA_F4, NULL,
- NULL)) == NULL
-# else /* SM_CONF_SHM */
- && 0 /* no shared memory: no need to generate key now */
-# endif /* SM_CONF_SHM */
- )
+ if (bitset(TLS_I_RSA_TMP, req)
+ && ShmId != SM_SHM_NO_ID)
{
- if (LogLevel > 7)
+ BIGNUM *bn;
+
+ bn = BN_new();
+ rsa_tmp = RSA_new();
+ if (!bn || !rsa_tmp || !BN_set_word(bn, RSA_F4)) {
+ RSA_free(rsa_tmp);
+ rsa_tmp = NULL;
+ }
+ if (rsa_tmp)
{
- sm_syslog(LOG_WARNING, NOQID,
- "STARTTLS=%s, error: RSA_generate_key failed",
- who);
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, who);
+ if (!RSA_generate_key_ex(rsa_tmp, RSA_KEYLENGTH, bn, NULL))
+ {
+ RSA_free(rsa_tmp);
+ rsa_tmp = NULL;
+ }
+ }
+ BN_free(bn);
+ if (!rsa_tmp)
+ {
+ if (LogLevel > 7)
+ {
+ sm_syslog(LOG_WARNING, NOQID,
+ "STARTTLS=%s, error: RSA_generate_key failed",
+ who);
+ if (LogLevel > 9)
+ tlslogerr(LOG_WARNING, who);
+ }
+ return false;
}
- return false;
}
+# else /* SM_CONF_SHM */
+ /* no shared memory: no need to generate key now */
+# endif /* SM_CONF_SHM */
# endif /* !TLS_NO_RSA */
/*
@@ -1210,9 +1272,15 @@ inittls(ctx, req, options, srv, certfile
sm_dprintf("inittls: Generating %d bit DH parameters\n", bits);
/* this takes a while! */
- dsa = DSA_generate_parameters(bits, NULL, 0, NULL,
- NULL, 0, NULL);
- dh = DSA_dup_DH(dsa);
+ dsa = DSA_new();
+ if (dsa) {
+ int r;
+
+ r = DSA_generate_parameters_ex(dsa, bits, NULL, 0,
+ NULL, NULL, NULL);
+ if (r != 0)
+ dh = DSA_dup_DH(dsa);
+ }
DSA_free(dsa);
}
else if (dh == NULL && bitset(TLS_I_DHFIXED, req))
@@ -1733,6 +1801,9 @@ tmp_rsa_key(s, export, keylength)
int export;
int keylength;
{
+ BIGNUM *bn;
+ int ret;
+
# if SM_CONF_SHM
extern int ShmId;
extern int *PRSATmpCnt;
@@ -1742,10 +1813,22 @@ tmp_rsa_key(s, export, keylength)
return rsa_tmp;
# endif /* SM_CONF_SHM */
- if (rsa_tmp != NULL)
- RSA_free(rsa_tmp);
- rsa_tmp = RSA_generate_key(RSA_KEYLENGTH, RSA_F4, NULL, NULL);
- if (rsa_tmp == NULL)
+ if (rsa_tmp == NULL) {
+ rsa_tmp = RSA_new();
+ if (!rsa_tmp)
+ return NULL;
+ }
+
+ bn = BN_new();
+ if (!bn)
+ return NULL;
+ if (!BN_set_word(bn, RSA_F4)) {
+ BN_free(bn);
+ return NULL;
+ }
+ ret = RSA_generate_key_ex(rsa_tmp, RSA_KEYLENGTH, bn, NULL);
+ BN_free(bn);
+ if (!ret)
{
if (LogLevel > 0)
sm_syslog(LOG_ERR, NOQID,
@@ -1971,9 +2054,9 @@ x509_verify_cb(ok, ctx)
{
if (LogLevel > 13)
tls_verify_log(ok, ctx, "x509");
- if (ctx->error == X509_V_ERR_UNABLE_TO_GET_CRL)
+ if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_UNABLE_TO_GET_CRL)
{
- ctx->error = 0;
+ X509_STORE_CTX_set_error(ctx, 0);
return 1; /* override it */
}
}
--- a/doc/op/op.me
+++ b/doc/op/op.me
@@ -10898,7 +10898,7 @@ C=FileName_of_CA_Certificate
ln -s $C `openssl x509 -noout -hash < $C`.0
.)b
A better way to do this is to use the
-.b c_rehash
+.b "openssl rehash"
command that is part of the OpenSSL distribution
because it handles subject hash collisions
by incrementing the number in the suffix of the filename of the symbolic link,

View File

@ -0,0 +1,20 @@
Not needed for 8.16
--- a/sendmail/tls.c
+++ b/sendmail/tls.c
@@ -1325,13 +1325,8 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
}
#if _FFR_TLS_EC
- ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
- if (ecdh != NULL)
- {
- SSL_CTX_set_options(*ctx, SSL_OP_SINGLE_ECDH_USE);
- SSL_CTX_set_tmp_ecdh(*ctx, ecdh);
- EC_KEY_free(ecdh);
- }
+ SSL_CTX_set_options(*ctx, SSL_OP_SINGLE_ECDH_USE);
+ SSL_CTX_set_ecdh_auto(*ctx, 1);
#endif /* _FFR_TLS_EC */
}

View File

@ -0,0 +1,76 @@
Must be rebased for 8.16
--- a/sendmail/main.c
+++ b/sendmail/main.c
@@ -17,6 +17,9 @@
#include <sm/xtrap.h>
#include <sm/signal.h>
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define OpenSSL_version_num SSLeay
+#endif
#ifndef lint
SM_UNUSED(static char copyright[]) =
"@(#) Copyright (c) 1998-2013 Proofpoint, Inc. and its suppliers.\n\
@@ -650,7 +653,7 @@ main(argc, argv, envp)
sm_dprintf(" OpenSSL: compiled 0x%08x\n",
(uint) OPENSSL_VERSION_NUMBER);
sm_dprintf(" OpenSSL: linked 0x%08x\n",
- (uint) SSLeay());
+ (uint) OpenSSL_version_num());
}
#endif /* STARTTLS */
--- a/sendmail/tls.c
+++ b/sendmail/tls.c
@@ -16,9 +16,25 @@ SM_RCSID("@(#)$Id: tls.c,v 8.127 2013-11-27 02:51:11 gshapiro Exp $")
# include <openssl/err.h>
# include <openssl/bio.h>
# include <openssl/pem.h>
+# include <openssl/bn.h>
+# include <openssl/dh.h>
+# include <openssl/dsa.h>
+# include <openssl/rsa.h>
# ifndef HASURANDOMDEV
# include <openssl/rand.h>
# endif /* ! HASURANDOMDEV */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define OpenSSL_version_num SSLeay
+#endif
+
+#ifndef CRYPTO_thread_id
+#define CRYPTO_thread_id() (0UL)
+#endif
+
+#ifndef SSL_CTX_set_tmp_rsa_callback
+#define SSL_CTX_set_tmp_rsa_callback(ctx, cb) while(0) (cb)(NULL, 0, 0)
+#endif
+
# if !TLS_NO_RSA
static RSA *rsa_tmp = NULL; /* temporary RSA key */
static RSA *tmp_rsa_key __P((SSL *, int, int));
@@ -380,6 +396,7 @@ init_tls_library(fipsmode)
{
bool bv;
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
/* basic TLS initialization, ignore result for now */
SSL_library_init();
SSL_load_error_strings();
@@ -388,6 +405,7 @@ init_tls_library(fipsmode)
/* this is currently a macro for SSL_library_init */
SSLeay_add_ssl_algorithms();
# endif /* 0 */
+#endif /* OPENSSL_VERSION_NUMBER */
bv = tls_rand_init(RandFile, 7);
# if _FFR_FIPSMODE
@@ -1207,7 +1225,7 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
** just the compile time version.
*/
- rt_version = SSLeay();
+ rt_version = OpenSSL_version_num();
if (rt_version >= 0x00908000L && rt_version <= 0x0090802fL)
{
comp_methods = SSL_COMP_get_compression_methods();