In this example code, we will create a secure connection between client and server using the TLS1.2 protocol. In this communication, the client sends an XML request to the server which contains the username and password. Then, the server will verifies the XML request, if it is valid then it sends a proper XML response to the client either give a message of Invalid Request.
How to install OpenSSL Lib:
sudo apt-get install libssl–dev
Generate your own certificate :
openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout mycert.pem -out mycert.pem
Example Client code for TLS1.2 communication
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include <sys/socket.h>
#include <resolv.h>
#include <netdb.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define FAIL -1
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include <sys/socket.h>
#include <resolv.h>
#include <netdb.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define FAIL -1
int OpenConnection(const char *hostname, int port)
{
int sd;
struct hostent *host;
struct sockaddr_in addr;
if ( (host = gethostbyname(hostname)) == NULL )
{
perror(hostname);
abort();
}
sd = socket(PF_INET, SOCK_STREAM, 0);
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = *(long*)(host->h_addr);
if ( connect(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 )
{
close(sd);
perror(hostname);
abort();
}
return sd;
}
SSL_CTX* InitCTX(void)
{
SSL_METHOD *method;
SSL_CTX *ctx;
OpenSSL_add_all_algorithms(); /* Load cryptos, et.al. */
SSL_load_error_strings(); /* Bring in and register error messages */
method = TLSv1_2_client_method(); /* Create new client-method instance */
ctx = SSL_CTX_new(method); /* Create new context */
if ( ctx == NULL )
{
ERR_print_errors_fp(stderr);
abort();
}
return ctx;
}
void ShowCerts(SSL* ssl)
{
X509 *cert;
char *line;
cert = SSL_get_peer_certificate(ssl); /* get the server's certificate */
if ( cert != NULL )
{
printf("Server certificates:\n");
line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
printf("Subject: %s\n", line);
free(line); /* free the malloc'ed string */
line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
printf("Issuer: %s\n", line);
free(line); /* free the malloc'ed string */
X509_free(cert); /* free the malloc'ed certificate copy */
}
else
printf("Info: No client certificates configured.\n");
}
int main(int count, char *strings[])
{
SSL_CTX *ctx;
int server;
SSL *ssl;
char buf[1024];
char acClientRequest[1024] = {0};
int bytes;
char *hostname, *portnum;
if ( count != 3 )
{
printf("usage: %s <hostname> <portnum>\n", strings[0]);
exit(0);
}
SSL_library_init();
hostname=strings[1];
portnum=strings[2];
ctx = InitCTX();
server = OpenConnection(hostname, atoi(portnum));
ssl = SSL_new(ctx); /* create new SSL connection state */
SSL_set_fd(ssl, server); /* attach the socket descriptor */
if ( SSL_connect(ssl) == FAIL ) /* perform the connection */
ERR_print_errors_fp(stderr);
else
{
char acUsername[16] = {0};
char acPassword[16] = {0};
const char *cpRequestMessage = "<Body>\
<UserName>%s<UserName>\
<Password>%s<Password>\
<\Body>";
printf("Enter the User Name : ");
scanf("%s",acUsername);
printf("\n\nEnter the Password : ");
scanf("%s",acPassword);
sprintf(acClientRequest, cpRequestMessage, acUsername,acPassword); /* construct reply */
printf("\n\nConnected with %s encryption\n", SSL_get_cipher(ssl));
ShowCerts(ssl); /* get any certs */
SSL_write(ssl,acClientRequest, strlen(acClientRequest)); /* encrypt & send message */
bytes = SSL_read(ssl, buf, sizeof(buf)); /* get reply & decrypt */
buf[bytes] = 0;
printf("Received: \"%s\"\n", buf);
SSL_free(ssl); /* release connection state */
}
close(server); /* close socket */
SSL_CTX_free(ctx); /* release context */
return 0;
}
Example Server code for TLS1.2 communication
#include <errno.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include
<arpa/inet.h>
#include
<sys/socket.h>
#include
<sys/types.h>
#include
<netinet/in.h>
#include <resolv.h>
#include "openssl/ssl.h"
#include "openssl/err.h"
#define FAIL
-1
// Create the SSL socket
and intialize the socket address structure
int OpenListener(int port)
{
int sd;
struct
sockaddr_in addr;
sd =
socket(PF_INET, SOCK_STREAM, 0);
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port
= htons(port);
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sd,
(struct sockaddr*)&addr, sizeof(addr)) != 0 )
{
perror("can't bind port");
abort();
}
if (
listen(sd, 10) != 0 )
{
perror("Can't configure listening port");
abort();
}
return sd;
}
int isRoot()
{
if (getuid()
!= 0)
{
return 0;
}
else
{
return 1;
}
}
SSL_CTX*
InitServerCTX(void)
{
SSL_METHOD
*method;
SSL_CTX *ctx;
OpenSSL_add_all_algorithms(); /* load & register all cryptos, etc. */
SSL_load_error_strings(); /* load all error messages */
method =
TLSv1_2_server_method(); /* create new server-method instance */
ctx =
SSL_CTX_new(method); /* create new context from method */
if ( ctx ==
NULL )
{
ERR_print_errors_fp(stderr);
abort();
}
return ctx;
}
void
LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile)
{
/* set the
local certificate from CertFile */
if (
SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM) <= 0 )
{
ERR_print_errors_fp(stderr);
abort();
}
/* set the
private key from KeyFile (may be the same as CertFile) */
if (
SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM) <= 0 )
{
ERR_print_errors_fp(stderr);
abort();
}
/* verify
private key */
if (
!SSL_CTX_check_private_key(ctx) )
{
fprintf(stderr, "Private key does not match the public certificate\n");
abort();
}
}
void ShowCerts(SSL* ssl)
{
X509 *cert;
char *line;
cert =
SSL_get_peer_certificate(ssl); /* Get certificates (if available) */
if ( cert !=
NULL )
{
printf("Server certificates:\n");
line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
printf("Subject: %s\n", line);
free(line);
line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
printf("Issuer: %s\n", line);
free(line);
X509_free(cert);
}
else
printf("No certificates.\n");
}
void Servlet(SSL* ssl) /*
Serve the connection -- threadable */
{
char
buf[1024] = {0};
int sd,
bytes;
const char*
ServerResponse="<\Body>\
<Name>reanlab.blogspot.com</Name>\
<year>1.5</year>\
<BlogType>OpenSSL with c\c++<\BlogType>\
<Author>amlendra<Author>\
<\Body>";
const char
*cpValidMessage = "<Body>\
<UserName>aticle<UserName>\
<Password>123<Password>\
<\Body>";
if (
SSL_accept(ssl) == FAIL ) /* do SSL-protocol accept */
ERR_print_errors_fp(stderr);
else
{
ShowCerts(ssl); /* get any certificates */
bytes = SSL_read(ssl, buf, sizeof(buf)); /* get request */
buf[bytes] = '\0';
printf("Client msg: \"%s\"\n", buf);
if ( bytes > 0 )
{
if(strcmp(cpValidMessage,buf) == 0)
{
SSL_write(ssl, ServerResponse, strlen(ServerResponse)); /* send reply */
}
else
{
SSL_write(ssl, "Invalid Message", strlen("Invalid Message")); /* send reply */
}
}
else
{
ERR_print_errors_fp(stderr);
}
}
sd =
SSL_get_fd(ssl); /* get socket connection */
SSL_free(ssl); /* release SSL state */
close(sd); /* close connection */
}
How to compile and run the client and server:
1.Server run first, using the below command we will run the server and wait for the client request.
Compile the Server : gcc -Wall -o server Server.c -L/usr/lib -lssl -lcrypto
Run : sudo ./server <portnum>
Example : sudo ./server 8081
2.Then, using the below command to compile and execute client request.
Compile the Client : gcc -Wall -o client Client.c -L/usr/lib -lssl -lcrypto
Run : ./client <host_name> <port_number>
Example : sudo ./client 127.0.0.1 8081
NOTE:
Client will end the message in XML format:
"<body>
<username>aticle</username>
<password>123</password>
</body>"
Server will response with the following message:
"<body>
<name>reanlab.blogspot.com</name>
<year>1.5</year>
<blogtype>OpenSSL with c
c++</blogtype>
<author>amlendra</author>
</body>"

Comments
Post a Comment