lars
Qt
KDE
Posted by lars
 in Qt, KDE
 on Wednesday, February 28, 2007 @ 15:26

As Zack already mentioned in his blog, we had George Staikos visiting us in our Oslo office last week. He, Andreas and myself sat down to hack on some rather big API additions to our networking module.

Some of these changes have been visible in the snapshots for a few days now, as the work I have done to add support for transparent HTTP proxies to Qt (up to now only Socks5 was supported). A new QAuthenticator class has been added, handling the most common authentication methods used with proxies and HTTP servers (Basic, Digest-Md5 and NTLM). In addition all our networking classes got signals to tell you when a server (or a proxy) requires authentication. Today I’ve also updated the http example in Qt adding one UI file and around 10 lines of code showing how to show an authentication dialog to the user if the web server requires it.

A side product of doing Digest-Md5 and NTLM authentication for Qt was a neat little class called QCryptographicHash, that can calculate Md4 (I know you shouldn’t use that, but NTLM requires it…), Md5 and Sha1 sums for you. The class is now part of QtCore.

The other big API addition that mainly Andreas (with help from George) has been working on is to add SSL support to QtNetwork. He submitted it to Qt about an hour ago, and you’ll be able to see the code and play around with it in tonight’s snapshots. We’ve done a few rounds on reviewing the API so we hope that the API is rather stable and includes most of the features required for doing SSL. The QSslSocket implementation is mostly done, but certificate and key handling still has quite a few rough edges in the implementation, which we’ll try iron out within the next week or two.

Anyone who’s ever tried to use the API of OpenSSL directly knows how hard it is. Opposed to that, we’ve tried hard to make it as simple as possible to use QSslSocket without compromising on security. In the end we came up with a design that should be trivial to use for anyone who ever used any of the Qt socket classes before. The whole design consists of 5 classes: QSslSocket, QSslCertificate, QSslCyper, QSslError and QSslKey.

QSslSocket derives from QTcpSocket and all you have in addition is a few methods to to the following:

  • key and certificate handling
  • start the server or client SSL handshake
  • one signal reporting errors
  • a slot to tell QSslSocket not to abort the connection after the error
  • some signals and properties for status reporting
  • and a convenience method to connect to a host and immediately enter SSL mode

We hope that the other classes are mostly self explanatory, but we hope to have enough time until 4.3 comes out to write a few nice examples.

For now, you can find a small example using QSslSocket here. It basically connects to an arbitrary server and port and will give a telnet alike command line after connecting to the server. Andreas states that the UI is ugly, so you better use the app with your eyes closed ;-)

15 Responses to “SSL, proxies and md5 sums”

» Posted by cartman
 on Wednesday, February 28, 2007 @ 15:45

Nice work! But why not naming api like QSSLSocket ? Possible because I use KSSLSocket extensively. Btw is QSslCyper a typo for QSslCipher ?

» Posted by Richard Moore
 on Wednesday, February 28, 2007 @ 15:49

Can this API support protocols like SMTP where you need to be unencrypted until a STARTTLS command?

Rich.

» Posted by Andreas
 on Wednesday, February 28, 2007 @ 17:33

QSSLSocket instead of QSslSocket? The same reason why it’s QHttp instead of QHTTP, and QUrl instead of QURL. It’s Qt’s naming convention; all caps class names are ugly.

SMTP with STARTTLS? Certainly. You can use QSslSocket to implement STARTTLS in any protocol. If you call QSslSocket::connectToHost(), the connection is still plain. You can later call QSslSocket::startClientHandShake() to initiate client-side TLS, and a similar function for server-side TLS. If you want all in one, call QSslSocket::connectToHostEncrypted().

» Posted by Thiago Macieira
 on Wednesday, February 28, 2007 @ 17:44

KDE has also adopted the first-uppercase-only in acronyms for KDE 4, to match Qt. So, KURL became KUrl. KSSLSocket should become KSslSocket too, if it’s to remain. It’ll be up to George to provide some convenience classes for automatically handling certificates, etc.

Anyways, thanks Lars, Andreas and George. With all the work you’ve done, I’m thinking of dropping KNetwork and adopting QtNetwork in its place. Maybe with a few wrapper classes for convenience and for setting the KDE default proxies, as well as auth dialogs.

Andreas is aware of what features are missing. The only last big feature missing is Unix sockets…

» Posted by mikael
 on Wednesday, February 28, 2007 @ 21:34

Ntlm? Is Kerberos supported? I’m asking because newer Windowses do not use NTLM anymore and the NTLM is quite aged (it’s beginning to be really weak solution).

» Posted by egonk
 on Wednesday, February 28, 2007 @ 21:35

“QSslSocket derives from QTcpSocket”

Does this mean that Qt won’t support SSL over custom stream implementations?

One realistic example is STUN - you are forced to use UDP, so if you would like to secure the client-client connection with SSL, you would typically implement reliable stream over UDP and wrap it into OpenSSL BIO interface.

» Posted by Fabrizio
 on Wednesday, February 28, 2007 @ 22:50

I’m happy to hear that I’m not the only one that finds the OpenSSL API a nightmare ;)
I’ve been working on a commercial (yes, I know… I don’t like commercial software either ;) POP3/SMTP and S/MIME library using both Qt and OpenSSL and the new additions to the networking module are very interesting.
You’re sure doing some great work out there guys :)

» Posted by Sutoka
 on Thursday, March 01, 2007 @ 00:42

Wow I’m going to LOVE the hashing and SSL support, now I’ll be able to dump one dependency as well as not have to add a dependency (directly at least) on OpenSSL! This is definitely going to be a time saver!

It looks like from your example application that it will be fairly trivial to convert an application from using QTcpSocket to use QSslSocket, should be easy enough that even I won’t be able to create a gaping security hole in it! :D

» Posted by Andreas
 on Thursday, March 01, 2007 @ 08:42

No SSL support for custom sockets, I’m afraid, although you can still use OpenSSL directly for that. If you only have a UDP channel, you can use various TCP-over-UDP solutions to workaround the limitation (as I have understood, many do). With STUN, you can typically open a new tap device and run a full P2P VPN between the two peers. Then QSslSocket will work like a charm :-).

Converting to SSL, indeed; QSslSocket /is/ QTcpSocket if all you do is use QTcpSocket’s API. That means the port is straight-forward. To add SSL, you need to connect two more signals: sslErrors(), and encrypted(), and then call connectToHostEncrypted() instead of connectToHost(). You can even use the groovy waitForEncrypted() function, or any other waitFor…() function with QSslSocket. And it’s all thread reentrant.

» Posted by x
 on Thursday, March 01, 2007 @ 15:01

> QCryptographicHash, that can calculate Md4, Md5 and Sha1 sums for you

MD5 and SHA1 are kind of weak too. (Although you can still use them of course.)
It would be great if this class will be extended in the future (tiger or whirlpool perhaps?)

» Posted by Brad Hards
 on Thursday, March 01, 2007 @ 19:50

Is this actually in the snapshots? (I’m rsyncing to rsync://rsync.trolltech.com/qt-x11-bleeding which I assume is the latest, but not seeing it)

» Posted by Andreas
 on Tuesday, March 06, 2007 @ 15:31

Snapshots will be available any time soon. Also look forward to the first beta package.

» Posted by mattes
 on Tuesday, March 06, 2007 @ 15:35

Any thoughts yet about smartcard support for the SSL crypto functions or for the certificate store?

» Posted by Shriramana Sharma
 on Friday, March 09, 2007 @ 10:18

Please see http://digestit.kennethballard.com/blog/ — collisions for md5 exist and I presume same for sha1. Please implement also sha256 and tiger and whirlpool. All source code is available at md5deep.sf.net but only Qt-ification needs to be done.

Thank you for Qt.

» Posted by Laurent Pinchart
 on Saturday, March 10, 2007 @ 11:54

It would be nice if QSslSocket could provide support for the Server Name Indication extension (RFC3546). This is required to access host-based virtual hosts. Support for the extension is planned in OpenSSL 0.9.9.