Seems I'm some kind of bug magnet lately for obscure issues. :(
Seems I'm some kind of bug magnet lately for obscure issues. :(
I tested the same test app I posted about 2.5h ago on my old Samsung Galaxy Note 2.
When run there it generates the following error when it tries to hit a web service:
error: 1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac.
The server in question is an IIS box acting as reverse proxy to a Delphi web service e.g. at present Delphi is not handling the SSL, it is just a plain service, and the SSL is handled by the IIS box. The web service being accessed is basically Delphi implemented SOAP invokable interfaces via SOAP client module imported with the Delphi WSDL importer.
Some quick googling seems to suggest this error happens in multiple environments/languages/servers and is related to OpenSSL version(s).
So it's not entirely clear if it's due to server, client or either/both, but note the following:
1) The same phone can access the web service just fine via the phone's browser.
2) The same app works fine when the it is compiled as Windows app
3) The same app works fine when run via the Android emulator
4) The web service has already been working fine in a staging semi-production environment for other third parties and non-delphi apps for some time (although access is not in this instance directly via SOAP but via JSON, but that's basically an irrelevance.)
So, although I can't totally discount issues with the server setup, it seems relatively unlikely, given that the only client that I know of that has a problem at this stage is the Delphi generated app, on my physical phone. (But note again, the same phone can talk to the service with its built in browser, so it's not just that the phone is borked. I might add the phone works just fine otherwise.)
Question: Has anyone doing Android app development with Delphi run into this? How did you fix it?
(Digressing, been thinking to pitch some app development work with Delphi, but the thought occurs that if I can't even deploy a simple app that uses SSL to my own Samsung Note 2 without instantly running into issues, then this might not be such a great idea. I realise this is a learning curve and it's early days still to some extent, but nonetheless I'm not really left very confident at the present moment to pitch App developments with Delphi. :( )
I tested the same test app I posted about 2.5h ago on my old Samsung Galaxy Note 2.
When run there it generates the following error when it tries to hit a web service:
error: 1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac.
The server in question is an IIS box acting as reverse proxy to a Delphi web service e.g. at present Delphi is not handling the SSL, it is just a plain service, and the SSL is handled by the IIS box. The web service being accessed is basically Delphi implemented SOAP invokable interfaces via SOAP client module imported with the Delphi WSDL importer.
Some quick googling seems to suggest this error happens in multiple environments/languages/servers and is related to OpenSSL version(s).
So it's not entirely clear if it's due to server, client or either/both, but note the following:
1) The same phone can access the web service just fine via the phone's browser.
2) The same app works fine when the it is compiled as Windows app
3) The same app works fine when run via the Android emulator
4) The web service has already been working fine in a staging semi-production environment for other third parties and non-delphi apps for some time (although access is not in this instance directly via SOAP but via JSON, but that's basically an irrelevance.)
So, although I can't totally discount issues with the server setup, it seems relatively unlikely, given that the only client that I know of that has a problem at this stage is the Delphi generated app, on my physical phone. (But note again, the same phone can talk to the service with its built in browser, so it's not just that the phone is borked. I might add the phone works just fine otherwise.)
Question: Has anyone doing Android app development with Delphi run into this? How did you fix it?
(Digressing, been thinking to pitch some app development work with Delphi, but the thought occurs that if I can't even deploy a simple app that uses SSL to my own Samsung Note 2 without instantly running into issues, then this might not be such a great idea. I realise this is a learning curve and it's early days still to some extent, but nonetheless I'm not really left very confident at the present moment to pitch App developments with Delphi. :( )
Can it be that one side is using SSL3 (which is broken) and the other side isn't?
ReplyDeletehttp://disablessl3.com/
Jeroen Wiert Pluimers Thanks for the comment, I'll investigate. The implication would be (perhaps) that the Delphi code seems to be leaving the choice of cipher to the default on the platform, consequently on my PC as Windows app and under emulator the choice defaults to something that works, while on my older phone, the /default/ choice (possibly SSL3 as you say) is resulting in this obscure error, while with other software on the same phone (presumably) the default is overridden and no problems occur.
ReplyDeleteAs an aside, I've tried to debug this by running with Debugging on, and although I then managed to at least get a EIdOSSLUnderlyingCryptoError the IDE then froze up and so (frustratingly) I've not been able to get a look at where/how this is happening. The fact that this is an Indy exception means I'll be investigating what Indy does (or does not) do w.r.t. SSL cipher choice.
Edit: The IDE eventually came back, with a CPU window so it wasn't entirely dead, just very very slow at breaking. (10 minutes ish, seriously?) Unfortunately no usable call stack or anything else presented. :(
The IDE socks at real debugging such things.
ReplyDeleteI've suggested an ssltest.sh issue so it can function as a server to see which options a client supports: https://github.com/drwetter/testssl.sh/issues/157 For now you could use testssl.sh to see what your server provides and seen if there are docs on what the client could provide. I've added Mac binaries there and there are Linux binaries (no Windows, sh is Unix thing) at https://github.com/drwetter/testssl.sh/tree/master/bin
For reference:
ReplyDeleteSimilar issue involving Delphi: http://goo.gl/WLiJE7
Google searches for this error message listing many places this has been seen:
https://goo.gl/XuiSFN
https://goo.gl/QtLONV
I've now tested the server in question with
ReplyDeleteopenssl s_client -connect xxxxxx:xxx -ssl3
In this case it fails to connect so the server doesn't support the old SSL3. So this is not the problem unfortunately. (The command works and uses TLS v1.2 when not forced to SSL3)
All the pages I've found so far points to some issue in OpenSSL, seemingly there's some issue that was fixed between 1.0.1g and 1.0.1h (or something like that), while I've checked and the phone's got 1.0.1e on. So I seem to be stepping on some obscure issue in slightly older versions of OpenSSL somehow.
Still, it should be possible to make this work -- everything but the Delphi app works.
I've spent a bit of time also perusing/reaquainting myself with some of the SOAP VCL code (notably Soap.SOAPHTTPTrans). As you will see, on Windows, it will preferentially use the WinInet stack, unless USE_INDY is defined.
On Android there is obviously no WinInet so it has to use Indy. This suggests to me that this could be a difference between the SSL handling between Indy and WinInet. Watch this space.
Are you using GZIP? GZIP+SSL in previous versions causes issues. XE8 uses the platform native HTTP client which removes the need for OpenSSL. For previous versions one solution is DPF Android which has a native HTTP client wrapper as well.
ReplyDeleteEli M Could you expand on the GZIP+SSL issue(s)?
ReplyDeleteEli M Thanks for responding.
ReplyDeleteAre you saying that Android also has effectively 2 SSL libraries, a "native" one and OpenSSL? (Analogous to WinInet and OpenSSL on a PC?)
Also, what does gzip have to do with the SSL handshake? Doesn't Gzip only enter the picture once a connection has been established?
Nicholas Ring In XE7 (and possibly earlier versions) SSL+GZIP with TRESTClient on IOS has a problem. SSL by itself and GZIP by itself both work okay.
ReplyDeleteSo it was an IOS issue - whew. I was wondering if it was a Windows thing :D
ReplyDeleteThanks Eli M
Walter Prins Under Android, Indy and AndroidHTTPClient appear to both use OpenSSL. In XE8 TRESTClient uses TNetHTTPClient which wraps AndroidHTTPClient. In XE5/XE6/XE7 TRESTClient uses TIdHTTP. So the route to interface with OpenSSL is different. You mentioned SOAP so not sure which component you're using (the SOAP client?). I'm also connecting to an IIS machine (Azure). We've had issues with the OpenSSL under XE7 where the connection would always fail the first time (under Windows). On XE7 IOS SSL+GZIP with TRESTClient (TIdHTTP) either the data is munged or I wasn't decoding it correctly. Haven't done a lot of testing under Android. We use Fiddler to figure what's going on: http://www.telerik.com/fiddler That all being said with XE8 use TNetHTTPClient and it should all work good. It wraps the native platform client on each platform so you don't have to distribute the SSL library and it will always be up to date with what the platform is running.
ReplyDeleteIn retrospect with a lot of these Android phone vendors NOT updating Android it's possible shipping your own OpenSSL might actually provide a more secure version to users on older devices.
ReplyDeleteStill got this on my "todo" list, haven't had much time to investigate further. But, I've found this link which is basically the same issue: https://code.google.com/p/android-developer-preview/issues/detail?id=1521
ReplyDelete(Doesn't help much.)
Eli M Thanks for the comments, just catching up with everything you've said. Re SSL: Shipping own SSL sounds good, but in practice this sounds like it could be problematic due to the native nature of the library(?) E.g. just as Delphi doesn't support every type of Android device out there due to targetting native, the SSL lib is also native and so you can't just ship a generic one-size-fits-all SSL replacement lib I'd have thought, though I'd love to be wrong about this. Do you know otherwise (e.g. have actually shipped replacement SSL libs)?
ReplyDeleteEli M Re TNetHTTPClient and XE8. OK I'll see about some more testing and pay attention to the Indy/OpenSSL vs. TNetHTTPClient distinction. Thanks for the input.
ReplyDeleteSo a minor update on my (mis)adventures with this, in case anyone's interested.
ReplyDelete1) Tried the XE5 experimental app with my Note 10.1 tablet. Works, no SSL error. Yay! At least one device that's demonstrably working, finally. (Unfortunately I really need it to be a phone for what I'm trying to do but it's a start at least.)
2) Next, given all the comments about OpenSSL and updating libs, I grudgingly decided to root and flash the Note 2 to Android 5.0 Lollipop (via Cyanogen mod 12.1) to see if this would fix the SSL problem. One would expect this to bring everything (including OpenSSL) bang up to date.
Unfortunately, this has so far turned out into another fruitless exercise as the app now crashes the same way it crashes on my Note 4. If run in debug mode some kind of "bus error" is generated.
Some further research on this suggests to me that this is an issue that was introduced in XE5 by Update 2 (http://codeverge.com/embarcadero.delphi.deployment/xe5-android-app-runs-on-note2-b/2034444).
I suppose that XE8 might make all my problems go away (though worryingly the referenced QC above is still open and doesn't sound the same as I'm seeing), but unfortunately I don't have it installed/available at home so cannot look into this now (not to mention the fact that XE8 is a bit academic where I'm working as yet, as preliminary testing of XE8 and the codebase quickly threw up some issues that required looking into that no-one had time for hence it was put on hold.)
I missed most of the discussion and am catching up. Is this the correct summary: XE5 plain is always OK. XE5U2 is OK on one device but not the other?
ReplyDeleteHi Jeroen. Basically yes. XE5U2 broke something for newer versions of Android, such that the test app I wrote would crash on startup on my Note 4, or my Note 2 with new firmware (one could extrapolate that this would be true for possibly many newer versions of Android.)
ReplyDeleteIn the meantime we've been (thankfully) upgrading such that I'm on the verge of revisiting this whole (mis)adventure on XE8 or perhaps DX. Perhaps things will go better this time round.
Keep us posted (:
ReplyDelete