HP Open Source Security for OpenVMS Volume 2: HP SSL for OpenVMS > Chapter 5 Example Programs 
       
      
      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:SSL$LIBCRYPTO_SHR32.EXE/SHARE *       SYS$LIBRARY:SSL$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:SSL$LIBCRYPTO_SHR.EXE/SHARE *       SYS$LIBRARY:SSL$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); }  |  
  
      
     |