Monday, June 22, 2009

OpenSSL: SSL Client/Server Example

I'm experimenting a bit with the new iPhone 3.0 SDK, Core Data, Game Kit, Push Notification Service and so on...

I'm using C, so today a little Example of SSL Client/Server written in C using OpenSSL, I've written a small wrapper for SSL Socket, and here is How to use it.


/* SERVER CODE
* ==============================
*/
SFSocketGlobalInit(); /* Initialize SSL */

/* Alloc Socket, Initialize SSL and Listen */
SFSocket *socket = SFSocketAlloc();
SFSocketInit(socket, CA_FILE, DH_FILE, KEY_FILE, KEY_PASSWORD, NULL);
SFSocketListen(socket, INADDR_ANY, PORT);

do {
SFSocket *clientSocket;
char buffer[64];
int rdSize;

/* Accept Client Connection */
if ((clientSocket = SFSocketAccept(socket)) == NULL)
break;

/* Read Data from Client */
if ((rdSize = SFSocketRead(clientSocket, buffer, 64 - 1)) > 0) {
buffer[rdSize] = '\0';
printf("Client: %s\n", buffer);
}

/* Write to Client */
strcpy(buffer, "Hello Client!");
SFSocketWrite(clientSocket, buffer, strlen(buffer));

/* Disconnect Client */
SFSocketRelease(clientSocket);
} while (1);

/* Close and Release Socket Resources */
SFSocketRelease(socket);


Above you've the simplified server code (without error check!) and below you've the client code. The client try to connects to server, send an "Hello" message and the server reply with other greetings.


/* CLIENT CODE
* ==============================
*/
SFSocketGlobalInit(); /* Initialize SSL */

/* Alloc Socket, Initialize SSL */
SFSocket *socket = SFSocketAlloc();
SFSocketInit(socket, CA_FILE, NULL, KEY_FILE, KEY_PASSWORD, NULL);

/* Connect to Host */
SFSocketConnectToHost(socket, HOSTNAME, PORT);

/* Send Message to Server */
char buffer[64];
strcpy(buffer, "Hello from Client!");
SFSocketWrite(socket, buffer, strlen(buffer));

/* Read Message from Server */
if ((rdSize = SFSocketRead(socket, buffer, 64 - 1)) > 0) {
buffer[rdSize] = '\0';
printf("Server: %s\n", buffer);
}

/* Close and Release Socket Resources */
SFSocketRelease(socket);



Remember that you need to generate, at least, the Authority Certificate, Server Certificate and Clients Certificates. and here is How to do it.


- AUTHORITY Certificate:
openssl genrsa -des3 -out ca.key 1024
openssl req -new -x509 -key ca.key -out ca.crt

- SERVER Certificate
openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
openssl x509 -req -in server.csr -out server.crt -sha1 \
-CA ca.crt -CAkey ca.key -CAcreateserial

- CLIENT Certificate
openssl genrsa -des3 -out client.key 1024
openssl req -new -key client.key -out client.csr
openssl x509 -req -in client.csr -out client.crt -sha1 \
-CA ca.crt -CAkey ca.key -CAcreateserial



The Full Source Code is Available Here: SSL Client/Server Example Source Code.

8 comments:

  1. Can you please recreate the keys and certificates and update the source code? The certificates seem to have expired. Thanks

    ReplyDelete
  2. I'll re-update the sources as soon as I can (but you've to wait a couple of days) meanwhile you can regenerate the Certificates following the openssl commands at the end of the post.

    ReplyDelete
  3. Thanks Matteo. The reason I requested you to do so is because, when I create a certificate using the commands above, I end up getting an error that says bad decrypt on server side. Which version of openssl are you using?

    ReplyDelete
  4. Another quick question. Did you finally create a PKCS12 file from the private key and the certificate?
    Thanks.

    ReplyDelete
  5. Hi Matteo,

    The code seemed to work only if I generated the rsa key for each (ca, server and client) without encryption (i.e. without -des3 in the command). Anyways, things look quite good for me now. Thank you so much for your help.

    ReplyDelete
  6. [...] AUTHORITY Certificate : openssl genrsa -des3 -out ca.key 1024 openssl req -new -x509 -key ca.key -out ca.crt - SERVER Certificate openssl genrsa -des3 -out server.key 1024 openssl req -new -key server.key -out server.csr openssl x509 …Continue Reading… [...]

    ReplyDelete
  7. Thanks a lot - your SW rocks.
    Looks like certificate on client side is mandatory - can it be changed to make it optional?

    ReplyDelete
  8. Hey!

    I've coded an OpenSSL client/server, but for some reason my client is not submitting the certificate. If I replace my server by "openssl s_server", it works fine (which makes me believe my problem is on my server).

    After looking heaps of tutorials and examples (including yours) I still haven't found the problem! Would you have any clue?

    Cheers!

    ReplyDelete