Failed to communicate when using SSL

299 views
Skip to first unread message

tamas....@gmail.com

unread,
May 15, 2015, 9:08:12 AM5/15/15
to qjsonrpc-d...@googlegroups.com
Hi,

I'm trying to use SSL with HTTP in a simple server-client test, but the client fails to invoke any remote method with following output (enabled debug in qjsonrpc):
sending: "{
"id": 1,
"jsonrpc": "2.0",
"method": "service.getInt"
}
"
static QJsonRpcMessage QJsonRpcMessage::fromJson(const QByteArray &) "illegal value"
response: QJsonRpcMessage(type=QJsonRpcMessage::Error, id=1, code=-32603, message="error with http request: 2", data=QJsonValue(string, "Connection closed") )

SSL is configured both in server and client: QSslConfiguration is filled with QSslCertificate and QSslKey (a generated one for localhost).

Without the setting the sslconfiguration to the server (QJsonRpcHttpServer) and client (QJsonRpcHttpClient) the whole story works - but I need encrypted communication.

How can I get it working?

Thanks,
Tamas

tamas....@gmail.com

unread,
May 15, 2015, 9:13:18 AM5/15/15
to qjsonrpc-d...@googlegroups.com
The error code 2 is RemoteHostClosedError.

Matt Broadstone

unread,
May 15, 2015, 9:21:10 AM5/15/15
to tamas....@gmail.com, qjsonrpc-d...@googlegroups.com
On Fri, May 15, 2015 at 9:13 AM, <tamas....@gmail.com> wrote:
The error code 2 is RemoteHostClosedError.

Hi Tamas,
I imagine you are running into ssl errors which are being silently ignored here: https://bitbucket.org/devonit/qjsonrpc/src/b83726b8ce72a9d1a201cfeee80802c21734066e/src/qjsonrpchttpserver.cpp?at=master#cl-273. Unfortunately the ssl server was really just a incremental prototype that I merged in - it still probably has a fair amount of work required to make it the best for most use cases. I would try hooking that error signal to a slot and checking the resulting error output.

Cheers,
Matt
 
 
--
You received this message because you are subscribed to the Google Groups "qjsonrpc-development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to qjsonrpc-develop...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

tamas....@gmail.com

unread,
May 15, 2015, 9:45:28 AM5/15/15
to qjsonrpc-d...@googlegroups.com, tamas....@gmail.com
On Friday, May 15, 2015 at 3:21:10 PM UTC+2, Matt Broadstone wrote:
> On Fri, May 15, 2015 at 9:13 AM, <tamas....@gmail.com> wrote:
> The error code 2 is RemoteHostClosedError.
>
>
>
>
>
>
> Hi Tamas,
> I imagine you are running into ssl errors which are being silently ignored here: https://bitbucket.org/devonit/qjsonrpc/src/b83726b8ce72a9d1a201cfeee80802c21734066e/src/qjsonrpchttpserver.cpp?at=master#cl-273. Unfortunately the ssl server was really just a incremental prototype that I merged in - it still probably has a fair amount of work required to make it the best for most use cases. I would try hooking that error signal to a slot and checking the resulting error output.
>
>
> Cheers,
> Matt
>  

Thanks.

I've created slots for all such signals of QSslSocket and connected them in the QJsonRpcHttpServer::incomingConnection() function.
The output on server side is a simple modechange to 2 (QSslSocket::SslServerMode) and then the socket gets disconnected. In backtrace I see:

0 QJsonRpcHttpServerPrivate::_q_socketDisconnected() qjsonrpchttpserver.cpp 345 0x100029810
1 QJsonRpcHttpServer::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) moc_qjsonrpchttpserver.cpp 98 0x100029983
2 QMetaObject::activate(QObject*, int, int, void**) QMetaObject::activate(QObject*, int, int, void**) 0x1004797ab
3 QSslSocket::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) QSslSocket::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) 0x10014126b
4 QMetaObject::activate(QObject*, int, int, void**) QMetaObject::activate(QObject*, int, int, void**) 0x1004797ab
5 QAbstractSocket::disconnectFromHost() QAbstractSocket::disconnectFromHost() 0x1001215cc
6 QAbstractSocket::close() QAbstractSocket::close() 0x1001212e5
7 QSslSocket::abort() QSslSocket::abort() 0x10013cd1e
8 QSslSocketBackendPrivate::startHandshake() QSslSocketBackendPrivate::startHandshake() 0x10014a8b4
9 QSslSocketBackendPrivate::transmit() QSslSocketBackendPrivate::transmit() 0x10014b7d8
...

So there is some problem with the handshake, but I get no ssl error (signal not emited).

tamas....@gmail.com

unread,
May 15, 2015, 10:08:24 AM5/15/15
to qjsonrpc-d...@googlegroups.com, tamas....@gmail.com
I've created slot for the error(QAbstractSocket::SocketError) signal, and I get 13 (SslHandshakeFailedError)

Matt Broadstone

unread,
May 15, 2015, 10:13:27 AM5/15/15
to Tamás Csomós, qjsonrpc-d...@googlegroups.com
On Fri, May 15, 2015 at 10:08 AM, <tamas....@gmail.com> wrote:
I've created slot for the error(QAbstractSocket::SocketError) signal, and I get 13 (SslHandshakeFailedError)


Have you tried verifying your certificates with openssl's s_server and s_client tools? Off the top of my head there is a pretty good example of how to run it in the "Check keys and certificates with OpenSSL" section on this page: https://www.rabbitmq.com/troubleshooting-ssl.html.

tamas....@gmail.com

unread,
May 18, 2015, 7:39:07 AM5/18/15
to qjsonrpc-d...@googlegroups.com, tamas....@gmail.com
> Have you tried verifying your certificates with openssl's s_server and s_client tools? Off the top of my head there is a pretty good example of how to run it in the "Check keys and certificates with OpenSSL" section on this page: https://www.rabbitmq.com/troubleshooting-ssl.html.

Great news! It's working now!

Your idea of checking with openssl directed me to the correct path. However this was just the first step, the rabbit hole was quite deep :)
With extensive debugging found the problem in QJsonRpcHttpServerSocket - see below.

Here I enlist the problems I've encountered:
- with openssl s_client utility I've discovered that I have to use QSslConfiguration::setLocalCertificateChain() as our certificate file contains the whole trust chain
- the httpServer was closing the socket too early: at https://bitbucket.org/devonit/qjsonrpc/src/b83726b8ce72a9d1a201cfeee80802c21734066e/src/qjsonrpchttpserver.cpp?at=master#cl-101 the QSslSocket::writeData is async and the close() in following line terminates the connection immediatelly, so the data did not arrive to the client. Fixed this with creating a slot for bytesWritten and compare the cumulated count wiht length of m_responseBuffer, and do the close and cleanup only when the response was sent.
- using protocol QSsl::TlsV1_2 with Qt5.3 was fine on Windows, but the server failed on Trusty Ubuntu 14.04.2 LTS with SSL error 20 and 21 (SslInternalError and SslInvalidUserDataError). Turned out to be a bug in Qt, fixed in 5.4. See: https://bugreports.qt.io/browse/QTBUG-40251

Thanks,
Tamas

Matt Broadstone

unread,
May 18, 2015, 9:24:46 AM5/18/15
to Tamás Csomós, qjsonrpc-d...@googlegroups.com
Hey,
Glad you figured it out :) The writeData issue is indeed a bug, all of my local tests must have been small enough to avoid the problem. Would you be willing to put together a small test case that expresses the problem in the http server auto tests? This would help me correct it and make sure it's fixed for good in master. I think it might be as simple as copying the sslTest that exists, and then creating a very large message that couldn't possible fit in the socket buffers.

Cheers,
Reply all
Reply to author
Forward
0 new messages