Skip to content

wolfjsse netty-tests#6

Open
JeremiahM37 wants to merge 2 commits intowolfSSL:mainfrom
JeremiahM37:netty-tests
Open

wolfjsse netty-tests#6
JeremiahM37 wants to merge 2 commits intowolfSSL:mainfrom
JeremiahM37:netty-tests

Conversation

@JeremiahM37
Copy link

@JeremiahM37 JeremiahM37 commented Dec 31, 2025

Add Netty SSL test image for wolfJSSE FIPS
Docker image that runs upstream Netty SSL tests with wolfJSSE in FIPS mode.
-Clones Netty 4.1.115.Final and applies FIPS compatibility patches via shell script
-Runs handler, handler-proxy, and testsuite modules (~800 tests after unsupported fips tests removed)
-Skips OpenSSL-specific tests and FIPS-incompatible algorithms (MD5, 3DES, etc)
-Uses wolfSSL example certs (fetched from GitHub during build)

Remaining disabled tests due to:

  1. Wrong provider (~200 of Netty's skips) — tests for OpenSSL, BoringSSL, Conscrypt,
      Amazon Corretto. These are other SSL providers that aren't installed. SunJSSE would
      skip these too.
      2. FIPS restrictions — algorithms/ciphers not allowed in FIPS mode (MD5, RC4, export
      ciphers, etc.). This is by design — FIPS compliance requires disabling insecure
      algorithms.
      3. Configure flags not enabled — SNI (--enable-sni), OCSP stapling. These could be
      enabled with different configure options but aren't in the current FIPS base image.
      4. InsecureTrustManagerFactory — Netty's client-side tests that bypass certificate
      verification. wolfJSSE in FIPS mode doesn't support skipping cert validation. This is a
       security feature, not a deficiency.
      5. Compiled jar dependencies — Spring Boot's Reactor Netty tests use
      InsecureTrustManagerFactory in pre-compiled jars that can't be patched.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a Docker test image for running upstream Netty SSL tests with wolfJSSE in FIPS mode. The implementation clones Netty 4.1.115.Final, applies FIPS compatibility patches, and configures the environment to run approximately 800 SSL tests using wolfSSL example certificates.

Key changes:

  • Adds build infrastructure and FIPS compatibility patch script for Netty testing
  • Replaces Netty's self-signed certificates with wolfSSL example certificates
  • Skips OpenSSL-specific tests and FIPS-incompatible algorithms (MD5, 3DES, weak ciphers)

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 13 comments.

File Description
build.sh Build script with argument parsing, Docker image validation, and build orchestration for the Netty test container
apply_netty_fips_fixes.sh Comprehensive patching script that modifies Netty source for wolfJSSE FIPS compatibility - replaces certificates, reorders cipher suites, disables incompatible tests
Dockerfile Multi-stage Docker build that compiles patched Netty, installs wolfSSL certificates, and creates test runner script
README.md Documentation with build instructions and usage examples for running the Netty test suite

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

sed -i '/public void testTLSv13DisabledIfNoValidCipherSuiteConfigured(/i \ @Disabled("wolfJSSE: TLS 1.3 prioritization differs")' "$SSLENGINE_TEST"
sed -i '/public void testSupportedSignatureAlgorithms(/i \ @Disabled("wolfJSSE: Signature algorithm handling differs")' "$SSLENGINE_TEST"

# Session handling tests
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we verify that these session handling test failures are not things we need to fix in wolfJSSE?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These session handling tests (testSessionCache, testSessionAfterHandshake, etc.) pass on non-FIPS wolfJSSE and only fail in fips mode.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to identify the exact reason why this is different. wolfCrypt FIPS enforces different algorithms (non-validated algorithms are not enabled), but I don't see how that would affect session handling. TLS logic is outside the FIPS boundary, which is why I think we need to dig into identifying the root cause here to confirm our wolfJSSE FIPS build does not have a bug.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These were real wolfJSSE session-cache/session-timeout bugs, not a FIPS-only difference. Addressed by session cache/timeout fixes

@cconlon
Copy link
Member

cconlon commented Jan 7, 2026

When I run this following the README steps, I see the following which looks like two tests have errors:

[INFO] Results:
[INFO]
[ERROR] Errors:
[ERROR]   SocketSslGreetingTest.testSslGreeting » Timeout testSslGreeting(io.netty.handl...
[ERROR]   SocketSslGreetingTest.testSslGreeting » Timeout testSslGreeting(io.netty.handl...
[INFO]
[ERROR] Tests run: 167, Failures: 0, Errors: 2, Skipped: 9
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  08:29 min
[INFO] Finished at: 2026-01-07T00:18:25Z
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.2:test (default-test) on project netty-testsuite: There are test failures.
[ERROR]
[ERROR] Please refer to /app/netty/testsuite/target/surefire-reports for the individual test results.
[ERROR] Please refer to dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstream.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

============================================================
=== AGGREGATE TEST SUMMARY (all mvn runs) ===
============================================================
- handler: [WARNING] Tests run: 497, Failures: 0, Errors: 0, Skipped: 158
- handler-proxy: [INFO] Tests run: 55, Failures: 0, Errors: 0, Skipped: 0
- testsuite: [ERROR] Tests run: 167, Failures: 0, Errors: 2, Skipped: 9

TOTAL: Tests run: 719, Failures: 0, Errors: 2, Skipped: 167

========================================
=== ALL TESTS COMPLETE ===
========================================
Some tests failed. Check logs above.

Earlier in the test log I also saw this OutOfMemoryError show up. Is this expected?

00:02:13.410 [main] DEBUG io.netty.handler.ssl.SslHandler - [id: 0xembedded, L:embedded - R:embedded] HANDSHAKEN: protocol:NONE cipher suite:NONE
00:02:15.414 [nioEventLoopGroup-176-3] DEBUG io.netty.buffer.PoolThreadCache - Freed 13 thread-local buffer(s) from thread: nioEventLoopGroup-176-3
00:02:15.414 [nioEventLoopGroup-176-2] DEBUG io.netty.buffer.PoolThreadCache - Freed 10 thread-local buffer(s) from thread: nioEventLoopGroup-176-2
Jan 07, 2026 12:09:04 AM org.junit.platform.launcher.core.DefaultLauncher handleThrowable
WARNING: TestEngine with ID 'junit-jupiter' failed to execute tests
java.lang.OutOfMemoryError: Java heap space

[INFO]
[INFO] Results:
[INFO]
[WARNING] Tests run: 497, Failures: 0, Errors: 0, Skipped: 158
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  12:31 min
[INFO] Finished at: 2026-01-07T00:09:34Z
[INFO] ------------------------------------------------------------------------

@JeremiahM37
Copy link
Author

Fixed the 2 failing tests (cert issue) and fixed the java heap space issue. At the end of the handler test I still get "There was a timeout or other error in the fork" but I have confirmed that it is running all of the tests we haven't disabled, and this only happens during the shutdown, and it does not happen on the non fips mode.

@JeremiahM37
Copy link
Author

Fixed the out of memory, jvm fork still crashes after tests have all run, but this is expected as it happens for sunjsse as well when I run individual test modules.

@JeremiahM37 JeremiahM37 assigned cconlon and unassigned JeremiahM37 Jan 19, 2026
@JeremiahM37 JeremiahM37 requested a review from cconlon February 11, 2026 17:41
Copy link
Member

@cconlon cconlon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I run

# 0b. Replace encrypted key references with unencrypted keys in all test files
# wolfSSL encrypted keys use different password than "12345" expected by tests
# ------------------------------------------------------------------------------
echo "Replacing encrypted key references with unencrypted keys..."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It sounds like the original encrypted keys used non-FIPS compliant algorithms? Did we consider replacing them with other encrypted keys that used algorithms in the FIPS boundary? It seems like we may lose some test coverage here around decryption of encrypted keys in FIPS mode.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced non-FIPS encrypted keys; 2 JDK-context PBES2 tests stay skipped as those tests tested specifically for those.


# ------------------------------------------------------------------------------
# 1. Patch InsecureTrustManagerFactory.java (minimal change)
# Only modify getAcceptedIssuers() to return CA cert instead of empty array
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was the root cause of why we need this change with wolfJSSE? I would generally think that wolfJSSE used with an "insecure" TrustManagerFactory should skip peer verification just like any other JSSE provider.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue was wolfJSSE verification callback behavior with external TrustManagers (including empty accepted issuers / InsecureTMF paths). I fixed the wolfJSSE verify callback path so Java TrustManager verification runs as expected instead of failing early in native verification.

\/\/ AES256 requires JCE unlimited strength jurisdiction policy files\.
defaultCiphers\.add\("TLS_RSA_WITH_AES_256_CBC_SHA"\);/ Set<String> defaultCiphers = new LinkedHashSet<String>();
\/\/ FIPS: TLS 1.3 ciphers FIRST - they work with any cert type and
\/\/ avoid non-blocking handshake issues that affect TLS 1.2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What were the TLS 1.2 non-blocking handshake issues? We do have wolfJSSE FIPS users who will be using TLS 1.2, so we should be precise in the reason here to identify if this is something we need to fix in wolfJSSE+FIPS combo.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No TLS 1.2 protocol bug. The failures were test infrastructure issues: GC logging corrupting Surefire output and heap pressure/OOM in large parameterized runs.

if ! grep -q "import org.junit.jupiter.api.Disabled;" "$TRUSTMGR_TEST"; then
sed -i '/^package /a import org.junit.jupiter.api.Disabled;' "$TRUSTMGR_TEST"
fi
sed -i '/^public class SslContextTrustManagerTest/i @Disabled("FIPS: Test certs not in FIPS native trust store")' "$TRUSTMGR_TEST"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know why the test certs were not in the native store? The base image here does have the $JAVA_HOME/lib/security/cacerts converted to WKS format, which might make a difference in the test depending on if it is trying to load the JKS version mabye?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It uses cross-signed certs. Cross-signed cert path needs WOLFSSL_ALT_CERT_CHAINS, not enabled in base image.

sed -i '/public void testHandshakeCompletesWithoutFilteringSupportedCipher(/i \ @Disabled("FIPS: TLS 1.0/1.1 not supported")' "$SSLENGINE_TEST"

# Hostname verification tests - FIPS uses pre-generated wolfSSL certs with CN=www.wolfssl.com
# Test expects localhost but FIPS environment requires approved cert generation
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we adjust these tests to expect "www.wolfssl.com" instead of "localhost", and then allow them to run?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are specifically intended for localhost. Generated proper localhost SAN cert and re-enabled hostname tests.

sed -i '/public void testClientHostnameValidationSuccess(/i \ @Disabled("FIPS: Cert CN is www.wolfssl.com, test expects localhost")' "$SSLENGINE_TEST"
sed -i '/public void testClientHostnameValidationFail(/i \ @Disabled("FIPS: Cert CN is www.wolfssl.com, test expects localhost")' "$SSLENGINE_TEST"

# Buffer handling tests - FIPS wolfSSL has different buffer state machine behavior
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should evaluate each of these tests to make sure we do not need to modify our buffer handling flow before just skipping them. Was that analysis already done?

Essentially we will want to make sure that our behavior will not break SSLEngine applications. If we can prove that it will not, and the test is written to test SunJSSE-specific behavior, then it is ok to skip. But, if it is something that will break real-world use cases, we should think about if this is something wolfJSSE needs to fix.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The failures exposed real wolfJSSE SSLEngine bugs (BUFFER_UNDERFLOW partial-record handling, BUFFER_OVERFLOW output handling, and verify callback behavior), which were fixed in wolfssljni.

fi

# Patch newTestParams to skip TLS 1.2 when wolfJSSE detected (using perl for multi-line)
echo " Patching SSLEngineTest to skip TLS 1.2 test params..."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like above, TLS 1.2 should work ok with wolfJSSE and FIPS. We should dig into why these tests were failing to find the root cause.

Copy link
Author

@JeremiahM37 JeremiahM37 Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as earlier: infrastructure/OOM + logging issue

fi
# FIPS environment uses pre-generated wolfSSL certs with CN=www.wolfssl.com
# SNI tests expect dynamic certs matching the requested hostname
sed -i '/^public class SniClientTest/i @Disabled("FIPS: Uses wolfSSL certs with fixed CN, SNI tests expect dynamic hostnames")' "$SNI_CLIENT_TEST"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we adjust the test to try and match "www.wolfssl.com" instead of skipping?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Root cause was first that Netty creates the client engine with newEngine(..., sniHostName, -1) and wolfJSSE rejected port < 0 (Bad argument). After fixing that,I also fixed server SSLEngine handshake-session SNI availability and non-null ExtendedSSLSession signature algorithm arrays so the class can run. Still left 2 tests disabled due to algorithm assertions.

sed -i '/import java.security.cert.CertificateException;/a import java.security.Security;' "$SSLECHO_TEST"
fi

# Add InsecureTrustManagerFactory import
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we switching this away from certificate verification to skipping verification (InsecureTrustManagerFactory)? If cert verification was failing, we should determine why. We might need to use a cert with a FIPS-compliant algorithm, load a different root CA, etc.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed wolfJSSE verification behavior instead. The InsecureTMF workaround was removed and proper certificate verification is used again.

fi

# Use InsecureTrustManagerFactory instead of CERT_FILE
sed -i 's/\.trustManager(CERT_FILE)/.trustManager(InsecureTrustManagerFactory.INSTANCE)/g' "$SSLREUSE_TEST"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above here, why are we skipping cert verification?

Copy link
Author

@JeremiahM37 JeremiahM37 Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wolfJSSE fix. workaround removed

@cconlon cconlon assigned JeremiahM37 and unassigned cconlon Feb 11, 2026
@JeremiahM37 JeremiahM37 force-pushed the netty-tests branch 2 times, most recently from ef180f4 to 92f1dc1 Compare February 23, 2026 06:05
@JeremiahM37 JeremiahM37 assigned cconlon and unassigned JeremiahM37 Feb 24, 2026
@JeremiahM37 JeremiahM37 force-pushed the netty-tests branch 4 times, most recently from 3212466 to b6fef38 Compare February 25, 2026 17:42
@JeremiahM37 JeremiahM37 force-pushed the netty-tests branch 3 times, most recently from 5ed8fcb to 14c4e31 Compare March 6, 2026 23:41
@JeremiahM37
Copy link
Author

JeremiahM37 commented Mar 11, 2026

There are a few wolfjsse gaps still, but these would warrant a much separate, larger pr, as they are full feature implementations. The test coverage these features provide is also very low (about 4 tests)

Certificate Chains: getPeerCertificates() currently only returns the leaf. Needs a JNI wrapper for the existing native wolfSSL_get_peer_cert_chain() to fetch the full chain.

Signature Algorithms: getPeerSupportedSignatureAlgorithms() returns an empty array. This requires implementing a new native API, wolfSSL_get_peer_sigalgs(), as it does not yet exist in the core library.

SNI Matching: SNIMatcher.matches() currently triggers post-handshake. To meet test expectations for an unrecognized_name alert during the handshake, the matcher must be integrated directly into the native SNI callback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants