summaryrefslogtreecommitdiff
path: root/logsrvd
diff options
context:
space:
mode:
authorTodd C. Miller <Todd.Miller@sudo.ws>2021-09-17 10:55:06 -0600
committerTodd C. Miller <Todd.Miller@sudo.ws>2021-09-17 10:55:06 -0600
commit219819bca31f7e7b70511ac91eec59ee94b48d69 (patch)
tree68289e6c52ac95a03ad05f8dedc5c0a529f66fb9 /logsrvd
parented0717ef83bef6edb8c3980dc0b28ae80505e3dc (diff)
downloadsudo-219819bca31f7e7b70511ac91eec59ee94b48d69.tar.gz
tls_init.c: use SSL_CTX_set0_tmp_dh_pkey if present.
Fixes a warning on OpenSSL 3.0 and plugs a memory leak of dhparams on config reload.
Diffstat (limited to 'logsrvd')
-rw-r--r--logsrvd/tls_init.c105
1 files changed, 84 insertions, 21 deletions
diff --git a/logsrvd/tls_init.c b/logsrvd/tls_init.c
index 5b9e47702..a8dcabc3e 100644
--- a/logsrvd/tls_init.c
+++ b/logsrvd/tls_init.c
@@ -30,6 +30,8 @@
#endif
#include <stdio.h>
#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
#if defined(HAVE_OPENSSL)
# include <openssl/ssl.h>
@@ -173,6 +175,85 @@ init_tls_ciphersuites(SSL_CTX *ctx, const char *ciphers_v12,
debug_return_bool(true);
}
+/*
+ * Load diffie-hellman parameters from bio and store in ctx.
+ * Returns true on success, else false.
+ */
+#ifdef HAVE_SSL_CTX_SET0_TMP_DH_PKEY
+static bool
+set_dhparams_bio(SSL_CTX *ctx, BIO *bio)
+{
+ EVP_PKEY *dhparams;
+ bool ret = false;
+ debug_decl(set_dhparams_bio, SUDO_DEBUG_UTIL);
+
+ dhparams = PEM_read_bio_Parameters(bio, NULL);
+ if (dhparams != NULL) {
+ /* dhparams is owned by ctx on success. */
+ ret = SSL_CTX_set0_tmp_dh_pkey(ctx, dhparams);
+ if (!ret) {
+ const char *errstr = ERR_reason_error_string(ERR_get_error());
+ sudo_warnx(U_("unable to set diffie-hellman parameters: %s"),
+ errstr);
+ EVP_PKEY_free(dhparams);
+ }
+ }
+ debug_return_bool(ret);
+}
+#else
+static bool
+set_dhparams_bio(SSL_CTX *ctx, BIO *bio)
+{
+ DH *dhparams;
+ bool ret = false;
+ debug_decl(set_dhparams_bio, SUDO_DEBUG_UTIL);
+
+ dhparams = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
+ if (dhparams != NULL) {
+ /* LEAK: dhparams leaked on config reload */
+ ret = SSL_CTX_set_tmp_dh(ctx, dhparams);
+ if (!ret) {
+ const char *errstr = ERR_reason_error_string(ERR_get_error());
+ sudo_warnx(U_("unable to set diffie-hellman parameters: %s"),
+ errstr);
+ DH_free(dhparams);
+ }
+ }
+ debug_return_bool(ret);
+}
+#endif /* HAVE_SSL_CTX_SET0_TMP_DH_PKEY */
+
+/*
+ * Load diffie-hellman parameters from the specified file and store in ctx.
+ * Returns true on success, else false.
+ */
+static bool
+set_dhparams(SSL_CTX *ctx, const char *dhparam_file)
+{
+ BIO *bio = NULL;
+ bool ret = false;
+ int fd;
+ debug_decl(set_dhparams, SUDO_DEBUG_UTIL);
+
+ fd = open(dhparam_file, O_RDONLY);
+ if (fd != -1)
+ bio = BIO_new_fd(fd, BIO_CLOSE);
+ if (bio != NULL) {
+ if (set_dhparams_bio(ctx, bio)) {
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "loaded diffie-hellman parameters from %s", dhparam_file);
+ ret = true;
+ }
+ } else {
+ sudo_warn(U_("unable to open %s"), dhparam_file);
+ if (fd != -1)
+ close(fd);
+ }
+ BIO_free(bio);
+
+ debug_return_bool(ret);
+}
+
SSL_CTX *
init_tls_context(const char *ca_bundle_file, const char *cert_file,
const char *key_file, const char *dhparam_file, const char *ciphers_v12,
@@ -270,27 +351,9 @@ init_tls_context(const char *ca_bundle_file, const char *cert_file,
* Failure to open the file is not a fatal error.
*/
if (dhparam_file != NULL) {
- FILE *fp = fopen(dhparam_file, "r");
- if (fp != NULL) {
- DH *dhparams = PEM_read_DHparams(fp, NULL, NULL, NULL);
- if (dhparams != NULL) {
- if (!SSL_CTX_set_tmp_dh(ctx, dhparams)) {
- errstr = ERR_reason_error_string(ERR_get_error());
- sudo_warnx(U_("unable to set diffie-hellman parameters: %s"),
- errstr);
- DH_free(dhparams);
- } else {
- sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
- "loaded diffie-hellman parameters from %s", dhparam_file);
- }
- } else {
- errstr = ERR_reason_error_string(ERR_get_error());
- sudo_warnx(U_("unable to read diffie-hellman parameters: %s"),
- errstr);
- }
- fclose(fp);
- } else {
- sudo_warn(U_("unable to open %s"), dhparam_file);
+ if (!set_dhparams(ctx, dhparam_file)) {
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "unable to load dhparam file, using default parameters");
}
} else {
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,