I am developing an Xmarain.Forms app to initially work on Android along with a service it will be connecting to. The service is a WCF service and needs to use a secure transport to send messages so is set to use https.
I can correctly connect and use the service with both SoapUI and a console program built using the same client proxy library but when I try using the Xamarin App it fails. When run in the emulator the exception is a TimeoutException but when installed on an actual device the exception is WebException with message of "Error: SecureChannelFailure (The authentication or decryption has failed" with inner exception stack of:
- IOException with message "The authentication or decryption has failed"
- IOException with message "Error while sending TLS Alert (Fatal:InternalError)"
- IOException with message "The authentication or decryption has failed.
- IOException with message "Unable to read data from the transport connection: Connection reset by peer"
The full stack trace is included below as attachments. The full code is available at https://github.com/staircase27/WcfXamarinHttpBugExample along with the instructions of how to set it up and use it. The example code has connections using both http and https to show the difference and to show that one works and the other doesn't. I have also checked while testing that the devices can access the service using their web browsers so it's not a firewall or routing issue.
I have also wiresharked the connection to see where exactly the connection is failing and it's failing at the TLS v1.0 level. The app (on both devices I've tested) is sending a Client Hello and the service is responding with a TCP RST packet rather than a Server Hello. I have also performed a connection from the testing device using a web browser that succeeded and the main differences are in the types of encryption supported specifically the app only offers to use
- TLS_RSA_WITH_AES_256_CBC_SHA
- TLS_RSA_WITH_AES_128_CBC_SHA
- TLS_RSA_WITH_3DES_EDE_CBC_SHA
- TLS_RSA_WITH_RC4_128_SHA
- TLS_RSA_WITH_RC4_128_MD5
- TLS_RSA_WITH_DES_CBC_SHA
where as the working connections both used
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
A filtered wireshark with two connections is at https://github.com/staircase27/WcfXamarinHttpBugExample/raw/master/Mobile%20WCF%20https%20Capture%20-%20Filtered.pcapng. The first connection is from the app and fails with a tcp rst. The second is the start of the connection from the android web browser.
I have enabled all versions of TLS and all cypher suites but it hasn't changed the wireshark trace or exception in the app.
I have also checked the SChannel Event Logs as recommended by @tomasr and found the following event:
- An SSL client handshake completed successfully. The negotiated cryptographic parameters are as follows. Protocol: TLS 1.0. CipherSuite: 0xc014. Exchange strength: 256
(Before enabling all version of TLS the events were:
- An TLS 1.0 connection request was received from a remote client application, but none of the cipher suites supported by the client application are supported by the server. The SSL connection request has failed.
- The following fatal alert was generated: 40. The internal error state is 1205.
)