Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
TCPClient SSL on Android
#1
I got a debug report from an Android user, where this happened:

The Client receives a "StartTLS" from the IdTCPServer (Part of my code).
The Client responces with a "STARTTLS" back, then does a Sleep(1000) (this solves some timing issues) and then switches the Passthrough to FALSE:

sleep(1000);
IdSSLIOHandlerSocketOpenSSL1.PassThrough := false;

The SSL Negotiating starts, and gets to this:
[S] [06:21:09Z] SSL StatusInfo: SSL status: "before/connect initialization"
[S] [06:21:09Z] SSL StatusInfo: SSL status: "before/connect initialization"
[S] [06:21:09Z] SSL StatusInfo: SSL status: "SSLv3 write client hello A"
[S] [06:21:09Z] SSL StatusInfo: SSL status: "SSLv3 write client hello A"


And then it stops. And there is no Exception raised.

The Internet connection is very unreliable at this point, and I expect there may have been major packet loss.

But the system did not recover from this situation, as there was no exception raised, it just hung there.

Question:
- At which point does the SSL negotiation start: Immediatly after PassThrough := false, OR after the first attempt to send data over the link?
- When the Internet connection fails at this point, (and possibly the *Server* got a TCP Reset) is should there be a time-out exception being raised? Because the actual TCP connection is already established.

Thanks, Bart
---
Bart Kindt
CEO and Developer
SARTrack Limited
New Zealand
www.sartrack.nz
Reply
#2
(10-12-2019, 10:16 PM)BartKindt Wrote: The Client receives a "StartTLS" from the IdTCPServer (Part of my code).

Why would the *server* send a STARTTLS to the *client*? That is an unusual design choice.

(10-12-2019, 10:16 PM)BartKindt Wrote: The Client responces with a "STARTTLS" back, then does a Sleep(1000) (this solves some timing issues) and then switches the Passthrough to FALSE

Sleeping should not be necessary. If you are having timing-related issues, you need to fix those separately.

(10-12-2019, 10:16 PM)BartKindt Wrote: The SSL Negotiating starts, and gets to this:
<snip>
And then it stops. And there is no Exception raised.

How are you configuring the SSLIOHandler on each end? Are you specifying which party is client and which is server, in terms of the SSL session (connect vs accept), not in term of the TCP connection? Have you tried sniffing the network traffic, such as with Wireshark, to make sure the handshake packets are correct?

(10-12-2019, 10:16 PM)BartKindt Wrote: - At which point does the SSL negotiation start: Immediatly after PassThrough := false, OR after the first attempt to send data over the link?

It is handled *inside* the PassThrough property setter. The setter does not return to your code until the handshake is complete.

(10-12-2019, 10:16 PM)BartKindt Wrote: - When the Internet connection fails at this point, (and possibly the *Server* got a TCP Reset) is should there be a time-out exception being raised?

Probably not, since Indy uses blocking sockets and there are no timeouts used at the socket layer by default. However, you can enable socket-layer timeouts manually if needed, via the TIdTCPConnection.Socket.SetSockOpt() method (in fact, TIdSSLIOHandlerSocketOpenSSL does enable socket-level timeouts, but only on Windows Vista+ as part of a bug fix for OpenSSL handling on Windows).

Reply
#3
(10-14-2019, 07:30 PM)rlebeau Wrote:
(10-12-2019, 10:16 PM)BartKindt Wrote: The Client receives a "StartTLS" from the IdTCPServer (Part of my code).

Why would the *server* send a STARTTLS to the *client*?  That is an unusual design choice.

(10-12-2019, 10:16 PM)BartKindt Wrote: The Client responces with a "STARTTLS" back, then does a Sleep(1000) (this solves some timing issues) and then switches the Passthrough to FALSE

Sleeping should not be necessary.  If you are having timing-related issues, you need to fix those separately.

(10-12-2019, 10:16 PM)BartKindt Wrote: The SSL Negotiating starts, and gets to this:
<snip>
And then it stops. And there is no Exception raised.

How are you configuring the SSLIOHandler on each end?  Are you specifying which party is client and which is server, in terms of the SSL session (connect vs accept), not in term of the TCP connection?  Have you tried sniffing the network traffic, such as with Wireshark, to make sure the handshake packets are correct?

(10-12-2019, 10:16 PM)BartKindt Wrote: - At which point does the SSL negotiation start: Immediatly after PassThrough := false, OR after the first attempt to send data over the link?

It is handled *inside* the PassThrough property setter.  The setter does not return to your code until the handshake is complete.

(10-12-2019, 10:16 PM)BartKindt Wrote: - When the Internet connection fails at this point, (and possibly the *Server* got a TCP Reset) is should there be a time-out exception being raised?

Probably not, since Indy uses blocking sockets and there are no timeouts used at the socket layer by default.  However, you can enable socket-layer timeouts manually if needed, via the TIdTCPConnection.Socket.SetSockOpt() method (in fact, TIdSSLIOHandlerSocketOpenSSL does enable socket-level timeouts, but only on Windows Vista+ as part of a bug fix for OpenSSL handling on Windows).
---
Bart Kindt
CEO and Developer
SARTrack Limited
New Zealand
www.sartrack.nz
Reply
#4
Um, did you forget to actually write something? You quoted my response, but didn't write anything new.

Reply
#5
I was trying to delete the original quotes, then typed a message, and now it looks the system deleted everyting I typed.
I am strugling with the way this forum works.

I will first try your ideas, but I just wonder if it would work under Android.

Else I will have to use my own timer to check if this 'blocking call' to the 'passthrough' in fact ever returns...

Bart

Must be me, but I cannot find ant reference to TIdTCPConnection.Socket.SetSockOpt().
It is not in TIdTCPConnection.Socket, not in TIdIOHandlerSocket, not in TIdIOHandler.

I am using Indy as supplied with Delphi 10.3.2

Bart
---
Bart Kindt
CEO and Developer
SARTrack Limited
New Zealand
www.sartrack.nz
Reply
#6
(10-15-2019, 05:15 PM)BartKindt Wrote: I will first try your ideas, but I just wonder if it would work under Android.

It should, if everything is configured properly. It would help if you could show your actual code that is not working for you.

(10-15-2019, 05:15 PM)BartKindt Wrote: Must be me, but I cannot find ant reference to TIdTCPConnection.Socket.SetSockOpt().
It is not in TIdTCPConnection.Socket, not in TIdIOHandlerSocket, not in TIdIOHandler.

Sorry, I meant TIdTCPConnection.Socket.Binding.SetSockOpt() (forgot the Binding property).

TIdTCPClient derives from TIdTCPConnection, which has a Socket property of type TIdIOHandlerSocket, which has a Binding property of type TIdSocketHandle, which has the SetSockOpt() method.

Reply
#7
Sorry Remy,
Now I have to ask you how I should use this SetSockOpt to set a Timeout for the SSL negotiation, that is, so that it returns (or causes an exception) when the negotiation takes longer that say 15 seconds...

Bart
---
Bart Kindt
CEO and Developer
SARTrack Limited
New Zealand
www.sartrack.nz
Reply
#8
(10-16-2019, 04:51 AM)BartKindt Wrote: Now I have to ask you how I should use this SetSockOpt to set a Timeout for the SSL negotiation

There is no "SSL negotiation" timeout. And even if there were, it wouldn't be set as a timeout at the socket layer, it would be set as a timeout at the OpenSSL layer. The SetSockOpt() method sets options on the underlying socket itself, such as SO_SNDTIMEO and SO_RCVTIMEO (did you read the documentation I linked to in my last reply?), eg:

Code:
// timeout blocking reads after 15 secs
IdTCPClient.Socket.Binding.SetSockOpt(Id_SOL_SOCKET, Id_SO_RCVTIMEO, 15000);

// timeout blocking sends after 15 secs
IdTCPClient.Socket.Binding.SetSockOpt(Id_SOL_SOCKET, Id_SO_SNDTIMEO, 15000);

Reply
#9
Thanks Remy, sorry again, I missed the link you included in your last reply.

I will give this a go, but it is going to be difficult to test, I would have to pull the plug of the WIFI unit just when it starts the negotiation, or something like that Smile

Thanks, Bart
---
Bart Kindt
CEO and Developer
SARTrack Limited
New Zealand
www.sartrack.nz
Reply
#10
(10-16-2019, 10:03 PM)BartKindt Wrote: I will give this a go, but it is going to be difficult to test, I would have to pull the plug of the WIFI unit just when it starts the negotiation, or something like that Smile

It would probably be easier to simply put a breakpoint/delay in your TIdTCPServer code where the SSL/TLS handshake is initiated, forcing the client to timeout while it is waiting for a reply.

Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)