On Mon, Mar 04, 2019 at 07:43:17PM -0500, Wietse Venema wrote: > Viktor Dukhovni: > > The reason there's no logging of a problem, is that there is no > > problem to log! :-( The certificate initialization was successful, > > but due to a bug in reporting success/failure to the caller, the > > successful outcome was treated as a failure (whose reason would > > have already been logged if it were a real failure). > > > > The patch is a one liner, below. > > I have uploaded postfix-3.4.1-RC1 (stable) and postfix-3.5-20190304 > (unstable).
Below is a more complete patch (relative to 3.4.0, including same one-liner), with tests that exercise the problem code-path. We could refactor functions in tls_certkey.c to be consistent with respect to whether 0 or non-zero is a successful return code. The lower-level internal functions return 0 on success, but the external API returns 0 on failure. I failed to handle one case of impedance mismatch. :-( -- Viktor. --- a/Makefile.in +++ b/Makefile.in @@ -58,6 +58,15 @@ tls_certkey_tests: test $(SHLIB_ENV) $(VALGRIND) ./tls_certkey -m $$pem > $$pem.out 2>&1 || exit 1; \ diff $$pem.ref $$pem.out || exit 1; \ echo " $$pem: OK"; \ + $(SHLIB_ENV) $(VALGRIND) ./tls_certkey -k $$pem $$pem > $$pem.out 2>&1 || exit 1; \ + diff $$pem.ref $$pem.out || exit 1; \ + echo " $$pem (with key in $$pem): OK"; \ + case $$pem in good-*) \ + ln -sf $$pem tmpkey.pem; \ + $(SHLIB_ENV) $(VALGRIND) ./tls_certkey -k tmpkey.pem $$pem > $$pem.out 2>&1 || exit 1; \ + diff $$pem.ref $$pem.out || exit 1; \ + echo " $$pem (with key in tmpkey.pem): OK";; \ + esac; \ done; \ for pem in bad-*.pem; do \ $(SHLIB_ENV) $(VALGRIND) ./tls_certkey $$pem > $$pem.out 2>&1 && exit 1 || : ok; \ --- a/tls_certkey.c +++ b/tls_certkey.c @@ -589,7 +589,7 @@ static int set_cert_stuff(SSL_CTX *ctx, const char *cert_type, * single pass, avoiding potential race conditions during key rollover. */ if (strcmp(cert_file, key_file) == 0) - return (load_mixed_file(ctx, cert_file)); + return (load_mixed_file(ctx, cert_file) == 0); /* * We need both the private key (in key_file) and the public key @@ -690,6 +690,7 @@ int main(int argc, char *argv[]) int ch; int mixed = 0; int ret; + char *key_file = 0; SSL_CTX *ctx; #if OPENSSL_VERSION_NUMBER < 0x10100000L @@ -707,8 +708,11 @@ int main(int argc, char *argv[]) tls_print_errors(); exit(1); } - while ((ch = GETOPT(argc, argv, "m")) > 0) { + while ((ch = GETOPT(argc, argv, "mk:")) > 0) { switch (ch) { + case 'k': + key_file = optarg; + break; case 'm': mixed = 1; break; @@ -722,7 +726,9 @@ int main(int argc, char *argv[]) if (argc < 1) usage(); - if (mixed) + if (key_file) + ret = set_cert_stuff(ctx, "any", argv[0], key_file) == 0; + else if (mixed) ret = load_mixed_file(ctx, argv[0]); else ret = load_chain_files(ctx, argv[0]);