From f3448f5481a8d1f6fbf5fd05caaca229af0b87f7 Mon Sep 17 00:00:00 2001 From: Pauli Date: Sat, 30 Mar 2019 11:22:51 +1000 Subject: [PATCH] issue-8493: Fix for filenames with newlines using openssl dgst The output format now matches coreutils *dgst tools. [ edited to remove trailing white space ] Reviewed-by: Richard Levitte Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/8578) --- CHANGES | 5 +++++ apps/dgst.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++- doc/man1/dgst.pod | 3 ++- test/README | 2 +- 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 5617fab573..1d093142b7 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,11 @@ Changes between 1.1.1 and 3.0.0 [xx XXX xxxx] + *) Added newline escaping functionality to a filename when using openssl dgst. + This output format is to replicate the output format found in the '*sum' + checksum programs. This aims to preserve backward compatibility. + [Matt Eaton, Richard Levitte, and Paul Dale] + *) Removed the heartbeat message in DTLS feature, as it has very little usage and doesn't seem to fulfill a valuable purpose. [Richard Levitte] diff --git a/apps/dgst.c b/apps/dgst.c index e38496ee0a..7b43338586 100644 --- a/apps/dgst.c +++ b/apps/dgst.c @@ -414,13 +414,52 @@ int dgst_main(int argc, char **argv) return ret; } +/* + * The newline_escape_filename function performs newline escaping for any + * filename that contains a newline. This function also takes a pointer + * to backslash. The backslash pointer is a flag to indicating whether a newline + * is present in the filename. If a newline is present, the backslash flag is + * set and the output format will contain a backslash at the beginning of the + * digest output. This output format is to replicate the output format found + * in the '*sum' checksum programs. This aims to preserve backward + * compatibility. + */ +static const char *newline_escape_filename(const char *file, int * backslash) +{ + size_t i, e = 0, length = strlen(file), newline_count = 0, mem_len = 0; + char *file_cpy = NULL; + + for (i = 0; i < length; i++) + if (file[i] == '\n') + newline_count++; + + mem_len = length + newline_count + 1; + file_cpy = app_malloc(mem_len, file); + i = 0; + + while(e < length) { + const char c = file[e]; + if (c == '\n') { + file_cpy[i++] = '\\'; + file_cpy[i++] = 'n'; + *backslash = 1; + } else { + file_cpy[i++] = c; + } + e++; + } + file_cpy[i] = '\0'; + return (const char*)file_cpy; +} + + int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, EVP_PKEY *key, unsigned char *sigin, int siglen, const char *sig_name, const char *md_name, const char *file) { size_t len; - int i; + int i, backslash = 0; for (;;) { i = BIO_read(bp, (char *)buf, BUFSIZE); @@ -468,9 +507,16 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, if (binout) { BIO_write(out, buf, len); } else if (sep == 2) { + file = newline_escape_filename(file, &backslash); + + if (backslash == 1) + BIO_puts(out, "\\"); + for (i = 0; i < (int)len; i++) BIO_printf(out, "%02x", buf[i]); + BIO_printf(out, " *%s\n", file); + OPENSSL_free((char *)file); } else { if (sig_name != NULL) { BIO_puts(out, sig_name); diff --git a/doc/man1/dgst.pod b/doc/man1/dgst.pod index 601f254e99..0116a792c3 100644 --- a/doc/man1/dgst.pod +++ b/doc/man1/dgst.pod @@ -79,7 +79,8 @@ Output the digest or signature in binary form. =item B<-r> -Output the digest in the "coreutils" format used by programs like B. +Output the digest in the "coreutils" format, including newlines. +Used by programs like B. =item B<-out filename> diff --git a/test/README b/test/README index 37722e79f3..ebe7784605 100644 --- a/test/README +++ b/test/README @@ -114,7 +114,7 @@ Generic form of C test executables int observed; observed = function(); /* Call the code under test */ - if (!TEST_int_equal(observed, 2)) /* Check the result is correct */ + if (!TEST_int_eq(observed, 2)) /* Check the result is correct */ goto end; /* Exit on failure - optional */ testresult = 1; /* Mark the test case a success */ -- 2.25.1