EnableSsl property

mentalhard

Well-known member
Joined
Aug 7, 2006
Messages
123
Programming Experience
Beginner
Hi,

Using an appliaction i have produced self-signed certificate.
Currently i have three files there:

cert.crt
cert.csr
cert.key

So my question is; how do i implement this certificate in the code in order to use an encrypted channel for transfering passwords and file contents.

The code i have works flawless with disabled FtpWebRequest's EnableSsl property.

VB.NET:
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
request.Credentials = new NetworkCredential("xxxxxl", "xxxxxx");
request.UsePassive = true;
request.EnableSsl = false;
request.Method = WebRequestMethods.Ftp.ListDirectory;

// normally the exception is always thrown on this line
FtpWebResponse response =  (FtpWebResponse)request.GetResponse();

If i enable the EnableSsl i am getting the next exception:

The remote certificate is invalid according to the validation procedure.

which is exception that is thrown when authentication fails for an authentication stream.

Ok then i tried to create new certificate from File:

VB.NET:
X509Certificate cert = X509Certificate.CreateFromCertFile(@"C:\TestTLS\CERTS\cert.crt");
request.ClientCertificates.Add(cert);

But i still get the same message/exception.


Now if i understand well this Wikipedia statement:

Typically, only the server is authenticated (i.e., its identity is ensured) while the client remains unauthenticated; this means that the end user (whether an individual or an application, such as a Web browser) can be sure with whom they are communicating. The next level of security—in which both ends of the "conversation" are sure with whom they are communicating—is known as mutual authentication.

I can go for the typical way of authentication only the server that means i do not need even self signed one.

However, i cannot find solution for my problem. I have noticed that actually many people are strugglling with the same problem but, it seems like there is not any good tutorial on how to properly either implement self-signed cert or use EnableSsl property along FtpWebRequest class without having cert on client side.

Thank you

_______________________________________________________
I was wondering if this can be of help; namely, I tested it from this FTP test web site http://www.g6ftpserver.com/en/ftptest and it returns following:

* About to connect() to domain.elementfx.com port 21
* Trying 70.86.238.xxx... connected
* Connected to domain.elementfx.com (xx.86.238.xxx) port 21
< 220---------- Welcome to Pure-FTPd [TLS] ----------
< 220-You are user number 2 of 50 allowed.
< 220-Local time is now 03:56. Server port: 21.
< 220-This is a private system - No anonymous login
< 220-IPv6 connections are also welcome on this server.
< 220 You will be disconnected after 15 minutes of inactivity.


> AUTH SSL
< 500 This security scheme is not implemented

> AUTH TLS
< 234 AUTH TLS OK.
* successfully set certificate verify locations:
* CAfile: d:\www-bin\curl\curl-ca-bundle.crt
CApath: none
* SSLv3, TLS handshake, Client hello (1):
SSLv3, TLS handshake, Server hello (2):
SSLv3, TLS handshake, CERT (11):
SSLv3, TLS handshake, Server finished (14):
SSLv3, TLS handshake, Client key exchange (16):
SSLv3, TLS change cipher, Client hello (1):
SSLv3, TLS handshake, Finished (20):
SSLv3, TLS change cipher, Client hello (1):
SSLv3, TLS handshake, Finished (20):
SSL connection using AES256-SHA
* Server certificate:
* subject: /C=US/ST=Unknown/L=Unknown/O=Unknown/OU=Unknown/CN=cossacks.x10hosting.com/emailAddress=ssl@cpanel.net
* start date: 2007-09-21 14:51:55 GMT
* expire date: 2035-02-05 14:51:55 GMT
* common name: cossacks.x10hosting.com (does not match 'domain.elementfx.com')
* issuer: /C=US/ST=Unknown/L=Unknown/O=Unknown/OU=Unknown/CN=cossacks.x10hosting.com/emailAddress=ssl@cpanel.net
* SSL certificate verify result: error number 1 (18), continuing anyway.

> USER trial
< 331 User trial OK. Password required

> PASS *****
< 230-User trial has group access to: trial
< 230 OK. Current restricted directory is /


> PBSZ 0
< 200 PBSZ=0

> PROT P
< 534 Fallback to [C]

> PWD
< 257 "/" is your current location
* Entry path is '/'

> CLNT Testing from http://www.g6ftpserver.com/ftptest from IP xx.205.28.xxx

< 500 Unknown command
* QUOT command failed with 500
* Connection #0 to host domain.elementfx.com left intact

* Closing connection #0
* SSLv3, TLS alert, Client hello (1):

Thanks ones agains
 
Nobody wants to help? At least confirm that it's a confirmed bug so that i can recreate it from ground using TCP connection and sending commands to the FTP server in lower lever.
EnableSsl made me so much trouble that i think i will do the same FtpWebRequest/Response classes with well implemented SSL protocol.
 
When I searched the error message I found that it means the server certificate isn't valid by regular validation rules. I also found this snippet to by-pass it:
VB.NET:
'Imports System.Security.Cryptography.X509Certificates
'Imports System.Net.Security

Sub ssl()
    Net.ServicePointManager.ServerCertificateValidationCallback = AddressOf validateCert
    'do request
End Sub

Public Function validateCert(ByVal sender As Object, _
                             ByVal certificate As X509Certificate, _
                             ByVal chain As X509Chain, _
                             ByVal sslPolicyErrors As SslPolicyErrors) As Boolean
    Return True
End Function
Returning True does defy the purpose of SSL since any certificate will pass, but you can do custom validation here that wouldn't pass the default but still considered safe.
 
Ok where you put this code? i have tried with pretty same trick in C# but it wasn't working.
VB.NET:
// This approves any Server Certificate (self-signed)
                ServicePointManager.ServerCertificateValidationCallback = delegate(Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
                {
                      return true;
                };

Anyway say i have this DisplayFileFromServer function:

VB.NET:
Public shared function DisplayFileFromServer(Byval serverUri As Uri) As Boolean

  Dim request As FtpWebRequest = Ctype(WebRequest.Create(serverUri), FtpWebRequest)
  request.Credentials = new NetworkCredential("trial", "123456")
  request.EnableSsl = true
  request.Method = WebRequestMethods.Ftp.ListDirectory

{...} response and stuff
End function

Where do you suggest that i call that "cheating" function?

Thanks :)
 
Ok this is my all testing code that actually throws an exception: The remote server returned an error: (534) 534 Fallback to [C]

VB.NET:
Public Function validateCert(ByVal sender As Object, _
                                 ByVal certificate As X509Certificate, _
                                 ByVal chain As X509Chain, _
                                 ByVal sslPolicyErrors As SslPolicyErrors) As Boolean
        Return True
    End Function

    Public Function Ssl(ByVal url As Uri) As Boolean
        Net.ServicePointManager.ServerCertificateValidationCallback = AddressOf validateCert
        Dim request As FtpWebRequest = CType(WebRequest.Create(url), FtpWebRequest)
        request.Credentials = New NetworkCredential("blah", "xxxxxxx")
        request.EnableSsl = True
        request.Method = WebRequestMethods.Ftp.ListDirectory

        Dim response As FtpWebResponse = DirectCast(request.GetResponse(), FtpWebResponse)

        Console.WriteLine("The content length is {0}", response.ContentLength)
        ' The following streams are used to read the data returned from the server.
        Dim responseStream As Stream = Nothing
        Dim readStream As StreamReader = Nothing

        Try
            responseStream = response.GetResponseStream()
            readStream = New StreamReader(responseStream, System.Text.Encoding.UTF8)
            If readStream IsNot Nothing Then
                ' Display the data received from the server.
                Console.WriteLine(readStream.ReadToEnd())
            End If
            Console.WriteLine("List status: {0}", response.StatusDescription)
        Finally
            If readStream IsNot Nothing Then
                readStream.Close()
            End If
            If response IsNot Nothing Then
                response.Close()

            End If
        End Try

        Console.WriteLine("Banner message: {0}", response.BannerMessage)

        Console.WriteLine("Welcome message: {0}", response.WelcomeMessage)

        Console.WriteLine("Exit message: {0}", response.ExitMessage)
        Return True

    End Function
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim serveraddress As Uri = New Uri("ftp://blah.elementfx.com/")
        Ssl(serveraddress)
    End Sub

Any suggestion is welcome :) Thanks!!!
 
That's actually the same error that PROT command throws as well.
check the original post:

> PROT P
< 534 Fallback to [C]

Any idea?

Thanks :)
 
That was the suggested method, and it works fine with the test server address you posted (Gene6). The validation triggers twice for same UntrustedRoot error, but continues since True is returned and give the requested ListDirectory.

Don't know about Prot, but when you run the test at site it lists Prot as one of the supported 211-Extensions, maybe your other server don't support this.
 
Could you please send me the test code ... i am strugglling with this issue for weeks so if you say that it works that's a miracle. Here iam getting the same exception all the time.
Please post the code that works avoiding this exception. If you have workable code than you are the best programmer around the globe at least best that i have ever met in my life.

Thanks :)
 
Sure, a basic FTP request with SSL:
VB.NET:
Sub ssl()
    Net.ServicePointManager.ServerCertificateValidationCallback = AddressOf validateCert 'same callback
    'do request
    Dim request As Net.FtpWebRequest = Net.WebRequest.Create("ftp://87.98.200.117")
    request.Credentials = New Net.NetworkCredential("anonymous", "")
    request.EnableSsl = True
    request.Method = Net.WebRequestMethods.Ftp.ListDirectory
    Dim resp As Net.FtpWebResponse = request.GetResponse
    Dim reader As New IO.StreamReader(resp.GetResponseStream)
    Dim message As String = reader.ReadToEnd
    reader.Close()
    MsgBox(message)
End Sub
 
It works for that particular web site ...but for all other websites i tried to get files from i get an exception:

The remote server returned an error: (500) Syntax error, command unrecognized

Any idea for something like catching exception and keep running assuming that itwill be connected to TLS instead SSL ??

Thanks!!
 
I tried your other server, I may be wrong, but it seems this this server not fully support SSL (TLS actually), the 534 exception is thrown for any command I try when SSL is enabled, so it seems also FTPWebrequest class always sends PROT P before all commands for SSL, this could also be wrong or just a limitation of current FtpWebRequest class version. Fallback to C means protected data channel isn't supported and that the connection reverts to clear text transmission, but you don't get a response therefore gets nowhere.
 
Ok it seems you are alright. But how can i resolve this issue in order to make it that if TLS is supported then to run over secure channel otherwise to keep running sending passwords and file contents in clear text?

I just need it working. Maybe if i catch the 534 exception and keep running but it's beyond my knowledge.

Thanks for any further help :)
 
Try SSL, if it don't work make a new request without SSL. You can't "keep running" when you haven't started.
 
You mean something like following?

VB.NET:
Try 
   'make request
   'set up the EnableSsl to true
   'get the response
Catch ex as Net.WebException
   if failed Then
    'new request
    'EnableSsl = false
    'response
    'etc.
End Try

Is that what do you suggest?
Hmm ... it seems very tricky as i am confused how the 3rd party vendors have implemented this feature with out any issue ... i tried chilkat's FTP library as well as the secure FTP from jscape.com. Their trials libraries work flawless supporting SSL 100 %

Thanks :)
 
Back
Top