Commons Net
  1. Commons Net
  2. NET-448

Self signed cert or ca not installed on client but FTPS still works

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Trivial Trivial
    • Resolution: Not A Problem
    • Affects Version/s: 2.0, 3.1
    • Fix Version/s: None
    • Component/s: FTP
    • Labels:
      None
    • Environment:

      client: Windows SP sp4, jdk 1.6.0_24
      server: Linux 2.6.32-220.4.2.el6.i686 running vsFTPd 2.2.2
      apache lib: commons-net-2.0.jar or commons-net-3.1.jar or commons-net-2.0-jdk14.jar (from zehon)

      Description

      I am using vsftpd ftp server on centos with our own self signed root ca certificate.

      I have not installed the self signed root certificate on the client machine. Neither am I setting the Trust Manager on the FTPSClient object, using X509TrustManager instance pointing to my physical cert file.

      But I am still able to use the FTPSClient bundled in any of the following jar file and send/receive the files.
      commons-net-2.0.jar
      commons-net-3.1.jar
      commons-net-2.0-jdk14.jar (from zehon)

      I was expecting that I will have to either install the self signed root ca on the client machine Or set Trust Manager etc.

      Can you please explain the behavior?

        Activity

        Hide
        Bogdan Drozdowski added a comment -

        The current default TrustManager of the FTPSClient only checks if the certificate's dates are valid (if the current date not eariler then the certificate's "valid from" date and not later than the certificate's "valid till" date). It doesn't check the certificate's chain, domains or issuers. Currently, you need to install your own TrustManager (perhaps use a default provided by the JRE, if any) to do that.

        Show
        Bogdan Drozdowski added a comment - The current default TrustManager of the FTPSClient only checks if the certificate's dates are valid (if the current date not eariler then the certificate's "valid from" date and not later than the certificate's "valid till" date). It doesn't check the certificate's chain, domains or issuers. Currently, you need to install your own TrustManager (perhaps use a default provided by the JRE, if any) to do that.
        Hide
        Sebb added a comment -

        Try using

        FTPSClient.setTrustManager(null)

        This will cause the default JVM implementation to be used.

        [Should probably update the Javadoc to make this clearer]

        Show
        Sebb added a comment - Try using FTPSClient.setTrustManager(null) This will cause the default JVM implementation to be used. [Should probably update the Javadoc to make this clearer]
        Hide
        Deepak Pant added a comment -

        Thanks for prompt responses. I have tried FTPSClient.setTrustManager(null) and there is no difference in behavior.

        Just to clarify the sequence of events:
        1. My program establishes connection to FTPS server in explicit mode using SSL or TLS protocol.
        2. Server returns the public certificate installed at the server, which happens to be self-signed certificate in my case.
        3. The default implementation of TrustManager checks if the public cert returned is valid in terms of dates. I think this is X509Certificate.checkValidity() method call, which only looks at dates.
        4. No additional checks are being made to check if public cert was issued by a CA or self signed etc.

        Show
        Deepak Pant added a comment - Thanks for prompt responses. I have tried FTPSClient.setTrustManager(null) and there is no difference in behavior. Just to clarify the sequence of events: 1. My program establishes connection to FTPS server in explicit mode using SSL or TLS protocol. 2. Server returns the public certificate installed at the server, which happens to be self-signed certificate in my case. 3. The default implementation of TrustManager checks if the public cert returned is valid in terms of dates. I think this is X509Certificate.checkValidity() method call, which only looks at dates. 4. No additional checks are being made to check if public cert was issued by a CA or self signed etc.
        Hide
        Sebb added a comment -

        Are you sure you set the trust manager to null before opening the connection?

        Show
        Sebb added a comment - Are you sure you set the trust manager to null before opening the connection?
        Hide
        Deepak Pant added a comment -

        Thanks. If I do FTPSClient.setTrustManager(null) then I get following exception. So if I really want, I can provide my own implementation of X509TrustManager class, which will write some additional code in checkServerTrusted() method. Besides calling X509Certificate.checkValidity(), it can also do checks for self signed cert authority etc.

        ===
        javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No X509TrustManager implementation available

        at com.sun.net.ssl.internal.ssl.BaseSSLSocketImpl.a(DashoA12275)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275)
        at com.sun.net.ssl.internal.ssl.SunJSSE_az.a(DashoA12275)
        at com.sun.net.ssl.internal.ssl.SunJSSE_az.a(DashoA12275)
        ===

        Show
        Deepak Pant added a comment - Thanks. If I do FTPSClient.setTrustManager(null) then I get following exception. So if I really want, I can provide my own implementation of X509TrustManager class, which will write some additional code in checkServerTrusted() method. Besides calling X509Certificate.checkValidity(), it can also do checks for self signed cert authority etc. === javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No X509TrustManager implementation available at com.sun.net.ssl.internal.ssl.BaseSSLSocketImpl.a(DashoA12275) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275) at com.sun.net.ssl.internal.ssl.SunJSSE_az.a(DashoA12275) at com.sun.net.ssl.internal.ssl.SunJSSE_az.a(DashoA12275) ===
        Hide
        Sebb added a comment -

        I get the response shown below when using the FTP client example to connect to Apache FTP server with a local certificate and using TrustManager = none.

        Perhaps the different result is because of the certificate I'm using.

        Without the "-T none", the command logs in OK.

        set CLASSPATH=commons-net-examples-3.1.jar;commons-net-3.1.jar
        java examples/ftp/FTPClientExample -l -p true -T none localhost:990 anonymous password
        
        Could not connect to server.
        javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: una
        ble to find valid certification path to requested target
                at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
                at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1731)
                at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
                at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
                at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206)
                at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)
                at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
                at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
                at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:925)
                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:201)
                at org.apache.commons.net.SocketClient.connect(SocketClient.java:172)
                at org.apache.commons.net.SocketClient.connect(SocketClient.java:192)
                at examples.ftp.FTPClientExample.main(FTPClientExample.java:249)
        Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certific
        ation path to requested target
                at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:323)
                at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217)
                at sun.security.validator.Validator.validate(Validator.java:218)
                at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
                at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
                at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
                at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185)
                ... 12 more
        Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
                at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
                at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
                at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318)
                ... 18 more
        
        Show
        Sebb added a comment - I get the response shown below when using the FTP client example to connect to Apache FTP server with a local certificate and using TrustManager = none. Perhaps the different result is because of the certificate I'm using. Without the "-T none", the command logs in OK. set CLASSPATH=commons-net-examples-3.1.jar;commons-net-3.1.jar java examples/ftp/FTPClientExample -l -p true -T none localhost:990 anonymous password Could not connect to server. javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: una ble to find valid certification path to requested target at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1731) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206) at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136) at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593) at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:925) 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:201) at org.apache.commons.net.SocketClient.connect(SocketClient.java:172) at org.apache.commons.net.SocketClient.connect(SocketClient.java:192) at examples.ftp.FTPClientExample.main(FTPClientExample.java:249) Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certific ation path to requested target at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:323) at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217) at sun.security.validator.Validator.validate(Validator.java:218) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185) ... 12 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174) at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238) at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318) ... 18 more
        Hide
        Sebb added a comment -

        The current behaviour is by design.

        Show
        Sebb added a comment - The current behaviour is by design.

          People

          • Assignee:
            Unassigned
            Reporter:
            Deepak Pant
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development