Java equivalent to OpenSSL s_client command

前端 未结 3 969
我寻月下人不归
我寻月下人不归 2021-01-17 14:06

I have a requirement to convert certain bash scripts to java and one such script connects to a server using openssl with a vanit

3条回答
  •  半阙折子戏
    2021-01-17 14:28

    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 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");
                }
    

提交回复
热议问题