|
import java.io.*; |
|
import java.net.*; |
|
import java.security.*; |
|
import javax.net.ssl.*; |
|
|
|
public class TlsEchoServer { |
|
|
|
public static void main(String[] args) { |
|
|
|
if (args.length != 4) { |
|
System.out.println("Usage: java TlsEchoServer <port> <jks> <jkspass> <certkeypass>"); |
|
return; |
|
// Prepare a JKS using keytool, containing: |
|
// - a cert for the server |
|
// - privkey for the cert |
|
// - alias should match CN/hostname |
|
// - jks format should be PKCS12 |
|
// Dump the handshake using -Djavax.net.debug=ssl,handshake |
|
} |
|
|
|
int port = Integer.parseInt(args[0]); |
|
String jkspath = args[1]; |
|
String jkspass = args[2]; |
|
String certpass = args[3]; |
|
|
|
try { |
|
//System.out.println("-- Crypto providers dump --"); |
|
//Provider[] providers = Security.getProviders(); |
|
//for (int i = 0; i < providers.length; ++i) { |
|
// System.out.println(" " + providers[i].toString()); |
|
//} |
|
|
|
KeyStore ks = KeyStore.getInstance("PKCS12"); |
|
ks.load(new FileInputStream(jkspath), jkspass.toCharArray()); |
|
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); |
|
kmf.init(ks, certpass.toCharArray()); |
|
|
|
SSLContext ctx = SSLContext.getInstance("TLS"); |
|
ctx.init(kmf.getKeyManagers(), null, null); |
|
|
|
System.out.println("SSLContext init'd"); |
|
System.out.println(" provider: " + ctx.getProvider().toString()); |
|
System.out.println(" protocol: " + ctx.getProtocol().toString()); |
|
|
|
SSLServerSocketFactory ssf = ctx.getServerSocketFactory(); |
|
|
|
SSLServerSocket s |
|
= (SSLServerSocket) ssf.createServerSocket(port); |
|
//s.setEnabledCipherSuites(new String[]{"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"}); |
|
printServerSocketInfo(s); |
|
|
|
SSLSocket c = null; |
|
BufferedWriter w = null; |
|
BufferedReader r = null; |
|
|
|
while (true) { |
|
try { |
|
c = (SSLSocket) s.accept(); |
|
printSocketInfo(c); |
|
w = new BufferedWriter(new OutputStreamWriter(c.getOutputStream())); |
|
r = new BufferedReader(new InputStreamReader(c.getInputStream())); |
|
String m; |
|
while ((m=r.readLine())!= null) { |
|
char[] a = m.toCharArray(); |
|
w.write(a,0,a.length); |
|
w.newLine(); |
|
w.flush(); |
|
System.out.println("echo'd back: |" + m + "|"); |
|
} |
|
} catch (SocketException e) { |
|
System.err.println(e.toString()); continue; |
|
} catch (SSLException e) { |
|
System.err.println(e.toString()); continue; |
|
} finally { |
|
w.close(); |
|
r.close(); |
|
c.close(); |
|
} |
|
} |
|
//s.close(); |
|
|
|
} catch (Exception e) { |
|
System.err.println(e.toString()); |
|
} |
|
} |
|
private static void printSocketInfo(SSLSocket s) { |
|
System.out.println("Socket class: " + s.getClass()); |
|
System.out.println(" Remote address = " + s.getInetAddress().toString()); |
|
System.out.println(" Remote port = " + s.getPort()); |
|
System.out.println(" Local socket address = " + s.getLocalSocketAddress().toString()); |
|
System.out.println(" Local address = " + s.getLocalAddress().toString()); |
|
System.out.println(" Local port = " + s.getLocalPort()); |
|
System.out.println(" Need client authentication = " + s.getNeedClientAuth()); |
|
SSLSession ss = s.getSession(); |
|
System.out.println(" Protocol = " + ss.getProtocol()); |
|
System.out.println(" Cipher suite = " + ss.getCipherSuite()); |
|
} |
|
private static void printServerSocketInfo(SSLServerSocket s) { |
|
System.out.println("Server socket class: " + s.getClass()); |
|
System.out.println(" Socket address = " + s.getInetAddress().toString() + ":" + s.getLocalPort()); |
|
System.out.println(" Need client authentication = " + s.getNeedClientAuth()); |
|
System.out.println(" Want client authentication = " + s.getWantClientAuth()); |
|
System.out.println(" Use client mode = " + s.getUseClientMode()); |
|
System.out.println(" Enabled protocols: " + String.join(" ", s.getEnabledProtocols())); |
|
System.out.println(" Enabled ciphersuites: " + String.join(" ", s.getEnabledCipherSuites())); |
|
} |
|
} |