Skip to content
This repository has been archived by the owner on Sep 9, 2022. It is now read-only.

SNI support #17

Open
bemasc opened this issue Jul 29, 2016 · 2 comments
Open

SNI support #17

bemasc opened this issue Jul 29, 2016 · 2 comments
Labels

Comments

@bemasc
Copy link
Contributor

bemasc commented Jul 29, 2016

My app was experiencing timeouts when connecting to some domains. To make a reduced testcase, I started with the 'TCP secure get https website three times' test (https://github.com/MobileChromeApps/cordova-plugin-chrome-apps-sockets-tcp/blob/master/tests/tests.js#L793). Running that test on my Nexus 5X, by clicking the "Run" button in the test app with only chrome-sockets-tcp selected, I see flakiness, with maybe an 80% success rate. (The second run in particular seems to fail frequently.) I modified the target domain from httpbin.org to a0.awsstatic.com, and saw similar results. However, when I changed the target domain to sdk.amazonaws.com, I saw 100% failure.

In the last case, I set breakpoints to locate the failure. It appears that chrome.sockets.tcp.secure() never calls its callback, resulting in a test timeout.

The flakiness of the test does not seem surprising. In particular, any nagling or similar aggregation would break the recvCounter mechanism. However, I'm not aware of any difference between the a0.awsstatic.com and sdk.amazonaws.com domains that would logically explain the difference in behavior. (Both domains are hosted on Amazon Cloudfront, so they should behave almost identically.)

The only difference I've been able to find between these domains is that sdk.amazonaws.com is defined by a CNAME record, whereas a0.awsstatic.com is defined by an A record. The extra DNS lookup and secondary name should not be a problem, but perhaps a buggy TLS client could fail in this case.

@bemasc
Copy link
Contributor Author

bemasc commented Aug 2, 2016

By debugging the unit tests when pointed to sdk.amazonaws.com, I've found that the failures occur after finishConnect() succeeds, but the SSL handshake fails. Debugging revealed that the server replies with 7 bytes before closing the socket: 21, 3, 3, 0, 2, 2, 40. Reading the TLS specification, I've determined that this is

21 // ContentType = alert
3 // ProtocolVersion = 3,3 (TLS 1.2)
3
0 // length = 0,2 (2 bytes)
2
// Alert:
2 // AlertLevel = 2 (fatal)
40 // AlertDescription = 40 (handshake_failure)

I don't yet know what is causing the handshake failure.

@bemasc bemasc changed the title SSL connections are flaky or just broken, depending on the domain SNI support Aug 4, 2016
@bemasc
Copy link
Contributor Author

bemasc commented Aug 4, 2016

After tracing this deeper, I'm now convinced that the issue is a lack of SNI (Server Name Indication). Chrome's sockets API always includes SNI when connecting to a domain by name. This plugin never includes SNI ... understandably, since the requisite method is only now being introduced in API 24 (Android N). The servers where this fails appear to require SNI.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

1 participant