5

I have been using:

  • Delphi XE8

  • Indy version 10.6.2.5263

  • precompiled open SSL dll files (Win 32bit) v1.0.2.l

  • TIdSSLIOHandlerSocketOpenSSL with Method set to sslvSSLv23

to submit a POST request against a server. It worked like a charm for many months.

All of a sudden, a wild error popped up:

14094410 sslv3 alert handshake failure.

A colleague is using SOAP UI to submit requests against the same server by forcing TLS 1.2 and it works. I tried to set the TIdSSLIOHandlerSocketOpenSSL1 Method to sslvTLSv1_2, and changed the Mode to sslmClient, but the result is always the same.

I thought by setting the Method to sslvTLSv1_2, it is impossible to receive an error related to SSLv3.

I have checked these stackoverflow posts:

and some other threads, but I am not able to find the root cause of this issue.

Maybe I am missing something. Could you please give me a hint?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Mr. Ajin
  • 325
  • 1
  • 3
  • 16
  • TLS is an extension of SSL 3.0, and OpenSSL uses SSLv3 functionality to implement TLS, that is why the alert says SSLv3. But without specific details about what the alert actually says, especially the alert number, there is no way to know why OpenSSL is failing. Also, your Indy is a little old, the current version is 10.6.2.5432, you should consider upgrading so you have the latest OpenSSL support code. – Remy Lebeau Aug 07 '17 at 16:46
  • Hello Remy, the exact error is: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure. I will try to get the latest Indy version and try again. – Mr. Ajin Aug 08 '17 at 07:30
  • 1
    Hi, I have updated the Indy components, but now the displayed version is 10.6.2.0. – Mr. Ajin Aug 08 '17 at 08:43
  • did you download directly from SVN, or did you download the nightly zip from Fulgan? The Zip has the correct version number. – Remy Lebeau Aug 08 '17 at 16:17
  • Hello Remy, I have downloaded my first Indy upgrade via SVN directly. It showed version 10.6.2.0. After your comment, I have downloaded the latest Fulgran zip (Indy10_5432.zip). De-installed the SVN Indy and did a clean install of the Fulgran zip Indy. The version is also showing 10.6.2.0 and the error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure still remains. – Mr. Ajin Aug 09 '17 at 07:54
  • the Fulgan zip should have the correct version number in it (see `IdVers.inc`), it should be 10.6.2.5432, same as the zip filename, not 10.6.2.0. In any case, you are receiving a generic alert failure, so it very hard to diagnose the cause. The server is rejecting your TLS handshake without really explaining why with a more specific alert. Try connecting with other libraries, like libCURL, or even OpenSSL's own s_client, and use a packet sniffer, like Wireshark, to compare the handshakes. – Remy Lebeau Aug 09 '17 at 08:44
  • 1
    Hello Remy, I did some tests with Wireshark and a little Java code. Wireshark revealed, that the Indy components always send TLSv1 requests - no matter what I select via SSLOptions.Method or SSLOptions.SSLVersions. The java code request uses TLSv1.2 and the request was successful. So my problem is, that the indy component always sends TLSv1 – Mr. Ajin Aug 09 '17 at 09:38
  • Indy is not the one sending the handshake, OpenSSL is. The version used depends on how Indy's `SSLOptions` is configured. If you set it to `sslvTLSv1_2` only, it should be sending a TLS 1.2 hello, unless you are using OpenSSL DLLs that have TLS 1.2 disabled, in which case Indy will fallback to TLS 1.0.. Does Indy's `IsOpenSSL_TLSv1_2_Available()` function return true or false (after OpenSSL is loaded into memory)? – Remy Lebeau Aug 09 '17 at 09:47
  • Hello Remy, `IsOpenSSL_TLSv1_2_Available()` reveals **TRUE**, _after_ I submitted the request. – Mr. Ajin Aug 09 '17 at 11:15

3 Answers3

6

Had the same problem and the source code below worked like a charm. I copied this code from this site but I can't find the link to credit the original answer. Note that source code is not mine.

TCustomIdHTTP = class(TIdHTTP)
  public
    constructor Create(AOwner: TComponent);
  private
    procedure OnStatusInfoEx(ASender: TObject; const AsslSocket: PSSL; const AWhere, Aret: TIdC_INT; const AType, AMsg: String);
  end;

constructor TCustomIdHTTP.Create(AOwner: TComponent);
begin
  IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  with IOHandler as TIdSSLIOHandlerSocketOpenSSL do
  begin
    OnStatusInfoEx := Self.OnStatusInfoEx;
    SSLOptions.Method := sslvSSLv23;
    SSLOptions.SSLVersions := [sslvTLSv1_2, sslvTLSv1_1, sslvTLSv1];
  end;
  inherited Create(AOwner);
end;

procedure TCustomIdHTTP.OnStatusInfoEx(ASender: TObject; const AsslSocket: PSSL;
  const AWhere, Aret: TIdC_INT; const AType, AMsg: String);
begin
  SSL_set_tlsext_host_name(AsslSocket, Request.Host);
end;
Ago
  • 755
  • 7
  • 28
3

Make sure you have the latest libeay32.dll and ssleay32.dll in your application folder

Marcoscdoni
  • 955
  • 2
  • 11
  • 31
0

I've had this same problem myself with some website. I've worked around it by using the TRESTClient instead of the TIdHTTP and OpenSSL.

  • TRESTClient
  • TRESTRequest
  • TRESTResponse

You can set up the URL, authentication and parameters in the REST Debugger in the Tools menu of the Delphi IDE and copy the components to clipboard to give you a head start.

Blazar
  • 13
  • 4
  • At first this was my solution, except then came the part of obtaining binary data, in which case `TRESTClient` has no idea how to handle binary data... – Jerry Dodge Jun 03 '19 at 23:37