diff --git a/src/fr/univ/lyon1/client/Client.java b/src/fr/univ/lyon1/client/Client.java index abb6001..ec650a1 100644 --- a/src/fr/univ/lyon1/client/Client.java +++ b/src/fr/univ/lyon1/client/Client.java @@ -1,12 +1,17 @@ package fr.univ.lyon1.client; import fr.univ.lyon1.common.Channel; +import fr.univ.lyon1.common.ChatSSL; import fr.univ.lyon1.common.Message; import fr.univ.lyon1.common.command.Command; import fr.univ.lyon1.common.command.CommandType; import fr.univ.lyon1.common.exception.ChatException; import fr.univ.lyon1.common.exception.UnknownCommand; +import javax.net.SocketFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLSocket; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; @@ -31,11 +36,24 @@ public class Client { this.port = port; this.username = username; this.password = password; - socket = new Socket(address, port); + socket = initSSL(); out = new ObjectOutputStream(socket.getOutputStream()); getIn(); } + private Socket initSSL() throws IOException { + SSLContext ctx = ChatSSL.getSSLContext(); + + SocketFactory factory = ctx.getSocketFactory(); + + Socket connection = factory.createSocket(address, port); + ((SSLSocket) connection).setEnabledProtocols(new String[] {ChatSSL.tlsVersion}); + SSLParameters sslParams = new SSLParameters(); + sslParams.setEndpointIdentificationAlgorithm("HTTPS"); + ((SSLSocket) connection).setSSLParameters(sslParams); + return connection; + } + public void disconnectedServer() throws IOException { socket.close(); out.close(); diff --git a/src/fr/univ/lyon1/common/ChatSSL.java b/src/fr/univ/lyon1/common/ChatSSL.java new file mode 100644 index 0000000..f00b7c1 --- /dev/null +++ b/src/fr/univ/lyon1/common/ChatSSL.java @@ -0,0 +1,57 @@ +package fr.univ.lyon1.common; + +import fr.univ.lyon1.server.Connection; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; +import java.io.IOException; +import java.io.InputStream; +import java.security.*; +import java.security.cert.CertificateException; + +/* +keytool -genkeypair -alias server -keyalg EC \ +-sigalg SHA384withECDSA -keysize 256 -keystore servercert.p12 \ +-storetype pkcs12 -v -storepass abc123 -validity 10000 -ext san=ip:127.0.0.1 + */ + +public class ChatSSL { + public static String trustStoreName = "servercert.p12"; + public static String keyStoreName = "servercert.p12"; + public static String tlsVersion = "TLSv1.2"; + private static char[] trustStorePassword = "abc123".toCharArray(); + private static char[] keyStorePassword = "abc123".toCharArray(); + + public static SSLContext getSSLContext() { + + try { + KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); + InputStream tstore = Connection.class + .getResourceAsStream("/" + trustStoreName); + trustStore.load(tstore, trustStorePassword); + tstore.close(); + TrustManagerFactory tmf = TrustManagerFactory + .getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(trustStore); + + KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); + InputStream kstore = Connection.class + .getResourceAsStream("/" + keyStoreName); + keyStore.load(kstore, keyStorePassword); + KeyManagerFactory kmf = KeyManagerFactory + .getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(keyStore, keyStorePassword); + SSLContext ctx = SSLContext.getInstance("TLS"); + ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), + SecureRandom.getInstanceStrong()); + + return ctx; + } catch (KeyStoreException | IOException | NoSuchAlgorithmException | KeyManagementException | CertificateException | UnrecoverableKeyException e) { + e.printStackTrace(); + System.exit(1); + } + + return null; + } +} diff --git a/src/fr/univ/lyon1/server/Connection.java b/src/fr/univ/lyon1/server/Connection.java index 7ab3b09..251f763 100644 --- a/src/fr/univ/lyon1/server/Connection.java +++ b/src/fr/univ/lyon1/server/Connection.java @@ -1,5 +1,8 @@ package fr.univ.lyon1.server; +import fr.univ.lyon1.common.ChatSSL; + +import javax.net.ssl.*; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; @@ -10,7 +13,20 @@ public class Connection implements Runnable { Connection(Server server) throws IOException { this.server = server; - this.serverSocket = new ServerSocket(server.getPort()); + this.serverSocket = initSSL(); + } + + private SSLServerSocket initSSL() throws IOException { + + SSLContext ctx = ChatSSL.getSSLContext(); + + SSLServerSocketFactory factory = ctx.getServerSocketFactory(); + ServerSocket listener = factory.createServerSocket(server.getPort()); + SSLServerSocket sslListener = (SSLServerSocket) listener; + + sslListener.setNeedClientAuth(true); + sslListener.setEnabledProtocols(new String[]{ChatSSL.tlsVersion}); + return sslListener; } public void run() { diff --git a/src/main/resources/servercert.p12 b/src/main/resources/servercert.p12 new file mode 100644 index 0000000..19df118 Binary files /dev/null and b/src/main/resources/servercert.p12 differ