Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Minimal SSL TCPClient and server, VCL
#1
Minimal SSL TCPServer and client
I am using delphi version 10.3.1 .
No certificate, it is not mandatory.
No errormessages, but only rubbish received in ServerExecute. Works fine when UseSSL = false;
Any ideas?

Place a button on an empty form, and link it to Button1Click.

Code:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, uIdContext, IdContext,
  IdServerIOHandler, IdSSL, IdSSLOpenSSL, IdBaseComponent, IdComponent,
  IdCustomTCPServer, IdTCPServer, Vcl.StdCtrls, IdIOHandler, IdIOHandlerSocket,
  IdIOHandlerStack, IdTCPConnection, IdTCPClient;

type
  TForm1 = class(TForm)
    Server: TIdTCPServer;
    Client: TIdTCPClient;
    cSSL: TIdSSLIOHandlerSocketOpenSSL;
    Button1: TButton;
    SSL: TIdServerIOHandlerSSLOpenSSL;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ServerExecute(AContext: TIdContext);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const usessl = false;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Client.Connect;
  Client.IOHandler.WriteLn('test');
  Client.Disconnect;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Server:= TIdTCPServer.Create;
  Server.DefaultPort := 443;
  Client:= TIdTCPClient.Create;
  Client.Host := 'Localhost';
  Client.Port := 443;
  Server.OnExecute := ServerExecute;
  if UseSSL then
  begin
    cSSL:= TIdSSLIOHandlerSocketOpenSSL.Create;
    SSL:= TIdServerIOHandlerSSLOpenSSL.Create;
    SSL.SSLOptions.Mode := sslmServer;
    SSL.SSLOptions.VerifyMode := [];
    SSL.SSLOptions.VerifyDepth  := 0;
    SSL.SSLOptions.SSLVersions := [sslvSSLv2..sslvTLSv1_2];
    TIdSSLIOHandlerSocketBase(cSSL).PassThrough := false;
    cSSL.SSLOptions.Mode := sslmClient;
    cSSL.SSLOptions.VerifyMode := [];
    cSSL.SSLOptions.VerifyDepth  := 0;
    cSSL.SSLOptions.SSLVersions := [sslvSSLv2..sslvTLSv1_2];    // Avoid using SSL}
    Server.IOHandler := SSL;   // TIdServerIOHandlerSSLOpenSSL
    Client.IOHandler := cSSL;  // TIdSSLIOHandlerSocketOpenSSL
  end;


  Server.Active := true;
end;

procedure TForm1.ServerExecute(AContext: TIdContext);
var s : string;
begin
  s :=  aContext.Connection.IOHandler.Alldata;
  s := s;
end;

end.
Reply
#2
The non cert SSL options are *very* weak and I dont think Indy supports those ciphers although Remy would know better. SSL was never my area.

Why not just use a self signed cert instead? They are free and easy to make.
Reply
#3
(10-15-2019, 08:48 PM)logihouse Wrote: No errormessages, but only rubbish received in ServerExecute.

You are not setting the SSLIOHandler to PassThrough=False on the server side. It is True by default, in order to support STARTTLS-like protocols. As such, your OnExecute code ends up reading the client's raw SSL/TLS data. You need to set PassThrough=False on the server side, on a per-connection basis. In your example, the OnConnect event would be the appropriate place to do so, since the client is initiating the SSL/TLS handshake as soon as the TCP connection is established and before any application data is sent:

Code:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, uIdContext, IdContext,
  IdServerIOHandler, IdSSL, IdSSLOpenSSL, IdBaseComponent, IdComponent,
  IdCustomTCPServer, IdTCPServer, Vcl.StdCtrls, IdIOHandler, IdIOHandlerSocket,
  IdIOHandlerStack, IdTCPConnection, IdTCPClient;

type
  TForm1 = class(TForm)
    Server: TIdTCPServer;
    Client: TIdTCPClient;
    cSSL: TIdSSLIOHandlerSocketOpenSSL;
    Button1: TButton;
    SSL: TIdServerIOHandlerSSLOpenSSL;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ServerConnect(AContext: TIdContext);
    procedure ServerExecute(AContext: TIdContext);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
  UseSSL = True;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Client.Connect;
  try
    Client.IOHandler.WriteLn('test');
  finally
    Client.Disconnect;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Server := TIdTCPServer.Create(Self);
  Server.DefaultPort := 443;
  Client := TIdTCPClient.Create(Self);
  Client.Host := 'localhost';
  Client.Port := 443;
  Server.OnConnect := ServerConnect;
  Server.OnExecute := ServerExecute;
  if UseSSL then
  begin
    cSSL := TIdSSLIOHandlerSocketOpenSSL.Create(Client);
    cSSL.PassThrough := False;
    cSSL.SSLOptions.Mode := sslmClient;
    cSSL.SSLOptions.VerifyMode := [];
    cSSL.SSLOptions.VerifyDepth  := 0;
    cSSL.SSLOptions.SSLVersions := [sslvSSLv2..sslvTLSv1_2];    // Avoid using SSL}
    Client.IOHandler := cSSL;  // TIdSSLIOHandlerSocketOpenSSL

    SSL := TIdServerIOHandlerSSLOpenSSL.Create(Server);
    SSL.SSLOptions.Mode := sslmServer;
    SSL.SSLOptions.VerifyMode := [];
    SSL.SSLOptions.VerifyDepth  := 0;
    SSL.SSLOptions.SSLVersions := [sslvSSLv2..sslvTLSv1_2];
    Server.IOHandler := SSL;   // TIdServerIOHandlerSSLOpenSSL
  end;

  Server.Active := True;
end;

procedure TForm1.ServerConnect(AContext: TIdContext);
begin
  if AContext.Connection.IOHandler is TIdSSLIOHandlerSocketBase then
    TIdSSLIOHandlerSocketBase(AContext.Connection.IOHandler).PassThrough := False;
end;

procedure TForm1.ServerExecute(AContext: TIdContext);
var
  s : string;
begin
  s := AContext.Connection.IOHandler.AllData;
end;

end.

Reply
#4
(10-15-2019, 11:47 PM)kudzu Wrote: The non cert SSL options are *very* weak and I dont think Indy supports those ciphers although Remy would know better. SSL was never my area.

Why not just use a self signed cert instead? They are free and easy to make.

We just want a very simple solution, so if we can, we will avoid certificates.
Reply
#5
Thanks a lot!
I got a little longer.
But next problem, now: It says "handshake failure" and "no shared cipher".
I am using Delphi Version 10.2 and DLLs are version 1.0.2.17
I also tried connecting with OpenSSL.exe, it says also
"Secure renegotiation IS NOT supported"
Any hints?
Reply
#6
(10-16-2019, 08:14 AM)logihouse Wrote: But next problem, now: It says "handshake failure" and "no shared cipher".
I am using Delphi Version 10.2 and DLLs are version 1.0.2.17
I also tried connecting with OpenSSL.exe, it says also
"Secure renegotiation IS NOT supported"

See No server certificate and “no shared cipher” when clients connect. You could try setting the IOHandler's CipherList on both ends to enable aNULL ciphers, but that is generally discouraged. Using a certificate on the server side, even a self-signed one, is the best option to avoid this problem.

Reply
#7
(10-16-2019, 05:37 PM)rlebeau Wrote: See No server certificate and “no shared cipher” when clients connect.  You could try setting the IOHandler's CipherList on both ends to enable aNULL ciphers, but that is generally discouraged. Using a certificate on the server side, even a self-signed one, is the best option to avoid this problem.

Thanks! I will try that.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)