Securing the socket --#-- OpenSSL uses two central structures for opening and managing secure connections -- SSL_ctx and SSL. SSL_ctx is a context object. It holds a list of ciphers, CA certificates for authenticating the server, client-side certificates, protocol specifiers, validation routines and other things that determine how secure the connection will be. In this example, we won't do a lot with it, but will rely on most of the OpenSSL defaults.

SSL is a central structure to the program. Once the connection is established, SSL holds pointers to practically everything -- including the SSL_ctx. That said, you don't really need to worry much about it, except to remember to keep tossing the SSL struct around to any of the business functions.

Let's start by initializing the two structures:

#include SSL *ssl = NULL; SSL_CTX *ssl_ctx = NULL; ssl_ctx = SSL_CTX_new(SSLv23_client_method()); ssl = SSL_new(ssl_ctx);
Not hard, was it? The only parameter we pass to the SSL_CTX initializer is a function pointer. In this case, we tell the context that we want to use a client method that will attempt an SSL v3 connection, but can fall back to SSL v2.

Now we need to define a function that will open a regular Internet socket for HTTP transfers, and rig it up for SSL. Rename sockets.c ssl_sockets.c and put this function there.

int SSLsocket(SSL *ssl, char *host, int port) { int sock, result; sock = openSocket(host, port); SSL_set_fd(ssl, sock); result = SSL_connect(ssl); return result; }
This function opens the socket just like Paul did, then associates the the SSL struct with the socket. The next line, result = SSL_connect(ssl) looks real simple, but a mountain of code runs as a result! This kicks off the famous SSL handshake where both ends of the connection exchange random bytes and agree on a key-exchange method and encryption cipher. If this function returns -1, the connection failed. Otherwise, we can use it.