Trolltech Home | Qt4-preview-feedback Home | Recent Threads | All Threads | Author | Date
All threads index page 1

Qt4-preview-feedback Archive, April 2007
QSslSocket with client certificates


Message 1 in thread

Hi,
I have been testing the QSslSocket (first: Thanks a lot, this is a long
awaited functionality in the open source edition),
and have a problem with double connections.

This is what I do:
1) I create the socket object, then assign a private key and a certificate
(in that order).

     It didn't work in the beta, but with snapshot 20070415, it works.

2) Then I try to connect to the server (a program still written in C with
openssl 0.9.8e).
     Using this code fragment:


      sock.connectToHostEncrypted("192.168.1.24", 10001);

      std::cout << "I am connecting...\n";
      sock.waitForConnected();
      if (sock.state() != QAbstractSocket::ConnectedState) {
	QString str = sock.errorString();
	std::cout << str.toLatin1().data() << "\n";
	return 1;
      }
      std::cout << "I am connected\n";

      sock.waitForEncrypted(timeout);
      std::cout << "I am encrypted\n";

      int numbytes = sock.write("hello", 6);
      std::cout << "wrote " << numbytes << " byte\n";

      sock.waitForReadyRead(timeout);

3) With snapshot 20070415, the server got a encrypted connection, but no
certificate.
     With snapshot 20070420 (due to a business trip, I haven't tested
anything in between),
     the server receives the certificate and is able to verify it (as it was
signed by a CA available to the server)

     However, no data is received, instead a second connection is made by
the client, without SSL and the old connection dies.
     Is this a bug in my code, or still a bug in the QSslSocket code?

Best regards,
     Michael


P.S.:  I am using Linux(Fedora Core 6) with kernel 2.6.20.6 and gcc  
version 4.1.1
The behaviour is the same thith the 20070421 snapshot of Qt 4.3.

Attachment:

Attachment: log
Description: Binary data


Message 2 in thread

Michael Bischoff wrote:
>      However, no data is received, instead a second connection is made by
> the client, without SSL and the old connection dies.
>      Is this a bug in my code, or still a bug in the QSslSocket code?

It sounds like a bug in QSslSocket, but I tried reproducing it and cannot
find the bug. Here's my testcase; maybe you can try modifying it to
reproduce your observed bug?

void tst_QSslSocket::waitForConnectedEncryptedReadyRead()
{
    QSslSocket socket;

    socket.connectToHostEncrypted("signin.ebay.com", 443);
    socket.write("GET / HTTP/1.1\r\nHOST: signin.ebay.com\r\n\r\n");

    QVERIFY(socket.waitForConnected(10000));
    QVERIFY(socket.waitForEncrypted(10000));
    QVERIFY(socket.waitForReadyRead(10000));
    QVERIFY(!socket.peerCertificate().isNull());
    QVERIFY(!socket.peerCertificateChain().isEmpty());
}

-- 
 [ signature omitted ] 

Message 3 in thread

On Fri, 27 Apr 2007 09:19:49 +0200, Andreas Aardal Hanssen  
<ahanssen@xxxxxxxxxxxxx> wrote:

> Michael Bischoff wrote:
>>      However, no data is received, instead a second connection is made  
>>      by the client, without SSL and the old connection dies.

> Here's my testcase; maybe you can try modifying it to
> reproduce your observed bug?
>
>     socket.connectToHostEncrypted("signin.ebay.com", 443);
>     socket.write("GET / HTTP/1.1\r\nHOST: signin.ebay.com\r\n\r\n");

Hello,
the example verifies that the server's certificate has been received.
This works in the given example and also in my old code from last week.

When I test the example code it works. When connecting to my own
server, it does not work. The difference is that I do not use an
official SSL certificate in my server, but a self-signed one.

As a next step, I added my own server's self-signed CA certificate
to the client's CA list. In fact, the handshake got further, but still
no data transfer happens.  I think that QSslSocket checks something
more to verify that a valid handshake has taken place, and falls
back to an unencrypted connection if it is not happy with the handshake.

Best regards,
     Michael




To unsubscribe - send "unsubscribe" in the subject to qt4-preview-feedback-request@xxxxxxxxxxxxx


Message 4 in thread

Hi,
it's solved:

This is what happened:
in QSslBackendPrivate::testConnection(), there is a test if the peer name  
matches
the common name of the server's certificate.
As I connected using a numeric IP address and the common name was the  
symbolic one,
the strings did not match ad the connection was refused by the client with
QSslError::HostNameMismatch
My client I wrote in C did not have such a verification and therefore  
worked.

I changed my program to connect via symbolic name, and voila! I can send  
data
to the server!

So, as far as I understand this, QSslSockets must be used asynchronously,  
i.e.
any errors that QaitForEncrypted might cause must be examined and only
if no error occured, data may be written to the server.
Otherwise, a second (unencrypted) connection will be tried.

Best regards,
     Michael

To unsubscribe - send "unsubscribe" in the subject to qt4-preview-feedback-request@xxxxxxxxxxxxx


Message 5 in thread

Michael Bischoff wrote:
> Hi,
> it's solved:

Fabulous!

> This is what happened:
> in QSslBackendPrivate::testConnection(), there is a test if the peer name
> matches
> the common name of the server's certificate.
> As I connected using a numeric IP address and the common name was the
> symbolic one,
> the strings did not match ad the connection was refused by the client with
> QSslError::HostNameMismatch
> My client I wrote in C did not have such a verification and therefore
> worked.

OK; I think you would have seen this also by calling errorString(), or at
least in sslErrors().

> I changed my program to connect via symbolic name, and voila! I can send
> data
> to the server!
> So, as far as I understand this, QSslSockets must be used asynchronously,
> i.e.
> any errors that QaitForEncrypted might cause must be examined and only
> if no error occured, data may be written to the server.
> Otherwise, a second (unencrypted) connection will be tried.

You can use it either way; synchronously or asynchronously. If the
connection verification fails, you are best off by connecting to the
sslErrors() signal to intercept any errors that occur, and maybe in your
case, you could call socket->ignoreSslErrors() if the host name mismatch
occurred (and you could otherwise verify that the peer is valid). In a
waitfor-scenario, you need to call ignoreSslErrors() before any wait...
function.

Andreas

-- 
 [ signature omitted ]