summaryrefslogtreecommitdiffstats
path: root/qmail-smtpd.c
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2022-01-26 10:24:26 +0100
committermanuel <manuel@mausz.at>2022-01-26 10:24:26 +0100
commit34bc44373eed99e37cbcd00bb528bcdabc1461f9 (patch)
tree523450fa8c048c2279d077893e0ae0f08931816e /qmail-smtpd.c
parentd13f178cf56e5ae38082abfbd28c68245b774f97 (diff)
downloadqmail-34bc44373eed99e37cbcd00bb528bcdabc1461f9.tar.gz
qmail-34bc44373eed99e37cbcd00bb528bcdabc1461f9.tar.bz2
qmail-34bc44373eed99e37cbcd00bb528bcdabc1461f9.zip
Add support for an alternative (ECDSA) certificate
Diffstat (limited to 'qmail-smtpd.c')
-rw-r--r--qmail-smtpd.c27
1 files changed, 19 insertions, 8 deletions
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();
72# include "tls.h" 72# include "tls.h"
73# include "ssl_timeoutio.h" 73# include "ssl_timeoutio.h"
74 74
75# define SERVERCERT "control/servercert.pem" 75# define SERVERCERT "control/servercert.pem"
76# define SERVERCERT2 "control/servercert2.pem"
76 77
77void tls_init(); 78void tls_init();
78void tls_nogateway(); 79void tls_nogateway();
@@ -1449,17 +1450,20 @@ void tls_init()
1449 stralloc saciphers = {0}; 1450 stralloc saciphers = {0};
1450 X509_STORE *store; 1451 X509_STORE *store;
1451 X509_LOOKUP *lookup; 1452 X509_LOOKUP *lookup;
1452 const char *servercert; 1453 const char *servercert, *servercert2;
1453 DH *dhparams; 1454 DH *dhparams;
1454#ifdef HAVE_ECC 1455#ifdef HAVE_ECC
1455 EC_GROUP *ecparams; 1456 EC_GROUP *ecparams;
1456 int nid; 1457 int nid;
1457 EC_KEY *eckey = NULL; 1458 EC_KEY *eckey = NULL;
1458#endif 1459#endif
1460 struct stat st;
1459 1461
1460 /* if set, use servercert selected through SMTP_SERVERCERT env var */ 1462 /* if set, use servercert selected through SMTP_SERVERCERT env var */
1461 servercert = env_get("SMTP_SERVERCERT"); 1463 servercert = env_get("SMTP_SERVERCERT");
1462 if (!servercert) servercert = SERVERCERT; 1464 if (!servercert) servercert = SERVERCERT;
1465 servercert2 = env_get("SMTP_SERVERCERT2");
1466 if (!servercert2) servercert2 = SERVERCERT2;
1463 1467
1464 SSL_library_init(); 1468 SSL_library_init();
1465 1469
@@ -1471,21 +1475,28 @@ void tls_init()
1471 SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE | 1475 SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE |
1472 SSL_OP_PRIORITIZE_CHACHA); 1476 SSL_OP_PRIORITIZE_CHACHA);
1473 1477
1478 /* set the callback here; SSL_set_verify didn't work before 0.9.6c */
1479 SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_cb);
1480
1474 if (!SSL_CTX_use_certificate_chain_file(ctx, servercert)) 1481 if (!SSL_CTX_use_certificate_chain_file(ctx, servercert))
1475 { SSL_CTX_free(ctx); tls_err("missing certificate"); return; } 1482 { SSL_CTX_free(ctx); tls_err("missing certificate"); return; }
1476 1483
1477 /* set the callback here; SSL_set_verify didn't work before 0.9.6c */ 1484 /* this will also check whether public and private keys match */
1478 SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_cb); 1485 if (!SSL_CTX_use_PrivateKey_file(ctx, servercert, SSL_FILETYPE_PEM))
1486 { SSL_free(myssl); tls_err("no valid private key"); return; }
1487
1488 if (stat(servercert2, &st) == 0) {
1489 if (!SSL_CTX_use_certificate_chain_file(ctx, servercert2))
1490 { SSL_CTX_free(ctx); tls_err("missing alternate certificate"); return; }
1491 if (!SSL_CTX_use_PrivateKey_file(ctx, servercert2, SSL_FILETYPE_PEM))
1492 { SSL_free(myssl); tls_err("no valid alternate private key"); return; }
1493 }
1479 1494
1480 /* a new SSL object, with the rest added to it directly to avoid copying */ 1495 /* a new SSL object, with the rest added to it directly to avoid copying */
1481 myssl = SSL_new(ctx); 1496 myssl = SSL_new(ctx);
1482 SSL_CTX_free(ctx); 1497 SSL_CTX_free(ctx);
1483 if (!myssl) { tls_err("unable to initialize ssl"); return; } 1498 if (!myssl) { tls_err("unable to initialize ssl"); return; }
1484 1499
1485 /* this will also check whether public and private keys match */
1486 if (!SSL_use_PrivateKey_file(myssl, servercert, SSL_FILETYPE_PEM))
1487 { SSL_free(myssl); tls_err("no valid private key"); return; }
1488
1489 ciphers = env_get("TLSCIPHERS"); 1500 ciphers = env_get("TLSCIPHERS");
1490 if (!ciphers) { 1501 if (!ciphers) {
1491 if (control_readfile(&saciphers, "control/tlsserverciphers", 0) == -1) 1502 if (control_readfile(&saciphers, "control/tlsserverciphers", 0) == -1)