+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 (66.2k 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 (138k points)
The server is rejecting the client's certificate with UnknownCA (unknown_ca) error response. According to RFC 5246, this means that:

A valid certificate chain or partial chain was received [by the server], but the
certificate was not accepted because the CA certificate could not
be located or couldn't be matched with a known, trusted CA.
by (200 points)
Hi Lukas,
yes...that is what i also thought. I also had quick contact to our server-developer.
He mentioned, that somehow the parent-certificate is not reaching the server.

How is the correct way of using a certificate-chain with the Rebex Websocket client?
We are doing the following:

client.Settings.SslClientCertificateRequestHandler = CertificateRequestHandler.CreateRequestHandler(Certificate.LoadDerWithKey(certPath, keyPath, password));

where certPath directs to a pem-file and keyPath is a pfx-file.

I checked the assemblys, but did find a proper way of providing a certificate with key and password in the CertificateChain-class.
by (138k points)
To pass the whole chain, you have to pass the whole chain to CertificateRequestHandler.CreateRequestHandler. To get the whole chain, you might try building it using CertificateChain.BuildFrom. That would normally be the preferred option (it would add the CA certificates if they are found in current user's certificate stores), but I'm not quite sure whether it would work for Ed25519 certificates, which are not supported by Windows API's yet.
So if that doesn't work (= it returns a chain with only a single certificate), you can construct the chain manually from the client certificate and the authorities

    // load the certificate
    var cert = Certificate.LoadDerWithKey(certPath, keyPath, password);

    // create the chain
    var chain = new CertificateChain(cert);

    // add intermediate CA certificates to the chain (in proper order)
    var caCert1 = Certificate.LoadDer(caCert1Path);
    chain.Add(caCert1);

    var caCert2 = Certificate.LoadDer(caCert2Path);
    chain.Add(caCert2);

    ...

    // create CertificateRequestHandler based on the chain

    client.Settings.SslClientCertificateRequestHandler = CertificateRequestHandler.CreateRequestHandler(chain);
by (200 points)
Hi Lukas,

we finally were able now to perform test on the different platforms (iOS and Android).
Both are working fine and we can establish a connection to our API.
Regarding the certificate chain -  we are using the second approach you proposed.

Great thanks for all your support and the changes in the library.

Do you already have some official release-date in mind?
by (138k points)
Hi, we would like to publish the R7.0 version this month. And if we miss this deadline, we could at least publish a release candidate build that would be supported in production.
...