Lazarus

Programming => Networking and Web Programming => Topic started by: JohnnieK on November 20, 2018, 11:18:54 am

Title: [Solved] Lazarus fphttpclient and ssl
Post by: JohnnieK on November 20, 2018, 11:18:54 am
Hi

I am trying to do a simple web page download using fphttpclient. I am running it on OpenSUSE Leap 15 (64bit).

The code below:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2.  Var S    : string;
  3.      HTTP : TFPHttpClient;
  4.   begin
  5.    HTTP := TFPHttpClient.Create(nil);
  6.    S := HTTP.Get('https://www.google.com');
  7.    HTTP.Free;
  8.    Memo1.Text:= S;
  9.   end;
  10.  
  11.  
crashes with an exception that GDB cannot catch. I traced it to this piece of code inside fpopenssl.

Code: Pascal  [Select][+][-]
  1. Constructor TSSLContext.Create(AType: TSSLType);
  2.  
  3. Var
  4.   C : PSSL_CTX;
  5.  
  6. begin
  7.   C := nil;
  8.   Case AType of
  9.     stAny:  C := SslCtxNew(SslMethodV23);
  10.     stSSLv2: C := SslCtxNew(SslMethodV2);
  11.     stSSLv3: C := SslCtxNew(SslMethodV3);
  12.     stTLSv1: C := SslCtxNew(SslMethodTLSV1);
  13.     stTLSv1_1: C := SslCtxNew(SslMethodTLSV1_1);
  14.     stTLSv1_2: C := SslCtxNew(SslMethodTLSV1_2);
  15.   end;
  16.   if (C=Nil) then
  17.      Raise ESSL.Create(SErrCountNotGetContext);
  18.   Create(C);
  19. end;

The above code return C=nil and then the exception is thrown. The installed version of openssl is 1.1

Any ideas on what could be wrong ?

Thanx
Title: Re: Lazarus fphttpclient and ssl
Post by: upsidasi on November 20, 2018, 12:41:49 pm
make sure you have openssl 1.0 installed.
You can check it running
  ldconfig -pv | grep 'libssl\.\|libcrypto\.'
Title: Re: Lazarus fphttpclient and ssl
Post by: Thaddy on November 20, 2018, 12:49:39 pm
This is enough:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$H+}
  2. uses fphttpclient, fpopenssl;
  3. Var S    : string;
  4.   HTTP : TFPHttpClient;
  5. begin
  6.   HTTP := TFPHttpClient.Create(nil);
  7.   try
  8.     S := HTTP.Get('https://www.google.com');
  9.     writeln(s);
  10.   finally
  11.     http.free;
  12.   end;  
  13. end.

Title: Re: Lazarus fphttpclient and ssl
Post by: JohnnieK on November 20, 2018, 12:59:34 pm
Output of ldconfig -pv | grep 'libssl\.\|libcrypto\.'
Code: Pascal  [Select][+][-]
  1.         libssl.so.1.1 (libc6,x86-64) => /usr/lib64/libssl.so.1.1
  2.         libssl.so.1.1 (libc6) => /usr/lib/libssl.so.1.1
  3.         libssl.so.1.0.0 (libc6,x86-64) => /usr/lib64/libssl.so.1.0.0
  4.         libssl.so (libc6,x86-64) => /usr/lib64/libssl.so
  5.         libcrypto.so.1.1 (libc6,x86-64) => /usr/lib64/libcrypto.so.1.1
  6.         libcrypto.so.1.1 (libc6) => /usr/lib/libcrypto.so.1.1
  7.         libcrypto.so.1.0.0 (libc6,x86-64) => /usr/lib64/libcrypto.so.1.0.0
  8.         libcrypto.so (libc6,x86-64) => /usr/lib64/libcrypto.so
Title: Re: Lazarus fphttpclient and ssl
Post by: Thaddy on November 20, 2018, 01:01:17 pm
Try my code. works.
Title: Re: Lazarus fphttpclient and ssl
Post by: CCRDude on November 20, 2018, 01:21:37 pm
Depending on the server on the other side, I had the experience that on Linux and Mac, I had to set the TLS version manually to be able to connect to https sources. That was Synapse, but that uses OpenSSL as well... see this thread (https://forum.lazarus.freepascal.org/index.php/topic,43113.msg301418.html#msg301418).
Title: Re: Lazarus fphttpclient and ssl
Post by: Thaddy on November 20, 2018, 01:43:25 pm
Note I came across some major sites (like a lot of google) that even dropped t;ls1.1. So best practice is at least tls 1.2 if you have to set it manually. I didn't have to do that with the above code.
Title: Re: Lazarus fphttpclient and ssl
Post by: JohnnieK on November 20, 2018, 02:06:11 pm
I have made some progress. On OpenSUSE Leap 15.0 openssl 1.1 is the default. libssl.so is a softlink to libssl.so.1.1 and the same for libcrypto. I created a softlink libssl1.so -> libssl.s0.1.0 and the same for libcrypto. I then modified openssl.pas lines 106 and 107 as follows:
Code: Pascal  [Select][+][-]
  1.   DLLSSLName: string = 'libssl1';
  2.   DLLUtilName: string = 'libcrypto1';
  3.  
Now I can connect to some https sites (like my home server running apache), but not to Google. This must be related to the TLS versions - I just don't know where to set the TLS version in fphttpclient.
Title: Re: Lazarus fphttpclient and ssl
Post by: Thaddy on November 20, 2018, 04:04:44 pm
Try the
   AllowRedirect := true property from TFPHTTPClient.

In general protocol handshakes are made with TLS1.2 first, so that is not likely the issue.

403
Title: Re: Lazarus fphttpclient and ssl
Post by: guest58172 on November 20, 2018, 06:55:44 pm
Maybe the SSL context ? There's this annoyinh issue : https://bugs.freepascal.org/view.php?id=32789

Basically this means that you cant do secure request out of the box, i.e using fcl-web >:(
Title: Re: [Solved] Lazarus fphttpclient and ssl
Post by: JohnnieK on November 21, 2018, 11:20:42 am
OK, so finally solved the issue. I had to do the following:

1. OpenSUSE Leap 15 ships with both openssl 1.0 and 1.1. openssl 1.1 is the default and libssl.so is soft linked to openssl 1.1. I created 2 new softlinks for libssl and libcrypto and changed the dll names in openssl.pas.

2. I had to allow redirects and add a useragent to get https://www.google.com to work. Code below works now:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2.  Var S    : string;
  3.      HTTP : TFPHttpClient;
  4.   begin
  5.    HTTP := TFPHttpClient.Create(nil);
  6. //   HTTP. .Sock.SSL.SSLType := LT_TLSv1_2;
  7.    HTTP.AllowRedirect:=True;
  8.    HTTP.AddHeader('User-Agent','Mozilla/5.0 (compatible; fpweb)');
  9.    S := HTTP.Get('https://www.google.com');
  10.    HTTP.Free;
  11.    Memo1.Text:= S;
  12.   end;    

Thanx for all who assisted
TinyPortal © 2005-2018