I have a requirement to convert certain bash
scripts to java
and one such script connects to a server using openssl
with a vanity-url
as a parameter to check if that is connectable using that vanity-url
. See command below
/usr/bin/openssl s_client -connect api.sys.found1.cf.company.com:443 -servername www.app.company.com 2>/dev/null
I wanted to do the similar activity in java
and test the connectivity. Any ideas on how to make a open-ssl
connection using Java .. Is this something that I need to use external Library ?
OpenSSL4J is a Java bridge to the native OpenSSL library.
The s_client command implements a generic SSL/TLS client which connects to a remote host using SSL/TLS. It is a very useful diagnostic tool for SSL servers.
OpenSSL's s_client command can be used to analyze client-server communication, including whether a port is open and if that port is capable of accepting an SSL/TLS connection. It is a useful tool for investigating SSL/TLS certificate-based plugins, and for confirming that a line of secure communications is available.
I was able to achieve this by referring the document over here
Basically, a SSLEngine
needs to be created and make a successful handshake along with SNI
private SocketChannel createSocketChannel() throws IOException {
InetSocketAddress socketAddress = new InetSocketAddress(PROXY_ADDRESS, PROXY_PORT);
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(socketAddress);
socketChannel.configureBlocking(false);
return socketChannel;
}
private SSLContext createSSLContext() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext sslContext = SSLContext.getInstance(TLS_VERSION);
sslContext.init(null,null,null);
return sslContext;
}
private SSLEngine createSSLEngine() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext sslContext = createSSLContext();
SSLEngine sslEngine = sslContext.createSSLEngine(PROXY_ADDRESS, PROXY_PORT);
sslEngine.setUseClientMode(true);
List<SNIServerName> serverNameList = new ArrayList<>();
serverNameList.add(new SNIHostName(SNI_HOST_NAME));
SSLParameters sslParameters = sslEngine.getSSLParameters();
sslParameters.setServerNames(serverNameList);
sslEngine.setSSLParameters(sslParameters);
return sslEngine;
}
After creating SSLEngine, the handShake
has to begin
SocketChannel channel = createSocketChannel();
SSLEngine sslEngine = createSSLEngine();
doHandShake(sslEngine,channel);
private void doHandShake(SSLEngine sslEngine, SocketChannel socketChannel) throws Exception {
System.out.println("Going to do Handshake");
SSLSession session = sslEngine.getSession();
ByteBuffer myAppData = ByteBuffer.allocate(session.getApplicationBufferSize());
ByteBuffer peerAppData = ByteBuffer.allocate(session.getApplicationBufferSize());
ByteBuffer myNetData = ByteBuffer.allocate(session.getPacketBufferSize());
ByteBuffer peerNetData = ByteBuffer.allocate(session.getPacketBufferSize());
sslEngine.beginHandshake();
SSLEngineResult result;
handshakeStatus = sslEngine.getHandshakeStatus();
while (handshakeStatus != SSLEngineResult.HandshakeStatus.FINISHED &&
handshakeStatus != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
switch (handshakeStatus) {
case NEED_UNWRAP:
if (! (socketChannel.read(peerNetData) <0)) {
peerNetData.flip();
result = sslEngine.unwrap(peerNetData,peerAppData);
peerNetData.compact();
handshakeStatus = result.getHandshakeStatus();
switch (result.getStatus()) {
case OK:
break;
}
}
break;
case NEED_WRAP:
myNetData.clear() ;// Empty the local network packet buffer
result = sslEngine.wrap(myAppData,myNetData);
handshakeStatus = result.getHandshakeStatus();
switch (result.getStatus()) {
case OK:
myNetData.flip();
while (myNetData.hasRemaining()) {
socketChannel.write(myNetData);
}
}
break;
case NEED_TASK:
Runnable task = sslEngine.getDelegatedTask();
if (null!=task) {
task.run();
}
handshakeStatus = sslEngine.getHandshakeStatus();
break;
}
}
Once the handShake
is done. you can get the Principal
object
Principal principal = sslEngine.getSession().getPeerPrincipal();
if (principal.getName().contains(SNI_HOST_NAME)) {
System.out.println("available ... ");
}else {
System.out.println("Not available");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With