0
votes

I'm trying to implement SSL support on my HTTP server and I'm getting an exception when I activate the server component:

The ordinal 3314 could not be located in the dynamic link library "ssleay32.dll".

This is an application that I ported from Delphi 2007 to Delphi XE7. It had been working in 2007.

Here's what I've tried:

  • Got the latest OpenSSL DLLs. Same error

  • Created a new XE7 test project that was simply a form with the HTTPServer and OpenSSL IOHandler components. It worked.

  • I'm not using the visual components in my primary app; so I thought I'd try creating a form in the primary app. I added the appropriate components, and it failed with the same error.

  • Since the project was ported from D2007, I thought there may be settings in the old project that may be interfering. I created a new DXE project and imported the forms, units, etc. Same error.

  • I thought possibly my manually generated code may be incorrect, so I copied it over to the test DXE project; and it worked.

I did discover the error is being thrown by a call to LoadLibrary in SafeLoadLibrary in System.Sysutils.

My only conjectures are.

  • There's a setting somewhere interfering with correct operation.

  • There's a path to a supporting DLL that is missing

Any ideas?


It turns out I have old libeay32.DLL and ssleay32.DLL (for Indy9) in the same folder as the EXE, and the latest versions in a sub-folder. I'm using IdOpenSSLSetLibPath to set the path to the sub-folder, but something must be loading the old libeay32.DLL prior to the Indy components. For historical reasons, I need to support both - I've still got some D2007 code running with Indy9 components. Any thoughts on how I can support this scenario (short of rewriting a lot of old code to use Indy 10)?

1
OpenSSL functions are typically exported by name, and Indy does not import any OpenSSL functions by ordinal. The only way that error should ever occur is if your app itself, or another DLL that it loads, is static-linking to ssleay32.dll functions using ordinals instead of names.Remy Lebeau
I'm sure it's another DLL now, simply because the exception occurs during the LoadLibrary call with ssleay32.dll. I'm not explicitly linking any DLL functions statically. This is also a port from Indy9. I wonder if there's any units I'm including that would be affecting this.Kevin Koehne
The only way (that I know of) for LoadLibrary() to report such an error about ssleay32.dll when loading ssleay32.dll is if ssleay32.dll has static references to itself in its own PE IMPORTS table. The standard OpenSSL DLLs (or any DLL, for that matter) should never do that. Which implies the DLLs you are using were likely compiled incorrectly to begin with, and that would also account for why the static imports are using ordinals instead of names.Remy Lebeau
As for the path issue, move the old DLLs to their own subfolder. Indy 9 does not have IdOpenSSLSetLibPath(), so call SetDllDirectory() or AddDllDirectory() at startup to add that path to the OS search path. Or use DLL redirection, or a manifest, to let the OS know the OpenSSL DLLs are located at that path. See MSDN for details...Remy Lebeau
... or just load the DLLs from the subfolder yourself at program startup (if you can do so before the other module does).Remy Lebeau

1 Answers

0
votes

Turns out I had included one of our internal libraries that uses the Synapse TCP/IP library. Its SSL implementation loads the DLLs during initialization, which were the DLLs installed at the root of the application. When Indy tried to load the latest, it failed. There didn't appear to be any way to override the path for the DLLs in Synapse, so I modified the source to load them from the sub-folder.