title: How to configure client authentication with apache.commons.net.ftps?
body: <p>I implemented a FTPS client (FTP over SSL/TLS) in java using the <em>apache.commons.net</em>-framework. 
  It is configured to do explicit security on the default port 21.</p>
  
  <pre><code>ftpsClient = new FTPSClient(false);
  ftpsClient.setTrustManager(getConfiguration().getCertificatesManager());
  ftpsClient.connect(getConfiguration().getHostName(), getConfiguration().getPort());
  </code></pre>
  
  <p>As long as I don't enforce client-authentication on the server, everything works fine. 
  But I need to enable client-authentication, so I enforce it on the server and configured the client-system properties:</p>
  
  <pre><code>-Djavax.net.ssl.keyStore="D:/.../ftps-client-auth.keystore"
  -Djavax.net.ssl.keyStorePassword="*****"
  -Djavax.net.ssl.keyStoreType=JKS
  </code></pre>
  
  <p>What I got was the same as if I did not set the system properties:</p>
  
  <pre><code>javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
      at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
      at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
      at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1806)
      at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:986)
      at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1170)
      at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1197)
      at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1181)
      at org.apache.commons.net.ftp.FTPSClient.sslNegotiation(FTPSClient.java:265)
      at org.apache.commons.net.ftp.FTPSClient._connectAction_(FTPSClient.java:207)
      at org.apache.commons.net.SocketClient.connect(SocketClient.java:172)
      at org.apache.commons.net.SocketClient.connect(SocketClient.java:192)
  </code></pre>
  
  <p>The server-log says:</p>
  
  <pre><code>DEBUG: Client "&lt;my ip address&gt;", "SSL_accept failed: error:140890C7:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:peer did not return a certificate"
  </code></pre>
  
  <p>Seems right - I enabled <em>-Djavax.net.debug=all</em>, what shows that the server sends a list of CNs it accepts, but the client sends an empty certificate chain. </p>
  
  <ul>
  <li><strong>What have I done wrong?</strong></li>
  <li><strong>Do I need to do some configuration programatically?</strong></li>
  <li><strong>Do the certificates or the private key need to support anything special for SSL/TLS?</strong></li>
  </ul>