39

Refactoring C Code: SSL Errors and Clients

 5 years ago
source link: https://www.tuicool.com/articles/hit/NB3aIr7
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Getting errors from SSL isn’t easy. Sometimes, I think that so much encryption has wrapped things up and error reporting are treated as secret information that must be withheld. The root of the problem is that SSL doesn’t really have a way for the two communicating parties to tell each other: “I don’t trust you because you wear glasses.” There are some well known error codes, but, for the most part, you’ll get a connection abort. I want to see what it would take to provide good error handling for network protocol using SSL that handles:

  • No certificate provided.
  • Expired/not yet valid certificate provided.
  • Unfamiliar certificate provided.

In order to do that, we must provide this error handling at a higher level than SSL. Therefore, we need to provide something in a higher layer. In this protocol, the first thing that the server will send to the client on connection will be " OK\r\n " if everything is okay, or some error string that will explain the issue, otherwise. This turned out to be rather involved, actually.

First, I had to ask OpenSSL to send the “please gimme a client cert”:

image_thumb.png

Note the callback? It will accept everything , since doing otherwise means that we are going to just disconnect with very bad error experience. After completing the  SSL_accept()   call, I’m explicitly checking the client certificate, like so:

image_thumb_1.png

I have to say, the sheer amount of code (and explicit error handling) can be exhausting. And the fact that C is a low level language is something that I certainly feel. For example, I have this piece of code:

image_thumb_2.png

This took a long time to write. And it should have been near nothing, to be honest. We get the digest of the certificate, convert it from raw bytes to hex and then do a case insensitive comparison on the registered certificates that we already know.

To be honest, that piece of code was stupidly hard to write. I messed up and forgot that snprintf()   will always insert a null terminator and I specified that it should insert only 2 characters. That led to some confusion, I have to say.

The last thing that this piece of code does is scan through the registered certificates and figure out if we are familiar with the one the client is using. You might note that this is a linked list, because this is pretty much the only data structure that you get in C. The good thing here is that it is easy to hide the underlying implementation, and this is a just some code that I write for fun. I don’t expect to have a lot of certificates to deal with, nor do I expect to have to optimize the connection portion of this code, but it bothers me.

In C#, I would use a dictionary and forget about it. In C, I need to make a decision on what dictionary to use. That adds a lot of friction to the process, to be honest. If I wasn’t using a dictionary, I would use a List<T>, which has the advantage that it is contiguous in memory and fast to scan. For completion’s sake, here is the code that register a certificate thumbprint:

image_thumb_3.png

As you can see, this isn’t really something that interesting. But even though it doesn’t really matter, I wonder how much effort it will take to avoid the usage of a link list… I think that I can do that without too much hassle with realloc . Let’s see, here is the new registration code:

image_thumb_4.png

And here is how I’m going to be iterating on it:

image_thumb_5.png

So that isn’t too bad, and we can be sure that this will be all packed together in memory. Of course, this is pretty silly, since if I have enough certificates to want to benefits from sequential scan performance, I might as well use a hash…

The next topic I want to tackle is actually handling more than a single connected client at a time, but that will be for the next post. The code for this one is here .


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK