From 34bc44373eed99e37cbcd00bb528bcdabc1461f9 Mon Sep 17 00:00:00 2001 From: manuel Date: Wed, 26 Jan 2022 10:24:26 +0100 Subject: Add support for an alternative (ECDSA) certificate --- qmail-smtpd.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'qmail-smtpd.c') diff --git a/qmail-smtpd.c b/qmail-smtpd.c index b722ee4..7867197 100644 --- a/qmail-smtpd.c +++ b/qmail-smtpd.c @@ -72,7 +72,8 @@ static const stralloc *client_get_session_id(); # include "tls.h" # include "ssl_timeoutio.h" -# define SERVERCERT "control/servercert.pem" +# define SERVERCERT "control/servercert.pem" +# define SERVERCERT2 "control/servercert2.pem" void tls_init(); void tls_nogateway(); @@ -1449,17 +1450,20 @@ void tls_init() stralloc saciphers = {0}; X509_STORE *store; X509_LOOKUP *lookup; - const char *servercert; + const char *servercert, *servercert2; DH *dhparams; #ifdef HAVE_ECC EC_GROUP *ecparams; int nid; EC_KEY *eckey = NULL; #endif + struct stat st; /* if set, use servercert selected through SMTP_SERVERCERT env var */ servercert = env_get("SMTP_SERVERCERT"); if (!servercert) servercert = SERVERCERT; + servercert2 = env_get("SMTP_SERVERCERT2"); + if (!servercert2) servercert2 = SERVERCERT2; SSL_library_init(); @@ -1471,21 +1475,28 @@ void tls_init() SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_PRIORITIZE_CHACHA); + /* set the callback here; SSL_set_verify didn't work before 0.9.6c */ + SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_cb); + if (!SSL_CTX_use_certificate_chain_file(ctx, servercert)) { SSL_CTX_free(ctx); tls_err("missing certificate"); return; } - /* set the callback here; SSL_set_verify didn't work before 0.9.6c */ - SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_cb); + /* this will also check whether public and private keys match */ + if (!SSL_CTX_use_PrivateKey_file(ctx, servercert, SSL_FILETYPE_PEM)) + { SSL_free(myssl); tls_err("no valid private key"); return; } + + if (stat(servercert2, &st) == 0) { + if (!SSL_CTX_use_certificate_chain_file(ctx, servercert2)) + { SSL_CTX_free(ctx); tls_err("missing alternate certificate"); return; } + if (!SSL_CTX_use_PrivateKey_file(ctx, servercert2, SSL_FILETYPE_PEM)) + { SSL_free(myssl); tls_err("no valid alternate private key"); return; } + } /* a new SSL object, with the rest added to it directly to avoid copying */ myssl = SSL_new(ctx); SSL_CTX_free(ctx); if (!myssl) { tls_err("unable to initialize ssl"); return; } - /* this will also check whether public and private keys match */ - if (!SSL_use_PrivateKey_file(myssl, servercert, SSL_FILETYPE_PEM)) - { SSL_free(myssl); tls_err("no valid private key"); return; } - ciphers = env_get("TLSCIPHERS"); if (!ciphers) { if (control_readfile(&saciphers, "control/tlsserverciphers", 0) == -1) -- cgit v1.2.3