You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Bogdan Drozdowski (JIRA)" <ji...@apache.org> on 2011/03/10 16:17:59 UTC
[jira] Commented: (NET-326) A KeyManager is required when the
protection level is set to 'P' with FTPSClient on active mode
[ https://issues.apache.org/jira/browse/NET-326?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13005100#comment-13005100 ]
Bogdan Drozdowski commented on NET-326:
---------------------------------------
Terence, you didn't show us:
* your code
* the way you're running your code
* the server's configuration.
Since you're saying that a KeyManager is required, I'm guessing that the FTP server connecting to you in active mode as a "client" requires you to provide your certificate/key. Since there's no default certificate, the connection fails. If this is true, then to reproduce this (if anyone's interested):
* install vsftpd (the easiest, I guess) and set in the config file:
** require_ssl_reuse=no
** ssl_enable=yes
** ssl_sslv3=yes
** ssl_tlsv1=yes
** rsa_cert_file=/path/to/your_certificate_and_key_file
** ssl_request_cert=yes
** require_cert=yes
* run the following code:
{code}
FTPSClient c = new FTPSClient ();
c.connect ("127.0.0.1", 21);
c.enterLocalActiveMode();
System.out.println (c.getReplyString());
c.login ("login", "password");
System.out.println (c.getReplyString());
c.execPROT ("P");
System.out.println (c.getReplyString());
String[] names = c.listNames();
{code}
Now, to the point: for this to work automatically, the FTPSClient class would have to have all the possible key/certificates. Because of the number of these, this is impossible to have. The solution is the FTPSClient constructor with the SSLContext parameter. A quick search on the Web (with the errors as the search term) made me produce the following code:
{code}
private static X509TrustManager s_x509TrustManager;
static {
s_x509TrustManager = new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[] {}; }
public boolean isClientTrusted(java.security.cert.X509Certificate[] chain) { return true; }
public boolean isServerTrusted(java.security.cert.X509Certificate[] chain) { return true; }
public void checkServerTrusted(java.security.cert.X509Certificate[] certificates, String authType)
{}
public void checkClientTrusted(java.security.cert.X509Certificate[] certificates, String authType) {}
};
}
private static void testFTPS () throws Exception
{
SSLContext ctx;
KeyManagerFactory kmf;
KeyStore ks;
char[] passphrase = "aaaaaa".toCharArray();
ctx = SSLContext.getInstance("TLS");
kmf = KeyManagerFactory.getInstance("SunX509");
ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("keystore"), passphrase);
kmf.init(ks, passphrase);
ctx.init(kmf.getKeyManagers(), new X509TrustManager[] {s_x509TrustManager}, null);
FTPSClient c = new FTPSClient (ctx);
c.connect ("127.0.0.1", 21);
c.enterLocalActiveMode();
System.out.println (c.getReplyString());
c.login ("login", "password");
System.out.println (c.getReplyString());
c.execPROT ("P");
System.out.println (c.getReplyString());
String[] names = c.listNames();
}
{code}
This code *works* when connecting to *the same* vsftpd server as before (when the previous code caused an exception). To run this code, add the following command-line options to "java" (don't know if still required actually, but won't hurt):
* -Djavax.net.ssl.trustStore=truststore
* -Djavax.net.ssl.trustStorePassword=aaaaaa
Please read the [JSSE Reference Guide|http://download.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html], especially the "Code Examples" section. That's where I got most of the information I needed (especially about creating the keystores in files: "keystore" used by the code, and "truststore" used on the command-line). I think that only a certificate for "localhost" is required, but just in case, I've also added a certificate for my hostname in the keystores.
Furthermore, if there's a KeyManager missing, you can always install your own with the FTPSClient.setKeyManager method.
> A KeyManager is required when the protection level is set to 'P' with FTPSClient on active mode
> -----------------------------------------------------------------------------------------------
>
> Key: NET-326
> URL: https://issues.apache.org/jira/browse/NET-326
> Project: Commons Net
> Issue Type: Bug
> Components: FTP
> Affects Versions: 2.0
> Environment: Windows XP profesional service pack 2, Java Java 1.6.0_12-b04
> Reporter: Terence Dudouit
>
> Using a simple FTPS client that list a directory, when execPROT("P") is set and the active mode is on, the following exception is thrown :
> javax.net.ssl.SSLException: No available certificate or key corresponds to the SSL cipher suites which are enabled.
> at com.sun.net.ssl.internal.ssl.SSLServerSocketImpl.checkEnabledSuites(SSLServerSocketImpl.java:303)
> at com.sun.net.ssl.internal.ssl.SSLServerSocketImpl.accept(SSLServerSocketImpl.java:253)
> at org.apache.commons.net.ftp.FTPClient._openDataConnection_(FTPClient.java:489)
> at org.apache.commons.net.ftp.FTPSClient._openDataConnection_(FTPSClient.java:494)
> at org.apache.commons.net.ftp.FTPClient.listNames(FTPClient.java:1950)
> at org.apache.commons.net.ftp.FTPClient.listNames(FTPClient.java:1996)
> at fr.enovacom.eai.actions.dynamiques.protocole.ftp.FTPGet.testFTPS(FTPGet.java:379)
> at fr.enovacom.eai.actions.dynamiques.protocole.ftp.FTPGet.main(FTPGet.java:401)
> This doesn't occur on passive mode.
> The only way to make it work is to set a keyManager although there is no need for a client authentication.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira