diff --git a/java_console/io/io.iml b/java_console/io/io.iml index de09d6d820..898ecf78d2 100644 --- a/java_console/io/io.iml +++ b/java_console/io/io.iml @@ -16,5 +16,6 @@ + \ No newline at end of file diff --git a/java_console/io/src/main/java/com/rusefi/io/tcp/BinaryProtocolServer.java b/java_console/io/src/main/java/com/rusefi/io/tcp/BinaryProtocolServer.java index be56a80b14..8d2aa2cf6c 100644 --- a/java_console/io/src/main/java/com/rusefi/io/tcp/BinaryProtocolServer.java +++ b/java_console/io/src/main/java/com/rusefi/io/tcp/BinaryProtocolServer.java @@ -7,8 +7,8 @@ import com.rusefi.binaryprotocol.*; import com.rusefi.config.generated.Fields; import com.rusefi.io.LinkManager; import com.rusefi.io.commands.HelloCommand; +import com.rusefi.server.rusEFISSLContext; -import javax.net.ssl.SSLServerSocketFactory; import java.io.*; import java.net.ServerSocket; import java.net.Socket; @@ -18,7 +18,8 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; import static com.rusefi.binaryprotocol.IoHelper.swap16; -import static com.rusefi.config.generated.Fields.*; +import static com.rusefi.config.generated.Fields.TS_PROTOCOL; +import static com.rusefi.config.generated.Fields.TS_RESPONSE_BURN_OK; /** * This class makes rusEfi console a proxy for other tuning software, this way we can have two tools connected via same @@ -35,13 +36,7 @@ public class BinaryProtocolServer implements BinaryProtocolCommands { public AtomicInteger unknownCommands = new AtomicInteger(); - public static final Function SECURE_SOCKET_FACTORY = port -> { - try { - return SSLServerSocketFactory.getDefault().createServerSocket(port); - } catch (IOException e) { - throw new IllegalStateException("Error binding secure server socket " + port, e); - } - }; + public static final Function SECURE_SOCKET_FACTORY = rusEFISSLContext::getSSLServerSocket; public static final Function PLAIN_SOCKET_FACTORY = port -> { try { @@ -79,7 +74,7 @@ public class BinaryProtocolServer implements BinaryProtocolCommands { * * @param port server port to accept connections * @param threadName - * @param socketRunnableFactory method to invoke on a new thread for each new client connection + * @param socketRunnableFactory method to invoke on a new thread for each new client connection * @param logger * @param serverSocketCreationCallback this callback is invoked once we open the server socket */ diff --git a/java_console/io/src/main/java/com/rusefi/server/rusEFISSLContext.java b/java_console/io/src/main/java/com/rusefi/server/rusEFISSLContext.java new file mode 100644 index 0000000000..31a26959bd --- /dev/null +++ b/java_console/io/src/main/java/com/rusefi/server/rusEFISSLContext.java @@ -0,0 +1,108 @@ +package com.rusefi.server; + +import javax.net.ssl.*; +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.ServerSocket; +import java.net.Socket; +import java.security.KeyStore; +import java.security.cert.X509Certificate; + +public class rusEFISSLContext { + private static final String TLS = "TLS"; +// private static KeyStore key; + + // todo: one day once rusEFI has a proper commercial certificate this should be removed + private static TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + + public void checkClientTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + + public void checkServerTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + } + }; + + public static void init(String fileName, String password) throws MalformedURLException { + // system property setup does not work under Jenkins? + Backend.setupCertificates(new File(fileName), password); + + //key = getFromPath(fileName, "PKCS12", password); + } + + public static ServerSocket getSSLServerSocket(int port) { + try { + return SSLServerSocketFactory.getDefault().createServerSocket(port); + } catch (IOException e) { + throw new IllegalStateException("Error binding secure server socket " + port, e); + } +// try { +// return getSSLServerSocketFactory(key, TLS).createServerSocket(port); +// } catch (Exception e) { +// throw new IllegalStateException(e); +// } + } + + public static Socket getSSLSocket(String host, int port) { + try { + return getSSLSocketFactory(null /*key*/, TLS).createSocket(host, port); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + + /* + private static SSLServerSocketFactory getSSLServerSocketFactory(KeyStore trustKey, String sslAlgorithm) { + try { + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(trustKey); + + SSLContext context = SSLContext.getInstance(sslAlgorithm); + context.init(null, tmf.getTrustManagers(), null); + + return context.getServerSocketFactory(); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + */ + private static SSLSocketFactory getSSLSocketFactory(KeyStore trustKey, String sslAlgorithm) { + try { +// TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); +// tmf.init(trustKey); + + SSLContext context = SSLContext.getInstance(sslAlgorithm); + context.init(null, trustAllCerts/*tmf.getTrustManagers()*/, null); + + return context.getSocketFactory(); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } +/* + private static KeyStore getFromPath(String path, String algorithm, String filePassword) { + try { + File f = new File(path); + + if (!f.exists()) + throw new RuntimeException("File not found: " + path); + + FileInputStream keyFile = new FileInputStream(f); + KeyStore keystore = KeyStore.getInstance(algorithm); + keystore.load(keyFile, filePassword.toCharArray()); + keyFile.close(); + + return keystore; + } catch (Exception e) { + throw new IllegalStateException(e); + } + } +*/ +} diff --git a/java_console/ui/src/test/java/com/rusefi/ServerTest.java b/java_console/ui/src/test/java/com/rusefi/ServerTest.java index ea67f5b2d0..c8cfb804d6 100644 --- a/java_console/ui/src/test/java/com/rusefi/ServerTest.java +++ b/java_console/ui/src/test/java/com/rusefi/ServerTest.java @@ -15,7 +15,6 @@ import com.rusefi.tools.online.ProxyClient; import org.junit.Before; import org.junit.Test; -import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.util.List; @@ -43,8 +42,7 @@ public class ServerTest { public void setTestCertificate() throws MalformedURLException { NetworkConnector.RUSEFI_PROXY_HOSTNAME = ProxyClient.LOCALHOST; - File certificate = new File("certificate/test_pkcs12.jks"); - Backend.setupCertificates(certificate, "password"); + rusEFISSLContext.init("certificate/test_pkcs12.jks", "password"); } @Test diff --git a/java_tools/proxy_server/src/main/java/com/rusefi/LocalApplicationProxy.java b/java_tools/proxy_server/src/main/java/com/rusefi/LocalApplicationProxy.java index 1ca750481f..62bca0b254 100644 --- a/java_tools/proxy_server/src/main/java/com/rusefi/LocalApplicationProxy.java +++ b/java_tools/proxy_server/src/main/java/com/rusefi/LocalApplicationProxy.java @@ -7,6 +7,7 @@ import com.rusefi.io.tcp.BinaryProtocolProxy; import com.rusefi.io.tcp.TcpIoStream; import com.rusefi.proxy.NetworkConnector; import com.rusefi.server.ApplicationRequest; +import com.rusefi.server.rusEFISSLContext; import javax.net.ssl.SSLSocketFactory; import java.io.IOException; @@ -26,7 +27,7 @@ public class LocalApplicationProxy { * @param authenticatorPort local port we would bind for TunerStudio to connect to */ static void startAndRun(Logger logger, int serverPortForRemoteUsers, ApplicationRequest applicationRequest, int authenticatorPort) throws IOException { - IoStream authenticatorToProxyStream = new TcpIoStream(logger, SSLSocketFactory.getDefault().createSocket(NetworkConnector.RUSEFI_PROXY_HOSTNAME, serverPortForRemoteUsers)); + IoStream authenticatorToProxyStream = new TcpIoStream(logger, rusEFISSLContext.getSSLSocket(NetworkConnector.RUSEFI_PROXY_HOSTNAME, serverPortForRemoteUsers)); LocalApplicationProxy localApplicationProxy = new LocalApplicationProxy(logger, applicationRequest); localApplicationProxy.run(authenticatorToProxyStream); diff --git a/java_tools/proxy_server/src/main/java/com/rusefi/proxy/NetworkConnector.java b/java_tools/proxy_server/src/main/java/com/rusefi/proxy/NetworkConnector.java index 79ed9175ca..17af730950 100644 --- a/java_tools/proxy_server/src/main/java/com/rusefi/proxy/NetworkConnector.java +++ b/java_tools/proxy_server/src/main/java/com/rusefi/proxy/NetworkConnector.java @@ -5,12 +5,11 @@ import com.rusefi.io.IoStream; import com.rusefi.io.commands.HelloCommand; import com.rusefi.io.tcp.BinaryProtocolServer; import com.rusefi.io.tcp.TcpIoStream; -import com.rusefi.proxy.BaseBroadcastingThread; import com.rusefi.server.ControllerInfo; import com.rusefi.server.SessionDetails; +import com.rusefi.server.rusEFISSLContext; import org.jetbrains.annotations.NotNull; -import javax.net.ssl.SSLSocketFactory; import java.io.IOException; /** @@ -29,7 +28,7 @@ public class NetworkConnector { SessionDetails deviceSessionDetails = new SessionDetails(ci, authToken, SessionDetails.createOneTimeCode()); - BaseBroadcastingThread baseBroadcastingThread = new BaseBroadcastingThread(SSLSocketFactory.getDefault().createSocket(RUSEFI_PROXY_HOSTNAME, serverPortForControllers), + BaseBroadcastingThread baseBroadcastingThread = new BaseBroadcastingThread(rusEFISSLContext.getSSLSocket(RUSEFI_PROXY_HOSTNAME, serverPortForControllers), deviceSessionDetails, logger) { @Override