From ad115fa4e589fa37cd97b7060ab3ec3c6fc953ae Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Wed, 25 Mar 2026 07:33:04 +0900 Subject: [PATCH 1/3] fix compile and unit test failure --- src/x509/clu_x509_sign.c | 24 +++++++++++++++--------- tests/ocsp/ocsp-interop-test.sh | 2 +- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/x509/clu_x509_sign.c b/src/x509/clu_x509_sign.c index 7d5625cd..ab409042 100644 --- a/src/x509/clu_x509_sign.c +++ b/src/x509/clu_x509_sign.c @@ -257,7 +257,7 @@ int wolfCLU_GenChimeraCertSign(WOLFSSL_BIO *bioCaKey, WOLFSSL_BIO *bioAltCaKey, const char *altSigAlgOid = "2.5.29.73"; const char *altSigValOid = "2.5.29.74"; - /* + /* * LARGE_TEMO_SZ defines the size of temporary buffers used for signature key, * verification key and signature value buffers. * The value 11264 is enough for P-521 and ML-DSA-87 PEM certs. @@ -397,7 +397,7 @@ int wolfCLU_GenChimeraCertSign(WOLFSSL_BIO *bioCaKey, WOLFSSL_BIO *bioAltCaKey, ret = WOLFCLU_FATAL_ERROR; } } - + if (ret == 0) { XMEMSET(caKeyBuf, 0, caKeySz); /* clear original buffer */ caKeySz = derObj->length; @@ -667,13 +667,13 @@ int wolfCLU_GenChimeraCertSign(WOLFSSL_BIO *bioCaKey, WOLFSSL_BIO *bioAltCaKey, if (ret == WOLFCLU_SUCCESS) { switch (level) { - case 2: + case 2: newCert.sigType = CTC_SHA256wECDSA; break; - case 3: + case 3: newCert.sigType = CTC_SHA384wECDSA; break; - case 5: + case 5: newCert.sigType = CTC_SHA512wECDSA; break; } @@ -691,7 +691,7 @@ int wolfCLU_GenChimeraCertSign(WOLFSSL_BIO *bioCaKey, WOLFSSL_BIO *bioAltCaKey, else { ret = WOLFCLU_SUCCESS; } - } + } } if (ret == WOLFCLU_SUCCESS) { @@ -715,7 +715,7 @@ int wolfCLU_GenChimeraCertSign(WOLFSSL_BIO *bioCaKey, WOLFSSL_BIO *bioAltCaKey, } if (ret == WOLFCLU_SUCCESS && isCA) { - ret = wc_MakeCert(&newCert, scratchBuf, + ret = wc_MakeCert(&newCert, scratchBuf, scratchSz, NULL, &caKey, &rng); if (ret <= 0) { wolfCLU_LogError("Error making certificate"); @@ -732,7 +732,7 @@ int wolfCLU_GenChimeraCertSign(WOLFSSL_BIO *bioCaKey, WOLFSSL_BIO *bioAltCaKey, scratchSz = ret; ret = WOLFCLU_SUCCESS; } - } + } } else if (ret == WOLFCLU_SUCCESS && !isCA) { ret = wc_MakeCert(&newCert, scratchBuf, scratchSz, @@ -1274,7 +1274,13 @@ int wolfCLU_CertSign(WOLFCLU_CERT_SIGN* csign, WOLFSSL_X509* x509) case WC_HASH_TYPE_BLAKE2B: case WC_HASH_TYPE_BLAKE2S: - #if LIBWOLFSSL_VERSION_HEX > 0x05001000 + #if LIBWOLFSSL_VERSION_HEX >= 0x05009000 + case WC_HASH_TYPE_SHA512_224: + case WC_HASH_TYPE_SHA512_256: + case WC_HASH_TYPE_SHAKE128: + case WC_HASH_TYPE_SHAKE256: + case WC_HASH_TYPE_SM3: + #elif LIBWOLFSSL_VERSION_HEX > 0x05001000 #ifndef WOLFSSL_NOSHA512_224 case WC_HASH_TYPE_SHA512_224: #endif diff --git a/tests/ocsp/ocsp-interop-test.sh b/tests/ocsp/ocsp-interop-test.sh index 49c8a75a..2ceda899 100755 --- a/tests/ocsp/ocsp-interop-test.sh +++ b/tests/ocsp/ocsp-interop-test.sh @@ -293,7 +293,7 @@ if [ $RESULT = 0 ]; then fi # Check for error message -grep -qi "fail\|error\|not found\|unable" "$TEST_DIR/test6.log" +grep -qi "fail\|error\|not found\|unable\|no such\|could not" "$TEST_DIR/test6.log" if [ $? != 0 ]; then echo "Test 6 failed: expected error message about invalid file" exit 99 From 4341bf6455f9100661938677ab03357c09ff2e1e Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Fri, 27 Mar 2026 09:02:42 +0900 Subject: [PATCH 2/3] fix shell command injection --- src/client/client.c | 11 +++++++++++ tests/client/client-test.sh | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/client/client.c b/src/client/client.c index 61fcf117..9a58721b 100644 --- a/src/client/client.c +++ b/src/client/client.c @@ -147,6 +147,17 @@ static WC_INLINE void clu_build_addr(SOCKADDR_IN4_T* addr, SOCKADDR_IN6_T* ipv6, FILE* fp; char host_out[100]; char cmd[100]; + const char* cp; + + /* Validate hostname: only allow characters valid in DNS names + * (RFC 1123) to prevent shell injection via popen(). */ + for (cp = peer; *cp != '\0'; cp++) { + if (!isalnum((unsigned char)*cp) && + *cp != '.' && *cp != '-') { + err_sys("invalid character in hostname"); + return; + } + } XSTRNCPY(cmd, "host ", 6); XSTRNCAT(cmd, peer, 99 - XSTRLEN(cmd)); diff --git a/tests/client/client-test.sh b/tests/client/client-test.sh index 88297c2d..968eacb1 100755 --- a/tests/client/client-test.sh +++ b/tests/client/client-test.sh @@ -25,5 +25,39 @@ fi rm tmp.crt +# Regression tests: shell injection via hostname must not execute injected command. +# Applies to the WOLFSSL_USE_POPEN_HOST path where peer is concatenated into a +# popen() shell command. On other builds, getaddrinfo/gethostbyname reject +# these hostnames before any shell is involved, so the tests pass either way. +INJFILE="clu_injection_probe.txt" +rm -f "$INJFILE" + +# Semicolon: "evil.com;touch clu_injection_probe.txt" passed as peer +./wolfssl s_client -connect 'evil.com;touch clu_injection_probe.txt:443' \ + 2>/dev/null +if [ -f "$INJFILE" ]; then + echo "SECURITY FAILURE: command injection via hostname (semicolon)" + rm -f "$INJFILE" + exit 99 +fi + +# Command substitution: "$(touch clu_injection_probe.txt)" passed as peer +./wolfssl s_client -connect '$(touch clu_injection_probe.txt):443' \ + 2>/dev/null +if [ -f "$INJFILE" ]; then + echo "SECURITY FAILURE: command injection via hostname (command substitution)" + rm -f "$INJFILE" + exit 99 +fi + +# Pipe: "evil.com|touch clu_injection_probe.txt" passed as peer +./wolfssl s_client -connect 'evil.com|touch clu_injection_probe.txt:443' \ + 2>/dev/null +if [ -f "$INJFILE" ]; then + echo "SECURITY FAILURE: command injection via hostname (pipe)" + rm -f "$INJFILE" + exit 99 +fi + echo "Done" exit 0 From 566a39f16f2302b9100c54d73cdc6e4405cd3c88 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Fri, 27 Mar 2026 09:48:43 +0900 Subject: [PATCH 3/3] addressed copilot review comments --- src/client/client.c | 2 ++ tests/client/client-test.sh | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/client/client.c b/src/client/client.c index 9a58721b..46c3ce75 100644 --- a/src/client/client.c +++ b/src/client/client.c @@ -34,6 +34,8 @@ #endif #include +#include + #include #include diff --git a/tests/client/client-test.sh b/tests/client/client-test.sh index 968eacb1..00e6a329 100755 --- a/tests/client/client-test.sh +++ b/tests/client/client-test.sh @@ -42,7 +42,7 @@ if [ -f "$INJFILE" ]; then fi # Command substitution: "$(touch clu_injection_probe.txt)" passed as peer -./wolfssl s_client -connect '$(touch clu_injection_probe.txt):443' \ +./wolfssl s_client -connect 'evil$(touch clu_injection_probe.txt).com:443' \ 2>/dev/null if [ -f "$INJFILE" ]; then echo "SECURITY FAILURE: command injection via hostname (command substitution)"