Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
790 views
in Technique[技术] by (71.8m points)

delphi - A simple TIdTCPServer with OpenSSL (no certificates) has "HandShake Failure" and "No Shared Cipher"

I have a very simple TIdTCPServer to test OpenSSL with no certificates. The libeay32.dll and ssleay32.dll OpenSSL files are in the same folder as the project. I use Delphi 10.3 and OpenSSL 1.0.2o.

I then test a connection to it by running openssl s_client -connect localhost:443.

This produces an exception on the server side of:

Project Project19.exe raised exception class EIdOSSLUnderlyingCryptoError with message 'Error accepting connection with SSL.
error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher'.

and an error on the s_client side of:

openssl s_client -connect localhost:443

WARNING: can''t open config file: /usr/local/ssl/openssl.cnf
CONNECTED(00000180)
18424:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:.ssls23_clnt.c:802:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 307 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : 0000
    Session-ID:
    Session-ID-ctx:
    Master-Key:
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1612443994
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

Even if I create simple TIdTCPClient to test with it produces the same handshake failure.

enter image description here

unit Unit19;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, IdSocketHandle, IdContext, IdTCPConnection, IdTCPClient,
  IdBaseComponent, IdComponent, IdCustomTCPServer, IdTCPServer, IdSSLOpenSSL,IdSSL,

  IdSSLOpenSSLHeaders, IdServerIOHandler, IdExplicitTLSClientServerBase, IdFTP;

type
  TForm18 = class(TForm)
    ButtonActivateServer: TButton;
    TCPServer: TIdTCPServer;
    procedure ButtonActivateServerClick(Sender: TObject);
    procedure TCPServerExecute(AContext: TIdContext);
    procedure TCPServerConnect(AContext: TIdContext);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form18: TForm18;

implementation

{$R *.dfm}

procedure TForm18.ButtonActivateServerClick(Sender: TObject);
var
  LSSLIOHandler : TIdServerIOHandlerSSLOpenSSL;
  Binding : TIdSocketHandle;
begin
  TCPServer.Bindings.Clear;
  TCPServer.DefaultPort := 443;
  Binding := TCPServer.Bindings.Add;
  Binding.IP := '0.0.0.0';

  LSSLIOHandler := TIdServerIOHandlerSSLOpenSSL.Create(TCPServer);
  LSSLIOHandler.SSLOptions.Mode := sslmServer;
  LSSLIOHandler.SSLOptions.VerifyMode := [];
  LSSLIOHandler.SSLOptions.VerifyDepth := 0;
  LSSLIOHandler.SSLOptions.SSLVersions := [sslvTLSv1..sslvTLSv1_2];

  TCPServer.IOHandler := LSSLIOHandler;
  TCPServer.Active := True;
end;

procedure TForm18.TCPServerConnect(AContext: TIdContext);
begin
  If AContext.Connection.IOHandler is TIdSSLIOHandlerSocketBase then
    TIdSSLIOHandlerSocketBase(AContext.Connection.IOHandler).PassThrough := False;
end;

procedure TForm18.TCPServerExecute(AContext: TIdContext);
var
  S : String;
begin
  S := AContext.Connection.IOHandler.AllData;
end;

end.

Any ideas on what I am doing wrong? Do I need to specify a CipherList or a more specific one? Are certificates a must?

question from:https://stackoverflow.com/questions/66046555/a-simple-tidtcpserver-with-openssl-no-certificates-has-handshake-failure-and

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

No, a server-side certificate is not required, but it is recommended. It has been a long time, but I remember that I have made successful SSL/TLS connections in the past between TIdTCPClient and TIdTCPServer without using any certificates.

Since the error message mentions "no shared cipher", double-check the SSLIOHandler's CipherList property on both sides of the connection. Just a few months before Delphi 10.3's release, logic was changed in TIdSSLIOHandlerSocketOpenSSL to stop using the IdSSLOpenSSLHeaders.SSL_DEFAULT_CIPHER_LIST constant (which is set to 'AES:ALL:!aNULL:!eNULL:+RC4:@STRENGTH') if the CipherList is empty (which is its default value). Under the new logic, Indy lets OpenSSL use its own defaults if the user doesn't specify their own list. I don't think that change made it into 10.3, so your TIdTCPClient and TIdTCPServer are likely using the wrong ciphers for TLS 1.2.

Make sure your Indy is up-to-date with the latest code from Indy's Gitub repo, or at least make sure to assign proper ciphers to the CipherList property, per OpenSSL 1.0.2's CIPHER LIST FORMAT documentation.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...