Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding SSL support to existing TCP & UDP code?

Here's my question.

Right now I have a Linux server application (written using C++ - gcc) that communicates with a Windows C++ client application (Visual Studio 9, Qt 4.5.)

What is the very easiest way to add SSL support to both sides in order to secure the communication, without completely gutting the existing protocol?

It's a VOIP application that uses a combination of UDP and TCP to initially set up the connection and do port tunneling stuff, and then uses UDP for the streaming data.

I've had lots of problems in the past with creating the security certificates from scratch that were necessary to get this stuff working.

Existing working example code would be ideal.

Thank you!

like image 301
Wannabe Tycoon Avatar asked Jul 09 '09 18:07

Wannabe Tycoon


2 Answers

SSL is very complex, so you're going to want to use a library.

There are several options, such as Keyczar, Botan, cryptlib, etc. Each and every one of those libraries (or the libraries suggested by others, such as Boost.Asio or OpenSSL) will have sample code for this.


Answering your second question (how to integrate a library into existing code without causing too much pain): it's going to depend on your current code. If you already have simple functions that call the Winsock or socket methods to send/receive ints, strings, etc. then you just need to rewrite the guts of those functions. And, of course, change the code that sets up the socket to begin with.

On the other hand, if you're calling the Winsock/socket functions directly then you'll probably want to write functions that have similar semantics but send the data encrypted, and replace your Winsock calls with those functions.

However, you may want to consider switching to something like Google Protocol Buffers or Apache Thrift (a.k.a. Facebook Thrift). Google's Protocol Buffers documentation says, "Prior to protocol buffers, there was a format for requests and responses that used hand marshalling/unmarshalling of requests and responses, and that supported a number of versions of the protocol. This resulted in some very ugly code. ..."

You're currently in the hand marshalling/unmarshalling phase. It can work, and in fact a project I work on does use this method. But it is a lot nicer to leave that to a library; especially a library that has already given some thought to updating the software in the future.

If you go this route you'll set up your network connections with an SSL library, and then you'll push your Thrift/Protocol Buffer data over those connections. That's it. It does involve extensive refactoring, but you'll end up with less code to maintain. When we introduced Protocol Buffers into the codebase of that project I mentioned, we were able to get rid of about 300 lines of marshalling/demarshalling code.

like image 144
Max Lybbert Avatar answered Sep 21 '22 21:09

Max Lybbert


I recommend to use GnuTLS on both the client and the server side, only for the TCP connection. Forget about the UDP data for now. The GnuTLS documentation has example code for writing both clients and servers. Please understand that at least the server side (typically the TCP responder) needs to have a certificate; the client side can work with anonymous identification (although there is even an example without server certificate, using only DH key exchange - which would allow man-in-the-middle attacks).

In general, it is likely that you will have to understand the principles of SSL, no matter what library you use. Library alternatives are OpenSSL (both Unix and Windows), and SChannel (only Windows).

like image 44
Martin v. Löwis Avatar answered Sep 17 '22 21:09

Martin v. Löwis