Indy 10 and OpenSSL
Asked Answered
P

2

6

I have recently upgraded my Delphi 7 to Delphi XE2 and I'm kinda new to it. I used Indy 10 with OpenSSL to receive HTTP Content. It works just fine and I would like to share my program with with other people. I just found out that my programs won't work on other PCs without the OpenSSL Libraries. I didn't even get an exception, error, etc. of missing DLL files. I thought Indy10 has either native SSL support or at least uses the DLLs from resources after compiling, so it would be portable. I have 2 questions:

1) How could I let the user know that he/she is missing the OpenSSL Libraries? (Friends of mine reported no exception, errors, etc. WITHOUT the OpenSSL DLLs.)

2) Is it possible to let Indy10 read the OpenSSL Libraries from resources?

Peppery answered 3/5, 2013 at 21:32 Comment(0)
J
11

Indy does not implement SSL natively. What it does is implements a flexible IOHandler architecture that allows for any SSL implementation to be plugged into Indy. Indy itself implements its own IOHandler class that is based on OpenSSL (MS CryptoAPI support is planned for the future). SecureBlackbox, for example, provides an Indy IOHandler class for its own SSL engine.

On most platforms, OpenSSL is used via external DLLs, which cannot be used from resources. Indy does not ship with OpenSSL DLLs, because OpenSSL encryption is restricted by international import/export laws, so either OS vendors that ship internationally have special licenses to ship OpenSSL DLLs, or end-users have to download/compile OpenSSL themselves locally. That is what makes Indy "portable" when it comes to OpenSSL - Indy uses whatever OpenSSL DLLs are pre-installed outside of Indy, either in the OS or in your app's own installation folder.

The only exception to this that concerns Indy is OpenSSL on iOS, which requires OpenSSL to be used statically because third-party dynamic libraries are not allowed on iOS devices.

If you want to use OpenSSL statically with Indy on other platforms, you have to compile/obtain the static version of OpenSSL yourself and add it to your project, then recompile Indy to enable its STATICLOAD_OPENSSL define (which is currently only defined for iOS), and finally include the IdSSLOpenSSLHeaders_static.pas unit in your code's uses clause to hook up the necessary support code. Note that this is supported only in the recently released Indy 10.6 version.

If that is too much work for you, then use a third-party SSL implementation that is compatible with Indy, such as SecureBlackbox, or write your own IOHandler class that does what you need.

As for your other questions:

1) Indy does raise exceptions if it cannot load OpenSSL correctly during socket operations. So chances are those exceptions are getting caught and swallowed before you have a chance to report them to your users. If you don't want to rely on that, then you can manually call Indy's Load() function in the IdSSLOpenSSLHeaders.pas unit before starting your socket work. Load() will load OpenSSL into memory if it is not already loaded. If Load() fails, you can then call the WhichFailedToLoad() function in that same unit to find out why Load() failed.

2) No, it is not possible to use OpenSSL from resources (without some really serious low-level trickery).

Jimmie answered 3/5, 2013 at 22:19 Comment(5)
Why doesn't Indy implement SSL natively? Everybody suffers because of these external dll required.Deangelo
It would be a major undertaking to implement SSL natively. Why waste the time and effort when others already provide implementations? In any case, I did mention that we plan on creating an IOHandler wrapper for CryptoAPI, so that will solve the DLL and import/export issues on Windows since it is built-in to the OS. On other platforms, OpenSSL is commonly used.Jimmie
Other popular libraries, like ICS and Synapse, do not implement SSL natively, either. They reli on external libs like OpenSSL and others.Jimmie
@Remy Does Indy implement a wrapper for CryptoAPI or not yet?Relevant
@NasreddineGalfout no, not yet. It is still on the todo listJimmie
T
1

1) Try to load e DLL yourself before call Indy, and if LoadLibrary fails you can raise an Exception.

2) You can, look this:

Load a DLL From a Resource Directly From Memory in Delphi Applications

Tedesco answered 3/5, 2013 at 21:43 Comment(5)
This should work, but I will have to edit the actual Indy SourceCode and I don't know where to start.Peppery
Why would you edit Indy Code? The application will load the dll only once, so if you load it before call indy, you will be fine.Tedesco
I don't know if this possible, what if Indy already calls LoadLibrary BEFORE I do (Initialization). And what if Indy calls GetModuleHandle, etc. It would load the libraries probably twice or something. Haven't tested anything yet but I will do so later to see if it works.Peppery
Does BTMemoryLoadLibary from BTMemoryModule actually add the Module into the list of loaded Modules of a process?Peppery
Indy does not load OpenSSL DLLs into memory until they are needed. Indy does not use GetModuleHandle(), it loads the DLLs via LoadLibrary() and keeps track of those handles, closing them when they are no longer needed.Jimmie

© 2022 - 2024 — McMap. All rights reserved.