commons-net icon indicating copy to clipboard operation
commons-net copied to clipboard

FTPES with TLS Session Reuse for FileZilla Server (need also BouncyCastle and a subclass).

Open deguich opened this issue 1 year ago • 2 comments

Connecting to ftp.example.com on the command port and then to the corresponding IP x.x.x.x on the data port prevents the server from accepting the same TLS session. Therefore, the Filezilla server needs to set peerHost before socket.connect to allow TLS session resumption.

With this new version, FTPeS to the server with TLS session resumption works with this subclass :

package org.mypackage;

import java.io.IOException;
import java.net.Socket;
import java.security.SecureRandom;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;

import org.apache.commons.net.ftp.FTPSClient;
import org.apache.commons.net.util.TrustManagerUtils;
import org.bouncycastle.jsse.BCExtendedSSLSession;
import org.bouncycastle.jsse.BCSSLSocket;
import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider;

public class FTPSClientSSLSessionReuse extends FTPSClient {

  public FTPSClientSSLSessionReuse (boolean isImplicit) throws Exception {
    super(isImplicit, createSSLContext());
    setEnabledProtocols(new String[] {"TLSv1.2"});
    setUseEPSVwithIPv4(true);
  }

  private static SSLContext createSSLContext() throws Exception {
    SSLContext context = SSLContext.getInstance("TLS", new BouncyCastleJsseProvider());
    context.init(
        null,
        new TrustManager[] {TrustManagerUtils.getValidateServerCertificateTrustManager()},
        new SecureRandom());
    return context;
  }

  @Override
  protected void _prepareDataSocket_(final Socket socket) throws IOException {
	  if (_socket_ instanceof BCSSLSocket sslSocket) {
	      BCExtendedSSLSession bcSession = sslSocket.getBCSession();
	      if (bcSession != null && bcSession.isValid() && socket instanceof BCSSLSocket dataSslSocket) {
	        dataSslSocket.setBCSessionToResume(bcSession); 
	        // Next line could be a solution if this function was called before connect
	        dataSslSocket.setHost(bcSession.getPeerHost());
	      }
	    }
  }
}

deguich avatar Jan 15 '25 11:01 deguich