Commit e7e7950998 for openssl.org
commit e7e79509986a3b6134ce3bbf30d7afcfd117c7eb
Author: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Wed Jun 25 16:41:30 2025 +0200
Enforce permissions 0600 for SSLKEYLOGFILE
Fixes #27890
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/27893)
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 34cde49496..9696a4c55f 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -33,6 +33,11 @@
#include "internal/ssl_unwrap.h"
#include "quic/quic_local.h"
+#ifndef OPENSSL_NO_SSLKEYLOG
+# include <sys/stat.h>
+# include <fcntl.h>
+#endif
+
static int ssl_undefined_function_3(SSL_CONNECTION *sc, unsigned char *r,
unsigned char *s, size_t t, size_t *u)
{
@@ -3983,6 +3988,33 @@ static void do_sslkeylogfile(const SSL *ssl, const char *line)
* via ssl.h.
*/
+#ifndef OPENSSL_NO_SSLKEYLOG
+static BIO *get_sslkeylog_bio(const char *keylogfile)
+{
+# ifdef _POSIX_C_SOURCE
+ BIO *b;
+ int fdno = -1;
+ FILE *fp = NULL;
+
+ fdno = open(keylogfile, O_WRONLY | O_CREAT | O_APPEND, 0600);
+ if (fdno < 0)
+ return NULL;
+
+ fp = fdopen(fdno, "a");
+ if (fp == NULL) {
+ close(fdno);
+ return NULL;
+ }
+
+ if ((b = BIO_new_fp(fp, BIO_CLOSE)) == NULL)
+ fclose(fp);
+ return b;
+# else
+ return BIO_new_file(keylogfile, "a");
+# endif
+}
+#endif
+
SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq,
const SSL_METHOD *meth)
{
@@ -4295,7 +4327,7 @@ SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq,
* if its already there.
*/
if (keylog_bio == NULL) {
- keylog_bio = BIO_new_file(keylogfile, "a");
+ keylog_bio = get_sslkeylog_bio(keylogfile);
if (keylog_bio == NULL) {
OSSL_TRACE(TLS, "Unable to create keylog bio\n");
goto out;
diff --git a/test/recipes/70-test_sslkeylogfile.t b/test/recipes/70-test_sslkeylogfile.t
index acff862229..99ff83e112 100644
--- a/test/recipes/70-test_sslkeylogfile.t
+++ b/test/recipes/70-test_sslkeylogfile.t
@@ -19,7 +19,12 @@ setup($test_name);
plan skip_all => "$test_name requires SSLKEYLOGFILE support"
if disabled("sslkeylog");
-plan tests => 1;
+my $tests = 1;
+if ($^O =~ /^(linux)$/) {
+ $tests = 2;
+}
+
+plan tests => $tests;
my $shlib_wrap = srctop_file("util", "wrap.pl");
@@ -75,3 +80,9 @@ kill 'HUP', $s_server_pid;
# Test 1: Compare the output of -keylogfile and SSLKEYLOGFILE, and make sure they match
# Note, the former adds a comment, that the latter does not, so ignore comments with -I in diff
ok(run(cmd(["diff", "-I" ,"^#.*\$", $sslkeylogfile, $trace_file])));
+
+# Test 2, linux-specific: the keylog file should have permission 0600
+if ($^O =~ /^(linux)$/) {
+ my $mode = sprintf("%04o", (stat($sslkeylogfile))[2] & 07777);
+ ok($mode eq "0600");
+}