2

My Win32 program fails after an upgrade from OpenSSL 1.02f to 1.02g.
I made sure to reboot after the upgrade, and I have verified that the correct libeay32.dll, libssl32.dll, and ssleay32.dll are in C:\Windows\SysWOW64 (and it does not help either if I copy them to my app directory).

var
  lIOHandleSSL      : TIdServerIOHandlerSSLOpenSSL;
  FWebBrokerBridge  : TIdHTTPWebBrokerBridge;       // = class(TIdCustomHTTPServer)
begin    
  FWebBrokerBridge := TIdHTTPWebBrokerBridge.Create(Self);    
  LIOHandleSSL := TIdServerIOHandlerSSLOpenSSL.Create(FWebBrokerBridge);    // LIOHandleSSL.SSLOptions.method is sslvTLSv1
  LIOHandleSSL.SSLOptions.CertFile     := ...
  LIOHandleSSL.SSLOptions.RootCertFile := ...
  LIOHandleSSL.SSLOptions.KeyFile      := ...
  LIOHandleSSL.OnGetPassword := HTTPSIOHandlerSSLOpenSSLGetPassword;
  FWebBrokerBridge.IOHandler := LIOHandleSSL;
  FWebBrokerBridge.Active := true;

The error is EIdOSSLCouldNotLoadSSLLibrary: Could not load SSL library on the 'Active' statement.

What can be going on, and how to fix it?

It's a Delphi XE2 app, the Indy version is 10.5.8.0

FWIW Here is the OpenSSL 1.02g changelog

[Edited to add]
- We use this OpenSSL binary installer.
- I added the WhichFailedToLoad() function (from IdSSLOpenSSLHeaders.pas) and it returns the following string: SSLv2_method,SSLv2_server_method,SSLv2_client_method
- I have removed the description of my certificate files from this question. Ken White correctly remarked that the code is not at the stage yet where the certs are loaded

Jan Doggen
  • 8,799
  • 13
  • 70
  • 144
  • 3
    Call `WhichFailedToLoad()` and report what it returns. Use Dependency Viewer profile mode to get detailed diagnostics of why the DLL cannot be loaded. I have to chide you on placing these DLLs in the system directory. The system directory belongs to the system. Please don't pollute it. – David Heffernan Mar 09 '16 at 15:13
  • @DavidHeffernan You have a point. It's the default option of the installer. Maybe we should instruct our customers otherwise. – Jan Doggen Mar 09 '16 at 15:19

1 Answers1

5

This is covered here: http://www.indyproject.org/sockets/blogs/changelog/20150907.en.aspx

In summary, SSLv2 is not secure, so some distributors of OpenSSL disable SSL2. You appear to be using such an OpenSSL. Older versions of Indy regard the following functions as critical:

  • SSLv2_method
  • SSLv2_server_method
  • SSLv2_client_method

These versions of Indy will fail to load if these functions are not exported by the OpenSSL DLLs.

To get past this problem you will need to do one of the following:

  • Find OpenSSL DLLs that do not disable SSLv2. This does not sound like a clever way to tackle your problem.
  • Upgrade to a version of Indy that can handle SSLv2 being disabled.
  • Upgrade to Delphi 10 Seattle Update 1 which includes Indy revision 5311 is the earliest Delphi version to deal with the issue.
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Or compile OpenSSL yourself, enabling the "enable-ssl2" option. Either way, if you obtain SSLv2-enabled DLLs, you won't be able to *use* SSLv2 if needed (but why would you?) if `TIdSSLIOHandlerSocketOpenSSL.SSLOptions.Method` is set to `sslvSSLv23` due to this note in OpenSSL's news release: "*Even if "enable-ssl2" is used, users who want to negotiate SSLv2 via the version-flexible `SSLv23_method()` will need to explicitly call either of: `SSL_CTX_clear_options(ctx, SSL_OP_NO_SSLv2);` or `SSL_clear_options(ssl, SSL_OP_NO_SSLv2);` as appropriate.*" You need the latest Indy to account for that. – Remy Lebeau Mar 09 '16 at 20:58
  • @Remy If I understand you correctly, compiling OpenSSL with that option, and *not* using SSL2, does *not* require an Indy update? – Jan Doggen Mar 10 '16 at 07:22
  • Additional note for readers: upgrading to the currenty latest Delphi 10 Seattle is not good enough. This has Indy files dated August 2015 (version 10.6.2.5311) and the change in the link David provides describes changes made to Indy in September 2015 – Jan Doggen Mar 10 '16 at 11:20
  • @JanDoggen: If the `sslvSSLv2` flag is not enabled in the `TIdSSLIOHandlerSocketOpenSSL.SSLOptions.SSLVersions` property, Indy will not use the DLL's `SSLv2_xxx_method()` functions. However, you will still need to use an Indy version that will not fail to load OpenSSL if the `SSLv2_...` functions are not present in the DLLs. That was part of the Sept 2015 update. – Remy Lebeau Mar 10 '16 at 19:49
  • @RemyLebeau Which SVN revision of Indy10 is included in Delphi 10 Seattle / Delphi 10 Seattle Update 1? – Marc Durdin Mar 10 '16 at 20:55
  • 1
    @MarcDurdin: Right-click on any Indy component in the Form Designer to see the installed Indy version, the SVN revision number is the last component of the version number. SVN revision 5298 is in the RTM release of Seattle (Delphi releases are tagged in Indy's SVN). Indy updates are not included in Delphi updates. The fixes to handle SSLv2 were made in revisions 5303 and 5346. – Remy Lebeau Mar 10 '16 at 21:55
  • @RemyLebeau Delphi 10 Seattle Update 1 includes an updated Indy revision 5311. – Marc Durdin Mar 11 '16 at 00:57
  • I have just verified dat Seattle Update 1 indeed handles OpenSSL 1.0.2.g correctly. – Jan Doggen Mar 21 '16 at 12:14
  • @JanDoggen: Not entirely, if Update 1 only includes rev 5311. Like I said earlier, rev 5346 has an additional fix related to 1.0.2g. – Remy Lebeau Mar 31 '16 at 20:18
  • @Remy Can you elaborate on that? I made a small test app that crashed on startup (Could not load SSL library SSLv2_method, SSLv2_server_method,SSLv2_client_method) when compiled with XE2, but ran correctly under Seattle Update 1. Was 'passing' that code (the TIdHTTPWebBrokerBridge.Active := True) not good enough? I don't need to 'handle' SSL2, only TLS versions are accepted in my code. – Jan Doggen Apr 01 '16 at 08:38