SSL with 5 lines of code ;-)

Published Monday March 26th, 2007
20 Comments on SSL with 5 lines of code ;-)
Posted in Qt

Gah… I’m currently working hard to finish QSslSocket, need to get it 100% rock solid before the 4.3.0 release. It’s tough; OpenSSL isn’t the easiest toolkit to deal with, but then again, the API that Qt 4.3 provides is looking so good that it’s all going to be worth it (/me tries to comfort himself).

For example, take a look at this little well-known snippet of code. It’s a stub for a Qt Console application, one of my favorite templates for writing nice little command line tools:

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);
}

Now, with 5 lines of code, we’ll add a QSslSocket that downloads PayPal’s front page using HTTPS. Don’t take these very few lines lightly; although you cannot see any certificates/keys/ciphers or anything, this code is as secure as SSL can get. And as is typical for Qt, it’s so easy to do that you’d want to add SSL to all your networking ;-).

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    QSslSocket socket;
    socket.connectToHostEncrypted("www.paypal.com", 443);
    socket.write("GET / HTTP/1.0rnrn");
    while (socket.waitForReadyRead())
        qDebug() << socket.readAll().data();
}

QSslSocket::connectToHostEncrypted() is a special version of connectToHost() that auto-initiates a client side hand shake after the connection has been established. QSslSocket uses the system’s default CA bundle (or, in lack of such a bundle, it uses a built-in bundle). And if anything goes wrong with the SSL handshake (i.e., the host identity is not established), the connection will be torn down, and the first waitForReadyRead() call will fail before any data is transmitted. Is that sweet, or what. πŸ˜‰

Now let’s take this a step further. Say you want to use one of the public proxy servers available. Ever been worried that these proxies can intercept your transmission? Well with QSslSocket, you no longer need to worry. Add one line to the above script to use an HTTP CONNECT proxy:

    QSslSocket socket;
    socket.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, "130.226.169.133", 3128));
    ...

Now, your 5-liner has become a 6-liner, with a fully-secured connection over an HTTP proxy (disclaimer: I have no clue who owns that proxy, I just know whomever it is cannot decrypt the transmission!).

Do you like this? Share it
Share on LinkedInGoogle+Share on FacebookTweet about this on Twitter

Posted in Qt

20 comments

Hub says:

But the OpenSSL license is not compatible with GPL as the FSF says here: http://www.fsf.org/licensing/licenses/

So Qt 4.3 is likely to cause problems with GPL licensed software distribution.

Correa says:

I suppose there will be a configure switch to disable it. The problem seams to be an advertisement clause like the old BSD had. Hopefully OpenSSL guys can revise it (?).

X says:

There is a configure-switch, but I guess that doesn’t help if you want to develop GPLed-Software.
But it seems that you can define exceptions to use with OpenSSL.

An option to build with GnuTSL would be great πŸ™‚

Andreas says:

Don’t worry, we’re aware of the licensing issues; Qt 4.3 comes with the necessary GPL exception to allow linking against OpenSSL (and we also include the required phrase in the docs). If you don’t want to pass this exception onto users of your own software, (e.g., if you don’t use QSslSocket,) you don’t have to. You can scroll to the bottom of http://doc.trolltech.com/snapshot/gpl.html to see the standard GPL exception itself.

Duncan says:

It’s actually very possible to do a MITM ‘attack’ with an HTTP proxy to grab SSL traffic. The proxy itself does the SSL handshake with you, gets the decoded data, saves it, then initiates an SSL connection out to the remote host, and repeats the decode, save routine to send the result back to your client. Without an SSL accelerator card it won’t be very fast (dependent on traffic), but it’s certainly doable. The hard part is not getting SSL conflict errors when hostnames etc don’t match up. There was, at one point, a company in Israel that made such a product, aimed at corporate border proxies so that you could scan HTTPS traffic for malware.

What about adding an enum to the socket with the standard SSL ports?
enum Ports { HttpPort = 443, ImapPort = 993

Andreas says:

Duncan: When connecting via a transparent proxy, the certificate is checked against the ultimate destination’s host name. If the hostnames don’t match the certificate, _even if the certificate otherwise checks out 100% OK_ (which requires the proxy to have a copy of the destination host’s private key and certificate), the handshake fails. So no, you cannot do MITM attacks. This is a fundamental concept with SSL; the transport layer can be completely compromised, but traffic is still safe. And proxies are just another part of the transport layer.

Thomas: We’ve had this suggestion before, even for adding a connectToHost overload that takes a string argument, socket->connectToHost(“imap.example.com”, “imap”)). It’s a good idea, with many solutions. If you want, you could post it as a suggestion through our public bugtracker.

Daniel Haas says:

Really great! Looking forward to use it!
But why is the method to connect called “connectToHostEncrypted” ? Wouldn’t connectToHost() suffice? I mean if I’m using a QSslSocket, I would expect it to open an encrypted connection, no? Wouldn’t that be more logical?

X says:

> Don’t worry
I trusted on you. πŸ˜‰

It seems to be a great feature.

Andreas says:

For STARTTLS to work, you have to have a way to establish a connection without encryption, and then enter encrypted mode later. STARTTLS allows servers to expose both plain and encrypted services on the same port, punching only one hole in the firewall.

matthias says:

any chance TT will ever support SOCKS4 proxy servers..? I already asked the question on the mailinglist but got no response.
glad with the SSL support though πŸ™‚

Andreas says:

SOCKS4 is a bit outdated… it seems to neither support UDP or IPv6, and even relies on the client to do the DNS lookup, which means it cannot be used reliably with SSL. I can’t deny us supporting it at some point, but I have my doubts. We don’t have any current plans to add SOCKS4.

jafarim says:

Remember that a vector of CA certificates is not enough and we usually need another vector of not-necessarily-trusted intermediate certificates in order for the host to build the trust chain. The host’s own certificate is also needed if client authentication is to be enabled. I think the SSL protocol itself needs more configuration than can be fit in 8 line of code! How about facilities to set the CA bundle in the QCoreApplication? It seems to be a clearer setup for using SSL.

Andreas says:

..These 5 lines aren’t the only API QSslSocket provides. If you trust your system’s CA bundle (which means you trust your Administrator user), and all you want is a secure connection to the server, these 5 lines are all you need. If you want to set your own CA bundle, you’re probably looking for something like http://doc.trolltech.com/snapshot/qsslsocket.html#setGlobalCaCertificates .

Correa says:

OpenSSL is not part of src/3rdparty even in the latest snapshots (commercial). Are you leaving it out due to the license or will it appear there? The way it is, I have to find some build openssl somewhere as I would rather not having to fiddle with it’s build system in windows. It would be much better if Qt would build it for me like it does for the other 3rdparty.

matthias says:

yes, I know socks4 is quite outdated, but most people who have have to work with a socks4 server simply don’t have any other choice due to corporate policy etc. So a lot of apps DO support socks4(a): thunderbird, firefox, gaim, ftpclients, … Unfortunately, most of the time this excludes Qt based apps, simply because Qt itself does not offer it. AFAIK, socks4a does support hostname lookup at the server side. I am not saying it is a secure solution or intelligent or whatever, it isn’t even a real standard, but offering socks4 would certainly be useful to a lot of people, also keeping in mind the very short development time needed to implement it. quick win for everyone, it seems to me πŸ˜‰

that being said, I certainly understand why it has very low or nonexistent priority πŸ™‚

Andreas says:

Correa: I agree, having libraries in 3rdparty is very convenient. However, we’re leaving it out for now, mostly to stabilize our build system; we’re approaching the end of 4.3-prerelease, and don’t want to risk delaying the release because of OpenSSL’s (somewhat complex) config/build.

matthias: I can’t find any registered suggestions for SOCKS4 (in history, even). Maybe you could submit this as a suggestion to our bugtracker, it’s easier to track suggestions that way.

matthias says:

I think the reason why you don’t find many suggestions, is that these requests normally aren’t directed to TT directly, but rather to the application developers using Qt. I’ll submit a bug, thanks

Georg says:

If I understand this right, https can be implemented by using QHttp and setSocket, so that the normal TCP-socket ist replaced by the QTs ssl-socket.
But how do I encrypt ftp with ssl? Is there any way to use QFtp together with QSslSocket?

Andreas says:

You can’t use plain FTP, so QFtp doesn’t work. But FTPS provides extensions to the protocol to allow SSL over FTP. QFtp doesn’t support these extensions.

Commenting closed.

Get started today with Qt Download now