TooTallNate / Java-WebSocket

A barebones WebSocket client and server implementation written in 100% Java.
http://tootallnate.github.io/Java-WebSocket
MIT License
10.33k stars 2.56k forks source link

[helpful] 1.3.0 upgrade to 1.5.6, trustAllHosts can not work, error: No subject alternative names matching IP address #1408

Open shenchunhang opened 1 month ago

shenchunhang commented 1 month ago

if you want to trustAllHosts , and version 1.3.0 to 1.5.6, maybe you will error (No subject alternative names matching IP address)

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names matching IP address xxxxxxxxxx found sun.security.ssl.Alert.createSSLException(Alert.java:131) sun.security.ssl.TransportContext.fatal(TransportContext.java:377) sun.security.ssl.TransportContext.fatal(TransportContext.java:320) sun.security.ssl.TransportContext.fatal(TransportContext.java:315) sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1355) sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1230) sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1173) sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:376) sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:479) sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:457) sun.security.ssl.TransportContext.dispatch(TransportContext.java:200) sun.security.ssl.SSLTransport.decode(SSLTransport.java:155) sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1320) sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1233) sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:417) sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:837) sun.security.ssl.SSLSocketImpl.access$200(SSLSocketImpl.java:76) sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:923) java.io.InputStream.read(InputStream.java:101) org.java_websocket.client.WebSocketClient.run(WebSocketClient.java:526) java.lang.Thread.run(Thread.java:750)

jdk8 old code; 1.3.0

TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {  }
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new SecureRandom());
            wsClient.setWebSocketFactory(new DefaultSSLWebSocketClientFactory(sc));
        } catch (Exception e) {
            log.error("check server trusted!", e);
        }

new code: 1.5.6 X509TrustManager -> X509ExtendedTrustManager wsClient.setWebSocketFactory(new DefaultSSLWebSocketClientFactory(sc)); -> wsClient.setSocketFactory(sc.getSocketFactory());

TrustManager[] trustAllCerts = new TrustManager[]{
                new X509ExtendedTrustManager() {  }
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new SecureRandom());
            wsClient.setSocketFactory(sc.getSocketFactory());
        } catch (Exception e) {
            log.error("check server trusted!", e);
        }

1.3.0 use SSLContextImpl, and the custom X509TrustManager cannot be used finally, DummyX509TrustManager.INSTANCE will return, so use X509ExtendedTrustManager is ok

    private X509TrustManager chooseTrustManager(TrustManager[] var1) throws KeyManagementException {
        for(int var2 = 0; var1 != null && var2 < var1.length; ++var2) {
            if (var1[var2] instanceof X509TrustManager) {
                if (SunJSSE.isFIPS() && !(var1[var2] instanceof X509TrustManagerImpl)) {
                    throw new KeyManagementException("FIPS mode: only SunJSSE TrustManagers may be used");
                }
                if (var1[var2] instanceof X509ExtendedTrustManager) {
                    return (X509TrustManager)var1[var2];
                }
                return new AbstractTrustManagerWrapper((X509TrustManager)var1[var2]);
            }
        }
        return DummyX509TrustManager.INSTANCE;
    }