sdk icon indicating copy to clipboard operation
sdk copied to clipboard

TCP Connections Aborting During TLS Handshake

Open aweinber opened this issue 1 year ago • 3 comments

Hi,

Writing here because I'm not sure the right place and this seems to involve dart:io (though that isn't necessarily the cause of this issue).

Issue background

~5 times in the last month, a recurring network call in my deployed flutter Windows application (on multiple different client computers) has begun to throw the following error when connecting to a particular API:

HandshakeException: Handshake error in client (OS Error: 
	BLOCK_TYPE_IS_NOT_01(../../third_party/boringssl/src/crypto/fipsmodule/rsa/padding.c:108)
	PADDING_CHECK_FAILED(../../third_party/boringssl/src/crypto/fipsmodule/rsa/rsa_impl.c:676)
	public key routines(../../third_party/boringssl/src/crypto/x509/a_verify.c:108)
	CERTIFICATE_VERIFY_FAILED: certificate signature failure(../../third_party/boringssl/src/ssl/handshake.cc:393))

This is the code in the dart sdk that invokes the boringssl validation

secure_socket_patch.dart in _SecureFilterImpl._handshake at line 99

The issue occurs for the duration of the lifespan of the application. Force quitting the application and restarting the machine both successfully resolve the issue; otherwise the recurring process continues to fail with this error. The same exception occurs in multiple places in my application where I call this endpoint. Here's one such example (running every 60 seconds) that is raising this exception (which happens whether I a /health endpoint from this healthcheck code or from the more important application code.:

  final client = HttpClient();
  try {
    final req = await client.getUrl(host);
    final res = await req.close();
    if (res.statusCode != 200) {
      throw Exception('Unexpected status code: ${res.statusCode}. Reason: ${res.reasonPhrase}.');
    }
  } on Exception catch (e, stackTrace) {
    // send to logging endpoint
  } finally {
    client.close(force: true);
  }

Why this might be a dart or flutter issue

I initially assumed there was a network failure or a certificate issue and have worked to disprove these theories. Here's what I've learned:

  • This issue only happens for some clients, some of the time, while other clients have no problem
  • This issue only happens to this one api - healthchecks to 8.8.8.8 succeed (thanks google)
  • The issue happens whether I instantiate a new HttpClient or use a Dio singleton
  • This issue only happens when connecting over HTTPS to this endpoint - http healthchecks to my endpoint succeed
  • While the instance of the app is impaired, https Requests from the rest of the OS to this endpoint succeed - curl and browser requests both succeed
  • Packet sniffing indicates that the client is sending FIN packets before the TLS connection is complete and application data is exchanged: I have generated a pcap file while the app is impaired and have found that at various stages of the TLS handshake the client has sent a FIN packet before the TLS handshake is done - sometimes between Server Hello and Server Key Exchange, sometimes after Server Key Exchange.

Reproduction steps

Unfortunately I haven't been able to reproduce this issue quite yet. If you have any suggestions I'd be very happy to try them.

Specs

Windows 10 (both my dev machine and the affected clients) Dart version: Dart version: 3.0.6 (stable) Flutter 3.10.6 (stable)

I'm at a bit of a loss and would appreciate any ideas to try to understand the source of this error. Thanks!

aweinber avatar Feb 07 '24 19:02 aweinber

//cc @brianquinlan @aam

a-siva avatar Feb 08 '24 18:02 a-siva

Hi, I just want to briefly update this ticket. It appears that another client saw a similar error today, with an unrelated endpoint not owned by my team - google.com. Here is the error message:

HealthCheckException{uri: https://google.com, error: HandshakeException: Handshake error in client (OS Error: 
	CALLED_WITH_EVEN_MODULUS(../../third_party/boringssl/src/crypto/fipsmodule/bn/exponentiation.c:590)
	public key routines(../../third_party/boringssl/src/crypto/x509/a_verify.c:108)
	CERTIFICATE_VERIFY_FAILED: certificate signature failure(../../third_party/boringssl/src/ssl/handshake.cc:393))}

This error happens here - https://github.com/google/boringssl/blob/c39e6cd9ec5acebb6de2adffc03cfe03b07f08ab/crypto/fipsmodule/bn/exponentiation.c#L589. The error is also happening repeatedly on other APIs, including those on our backend. I don't think my application is doing anything unusual with how it creates HTTP requests, but let me know if there's anything I can do to fix this or illuminate the problem.

aweinber avatar Feb 12 '24 20:02 aweinber

@aweinber can you send us a wireshark dump when the error happens, maybe that might give us some clues. Without a reliable reproduction it is going to be hard for us to investigate this.

a-siva avatar Feb 14 '24 21:02 a-siva

Without additional information we're not able to resolve this issue. Feel free to add more info or respond to any questions above and we can reopen the case. Thanks for your contribution!

github-actions[bot] avatar Feb 29 '24 08:02 github-actions[bot]

@a-siva sorry about the delay here. Here's a zip of one such example. If you open in wireshark and examine tcp.stream eq 17, you will see a representative example. Ip addr 54.... is the backend. If I'm reading this correctly, after the Server Hello Done, my machine abruptly sends a FIN packet to the backend. I'm not sure how useful this will be, but please let me know if it gives you any ideas for other things I should explore.

Thanks!

2-7-failure-zip.zip

aweinber avatar Mar 01 '24 14:03 aweinber