Problem with secure websocket example
-
wrote on 10 Jan 2018, 08:29 last edited by
Hi All,
I have my websocket server (with protocol scheme ws://) working on my embedded linux device.
To add security to the communication (since password auth is involved), I decided to move on using secure websocket server (wss://). I took a look at example here http://doc.qt.io/qt-5/qtwebsockets-examples.html and ported it on my embedded linux device.The example (sslechoclient & sslechoserver) should work out of the box (my expectation). But it looks like either I have messed up something or this Qt Example was never working (which might be improbable).
When I run sslechoserver and then try to run sslechoclient, the QWebSocket::disconnected signal is emitted. I tried printing the QWebSocket::closeReason(), it was empty string. No other signals of QWebSocket were emitted. I also tried printing QSslSocket::supportsSsl(), this was True.
I also tried putting logs in all functions of sslechoserver. Nothing was printed on server terminal. Not even for new connection coming.
I am wondering what else could go wrong.
- Should I try generating new certificates and keys? (in anticipation of Qt generated keys and certificates might be expired)
- Do I need to install any development package or libs on linux platform?
Is there any additional work needed for setting up Qt while compiling Qt?
I tried running the same application on my development linux machine, the output was exactly same as was on embedded linux device.
Could anyone please help me here. I am halted on this.
Regards,
-
wrote on 10 Jan 2018, 10:29 last edited by VRonin 1 Oct 2018, 10:47
From http://doc.qt.io/qt-5/qtwebsockets-sslechoserver-sslechoserver-cpp.html :
QFile certFile(QStringLiteral(":/localhost.cert"));
QFile keyFile(QStringLiteral(":/localhost.key"));
You need to generate those keys and certificates.
Almost surely you'll have a self signed certificate so you'll also have to connect to
sslErrors(const QList<QSslError> &errors)
signal, check the only error is the self sign andignoreSslErrors
in your test environment -
wrote on 11 Jan 2018, 07:41 last edited by niku.ifm 1 Nov 2018, 07:42
Thank you so much.
Yes indeed, generating new certificates made the standard Qt Examples sslechoserver/sslechoclient from http://doc.qt.io/qt-5/qtwebsockets-examples.html work for me.
So I took the same approach to my application on linux embedded device. In my application I use QML WebSocket element for my local UI qmlclient. This client is supposed to connect to the websocketserver on the same device. In near future I will have a html client connecting to the same server from a remote PC (This is why I am moving to a WSS scheme instead of WS).
With QML WebSocket element, I have issues connecting to the server. The error I face is
qml: Error: The host name did not match any of the valid hosts for this certificateI am taking a guess here that I can solve this is by adding localhost as a host in certificate. But when I will have HTML client (running from remote PC), the host will have to be a solid IP address and I will have to keep on adding hosts to the certificate. This looks like nonextensible solution.
Is there a way out of this situation?
Regards,
-
Thank you so much.
Yes indeed, generating new certificates made the standard Qt Examples sslechoserver/sslechoclient from http://doc.qt.io/qt-5/qtwebsockets-examples.html work for me.
So I took the same approach to my application on linux embedded device. In my application I use QML WebSocket element for my local UI qmlclient. This client is supposed to connect to the websocketserver on the same device. In near future I will have a html client connecting to the same server from a remote PC (This is why I am moving to a WSS scheme instead of WS).
With QML WebSocket element, I have issues connecting to the server. The error I face is
qml: Error: The host name did not match any of the valid hosts for this certificateI am taking a guess here that I can solve this is by adding localhost as a host in certificate. But when I will have HTML client (running from remote PC), the host will have to be a solid IP address and I will have to keep on adding hosts to the certificate. This looks like nonextensible solution.
Is there a way out of this situation?
Regards,
wrote on 11 Jan 2018, 08:07 last edited by@niku.ifm said in Problem with secure websocket example:
solid IP address and I will have to keep on adding hosts to the certificate.
Don't think that's necessary, that's what DNSs are meant to solve
-
wrote on 11 Jan 2018, 13:51 last edited by
Yes you are right, I can use some host name.
But my current problem is with QML WebSocket, there is no way to ignoreSslErrors.
In the standard http://doc.qt.io/qt-5/qtwebsockets-examples.html, I am using ignoreSslErrors in sslechoclient which help me suppress this (qml: Error: The host name did not match any of the valid hosts for this certificate) error.
is there a way to ignore ssl errors in QML WebSocket ?
regards,
-
wrote on 11 Jan 2018, 14:06 last edited by
I'm afraid there isn't. the QML WebSocket is just a wrapper around the C++ one and
- ignoreSslErrors is not a slot nor
Q_INVOKABLE
- I don't think QML can handle
QList<QSslError>
- ignoreSslErrors is not a slot nor
-
wrote on 11 Jan 2018, 14:30 last edited by
Is this then a limitation?
Can't I at all use WebSocket element of QML to connect to a secure websocket server having self-signed certificate? (I am insisting on using QML WebSocket element because I want to use WebChannel for accessing server data structure on QML and HTML)
Would it be possible to raise this with Qt Development team? Which forum should I raise this to?
Regards,
-
wrote on 11 Jan 2018, 14:42 last edited by
Can't you just separate the logic from the ui and keep WebSocket on the C++ side?
Would it be possible to raise this with Qt Development team? Which forum should I raise this to?
In theory yes, and https://bugreports.qt.io would be the place to do it but it's not easy to implement so I wouldn't hope in a quick solution
-
wrote on 11 Jan 2018, 16:11 last edited by
@niku-ifm it looks like you have a digital certificate issue and not a QML one. I mean, have you tried connecting with HTML (i.e. web browser) even locally (from same location you're running your QML client) to your current sslechoserver? I'd bet you'll also have your browser complaining about security issues.
Could it be possible you list the properties of the server certificate you've created? -
wrote on 12 Jan 2018, 13:47 last edited by
Thank you for your reply Pablo,
Yes, browser do complain about it.
Quite possible that I have messed up with certificate generation, I would like to share my cert and key file here but I cant upload any file here. I dont mind sharing it because its just a self signed certificate. I am also wondering on this point that whether QML WebSocket really works with self signed certificate?Also could you please tell me what properties do you want me to list here?
regards,
-
wrote on 12 Jan 2018, 13:52 last edited by
if it helps, this is what i usually use to do testing: https://www.akadia.com/services/ssh_test_certificate.html
-
Can't you just separate the logic from the ui and keep WebSocket on the C++ side?
Would it be possible to raise this with Qt Development team? Which forum should I raise this to?
In theory yes, and https://bugreports.qt.io would be the place to do it but it's not easy to implement so I wouldn't hope in a quick solution
wrote on 12 Jan 2018, 14:19 last edited by@VRonin As you said, I can keep the websocket logic on C++ side but how would I create the webchannel and get the data which is exposed on webchannel from WebSocketServer.
As I said earlier, this QML websocket code is part of Client application which connects to WebSocketServer application and calls some C++ methods on WebSocketServer through WebChannel.
-
if it helps, this is what i usually use to do testing: https://www.akadia.com/services/ssh_test_certificate.html
wrote on 15 Jan 2018, 13:44 last edited by@VRonin , as suggested by you, I tried creating WebSocket on C++ side. But using WebChannel with it wasn't possible.
From WebChannel.js, WebChannel takes QML WebSocket as input. I tried passing a C++ side created WebSocket to it but it doesnt work. It gives error from the JS file itself. So this option is gone for me :( -
@niku-ifm it looks like you have a digital certificate issue and not a QML one. I mean, have you tried connecting with HTML (i.e. web browser) even locally (from same location you're running your QML client) to your current sslechoserver? I'd bet you'll also have your browser complaining about security issues.
Could it be possible you list the properties of the server certificate you've created?wrote on 15 Jan 2018, 13:54 last edited by@Pablo-J.-Rogina
I used following command to create my certificate and private key. Do you see any problem with this command?openssl req -newkey rsa:2048 -nodes -keyout setup.key -x509 -days 36500 -out setup.crt
Regards,
-
wrote on 15 Jan 2018, 14:30 last edited by
@niku-ifm it looks like the QtWebSockets in QML has the limitation of preventing ignoring SSL errors, as @VRonin already pointed out before.
From running the QML WebSocket Client Example connecting to the SSL Echo Server Example
I was able to use the certificate provided with the server example (localhost.cert) and the QML client displayed this error: "qml: Error: The certificate is self-signed, and untrusted", which was not related to DNS as the common name (CN) in the certificate was "localhost" and the URL I used was "wss://localhost:1234" but it is an expected error that I think cannot avoided in the QML WebSocket component.However, if using secure web sockets in QML is a must condition for you, I guess you could implement a WebSocket class in C++ as the current QML implementation is doing but adding the missing pieces, in particular a way of handling SSL errors from QML, following the guidelines of invoking C++ functionality from QML (i.e. the class must be registered as an instantiable QML type).
Happy coding!
1/15