Recent

Author Topic: [SOLVED] OpenSSL, fphttpclient, and Windows  (Read 5543 times)

edvard

  • Full Member
  • ***
  • Posts: 172
[SOLVED] OpenSSL, fphttpclient, and Windows
« on: July 20, 2017, 10:22:37 am »
Hello good folks, I have a bit of a problem. 
A while ago, I wrote a Pastebin app.  Simple really, nothing to get excited about.  Lately, Pastebin.com has announced that by August 1st, all calls to the API will be HTTPS-only, and calls to the API over HTTP will be rejected.  No problem in the application, because fphttpclient supports HTTPS, so I simply convert all the "http" in my code to "https".  Voila!  It works for Linux and Mac, because most (if not all) Linux distributions have OpenSSL installed by default, and Mac users can find it a simple install step away.  Windows users...  :'(

I did some testing in a Windows 10 VM, and the app works just fine as long as OpenSSL binaries matching the application's architecture are either present in the application directory, or copied to C:\windows\system32.  So that means my Windows users have to search for a binary, download one that matches the architecture of my Pastebin app, unzip the archive, and finally place the .dll files in the appropriate place.  I'd rather spare them that bit of pain.  "But edvard," you might say, "your users downloaded and used your application just fine, this should be trivial."  I'd like to say so, but I'd rather be safe than sorry and make it as painless as possible. 

Some things I've thought up (in order of difficulty):
1- Post a simple README on my SourceForge page that warns people of the situation before downloading, and maybe some instructions.
2- Do a check if SSL is installed on the machine at app startup, and popping up a warning (with instructions) if it is not found.
3- Use a network library other than fphttpclient that contains an SSL implementation, so installing 3rd-party libraries is not necessary. 

There is a 4th option, bundling the DLLs in the package for Windows users, but I am not interested in being a distributor of someone else's binaries and keeping up to speed on all the licensing requirements. 
I'd like to do #2, but I have no idea how to do such a simple check (Google was no help). #3 could be elegant, or it could be a total kluge, and I have no idea either way, SO:
- Do you think #1 should be enough? (I'm thinking it's the least I should do, really)
- I like #2, but how would I implement it?
- Is #3 even possible? (using Indy, I suppose... dunno really)
- Is there another way to go about this that I am totally missing?
« Last Edit: July 24, 2017, 06:11:31 am by edvard »
All children left unattended will be given a mocha and a puppy.

Arch (though I may go back to Debian)| FreePascal 3.2.2 + Lazarus 2.2.4, GTK2+ and Qt.  Mostly Qt...

balazsszekely

  • Guest
Re: OpenSSL, fphttpclient, and Windows
« Reply #1 on: July 20, 2017, 11:11:56 am »
@edvard
Quote
2- Do a check if SSL is installed on the machine at app startup, and popping up a warning (with instructions) if it is not found

Lazarus already implemented this feature for you  ;):
Code: Pascal  [Select][+][-]
  1. uses zipper, fphttpclient;
  2.  
  3. function TForm1.IsOpenSSLAvailable: Boolean;
  4. const
  5.   {$IFDEF WIN64}
  6.     cOpenSSLURL = 'http://packages.lazarus-ide.org/openssl-1.0.2j-x64_86-win64.zip';
  7.   {$ENDIF}
  8.   {$IFDEF WIN32}
  9.     cOpenSSLURL = 'http://packages.lazarus-ide.org/openssl-1.0.2j-i386-win32.zip';
  10.   {$ENDIF}
  11. var
  12.   {$IFDEF MSWINDOWS}
  13.   UnZipper: TUnZipper;
  14.   FHTTPClient: TFPHTTPClient;
  15.   ParamPath, LibeayDLL, SsleayDLL, ZipFile: String;
  16.   {$EndIf}
  17. begin
  18.   {$IFDEF MSWINDOWS}
  19.   ParamPath := ExtractFilePath(ParamStr(0));
  20.   LibeayDLL := ParamPath + 'libeay32.dll';
  21.   SsleayDLL := ParamPath + 'ssleay32.dll';
  22.   Result := FileExists(Libeaydll) and FileExists(Ssleaydll);
  23.   if not Result then
  24.   begin
  25.     ZipFile := ParamPath + ExtractFileName(cOpenSSLURL);
  26.     FHTTPClient := TFPHTTPClient.Create(nil);
  27.     try
  28.       try
  29.         FHTTPClient.Get(cOpenSSLURL, ZipFile);
  30.        except
  31.        end;
  32.     finally
  33.       FHTTPClient.Free;
  34.     end;
  35.     if FileExists(ZipFile) then
  36.     begin
  37.       UnZipper := TUnZipper.Create;
  38.       try
  39.         try
  40.           UnZipper.FileName := ZipFile;
  41.           UnZipper.Examine;
  42.           UnZipper.UnZipAllFiles;
  43.         except
  44.         end;
  45.       finally
  46.         UnZipper.Free;
  47.       end;
  48.       DeleteFile(ZipFile);
  49.       Result := FileExists(Libeaydll) and FileExists(Ssleaydll);
  50.     end;
  51.   end;
  52.   {$ELSE}
  53.   FOpenSSLAvailable := True;
  54.   {$ENDIF}
  55. end;
  56.  
  57. procedure TForm1.FormCreate(Sender: TObject);
  58. begin
  59.   if not IsOpenSSLAvailable then
  60.     MessageDlg('OpenSSL dll''s are not available', mtInformation, [mbOk], 0);
  61. end;
  62.  
« Last Edit: July 20, 2017, 11:29:58 am by GetMem »

edvard

  • Full Member
  • ***
  • Posts: 172
Re: OpenSSL, fphttpclient, and Windows
« Reply #2 on: July 20, 2017, 11:13:46 am »
I love this place.    8)
All children left unattended will be given a mocha and a puppy.

Arch (though I may go back to Debian)| FreePascal 3.2.2 + Lazarus 2.2.4, GTK2+ and Qt.  Mostly Qt...

Phil

  • Hero Member
  • *****
  • Posts: 2737
Re: OpenSSL, fphttpclient, and Windows
« Reply #3 on: July 20, 2017, 03:06:12 pm »
and Mac users can find it a simple install step away.  Windows users...  :'(

All Macs include old version of OpenSLL libraries that have been deprecated for many years:

https://developer.apple.com/library/content/documentation/Security/Conceptual/cryptoservices/SecureNetworkCommunicationAPIs/SecureNetworkCommunicationAPIs.html#//apple_ref/doc/uid/TP40011172-CH13-SW3

On Mac, instead of fphttpclient, use the ns_url_request unit here:

https://macpgmr.github.io/ObjP/nsunits-src.zip

It uses Apple's Secure Transport API.

 

TinyPortal © 2005-2018