From c521a258441c40bd8d14993cfaa6936c02b2a2f1 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Fri, 27 Mar 2026 07:02:25 +0900 Subject: [PATCH 1/7] fix stack buffer overflow in encryption setup --- src/crypto/clu_crypto_setup.c | 17 +++++++++++--- tests/encrypt/enc-test.sh | 42 +++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/crypto/clu_crypto_setup.c b/src/crypto/clu_crypto_setup.c index 95cf8ac6..02fe4c84 100644 --- a/src/crypto/clu_crypto_setup.c +++ b/src/crypto/clu_crypto_setup.c @@ -347,7 +347,10 @@ int wolfCLU_setup(int argc, char** argv, char action) WOLFCLU_LOG(WOLFCLU_L0, "-in flag was not set, please enter a string or" "file name to be encrypted: "); - ret = (int) scanf("%s", inName); + ret = (fgets(inName, sizeof(inName), stdin) != NULL) ? 1 : 0; + if (ret > 0) { + inName[strcspn(inName, "\n")] = '\0'; + } } in = inName; WOLFCLU_LOG(WOLFCLU_L0, "Encrypting :\"%s\"", inName); @@ -397,7 +400,11 @@ int wolfCLU_setup(int argc, char** argv, char action) while (ret == 0) { WOLFCLU_LOG(WOLFCLU_L0, "Please enter a name for the output file: "); - ret = (int) scanf("%s", outNameEnc); + ret = (fgets(outNameEnc, sizeof(outNameEnc), stdin) != NULL) + ? 1 : 0; + if (ret > 0) { + outNameEnc[strcspn(outNameEnc, "\n")] = '\0'; + } out = (ret > 0) ? outNameEnc : '\0'; } } @@ -419,7 +426,11 @@ int wolfCLU_setup(int argc, char** argv, char action) while (ret == 0) { WOLFCLU_LOG(WOLFCLU_L0, "Please enter a name for the output file: "); - ret = (int) scanf("%s", outNameDec); + ret = (fgets(outNameDec, sizeof(outNameDec), stdin) != NULL) + ? 1 : 0; + if (ret > 0) { + outNameDec[strcspn(outNameDec, "\n")] = '\0'; + } out = (ret > 0) ? outNameDec : '\0'; } } diff --git a/tests/encrypt/enc-test.sh b/tests/encrypt/enc-test.sh index 13631cf0..ac24c01c 100755 --- a/tests/encrypt/enc-test.sh +++ b/tests/encrypt/enc-test.sh @@ -209,5 +209,47 @@ if grep -q "HAVE_CAMELLIA" wolfssl/wolfssl/options.h 2>/dev/null; then rm -f test_maxlen_camellia.bin test_maxlen_camellia.enc test_maxlen_camellia.dec fi +# Regression tests for stack buffer overflow fix (scanf -> fgets) + +# Test: -in not provided, filename supplied via stdin (inName path, L344) +printf "certs/crl.der\n" | ./wolfssl enc -aes-128-cbc -out test-stdin-in.enc -k "testpass" > /dev/null 2>&1 +if [ $? != 0 ]; then + echo "Failed: enc with stdin input (no -in flag)" + exit 99 +fi +./wolfssl enc -d -aes-128-cbc -in test-stdin-in.enc -out test-stdin-in.dec -k "testpass" > /dev/null 2>&1 +diff certs/crl.der test-stdin-in.dec > /dev/null 2>&1 +if [ $? != 0 ]; then + echo "Failed: stdin enc/dec roundtrip mismatch" + exit 99 +fi +rm -f test-stdin-in.enc test-stdin-in.dec + + +# Test: outNameEnc/outNameDec via stdin (non-EVP path, Camellia) +./wolfssl enc -camellia-128-cbc -in certs/crl.der -out test-cam-probe.enc -k "testpass" > /dev/null 2>&1 +if [ $? -eq 0 ]; then + # outNameEnc: -out omitted, filename supplied via stdin + printf "test-cam-stdin.enc\n" | ./wolfssl enc -camellia-128-cbc -in certs/crl.der -k "testpass" > /dev/null 2>&1 + if [ $? != 0 ]; then + echo "Failed: Camellia enc with stdin output name (no -out flag)" + exit 99 + fi + + # outNameDec: -out omitted, filename supplied via stdin + printf "test-cam-stdin.dec\n" | ./wolfssl enc -d -camellia-128-cbc -in test-cam-stdin.enc -k "testpass" > /dev/null 2>&1 + if [ $? != 0 ]; then + echo "Failed: Camellia dec with stdin output name (no -out flag)" + exit 99 + fi + diff certs/crl.der test-cam-stdin.dec > /dev/null 2>&1 + if [ $? != 0 ]; then + echo "Failed: Camellia stdin outName enc/dec roundtrip mismatch" + exit 99 + fi + + rm -f test-cam-probe.enc test-cam-stdin.enc test-cam-stdin.dec +fi + echo "Done" exit 0 From b8b7828c5d3e1d3ed8970a633957eeb410c3cf77 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Fri, 27 Mar 2026 08:37:41 +0900 Subject: [PATCH 2/7] addressed copilot comments --- src/crypto/clu_crypto_setup.c | 56 ++++++++++++++++++++++++++++------- tests/encrypt/enc-test.sh | 40 +++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 11 deletions(-) diff --git a/src/crypto/clu_crypto_setup.c b/src/crypto/clu_crypto_setup.c index 02fe4c84..4c34423b 100644 --- a/src/crypto/clu_crypto_setup.c +++ b/src/crypto/clu_crypto_setup.c @@ -346,11 +346,25 @@ int wolfCLU_setup(int argc, char** argv, char action) while (ret == 0) { WOLFCLU_LOG(WOLFCLU_L0, "-in flag was not set, please enter a string or" - "file name to be encrypted: "); - ret = (fgets(inName, sizeof(inName), stdin) != NULL) ? 1 : 0; - if (ret > 0) { + " file name to be encrypted: "); + if (fgets(inName, sizeof(inName), stdin) == NULL) { + /* Failed to read input, continue */ + continue; + } + /* If no newline is present, the line was too long. */ + if (strchr(inName, '\n') == NULL) { + int ch; + do { + ch = getchar(); + } while (ch != '\n' && ch != EOF); + } else { inName[strcspn(inName, "\n")] = '\0'; } + /* Do not accept an empty string as valid input */ + if (inName[0] == '\0') { + continue; + } + ret = 1; } in = inName; WOLFCLU_LOG(WOLFCLU_L0, "Encrypting :\"%s\"", inName); @@ -400,12 +414,22 @@ int wolfCLU_setup(int argc, char** argv, char action) while (ret == 0) { WOLFCLU_LOG(WOLFCLU_L0, "Please enter a name for the output file: "); - ret = (fgets(outNameEnc, sizeof(outNameEnc), stdin) != NULL) - ? 1 : 0; - if (ret > 0) { + if (fgets(outNameEnc, sizeof(outNameEnc), stdin) == NULL) { + continue; + } + if (strchr(outNameEnc, '\n') == NULL) { + int ch; + do { + ch = getchar(); + } while (ch != '\n' && ch != EOF); + } else { outNameEnc[strcspn(outNameEnc, "\n")] = '\0'; } - out = (ret > 0) ? outNameEnc : '\0'; + if (outNameEnc[0] == '\0') { + continue; + } + out = outNameEnc; + ret = 1; } } ret = wolfCLU_encrypt(alg, mode, pwdKey, key, keySize, in, out, @@ -426,12 +450,22 @@ int wolfCLU_setup(int argc, char** argv, char action) while (ret == 0) { WOLFCLU_LOG(WOLFCLU_L0, "Please enter a name for the output file: "); - ret = (fgets(outNameDec, sizeof(outNameDec), stdin) != NULL) - ? 1 : 0; - if (ret > 0) { + if (fgets(outNameDec, sizeof(outNameDec), stdin) == NULL) { + continue; + } + if (strchr(outNameDec, '\n') == NULL) { + int ch; + do { + ch = getchar(); + } while (ch != '\n' && ch != EOF); + } else { outNameDec[strcspn(outNameDec, "\n")] = '\0'; } - out = (ret > 0) ? outNameDec : '\0'; + if (outNameDec[0] == '\0') { + continue; + } + out = outNameDec; + ret = 1; } } ret = wolfCLU_decrypt(alg, mode, pwdKey, key, keySize, in, out, diff --git a/tests/encrypt/enc-test.sh b/tests/encrypt/enc-test.sh index ac24c01c..ee893ec9 100755 --- a/tests/encrypt/enc-test.sh +++ b/tests/encrypt/enc-test.sh @@ -251,5 +251,45 @@ if [ $? -eq 0 ]; then rm -f test-cam-probe.enc test-cam-stdin.enc test-cam-stdin.dec fi +# Test: inName empty line is rejected, re-prompt accepts valid filename +printf "\ncerts/crl.der\n" | ./wolfssl enc -aes-128-cbc -out test-empty-in.enc -k "testpass" > /dev/null 2>&1 +if [ $? != 0 ]; then + echo "Failed: enc should accept filename after empty line on stdin (-in path)" + exit 99 +fi +./wolfssl enc -d -aes-128-cbc -in test-empty-in.enc -out test-empty-in.dec -k "testpass" > /dev/null 2>&1 +diff certs/crl.der test-empty-in.dec > /dev/null 2>&1 +if [ $? != 0 ]; then + echo "Failed: enc/dec roundtrip mismatch after empty-line re-prompt (-in path)" + exit 99 +fi +rm -f test-empty-in.enc test-empty-in.dec + +# Test: outNameEnc/outNameDec empty line is rejected (non-EVP path, Camellia) +./wolfssl enc -camellia-128-cbc -in certs/crl.der -out test-cam-probe2.enc -k "testpass" > /dev/null 2>&1 +if [ $? -eq 0 ]; then + rm -f test-cam-probe2.enc + + # outNameEnc: empty line rejected, then valid output name accepted + printf "\ntest-cam-empty.enc\n" | ./wolfssl enc -camellia-128-cbc -in certs/crl.der -k "testpass" > /dev/null 2>&1 + if [ $? != 0 ]; then + echo "Failed: Camellia enc should accept output name after empty line (outNameEnc)" + exit 99 + fi + + # outNameDec: empty line rejected, then valid output name accepted + printf "\ntest-cam-empty.dec\n" | ./wolfssl enc -d -camellia-128-cbc -in test-cam-empty.enc -k "testpass" > /dev/null 2>&1 + if [ $? != 0 ]; then + echo "Failed: Camellia dec should accept output name after empty line (outNameDec)" + exit 99 + fi + diff certs/crl.der test-cam-empty.dec > /dev/null 2>&1 + if [ $? != 0 ]; then + echo "Failed: enc/dec roundtrip mismatch after empty-line re-prompt (outNameEnc/Dec)" + exit 99 + fi + rm -f test-cam-empty.enc test-cam-empty.dec +fi + echo "Done" exit 0 From f53da5bdad4d53d28f30f9d9d64a625d13b8e748 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Fri, 27 Mar 2026 09:12:04 +0900 Subject: [PATCH 3/7] addressed copilot comment --- tests/encrypt/enc-test.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/encrypt/enc-test.sh b/tests/encrypt/enc-test.sh index ee893ec9..5d11bae5 100755 --- a/tests/encrypt/enc-test.sh +++ b/tests/encrypt/enc-test.sh @@ -248,9 +248,11 @@ if [ $? -eq 0 ]; then exit 99 fi - rm -f test-cam-probe.enc test-cam-stdin.enc test-cam-stdin.dec + rm -f test-cam-stdin.enc test-cam-stdin.dec fi +rm -f test-cam-probe.enc + # Test: inName empty line is rejected, re-prompt accepts valid filename printf "\ncerts/crl.der\n" | ./wolfssl enc -aes-128-cbc -out test-empty-in.enc -k "testpass" > /dev/null 2>&1 if [ $? != 0 ]; then From ea94a0fff5feb294c6edeed0816e478e838dcd63 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Fri, 27 Mar 2026 09:33:53 +0900 Subject: [PATCH 4/7] addressed copilot comments --- src/crypto/clu_crypto_setup.c | 40 +++++++++++++++++++++++++---------- tests/encrypt/enc-test.sh | 2 +- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/crypto/clu_crypto_setup.c b/src/crypto/clu_crypto_setup.c index 4c34423b..d5af5f50 100644 --- a/src/crypto/clu_crypto_setup.c +++ b/src/crypto/clu_crypto_setup.c @@ -348,18 +348,24 @@ int wolfCLU_setup(int argc, char** argv, char action) "-in flag was not set, please enter a string or" " file name to be encrypted: "); if (fgets(inName, sizeof(inName), stdin) == NULL) { - /* Failed to read input, continue */ - continue; + /* EOF or read error: cannot prompt further */ + wolfCLU_LogError("failed to read input file name"); + wolfCLU_freeBins(pwdKey, iv, key, NULL, NULL); + if (mode != NULL) + XFREE(mode, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + return WOLFCLU_FATAL_ERROR; } - /* If no newline is present, the line was too long. */ + /* If no newline is present, the line was too long: flush and + * re-prompt rather than proceeding with a truncated filename. */ if (strchr(inName, '\n') == NULL) { int ch; do { ch = getchar(); } while (ch != '\n' && ch != EOF); - } else { - inName[strcspn(inName, "\n")] = '\0'; + wolfCLU_LogError("input too long, please try again"); + continue; } + inName[strcspn(inName, "\n")] = '\0'; /* Do not accept an empty string as valid input */ if (inName[0] == '\0') { continue; @@ -415,16 +421,22 @@ int wolfCLU_setup(int argc, char** argv, char action) WOLFCLU_LOG(WOLFCLU_L0, "Please enter a name for the output file: "); if (fgets(outNameEnc, sizeof(outNameEnc), stdin) == NULL) { - continue; + /* EOF or read error: cannot prompt further */ + wolfCLU_LogError("failed to read output file name"); + wolfCLU_freeBins(pwdKey, iv, key, NULL, NULL); + if (mode != NULL) + XFREE(mode, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + return WOLFCLU_FATAL_ERROR; } if (strchr(outNameEnc, '\n') == NULL) { int ch; do { ch = getchar(); } while (ch != '\n' && ch != EOF); - } else { - outNameEnc[strcspn(outNameEnc, "\n")] = '\0'; + wolfCLU_LogError("input too long, please try again"); + continue; } + outNameEnc[strcspn(outNameEnc, "\n")] = '\0'; if (outNameEnc[0] == '\0') { continue; } @@ -451,16 +463,22 @@ int wolfCLU_setup(int argc, char** argv, char action) WOLFCLU_LOG(WOLFCLU_L0, "Please enter a name for the output file: "); if (fgets(outNameDec, sizeof(outNameDec), stdin) == NULL) { - continue; + /* EOF or read error: cannot prompt further */ + wolfCLU_LogError("failed to read output file name"); + wolfCLU_freeBins(pwdKey, iv, key, NULL, NULL); + if (mode != NULL) + XFREE(mode, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + return WOLFCLU_FATAL_ERROR; } if (strchr(outNameDec, '\n') == NULL) { int ch; do { ch = getchar(); } while (ch != '\n' && ch != EOF); - } else { - outNameDec[strcspn(outNameDec, "\n")] = '\0'; + wolfCLU_LogError("input too long, please try again"); + continue; } + outNameDec[strcspn(outNameDec, "\n")] = '\0'; if (outNameDec[0] == '\0') { continue; } diff --git a/tests/encrypt/enc-test.sh b/tests/encrypt/enc-test.sh index 5d11bae5..7fd5cbac 100755 --- a/tests/encrypt/enc-test.sh +++ b/tests/encrypt/enc-test.sh @@ -211,7 +211,7 @@ fi # Regression tests for stack buffer overflow fix (scanf -> fgets) -# Test: -in not provided, filename supplied via stdin (inName path, L344) +# Test: -in not provided, filename supplied via stdin to exercise the inName Path printf "certs/crl.der\n" | ./wolfssl enc -aes-128-cbc -out test-stdin-in.enc -k "testpass" > /dev/null 2>&1 if [ $? != 0 ]; then echo "Failed: enc with stdin input (no -in flag)" From 8aaa137e99c077d41ee59a492f47a772ef22937c Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Thu, 9 Apr 2026 08:54:58 +0900 Subject: [PATCH 5/7] addressed Copilot review comments --- tests/encrypt/enc-test.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/encrypt/enc-test.sh b/tests/encrypt/enc-test.sh index 7fd5cbac..2ade072d 100755 --- a/tests/encrypt/enc-test.sh +++ b/tests/encrypt/enc-test.sh @@ -212,11 +212,13 @@ fi # Regression tests for stack buffer overflow fix (scanf -> fgets) # Test: -in not provided, filename supplied via stdin to exercise the inName Path +rm -f test-stdin-in.enc test-stdin-in.dec printf "certs/crl.der\n" | ./wolfssl enc -aes-128-cbc -out test-stdin-in.enc -k "testpass" > /dev/null 2>&1 if [ $? != 0 ]; then echo "Failed: enc with stdin input (no -in flag)" exit 99 fi +rm -f test-stdin-in.dec ./wolfssl enc -d -aes-128-cbc -in test-stdin-in.enc -out test-stdin-in.dec -k "testpass" > /dev/null 2>&1 diff certs/crl.der test-stdin-in.dec > /dev/null 2>&1 if [ $? != 0 ]; then From c109e75c59ccf364442bf9e2326064774c852351 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Thu, 9 Apr 2026 09:16:26 +0900 Subject: [PATCH 6/7] addressed Copilot review comments --- src/crypto/clu_crypto_setup.c | 9 ++++++--- src/tools/clu_funcs.c | 10 ++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/crypto/clu_crypto_setup.c b/src/crypto/clu_crypto_setup.c index d5af5f50..f46f892b 100644 --- a/src/crypto/clu_crypto_setup.c +++ b/src/crypto/clu_crypto_setup.c @@ -365,9 +365,10 @@ int wolfCLU_setup(int argc, char** argv, char action) wolfCLU_LogError("input too long, please try again"); continue; } - inName[strcspn(inName, "\n")] = '\0'; + inName[strcspn(inName, "\r\n")] = '\0'; /* Do not accept an empty string as valid input */ if (inName[0] == '\0') { + wolfCLU_LogError("empty input, please enter a file name"); continue; } ret = 1; @@ -436,8 +437,9 @@ int wolfCLU_setup(int argc, char** argv, char action) wolfCLU_LogError("input too long, please try again"); continue; } - outNameEnc[strcspn(outNameEnc, "\n")] = '\0'; + outNameEnc[strcspn(outNameEnc, "\r\n")] = '\0'; if (outNameEnc[0] == '\0') { + wolfCLU_LogError("empty input, please enter a file name"); continue; } out = outNameEnc; @@ -478,8 +480,9 @@ int wolfCLU_setup(int argc, char** argv, char action) wolfCLU_LogError("input too long, please try again"); continue; } - outNameDec[strcspn(outNameDec, "\n")] = '\0'; + outNameDec[strcspn(outNameDec, "\r\n")] = '\0'; if (outNameDec[0] == '\0') { + wolfCLU_LogError("empty input, please enter a file name"); continue; } out = outNameDec; diff --git a/src/tools/clu_funcs.c b/src/tools/clu_funcs.c index f52d467e..10d9b691 100644 --- a/src/tools/clu_funcs.c +++ b/src/tools/clu_funcs.c @@ -1249,14 +1249,16 @@ void wolfCLU_AddNameEntry(WOLFSSL_X509_NAME* name, int type, int nid, char* str) WOLFSSL_X509_NAME_ENTRY *entry; if (str != NULL) { - /* strip off newline character if found at the end of str */ - i = (int)XSTRLEN((const char*)str); + /* strip off newline/carriage-return characters at the end of str */ + i = (int)XSTRLEN((const char*)str) - 1; while (i >= 0) { - if (str[i] == '\n') { + if (str[i] == '\n' || str[i] == '\r') { str[i] = '\0'; + i--; + } + else { break; } - i--; } /* treats a '.' string as 'do not add' */ From 6f2525c21be71746d3be09507b5eae6d5d03f16d Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Sat, 11 Apr 2026 05:24:45 +0900 Subject: [PATCH 7/7] Addressed review comments --- src/crypto/clu_crypto_setup.c | 138 +++++++++++++--------------------- tests/encrypt/enc-test.sh | 46 ++++++++++++ 2 files changed, 99 insertions(+), 85 deletions(-) diff --git a/src/crypto/clu_crypto_setup.c b/src/crypto/clu_crypto_setup.c index f46f892b..cce5dc3e 100644 --- a/src/crypto/clu_crypto_setup.c +++ b/src/crypto/clu_crypto_setup.c @@ -25,6 +25,35 @@ #ifndef WOLFCLU_NO_FILESYSTEM +/* Prompt for a filename on stdin with validation. + * Returns WOLFCLU_SUCCESS on success, WOLFCLU_FATAL_ERROR on EOF/read error. + * buf is filled with the stripped, non-empty filename on success. */ +static int wolfCLU_readFilename(char* buf, int bufSz, const char* prompt) +{ + while (1) { + WOLFCLU_LOG(WOLFCLU_L0, "%s", prompt); + if (fgets(buf, bufSz, stdin) == NULL) { + wolfCLU_LogError("failed to read file name"); + return WOLFCLU_FATAL_ERROR; + } + /* If no newline, line was too long: flush remainder and re-prompt */ + if (strchr(buf, '\n') == NULL) { + int ch; + do { + ch = getchar(); + } while (ch != '\n' && ch != EOF); + wolfCLU_LogError("input too long, please try again"); + continue; + } + buf[strcspn(buf, "\r\n")] = '\0'; + if (buf[0] == '\0') { + wolfCLU_LogError("empty input, please enter a file name"); + continue; + } + return WOLFCLU_SUCCESS; + } +} + static const struct option crypt_options[] = { {"-sha", no_argument, 0, WOLFCLU_CERT_SHA }, {"-sha224", no_argument, 0, WOLFCLU_CERT_SHA224}, @@ -342,38 +371,15 @@ int wolfCLU_setup(int argc, char** argv, char action) } if (inCheck == 0 && encCheck == 1) { - ret = 0; - while (ret == 0) { - WOLFCLU_LOG(WOLFCLU_L0, - "-in flag was not set, please enter a string or" - " file name to be encrypted: "); - if (fgets(inName, sizeof(inName), stdin) == NULL) { - /* EOF or read error: cannot prompt further */ - wolfCLU_LogError("failed to read input file name"); - wolfCLU_freeBins(pwdKey, iv, key, NULL, NULL); - if (mode != NULL) - XFREE(mode, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFCLU_FATAL_ERROR; - } - /* If no newline is present, the line was too long: flush and - * re-prompt rather than proceeding with a truncated filename. */ - if (strchr(inName, '\n') == NULL) { - int ch; - do { - ch = getchar(); - } while (ch != '\n' && ch != EOF); - wolfCLU_LogError("input too long, please try again"); - continue; - } - inName[strcspn(inName, "\r\n")] = '\0'; - /* Do not accept an empty string as valid input */ - if (inName[0] == '\0') { - wolfCLU_LogError("empty input, please enter a file name"); - continue; - } - ret = 1; + ret = wolfCLU_readFilename(inName, sizeof(inName), + "-in flag was not set, please enter a string or" + " file name to be encrypted: "); + if (ret != WOLFCLU_SUCCESS) { + wolfCLU_freeBins(pwdKey, iv, key, NULL, NULL); + if (mode != NULL) + XFREE(mode, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + return WOLFCLU_FATAL_ERROR; } - in = inName; WOLFCLU_LOG(WOLFCLU_L0, "Encrypting :\"%s\"", inName); inCheck = 1; } @@ -417,34 +423,15 @@ int wolfCLU_setup(int argc, char** argv, char action) } else { if (outCheck == 0) { - ret = 0; - while (ret == 0) { - WOLFCLU_LOG(WOLFCLU_L0, - "Please enter a name for the output file: "); - if (fgets(outNameEnc, sizeof(outNameEnc), stdin) == NULL) { - /* EOF or read error: cannot prompt further */ - wolfCLU_LogError("failed to read output file name"); - wolfCLU_freeBins(pwdKey, iv, key, NULL, NULL); - if (mode != NULL) - XFREE(mode, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFCLU_FATAL_ERROR; - } - if (strchr(outNameEnc, '\n') == NULL) { - int ch; - do { - ch = getchar(); - } while (ch != '\n' && ch != EOF); - wolfCLU_LogError("input too long, please try again"); - continue; - } - outNameEnc[strcspn(outNameEnc, "\r\n")] = '\0'; - if (outNameEnc[0] == '\0') { - wolfCLU_LogError("empty input, please enter a file name"); - continue; - } - out = outNameEnc; - ret = 1; + ret = wolfCLU_readFilename(outNameEnc, sizeof(outNameEnc), + "Please enter a name for the output file: "); + if (ret != WOLFCLU_SUCCESS) { + wolfCLU_freeBins(pwdKey, iv, key, NULL, NULL); + if (mode != NULL) + XFREE(mode, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + return WOLFCLU_FATAL_ERROR; } + out = outNameEnc; } ret = wolfCLU_encrypt(alg, mode, pwdKey, key, keySize, in, out, iv, block, ivCheck, inputHex); @@ -460,34 +447,15 @@ int wolfCLU_setup(int argc, char** argv, char action) } else { if (outCheck == 0) { - ret = 0; - while (ret == 0) { - WOLFCLU_LOG(WOLFCLU_L0, - "Please enter a name for the output file: "); - if (fgets(outNameDec, sizeof(outNameDec), stdin) == NULL) { - /* EOF or read error: cannot prompt further */ - wolfCLU_LogError("failed to read output file name"); - wolfCLU_freeBins(pwdKey, iv, key, NULL, NULL); - if (mode != NULL) - XFREE(mode, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFCLU_FATAL_ERROR; - } - if (strchr(outNameDec, '\n') == NULL) { - int ch; - do { - ch = getchar(); - } while (ch != '\n' && ch != EOF); - wolfCLU_LogError("input too long, please try again"); - continue; - } - outNameDec[strcspn(outNameDec, "\r\n")] = '\0'; - if (outNameDec[0] == '\0') { - wolfCLU_LogError("empty input, please enter a file name"); - continue; - } - out = outNameDec; - ret = 1; + ret = wolfCLU_readFilename(outNameDec, sizeof(outNameDec), + "Please enter a name for the output file: "); + if (ret != WOLFCLU_SUCCESS) { + wolfCLU_freeBins(pwdKey, iv, key, NULL, NULL); + if (mode != NULL) + XFREE(mode, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + return WOLFCLU_FATAL_ERROR; } + out = outNameDec; } ret = wolfCLU_decrypt(alg, mode, pwdKey, key, keySize, in, out, iv, block, keyType); diff --git a/tests/encrypt/enc-test.sh b/tests/encrypt/enc-test.sh index 2ade072d..234b6e02 100755 --- a/tests/encrypt/enc-test.sh +++ b/tests/encrypt/enc-test.sh @@ -295,5 +295,51 @@ if [ $? -eq 0 ]; then rm -f test-cam-empty.enc test-cam-empty.dec fi +# Test: 'input too long' path — inName buffer overflow prevention +# Pipe a 255-char line (no newline within fgets buffer), triggering the +# strchr(buf,'\n')==NULL flush branch, then supply a valid filename. +LONG_INPUT=$(printf '%255s' ' ') +printf "%s\ncerts/crl.der\n" "$LONG_INPUT" | \ + ./wolfssl enc -aes-128-cbc -out test-toolong-in.enc -k "testpass" > /dev/null 2>&1 +if [ $? != 0 ]; then + echo "Failed: enc should recover and accept filename after too-long input (-in path)" + exit 99 +fi +./wolfssl enc -d -aes-128-cbc -in test-toolong-in.enc -out test-toolong-in.dec -k "testpass" > /dev/null 2>&1 +diff certs/crl.der test-toolong-in.dec > /dev/null 2>&1 +if [ $? != 0 ]; then + echo "Failed: enc/dec roundtrip mismatch after too-long re-prompt (-in path)" + exit 99 +fi +rm -f test-toolong-in.enc test-toolong-in.dec + +# Test: 'input too long' path — outNameEnc/outNameDec (non-EVP path, Camellia) +./wolfssl enc -camellia-128-cbc -in certs/crl.der -out test-cam-probe3.enc -k "testpass" > /dev/null 2>&1 +if [ $? -eq 0 ]; then + rm -f test-cam-probe3.enc + + # outNameEnc: too-long input flushed, then valid output name accepted + printf "%s\ntest-cam-toolong.enc\n" "$LONG_INPUT" | \ + ./wolfssl enc -camellia-128-cbc -in certs/crl.der -k "testpass" > /dev/null 2>&1 + if [ $? != 0 ]; then + echo "Failed: Camellia enc should recover after too-long output name (outNameEnc)" + exit 99 + fi + + # outNameDec: too-long input flushed, then valid output name accepted + printf "%s\ntest-cam-toolong.dec\n" "$LONG_INPUT" | \ + ./wolfssl enc -d -camellia-128-cbc -in test-cam-toolong.enc -k "testpass" > /dev/null 2>&1 + if [ $? != 0 ]; then + echo "Failed: Camellia dec should recover after too-long output name (outNameDec)" + exit 99 + fi + diff certs/crl.der test-cam-toolong.dec > /dev/null 2>&1 + if [ $? != 0 ]; then + echo "Failed: enc/dec roundtrip mismatch after too-long re-prompt (outNameEnc/Dec)" + exit 99 + fi + rm -f test-cam-toolong.enc test-cam-toolong.dec +fi + echo "Done" exit 0