Use X509ExtendedTrustManager to avoid JDK AlgorithmChecker constraints

Netty 4.2.15 fixed CVE-2026-50010 by removing the silent wrapping of
plain X509TrustManager in X509ExtendedTrustManager. When a plain
X509TrustManager is used, the JDK wraps it in AbstractTrustManagerWrapper
and runs TrustManagerImpl.checkTrusted() with AlgorithmChecker before
calling the custom trust manager.

This caused client certificates signed with SHA3-512withECDSA to be
rejected even though they are not explicitly blacklisted in java.security,
because the JDK's internal PKIX validator applies stricter constraints.

By making our custom trust managers implement X509ExtendedTrustManager
directly, the JDK calls the 3-arg methods directly and bypasses its
internal TrustManagerImpl, restoring the pre-4.2.15 behavior where
only our custom PKIX validation runs.

Files changed:
- rbcs-common/RBCS.kt: getTrustManager() returns X509ExtendedTrustManager
- rbcs-client/RemoteBuildCacheClient.kt: trust-all manager uses X509ExtendedTrustManager
This commit is contained in:
opencode
2026-06-12 00:29:46 +00:00
committed by Walter Oggioni
parent 6b798f3046
commit 7dc12a37e4
2 changed files with 35 additions and 5 deletions
@@ -10,6 +10,7 @@ import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException
import java.util.concurrent.atomic.AtomicInteger
import javax.net.ssl.TrustManagerFactory
import javax.net.ssl.X509ExtendedTrustManager
import javax.net.ssl.X509TrustManager
import kotlin.random.Random
import io.netty.util.concurrent.Future as NettyFuture
@@ -74,13 +75,25 @@ class RemoteBuildCacheClient(private val profile: Configuration.Profile) : AutoC
)
profile.tlsTruststore?.let { trustStore ->
if (!trustStore.verifyServerCertificate) {
trustManager(object : X509TrustManager {
trustManager(object : X509ExtendedTrustManager() {
override fun checkClientTrusted(certChain: Array<out X509Certificate>, p1: String?) {
}
override fun checkClientTrusted(certChain: Array<out X509Certificate>, p1: String?, socket: java.net.Socket) {
}
override fun checkClientTrusted(certChain: Array<out X509Certificate>, p1: String?, engine: javax.net.ssl.SSLEngine) {
}
override fun checkServerTrusted(certChain: Array<out X509Certificate>, p1: String?) {
}
override fun checkServerTrusted(certChain: Array<out X509Certificate>, p1: String?, socket: java.net.Socket) {
}
override fun checkServerTrusted(certChain: Array<out X509Certificate>, p1: String?, engine: javax.net.ssl.SSLEngine) {
}
override fun getAcceptedIssuers() = null
})
} else {