skip book previous and next navigation links
go up to top of book: HP Open Source Security for OpenVMS Volume 2:... HP Open Source Security for OpenVMS Volume 2:...
go to beginning of chapter: Example Programs Example Programs
go to previous page: Template for Creating Certificates and Keys for the Example Programs Template for Creating Certificates and Keys for the Example Programs
go to next page: Simple SSL Server ProgramSimple SSL Server Program
end of book navigation links

Simple SSL Client Program 



The following is the program listing of the SSL$SIMPLE_CLI.C example program.
/*
* ++
* FACILITY:
*
*	Simplest SSL Client
*
* ABSTRACT:
*
*      This is an example of an SSL client with minimum functionality.
*      The socket APIs are used to handle TCP/IP operations. 
*
*	This SSL client verifies the server's certificate against the CA
*	certificate loaded in the client.  
*
*	This SSL client does not load its own certificate and key because 
*	the SSL server does not request nor verify the client certificate.
*
*/
/* Assumptions, Build, Configuration, and Execution Instructions */
/*
*  ASSUMPTIONS:
*
*    The following are assumed to be true for the
*    execution of this program to succeed:
*
*    - SSL is installed and started on this system.
*
*    - this server program, and its accompanying client
*      program are run on the same system, but in different
*      processes.
*
*    - the certificate and keys referenced by this program
*      reside in the same directory as this program.  There 
*      is a command procedure, SSL$EXAMPLES_SETUP.COM, to 
*      help set up the certificates and keys.
*
*
*  BUILD INSTRUCTIONS:
*
*    To build this example program use commands of the form,
*
*      For a 32-bit application using only SSL APIs needs to run the 
*      following commands for SSL_APP.C .
*       -----------------------------------------------------------------
*       $CC/POINTER_SIZE=32/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES SSL_APP.C
*       $LINK SSL_APP.OBJ, VMS_DECC_OPTIONS.OPT/OPT
*       -----------------------------------------------------------------
*       VMS_DECC_OPTIONS.OPT should include the following lines.
*       -------------------------------------------------
*       SYS$LIBRARY:OPENSSL$LIBCRYPTO_SHR32.EXE/SHARE
*       SYS$LIBRARY:OPENSSL$LIBSSL_SHR32.EXE/SHARE
*       -------------------------------------------------
*
*       Creating a 64-bit application of SSL_APP.C should run the 
*       following commands.
*       -----------------------------------------------------------------
*       $CC/POINTER_SIZE=64/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES SSL_APP.C
*       $LINK SSL_APP.OBJ, VMS_DECC_OPTIONS.OPT/OPT
*       -----------------------------------------------------------------
*       VMS_DECC_OPTIONS.OPT should include the following lines.
*       -------------------------------------------------
*       SYS$LIBRARY:OPENSSL$LIBCRYPTO_SHR.EXE/SHARE
*       SYS$LIBRARY:OPENSSL$LIBSSL_SHR.EXE/SHARE
*       -------------------------------------------------
*
*
* CONFIGURATION INSTRUCTIONS:
*
*
* RUN INSTRUCTIONS:
*
*    To run this example program:
*
*    1) Start the server program,
*
*       $ run server on this system
*
*    2) Start the client program on this same system,
*
*       $ run client
*
*/
 
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <unistd.h>
#ifdef __VMS
#include <socket.h>
#include <inet.h>
 
#include <in.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
 
#include <openssl/crypto.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
 
#define RETURN_NULL(x) if ((x)==NULL) exit (1)
#define RETURN_ERR(err,s) if ((err)==-1) { perror(s); exit(1); }
#define RETURN_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr); exit(1); }
 
static int verify_callback(int ok, X509_STORE_CTX *ctx);
 
#define RSA_CLIENT_CERT	"client.crt"
#define RSA_CLIENT_KEY 	"client.key"
 
#define RSA_CLIENT_CA_CERT      "client_ca.crt"
#define RSA_CLIENT_CA_PATH      "sys$common:[syshlp.examples.ssl]"
 
#define ON      1
#define OFF     0
 
void main()
{
  	int 	err;
  	int 	verify_client = OFF; /* To verify a client certificate, set ON */
  	int 	sock;
	  struct sockaddr_in server_addr;
	  char	*str;
  	char  	buf [4096];
  	char 	hello[80];
	SSL_CTX 	*ctx;
        SSL     	*ssl;
	SSL_METHOD 	*meth;
	X509    	*server_cert;
        EVP_PKEY        *pkey;
	short int 	s_port = 5555;
	const char	*s_ipaddr = "127.0.0.1";
 
	/*----------------------------------------------------------*/
  	printf ("Message to be sent to the SSL server: ");
  	fgets (hello, 80, stdin);
 
	/* Load encryption & hashing algorithms for the SSL program */
	SSL_library_init();
 
	/* Load the error strings for SSL & CRYPTO APIs */
	SSL_load_error_strings();
 
	/* Create an SSL_METHOD structure (choose an SSL/TLS protocol version) */
  	meth = SSLv3_method();
 
	/* Create an SSL_CTX structure */
  	ctx = SSL_CTX_new(meth);                        
 
	RETURN_NULL(ctx);
	/*----------------------------------------------------------*/
	if(verify_client == ON)
 
	{
 
		/* Load the client certificate into the SSL_CTX structure */
		if (SSL_CTX_use_certificate_file(ctx, RSA_CLIENT_CERT, 
 
     SSL_FILETYPE_PEM) <= 0) {
                	ERR_print_errors_fp(stderr);
                	exit(1);
		}
 
		/* Load the private-key corresponding to the client certificate */
        	if (SSL_CTX_use_PrivateKey_file(ctx, RSA_CLIENT_KEY, 
          SSL_FILETYPE_PEM) <= 0) {
                	ERR_print_errors_fp(stderr);
                	exit(1);
        	}
 
		/* Check if the client certificate and private-key matches */
        	if (!SSL_CTX_check_private_key(ctx)) {
                	fprintf(stderr,"Private key does not match the 
                  certificate public key\n");
                	exit(1);
        	}
	}
 
	/* Load the RSA CA certificate into the SSL_CTX structure */
	/* This will allow this client to verify the server's     */
	/* certificate.                                           */
	if (!SSL_CTX_load_verify_locations(ctx, RSA_CLIENT_CA_CERT, NULL)) {
       	        ERR_print_errors_fp(stderr);
       	        exit(1);
	}
 
        /* Set flag in context to require peer (server) certificate */
        /* verification */
 
        SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL);
 
        SSL_CTX_set_verify_depth(ctx,1);
  	/* ------------------------------------------------------------- */
  	/* Set up a TCP socket */
 
  	sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);       
 
	RETURN_ERR(sock, "socket");
 
  	memset (&server_addr, '\0', sizeof(server_addr));
  	server_addr.sin_family      = AF_INET;
 
	server_addr.sin_port        = htons(s_port);       /* Server Port number */
 
  	server_addr.sin_addr.s_addr = inet_addr(s_ipaddr); /* Server IP */
 
	/* Establish a TCP/IP connection to the SSL client */
 
  	err = connect(sock, (struct sockaddr*) &server_addr, sizeof(server_addr)); 
 
	RETURN_ERR(err, "connect");
  	/* ----------------------------------------------- */
  	/* An SSL structure is created */
 
  	ssl = SSL_new (ctx);
 
	RETURN_NULL(ssl);
 
	/* Assign the socket into the SSL structure (SSL and socket without BIO) */
  	SSL_set_fd(ssl, sock);
 
	/* Perform SSL Handshake on the SSL client */
	err = SSL_connect(ssl);
 
	RETURN_SSL(err);
 
	/* Informational output (optional) */
  	printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
 
  	/* Get the server's certificate (optional) */
  	server_cert = SSL_get_peer_certificate (ssl);    
 
	if (server_cert != NULL)
        {
		printf ("Server certificate:\n");
		str = X509_NAME_oneline(X509_get_subject_name(server_cert),0,0);
		RETURN_NULL(str);
		printf ("\t subject: %s\n", str);
		free (str);
 
		str = X509_NAME_oneline(X509_get_issuer_name(server_cert),0,0);
		RETURN_NULL(str);
		printf ("\t issuer: %s\n", str);
		free(str);
 
		X509_free (server_cert);
	}
        else
                printf("The SSL server does not have certificate.\n");
 
	/*-------- DATA EXCHANGE - send message and receive reply. -------*/
	/* Send data to the SSL server */
  	err = SSL_write(ssl, hello, strlen(hello));  
 
	RETURN_SSL(err);
 
	/* Receive data from the SSL server */
  	err = SSL_read(ssl, buf, sizeof(buf)-1);                     
 
	RETURN_SSL(err);
  	buf[err] = '\0';
  	printf ("Received %d chars:'%s'\n", err, buf);
 
        /*--------------- SSL closure ---------------*/
        /* Shutdown the client side of the SSL connection */
 
        err = SSL_shutdown(ssl);
        RETURN_SSL(err);
 
        /* Terminate communication on a socket */
        err = close(sock);
 
        RETURN_ERR(err, "close");
 
        /* Free the SSL structure */
        SSL_free(ssl);
 
        /* Free the SSL_CTX structure */
        SSL_CTX_free(ctx);
}

go to previous page: Template for Creating Certificates and Keys for the Example Programs Template for Creating Certificates and Keys for the Example Programs
go to next page: Simple SSL Server ProgramSimple SSL Server Program