Home > Articles > Security > Network Security

Securing Sockets with OpenSSL (Part 2)

  • PrintPrint
  • Share ThisShare This
  • DiscussDiscuss
Linux Socket Programming

From the author of
Linux Socket Programming

Concluding his two-part series on message security, Sean Walton describes OpenSSL, a production-ready SSL library. (Part 2 of 2)

As you write programs that interface with networks, you quickly find that nothing is really private or confidential. Almost effortlessly, you can write network snoopers that grab every message that passes along your network segment. This also means that others, who may be not as trustworthy, can do the same to your messages. The Internet is moving more toward privacy. Of course, because of the public nature of the Internet, however, this is impossible. How close to data security and privacy can the industry get?

While privacy is unreachable in a public setting like the Internet, you can get pretty close with encryption. The Secure Socket Layer (SSL) provides a standard and reliable mechanism to interface two networked computers. This is the second part of an article on OpenSSL (from http://www.openssl.org), a production-ready SSL API. The first part discussed the terminology and issues of securing the channel over TCP/IP. This part completes the discussion with program examples for a secure client and server.

A secure HTTP server (or HTTPS) is a good example for demonstrating how to connect with existing web browser applications such as Netscape, Konqueror, or Internet Explorer. This article lists some of the program statements that you use to interface with OpenSSL's API. You can get the complete code listings for all the code fragments in this article from http://www.linuxsocket.org.

Writing an HTTPS Server

Writing a program to serve up secure messages requires only a few changes to the TCP server. Once you have completed those steps, you're free and clear to send and receive private information.

Before creating a socket, you must initialize the OpenSSL library. Initialization includes loading the ciphers, error messages, creating server instances, and creating an SSL context. The only time that you change the following code is when and if you need to set up separate contexts (for example, when supporting TLS and SSLv3 in the same program). To set up a context, you can use the following code fragment:

SSL_METHOD *method;
SSL_CTX *ctx;
OpenSSL_add_all_algorithms();   /* load & register cryptos */
SSL_load_error_strings();     /* load all error messages */
method = SSLv2_server_method();   /* create server instance */
ctx = SSL_CTX_new(method);         /* create context */

The next step is to load the server's certificates. The certificates are stored in a file along with your private key. The certificates must be ready before the client connects; this is why you have to take these steps prior to setting up a socket. The code fragment below lists the code to load the certificate and private key from CertFile and KeyFile. (Remember, you can store both in the same file.)

CAUTION

This source listing leaves out the error checking for presentation clarity. Be sure you include checks for any errors in production code.

 /* set the local certificate from CertFile */
SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM);
 /* set the private key from KeyFile */
SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM);
 /* verify private key */
if ( !SSL_CTX_check_private_key(ctx) )
 abort();

The first two calls, SSL_CTX_use_certificate_file() and SSL_CTX_use_PrivateKey_file(), get the certificate and the private key, respectively. The last call, SSL_CTX_check_private_key(), verifies the private key against the known certificate. This makes sure that nothing got corrupted (or even cracked).

The next step is to create the server socket. This is identical to a typical TCP listening socket: You create the socket, bind it to a particular port, and convert it to a listening socket.

/*--- Standard TCP server setup and connection ---*/
int sd, client;
struct sockaddr_in addr;
sd = socket(PF_INET, SOCK_STREAM, 0); /* create stream socket */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);         /* select 'port' */
addr.sin_addr.s_addr = INADDR_ANY;   /* any available addr */
bind(sd, (struct sockaddr*)&addr, sizeof(addr));  /* bind it */
listen(sd, 10);         /* make into listening socket */
client = accept(sd, 0, 0);  /* await and accept connections */

OpenSSL sits on top of the TCP stack, so all you have to do is hand off the client socket descriptor. When the library gets the newly connected client, it begins the SSL handshake. And, when it's finally done, your program has a fully qualified and secure connection. The following code fragment demonstrates the last couple of steps to securing the connection: getting an SSL state and performing the handshake.

int client, bytes;
SSL *ssl = SSL_new(ctx);  /* get new SSL state with context */
SSL_set_fd(ssl, client);    /* set connection to SSL state */
SSL_accept(ssl);           /* start the handshaking */
 /* now you can read/write */
bytes = SSL_read(ssl, buf, sizeof(buf)); /* get HTTP request */
/*...process request */
SSL_write(ssl, reply, strlen(reply));	     /* send reply */
/*...*/
 /* close connection & clean up */
client = SSL_get_fd(ssl);      /* get the raw connection */
SSL_free(ssl);              /* release SSL state */
close(sd);                /* close connection */

Each connection gets its own SSL connection state with the SSL_new() library call. The program sets the raw client connection to this connection state. From that point on, the OpenSSL library uses the connection state for all I/O and control. The library replaces recv() and send() with SSL_read() and SSL_write(). The last step that calls SSL_accept() completes the SSL handshaking.

  • Share ThisShare This
  • Your Account

Discussions

Make a New Comment

You must log in in order to post a comment.

Related Resources

Danny KalevMinutes from the October 2009 Meeting
By Danny Kalev on Yesterday No Comments

The minutes from the Santa Cruz (October 2009) meeting are available here. Even if you're not a language layer at heart, I encourage you to read them.

Social Networking for the Anti-Socialites
By John Traenkenschuh on November 11, 2009 No Comments

How would Scrooge handle today's emphasis on social networking?

Danny KalevA Reader's Opinion on Attributes
By Danny Kalev on October 20, 2009 No Comments

In August I dedicated a series to the debate about C++0x attributes. I believe that it covered the subject in a balanced and detailed way, but I keep getting complaints from C++ users who don't like attributes for various reasons. Here's a recent email I received from a Polish C++ programmer. While it  doesn't represent my opinion about attributes -- I'm rather neutral about this feature and consider it a "solution waiting for a problem" -- but it suggests that attributes are still a highly controversial issue that will haunt C++ for a long time. The email is quoted here with minor edits that and as usual, with all private details removed.

See All Related Blogs

Informit Network