Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EIdOSSLUnderlyingCryptoError Exception

I am using Indy (IdHTTP, OpenSSL). I use this simple code to download a page

var
  IdHTTP: TIdHTTP;
begin
  IdHTTP:=TIdHTTP.Create;
  try
    IdHTTP.Get('https://ezfile.ch/?m=help&a=tos');
  finally
    IdHTTP.Free;
  end;
end;

It returns:

EIdOSSLUnderlyingCryptoError exception "Error connecting with SSL.
    error:14094438:SSL routines:SSL3_READ_BYTES:tlsv1 alert internal error"

The site uses TLS 1.1, AES_128_CBC_SHA1, ECDHE-ECDSA. It should be easily reproducible.

Tried with various Delphi versions, Indy 10.6.2, various OpenSSL version. Changing SSLVersion option did not help.

What could be the problem?

like image 800
smooty86 Avatar asked Dec 24 '22 20:12

smooty86


1 Answers

Here is sample code on how to fix this issue using SSL_set_tlsext_host_name

It is done by creating a custom class inheriting from TIdHTTP, and calling SSL_set_tlsext_host_name with the correct parameters by using the OnStatusInfoEx event of TIdSSLIOHandlerSocketOpenSSL

This issue started appearing on all Cloudflare SSL-enabled websites about a month ago.

program Project1;

{$APPTYPE CONSOLE}

uses
  System.Classes, IdHTTP, IdSSL, IdSSLOpenSSL, IdSSLOpenSSLHeaders, IdCTypes;

type
  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;

{ TCustomIdHTTP }

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;
//////////////////

var
  MyHTTP: TCustomIdHTTP;
begin
  MyHTTP := TCustomIdHTTP.Create(nil);
  // Your normal Indy HTTP code here
  MyHTTP.Free;
end.
like image 191
Sierra C Avatar answered Dec 27 '22 20:12

Sierra C