Can I use Indy in Android and iOS apps? [duplicate] - delphi

I'm trying to download a file with TIdHTTP.Get in Delphi Seattle. It's an app for android and all my attempts fails. All i get it's the same error "Could not load SSL library". This is the procedure:
procedure TfrmMain.DownloadPicture(const AURL: string);
var
MeS: TMemoryStream;
cidSSL: TIdSSLIOHandlerSocketOpenSSL;
cidHTTP: TIdHTTP;
begin
cidHTTP:= TIdHTTP.Create(nil);
cidSSL:= TIdSSLIOHandlerSocketOpenSSL.Create(nil);
Mes := TMemoryStream.Create;
try
cidHTTP.ReadTimeout := 30000;
cidHTTP.IOHandler := IdSSL;
cidSSL.SSLOptions.Method := sslvSSLv3;
cidSSL.SSLOptions.Mode := sslmUnassigned;
cidSSL.StartSSL;
cidHTTP.Get(AURL, Mes);
except
on E : Exception do
begin showmessage('Error: '+E.Message);
end;
end;
Mes.Position := 0;
frmImage.Image.Bitmap.LoadFromStream(Mes);
end;

If you are NOT using Android 6 Marshmallow, OpenSSL should be working fine on Android. When you get the "could not load" error, you can call Indy's WhichFailedToLoad() function in the IdSSLOpenSSLHeaders unit to find out why OpenSSL could not be loaded. If your device does not have OpenSSL pre-installed, you can deploy the OpenSSL binaries with your app, and use Indy's IdOpenSSLSetLibPath() function to tell Indy where to load them from.
That being said, starting with Android 6 Marshmallow, Google no longer supports OpenSSL on Android. It has been replaced with a custom fork named BoringSSL, which Indy does not fully support yet (although some BoringSSL-related changes have been made to Indy after Seattle's release). So, if you are having trouble with using Indy SSL/TLS on Android 6, you can try upgrading to the latest Github snapshot to see if it helps.
BoringSSL makes some major changes to the OpenSSL API interface (dropping functions, changing data types, etc), so it is not backwards-compatible with existing OpenSSL code. But to make matters worse, BoringSSL uses the same library filenames as OpenSSL, and is pre-loaded at device startup, so it is not possible to deploy custom-built OpenSSL library binaries with your Android app. Android will simply use the pre-loaded BoringSSL binaries when the app tries to load the OpenSSL library filenames at runtime (regardless of whether you call Indy's IdOpenSSLSetLibPath() function).
Indy operates at the NDK level of Android, not the Java level, so to make Indy avoid BoringSSL would require users to either:
recompile the OpenSSL libraries with new filenames that don't conflict with BoringSSL (AFAIK no known version of this is available), and then update Indy to use those filenames.
compile the OpenSSL source code directly into their Android app. Indy is not currently setup to support static-linking of OpenSSL on any platform other than iOS, but this should be a minor change to update Indy's IdSSLOpenSSLHeaders_static unit with the relevant definitions if someone can produce viable .a files for OpenSSL on Android. I do know of at least one user attempting this route, but that user has not had success yet (errors getting the source code to fully link correctly).
switch to Android's higher-level Java-based crypto APIs. This is Google's preferred solution. But Indy does not support it at this time. Doing so would require writing a whole new set of TIdStack and TIdIOHandler classes for Android socket I/O and SSL/TLS, using JNI calls to access the Java APIs. But this has performance and threading issues that need to be dealt with.
So, there is no known viable workaround available at this time to make Indy SSL/TLS work on Android 6+.
Update: a user in the Embarcadero forums was able to find OpenSSL .so files that are compatible with Indy and work on Android 6:
https://forums.embarcadero.com/thread.jspa?threadID=211089
After many reports of my apps crashing if installed in Android 6 devices I've searched the net for some tips and the couple of needed .so compiled files, 1.02 version, added the two files to the play store deployment of my apps (assets\internal) and changed the Indy's path calling
IdOpenSSLSetLibPath(TPath.GetDocumentsPath)
in the OnCreate of my datamodule.
After those modifications of my code my Apps run perfectly on my brand new S7 with Android 6.0.1, and on all the other recent Android devices (tested using the Play Store deployment).
And now the Google warning pops up telling me that the OpsnSSL files deployed with my apps are not of the minimum required 1.02f version (or 1.01r).... and so my post in this forum.
...
Anyway you can download here the latest .so files, the ones that I deploy at this moment:
https://drive.google.com/file/d/0B7AxqW32K0oXWW9nUk9qaFpHT0k/view?usp=sharing
Another user in the same discussion also seems to have some success as well:
Ive been running on android 6 loading the .so libraries just fine for months. The new problem is we need to compile new versions of the openssl libraries. Cygwin is not working correctly to compile for me so im switching to a linux install to create them (if possible) https://wiki.openssl.org/index.php/Android#Build_the_OpenSSL_Library_2
heres a repository you can grab some current prebuilt ones https://github.com/emileb/OpenSSL-for-Android-Prebuilt.git
Update: The following (German) forum discussion provides OpenSSL 1.0.2g binaries for Android (and iOS Simulator) to registered users. They do not display the security warning in the Google Play store:
http://www.delphipraxis.net/188736-kompilierte-openssl-bibliotheken-fuer-android.html
OpenSSL 1.0.2g Android.zip
OpenSSL 1.0.2g iOS Simulator.zip
Update: the Android binaries for OpenSSL 1.0.2g are now available in the Embarcadero Attachments forum:
https://forums.embarcadero.com/thread.jspa?threadID=211147
Then, to load OpenSSL instead of BoringSSL, follow these steps:
Add the 2 .so files to your project deployment and set them to deploy to the .\assets\internal\ folder
add the System.StartupCopy unit as the first unit in your DPR's uses clause.
call IdOpenSSLSetLibPath(TPath.GetDocumentsPath) at app startup.
Update: OpenSSL 1.0.1t and 1.0.2h binaries are now in the Embarcadero Attachments forum:
https://forums.embarcadero.com/thread.jspa?threadID=211147
Update: the binaries have now been posted on Indy's Fulgan mirror:
http://indy.fulgan.com/SSL/
Update: Indy is no longer using the Fulgan mirror for hosting OpenSSL binaries. They are now in their own GitHub repo:
https://www.indyproject.org/2020/06/16/openssl-binaries-moved-to-github/
https://github.com/IndySockets/OpenSSL-Binaries

Just swap the TidHTTP component for TNetHTTPClient

Probably you have a new OpenSSL library and an older Indy version. Check this:
Indy 10 - IdSMTP.Connect raising "Could not load SSL library."

There are versions for 32/64 bits.
Make sure you have the correct version of the files.
See this FTP for correct version.
Other mirror for download binaries here.

I use this code and this works:
procedure TfPrecos.GetImageByUrl(URL: string);
var
Strm: TMemoryStream;
vIdHTTP: TIdHTTP;
cidSSL: TIdSSLIOHandlerSocketOpenSSL;
begin
IdOpenSSLSetLibPath(TPath.GetDocumentsPath); //libcrypto.so and libssl.so in ./assets/internal
vIdHTTP.IOHandler := cidSSL;
cidSSL.SSLOptions.Method := sslvSSLv23; // version 2.3
cidSSL.SSLOptions.Mode := sslmUnassigned;
cidSSL.StartSSL;
try
vIdHTTP.Get(URL, Strm);
if (Strm.Size > 0) then
begin
Strm.Position := 0;
try
Image1.Bitmap.LoadFromStream(Strm);
finally
end;
end;
finally
Strm.DisposeOf;
vIdHTTP.DisposeOf;
end;
end;

Related

Could not load SSL library [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 3 years ago.
Improve this question
I'm trying to use REST. So I'm using the TIdHTTP component. But it says 'Could not load SSL Library'.
What am I missing? My knowledge about SSL is zero.
I'm using Delphi 2007, Indy 10.1.5, and Windows 32-bit.
I put libeay32.dll and ssleay32.dll in my EXE directory (I found these DLL files at https://indy.fulgan.com/SSL/, file openssl-1.0.2t-i386-win32.rar).
type
TForm1 = class(TForm)
IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL;
...
procedure TForm1.btn_ReqCheckServerClick(Sender: TObject);
var
s: string;
lHTTP: TIdHTTP;
const
URL_CHECK_SERVER = 'http://example'; // some URL site to ping
begin
lHTTP := TIdHTTP.Create(nil);
try
lHTTP.IOHandler:=IdSSLIOHandlerSocketOpenSSL1;
IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method:=sslvTLSv1;
lHTTP.ProtocolVersion:=pv1_1;
lHTTP.Request.ContentType := 'application/json';
lHTTP.HandleRedirects := True;
s := lHTTP.Get(URL_CHECK_SERVER);
ShowMessage(s);
finally
lHTTP.Free;
end;
end;
Does anybody know where the latest version of Indy can be download? At https://www.indyproject.org, many links are broken.
Indy's SVN repository is being retired. Indy's GitHub repository at https://github.com/IndySockets/Indy is now the active repository moving forward. Fulgan has recently turned off its sync between Indy's SVN and GitHub repositories.
Fulgan's nightly zip file at https://indy.fulgan.com/ZIP/ is no longer the latest dev snapshot of Indy (there have been a few check-ins to GitHub since the last time Fulgan pulled its snapshot from SVN). It has become redundant since users can pull zip files of Indy's source code from GitHub instead.
Indy will also soon be making a new GitHub repository for its OpenSSL lib binaries, which will be the final nail in the coffin for Indy's Fulgan mirror.
Indy's website at https://www.indyproject.org has not been updated yet to reflect this new information. Though there is a link to the GitHub repository in the download section for the dev snapshot.
You can go to the GitHub repository and grab the /Lib folder. You only need the /Lib/Core, /Lib/Protocols and /Lib/System folders at a minimum to compile Indy.
I'm trying to use REST. So I'm using the TIdHTTP component. But it is not working. It says 'Could not load SSL Library'. I already read about this error from this forum, but still it is not working.
You can use Indy's WhichFailedToLoad() function in the IdSSLOpenSSLHeaders unit to find out why Indy could not load OpenSSL. Either the DLLs could not be loaded in memory, or the DLLs are missing exports that Indy requires.
Note, though, that 10.1.5 is an extremely old version of Indy, the latest version is 10.6.2. It is likely that 10.1.5 simply can't handle changes made to OpenSSL over the years since 10.1.5 was released. For instance, the removal of support for SSLv2 and SSLv3 is a likely culprit for an old version of Indy failing to load newer OpenSSL DLLs.
I am using :
Delphi 2007 (package version 110).
Windows 7.
Upgrade old Indy version ( Indy 10.1.5 ) to relative new Indy version ( Indy 10.6.2.5516 ).
Steps that I tried :
Component | Install packages... | Design Packages
point to Indy 10 Core Design Time, then click Remove button
point to Indy 10 Protocols Design Time, then click Remove button
delete all library path that refer to old Indy version
( Tool | Options | Environment Options | Delphi Options | Library - Win32 )
delete all IndySystem110.* IndyCore110.* and IndyProtocols110.* on PC.
open the individual DPK files in the IDE and I compile them, in the following order :
IndySystem110.dpk ( in Lib\System ) compile only.
IndyCore110.dpk ( in Lib\Core ) compile only.
IndyProtocols110.dpk ( in Lib\Protocols ) compile only.
dclIndyCore110.dpk ( in Lib\Core ), compile then install.
dclIndyProtocols110.dpk ( in Lib\Protocols ), compile then install.
Add Lib\System, Lib\Core, and Lib\Protocols to Delphi library path.
( Tool | Options | Environment Options | Delphi Options | Library - Win32 )
then I put libeay32.dll and ssleay32.dll with modified date 11/13/2015 7:55 AM both in my executable file folder location. It works !

Unable to load Firebird client library on Windows 10

Tw days ago, I installed Windows 10 build 1709 16299.192 and Embarcadero Delphi 10.2.2 Tokyo.
Since I installed them, my applications can't load the Firebird client library at runtime.
If I have an exe file compiled with older Windows and Delphi 10.2.2, it works fine, but every exe file compiled with the new Windows and Delphi are not working.
If I test a connection through TFDConnection, it connects successfully, but when I run the application I get this error:
[firedac][phys][fb]-314 cannot load vendor library [c:\users\username\desktop\projectname\bin\fbclient.dll] The specified module could not be found
Hint: check it is in the PATH or application EXE directories, and has x86 bitness.
The path is correct, and the client library is for x86. The same application was working before installing Windows 10 build 1907 16299.192.
I tried DevArt UniDac and compiled as Win64, still have the same problem.
Reinstalling Windows and Delphi 10.2.2 (tested with 2 versions 25.0.28979.1978 and 25.0.29039.2004) still didn't help.
I think it's a permissions issue, but I don't know how to fix it. I gave bds.exe all permissions over all groups, but still not working.
I have only this code on my test application
procedure TForm1.FormCreate(Sender: TObject);
var
Path: string;
begin
Path := IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName));
FDPhysFBDriverLink1.VendorHome := Path;
FDPhysFBDriverLink1.VendorLib := 'fbclient.dll';
FDConnection1.Params.Database := Path + 'FBDV3.0.FDB';
FDConnection1.DriverName := 'FB';
FDConnection1.Params.UserName := 'sysdba';
FDConnection1.Params.Password := 'masterke';
FDConnection1.LoginPrompt := False;
FDConnection1.Connected := True;
end;
Included Files and Folders in bin Folder:
plugins (Folder contain engine12.dll)
fbclient.dll
ib_util.dll
icudt52.dll
icudt52l.dat
icuuc52.dll
I just had to install the Microsoft Visual C++ 2010 Redistributable.
It took me hours of trying and trying many things, I couldn't find any clue what causes it, even by debugging deep into the FD sources (Delphi 10.4.2). Too bad there is no useful error message anywhere. But then I used SysInternals Process Explorer and found this dependency. Thanks to #Remy.
(Just copying msvcr100.dll didn't help in my case.)
Of course I cannot say if this would have helped here, but at least it could help many others. The symptoms were the same - it worked in the IDE (data explorer), but not in the compiled application, even though the dll was there.
By debugging I also verified that the error message asking for not only fbclient.dll, but also fbembed.dll, is not a sign of any wrong parameters: it is always looking for the second one if the first one cannot be loaded (not only if it is not found).

JEDI JclCompression extraction issues with latest 7z.dll

I have used JclCompression with the 32-bit version of 7z.dll 9.20 for quite a while and have recently tried to upgrade to a more recent version (16.04). With the update in 7z.dll versions, I am unable to extract Bzip2 archives or tarballs (.tgz), as well as some other formats. Is there something that changed with 7z.dll between 9.20 and 16.4 that would cause this?
I also tried 7z.dll from 9.38 and 15.14 but ran into the same issue.
More details:
Delphi XE3
JCL 2.8 Testing Build 5677
7z.dll from 7z1604.exe (32-bit)
Any .bz2 file I've tried gives me the following error:
First chance exception at $0040D523. Exception class $C0000094 with
message 'integer divide by zero at 0x0040d523'.
Debug Output: Exception:Catastrophic failure Process myapp.exe (2400)
I've followed the extraction code on this post. Here's my thread's procedure for extraction where I see the error:
procedure TExtractThread.Execute();
begin
if FArchive.ItemCount > 0 then
begin
FArchive.OnProgress := ArchiveProgress;
FExtractionError := False;
try
FArchive.ExtractAll(FOutputDir);
except on E: Exception do
begin
FExtractionError := True;
OutputDebugString(pchar('Exception:'+E.Message));
end;
end;
end;
end;
7zip was in alpha/beta mode for years after v9.20 (2010). The first subsequent stable release was V15.12 (Nov 2015) which came out several months after the JCL version you are using was released (2.8 Testing Build 5677, Sep 2015). Support for 7z.dll version 15.14 was added Jan 3, 2016. There does not seem to be any further updates checked in for newer DLL versions than this. If you want to use a newer version of 7Zip you should probably update your JCL to a current version.
If you don't want to be testing beta or daily builds then the current stable JCL release (V2.4.1) is distributed with 7z.dll version 9.22 and you should stick with that if you need reliability more than any new features that have been introduced in the meantime.

Safest way of using Outlook ActiveX

Just after running my Delphi application i check for the installed MS Outlook version because my app works differntly if in the machine there is a Outlook version greater than 2007.
I also wrote an Outlook Addin that sometimes crashes. I suspect
those crashes are related to the Outlook instances I create at startup.
Is there a way to create these ActiveX instances in a "softer way". As i create the OLE object now I see in Tray Bar an icon whose hint says "Outlook is being used by another application", may be if it were possible to remove this I would also see my problems disappear.
Somehow what I would like to achive is the same done here, where the wdDoNotSaveChanges parameter allows a "smoother" use of the OLE Object.
This is the code i use to check for Outlook version:
var
OutlookApp: OLEVariant;
Version : String;
begin
{ Create the OLE Object }
Try
OutlookApp := CreateOLEObject('Outlook.Application');
Version := OutlookApp.version;
OutlookVersion := StrToint(SubstrEx(1,Version,'.'));
OutlookApp := VarNull;
except
on E: Exception do
begin
OutlookVersion := -1;
end;
End;
Your approach is different from the one suggested by Microsoft here:
How to: Check the Version of Outlook .
Their version uses the Microsoft Installer functionality to detect the location of the Outlook executable, then extract the file version straight from there. This approach doesn't suffer from any of the problems you might encounter when instancing Outlook like you do. It is also a lot faster.
It does however suffer from one major disadvantage: it will only work if Outlook is deployed properly, the Microsoft way. On consumer machines this isn't so much of a problem, but in enterprise environments you might (/will) occasionally run into stripped down custom installs by overzealous IT departments that do not include the necessary MSI footprint.
Depending on your target audience, that might not be a real problem at all.

How can I get Delphi XE2 to talk to Google Calendar APIs over SSL?

It's time for this question again, but this time with Delphi XE2.
I am using the Indy version 10.5.8.0 that ships with XE2, and I have tried four different versions of the SSL dlls. I have tried 1.0.x latest, and about 3 different 0.9.8 versions (e,h,x,....).
None of them works, when communicating to https:// urls at calendar.google.com. The author of the Delphi Google Calendar component at "Sync-components.com" ships his own binary
openssl DLL runtimes that have no version information in it, but it seems to be a very small, very old version of SSL libs older than 0.9.8. The author of the component says only his private unversioned DLLs are known to work. I can't believe that. Surely at least one version of the openSSL dlls works well enough with Delphi XE2 to connect to Google Calendar.
In order to get his custom ancient DLL to load into Indy 10 in Delphi XE2, he modifies IdSSLOpenHeaders.pas method Load, like this, at the end:
function Load: Boolean;
begin
/// ... lots of stuff
//Result := (FFailedFunctionLoadList.Count = 0); // original.
Result := (FFailedFunctionLoadList.Count <= 18); // changed to.
end;
Of course, the component that I am evaluating does not work in XE2, but I suspect it's the brokenness of either (a) this particular snapshot of Indy 10 that ships with XE2, or (b) the fact that the World of SSL DLLs is a veritable hell of "broken for you but works for me" different versions.
What do I have to do to get an SSL connection to Google Calendar, using Indy (or any other delphi component library with SSL support), in Delphi XE2?
Alternatively, if anyone has a google calendar API implementation that works with anything other than Indy that I could use for testing, I would appreciate links and pointers.
There is something wrong with the snapshot of Indy10 that ships with XE2, in that the idHTTP object appears not to work well with any of the OpenSSL dlls I found, in that I could not communicate with any Google Calendar server services with them.
The actual underlying nature of the problem seems to be that Indy doesn't handle HTTP redirects as transparently as we might have hoped. The code that is manipulating Indy (third party component) does some really hard to understand things with the Indy "http redirect" handling logic that appears to be a set of workarounds, that don't work. What is furthermore confusing, is that the exact places in the code where HTTP redirects occur varies from one person testing Google Calendars, to another, so these redirect glitches do not always appear in the same places for each person testing it.
Note that the login method, and method to get the calendars worked. But the methods and code that were to read events, seem not to work. I was unable to figure out the difference between the two, but the code I am using is commercial and I can't post any of it. I will update this message if I ever figure out the actual technical reason that the HTTP get request was returning "0 bytes" in its response for urls like this:
https://www.google.com/calendar/feeds/firstname.lastname%40gmail.com/private/full?max-results=100000
Those zero byte results were really HTTP 302 redirect response code, which the code I was using, did not check for or expect. It was expecting Indy to automatically handle redirects.
The problem could either that Indy10 version is very specific and only works with a version of the openSSL dlls that I didn't happen to find in my searching today, or that the Indy10 version that ships with XE2 doesn't work with ANY version of the OpenSSL dlls that I could find, at least not when the target it's talking to is google's HTTPS calendar servers.
The code I am running creates an IdHTTP object with a TIdSSLIOHandlerSocketOpenSSL.
This works in all versions of Delphi up to and including XE, but breaks with a factory XE2 system, due to the Indy version shipping with XE2.
The only fix I have found is to install a new nightly build of Indy, I grabbed 4760, which appears to work fine, when combined with OpenSSL dll version 1.0.1.
It looks to me like using OpenSSL with Delphi XE2 is a bit difficult out of the box. A huge thank you to the Indy team for working so hard.... But can someone please help them out? This is really a great project and a great product, but when it breaks, and when you have to follow a moving standard (like the openSSL implementation), perhaps a bit more documentation, and testing, and eyeballs would help. I stand ready to assist if anybody can show me how I could help out. The problems with SSL are not indy-specific, as I notice that other component vendors and open source people have specific versions of the OpenSSL dlls that they support or don't support.
Another sad things I learned today: Some of the installers from OpenSSL install their DLLs by default (without warning) into your windows System32 directory, causing not only your app, but others, like TortoiseHG and TortoiseSVN, to perhaps break. If you didn't have a big problem with SSL before you started playing around, you could easily make it worse if you install a bunch of installer-versions from the OpenSSL website.

Resources