0

I'm using Delphi 10.3.3. The code below used to work but now I'm getting an error when trying to download a file over HTTPS:

Error connecting with SSL error:1409442E:SSL routines:SSL3_READ_BYTES:tlsv1 alert protocol version'

var
  ms : tmemorystream;
  ssl : TIdSSLIOHandlerSocketOpenSSL;
  source,dest : string;
begin
  source := 'https://www.myaddress.com/myfile.zip';
  dest := 'c:\myfile.zip';
  ms := TMemoryStream.Create;
  try
    if pos('https',source) > 0 then
    begin
      ssl := TIdSSLIOHandlerSocketOpenSSL.Create();
      idh.IOHandler := ssl;
    end;
    idhttp1.get(source,ms);
    ms.savetofile(dest);
    result := 'ok';
  finally
    ms.Free;
  end;
end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
delphirules
  • 6,443
  • 17
  • 59
  • 108
  • Possible duplicate: https://stackoverflow.com/questions/48984539/how-can-we-connect-with-a-website-getting-ssl-error-1409442e (first Google match for "tlsv1 alert protocol version indy"). – Andreas Rejbrand Mar 07 '20 at 19:14

2 Answers2

4

TIdSSLIOHandlerSocketOpenSSL uses only TLS v1.0 by default and the server is rejecting that. You must explicitly allow newer TLS versions:

ssl := TIdSSLIOHandlerSocketOpenSSL.Create();
ssl.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
idh.IOHandler := ssl;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Pethical
  • 1,472
  • 11
  • 18
1

Recent versions of Indy have https support built-in (so no need to create SSL IOHandler, Indy will take care of that automatically). Also when dealing with files, it is better to use TFilestream instead of TMemoryStream because you you will get into trouble when trying to download files that don't fit into memory.

Here is a MRE for you:

program SO60578855;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  idHttp,
  Classes,
  System.SysUtils;

var
  Http : TidHttp;
  Fs   : TFileStream;

begin
  try
   Fs := TFileStream.Create('c:\temp\100mb.bin', fmcreate);
   Http := TidHttp.Create(nil);
   try
    Http.Get('https://speed.hetzner.de/100MB.bin', Fs);
   finally
    Http.Free;
    Fs.Free;
   end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
 Readln;
end.
whosrdaddy
  • 11,720
  • 4
  • 50
  • 99
  • I'm on Delphi 10.3.3 so i guess i'm in an updated Indy version, but still i need the SSL component – delphirules Mar 07 '20 at 16:44
  • 1
    @delphirules https://www.indyproject.org/2014/12/22/new-https-functionality-for-tidhttp/ but you are right, you will need to create the component explicitly since you need to tweak its SSLVersions. – Remy Lebeau Mar 07 '20 at 18:53