commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Bogdan Drozdowski (JIRA)" <j...@apache.org>
Subject [jira] Commented: (NET-326) A KeyManager is required when the protection level is set to 'P' with FTPSClient on active mode
Date Thu, 10 Mar 2011 15:17:59 GMT

    [ 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

Mime
View raw message