+1 vote
by (130 points)

How to connect to a secure web socket server using wss:// and a key or a certificate ?

1 Answer

0 votes
by (65.1k points)

To handle client certificate requests, please use the WebSocketClient.Settings.SslClientCertificateRequestHandler property.

It can look like this:

// initialize new web socket client instance
var client = new WebSocketClient();

// implement your own ICertificateRequestHandler or use one of predefined
client.Settings.SslClientCertificateRequestHandler =
                    CertificateRequestHandler.StoreSearch;

// connect to desired server
client.Connect("wss://example.com");

For more examples, please visit Client certificate authentication.

by (136k points)
In that case, Rebex.Castle.dll is needed (on Xamarin.Android) because it implements ECDSA and ECDH based on the most common NIST-P curves. Rebex.Curve25519.dll is optional (only implements ECDH with X25519).
by (130 points)
edited by
calling AsymmetricKeyAlgorithm.Register(castle.create) does not work, How could I set it  ?
AsymmetricKeyAlgorithm.Register(EllipticCurveAlgorithm.Create);
 is it correct?
When I set to the above Iagain get the error  :
2023-02-23 12:56:36.262 DEBUG WebSocketClient(1)[35] Proxy: Connection established.
2023-02-23 12:56:36.343 DEBUG WebSocketClient(1)[35] TLS: Using classic TLS core.
2023-02-23 12:56:36.351 DEBUG WebSocketClient(1)[35] TLS: Enabled cipher suites: 0x000F3DF7EBE00640.
2023-02-23 12:56:36.436 DEBUG WebSocketClient(1)[35] TLS: Applicable cipher suites: 0x000F3DF7EBE00640.
2023-02-23 12:56:36.445 VERBOSE WebSocketClient(1)[35] TLS: Sent TLS packet:
 0000 |16-03-03-00-AF-01-00-00 AB-03-03-63-F7-46-64-89| ...........c.Fd.
 0010 |60-EE-4D-D8-B9-83-DA-90 FE-27-EA-D8-63-83-80-2C| `.M......'..c..,
 0020 |6B-C3-4E-23-81-F3-56-41 66-F9-7B-00-00-3A-C0-23| k.N#..VAf.{..:.#
 0030 |C0-24-C0-2B-C0-2C-C0-2F C0-30-C0-27-C0-28-C0-09| .$.+.,./.0.'.(..
 0040 |C0-0A-C0-13-C0-14-00-9F 00-9E-00-6B-00-67-00-9D| ...........k.g..
 0050 |00-9C-00-3D-00-3C-00-33 00-39-00-2F-00-35-C0-08| ...=.<.3.9./.5..
 0060 |C0-12-00-16-00-0A-00-FF 01-00-00-48-00-00-00-10| ...........H....
 0070 |00-0E-00-00-0B-31-39-32 2E-31-36-38-2E-30-2E-31| .....192.168.0.1
 0080 |00-0A-00-0E-00-0C-00-17 00-18-00-19-00-1A-00-1B| ................
 0090 |00-1C-00-0B-00-02-01-00 00-0D-00-14-00-12-04-01| ................
 00A0 |04-03-05-01-05-03-06-01 06-03-02-01-02-03-02-02| ................
 00B0 |00-17-00-00                                    | ....
2023-02-23 12:56:36.446 DEBUG WebSocketClient(1)[35] TLS: HandshakeMessage:ClientHello was sent.
2023-02-23 12:56:36.785 VERBOSE WebSocketClient(1)[35] TLS: Received TLS packet:
 0000 |15-03-03-00-02-02-28                           | ......(
2023-02-23 12:56:36.787 INFO WebSocketClient(1)[35] TLS: Fatal Alert:HandshakeFailure was received.
2023-02-23 12:56:36.794 DEBUG WebSocketClient(1)[35] TLS: Rebex.Net.TlsException: Fatal error 'HandshakeFailure' has been reported by the remote connection end.
  at zbfys.kmzch.gcbov (System.Byte[] p0, System.Int32 p1, System.Int32 p2) [0x00085] in <92378deb221948dfa4cafbbc95220b36>:0
  at zbfys.sbkup.xpfij (System.Byte[] p0, System.Int32 p1, System.Int32 p2) [0x00065] in <92378deb221948dfa4cafbbc95220b36>:0
by (136k points)
Actually, the log shows that the plugin did work - note the difference in the "Applicable cipher suites" log entry and the increased size of ClientHello message due to additional ciphers listed. So while Lukas Matyska's guess was sensible, enabling additional ciphers apparently did not resolve the problem.

We could continue guessing for a long time - for example, this could be due to the server a) not actually accepting connections at an IP address, b) requiring TLS 1.3, c) The server requiring some yet-unsupported extensions to be enabled, d) using some kind of fingerprinting to only accept connections from whitelisted browsers.

However, I would instead recommend to consult the service provider and simply ask about the requirements the server imposes on clients. Then, we could easily tell whether it's possible to configure Rebex WebSocket client that way, and how to achieve that. Alternatively, the server operator could look into the log and tell you why the server rejected client's attempt to establish a session.
by (100 points)
Hi Lukas,
i'm a colleagues from chrisg and was recently also debugging the websocket issue we are having.

The server responded with this:
[Error: 140704529921664:error:1417A0C1:SSL routines:tls_post_process_client_hello:no shared cipher:../deps/openssl/openssl/ssl/statem/statem_srvr.c:2284:
] {
  library: 'SSL routines',
  function: 'tls_post_process_client_hello',
  reason: 'no shared cipher',
  code: 'ERR_SSL_NO_SHARED_CIPHER'
}

Available cipher suites on the current (rebex-)client:
        {0xC0, 0x23} TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
        {0xC0, 0x24} TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
        {0xC0, 0x2B} TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        {0xC0, 0x2C} TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
        {0xC0, 0x2F} TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        {0xC0, 0x30} TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        {0xC0, 0x27} TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
        {0xC0, 0x28} TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
        {0xC0, 0x09} TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
        {0xC0, 0x0A} TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
        {0xC0, 0x13} TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
        {0xC0, 0x14} TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
        {0x00, 0x9F} TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
        {0x00, 0x9E} TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
        {0x00, 0x6B} TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
        {0x00, 0x67} TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
        {0x00, 0x9D} TLS_RSA_WITH_AES_256_GCM_SHA384
        {0x00, 0x9C} TLS_RSA_WITH_AES_128_GCM_SHA256
        {0x00, 0x3D} TLS_RSA_WITH_AES_256_CBC_SHA256
        {0x00, 0x3C} TLS_RSA_WITH_AES_128_CBC_SHA256
        {0x00, 0x33} TLS_DHE_RSA_WITH_AES_128_CBC_SHA
        {0x00, 0x39} TLS_DHE_RSA_WITH_AES_256_CBC_SHA
        {0x00, 0x2F} TLS_RSA_WITH_AES_128_CBC_SHA
        {0x00, 0x35} TLS_RSA_WITH_AES_256_CBC_SHA
        {0xC0, 0x08} TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
        {0xC0, 0x12} TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
        {0x00, 0x16} TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
        {0x00, 0x0A} TLS_RSA_WITH_3DES_EDE_CBC_SHA
        {0x00, 0xFF} TLS_EMPTY_RENEGOTIATION_INFO_SCSV

Available cipher suites on the server:
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_GCM_SHA256
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-ECDSA-AES256-GCM-SHA384
DHE-RSA-AES128-GCM-SHA256
ECDHE-RSA-AES128-SHA256
DHE-RSA-AES128-SHA256
ECDHE-RSA-AES256-SHA384
DHE-RSA-AES256-SHA384
ECDHE-RSA-AES256-SHA256
DHE-RSA-AES256-SHA256


Could it be, that just the names of the cipher are different? So that they do not match, even though they are the same:
e.g.
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (rebex)
        ECDHE-ECDSA-AES128-GCM-SHA256 (server)

Just and idea - if you have some other advice, please let me know.

Maybe one more word about our setup:
- we have to connect to a piece of hardware with TLS Client authentication
- client will be a mobile application
- we are currently working with a mock-server (therefore we have access to it - it is a node.js application). The mock is supposed to be according to the specification (you never know, unfortuantely)

We are now concerned, not being able to connect to the hardware, as we are not able to to connect to the mock. Hopefully issues will be resolved soon.
by (65.1k points)
Please note that TLS cipher suites are sent as two bytes codes, there is no string comparison. The code is actually present in your listing, see:

   {0xC0, 0x2B} TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256

The two hex-values are the two bytes code of the cipher suite.


If your listing of available cipher suites at the server is correct, then we can clearly see that the ERR_SSL_NO_SHARED_CIPHER reported by the server is misleading or incorrect, because there are some shared cipher suites.

However, I have noticed the error log contains a reference to source code: ./deps/openssl/openssl/ssl/statem/statem_srvr.c:2284
and I have found it at https://github.com/openssl/openssl/blob/master/ssl/statem/statem_srvr.c

It was not much helpful, but I have searched for "no shared cipher" string in the repository and I got this interesting hit:
https://github.com/openssl/openssl/commit/b4eee58a5f9dfa493d6cc34b4af871415c67beda

1. It seems that OpenSSL has/had some issues with TLS 1.3 enabled. Please, try to disable TLS 1.3 at the server.
2. If disabling TLS 1.3 does not help, please, upgrade to the latest version of OpenSSL, since it seems we are facing a server side issue.
...