TCP/IP SSL クライアント・プログラムの例を紹介しよう。
SSLサーバーの例で既に説明したように SSLクライアントも Socketの代わりに
SSLハンドルを使用するだけのものである。
/**********************************************************************
/*
/* SSLCLT: TEST SSL CLIENT
/*
/**********************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <ssl.h>
#include <errno.h>
#define TRUE 0
#define FALSE -1
#define SSL_HANDSHAKE_AS_CLIENT 0
typedef struct {
int BYTESPRO;
int BYTESAVL;
char MSGID[7];
char RESRVD;
char EXCPDATA[100];
} ERRSTRUCTURE; /* Define the error return structure */
ERRSTRUCTURE errcode;/* Error Code Structure for RCVMSG */
char addr[11] = "192.168.1.3";
SSLHandle* sslh;
SSLInitApp sslinit;
void * malloc_ptr = (void*)NULL;
unsigned int malloc_size = 8192;
unsigned short int cipher = SSL_RSA_WITH_RC4_128_SHA;
char ssl_msg[256];
int PORT = 443;
void INZSR(void);
int SSL_INZSR(void);
int SSL_CREATE(int *sockfd);
char* SSL_error(int rc);
void err_log(char* msg, int opt, char* function, int line);
void main(void){
int sockfd, len, rc;
struct sockaddr_in iaddr;
char buff[48];
printf("** SSLCLT **n");
getchar();
INZSR();
if(SSL_INZSR() == FALSE){/*SSL_INZSR*/
exit(0);
}/*SSL_INZSR*/
/*-------------------------------------------------------*/
/* socket : Get a socket descriptor */
/*-------------------------------------------------------*/
if((sockfd = socket(AF_INET, SOCK_STREAM, 0 )) < 0){
perror("SOCKET"); getchar(); exit(0);
}
/*---------------------------------------------------------*/
/* SSL_Create : enable SSL support */
/*---------------------------------------------------------*/
sslh = SSL_Create(sockfd, SSL_ENCRYPT);
if(sslh == NULL){
printf("SSL_CREATE failed with errno = %d・n", errno);
close(sockfd); getchar(); exit(0);
}
/*-----------------------------------------------------------*/
/* connect: connect to the server using a set of port number */
/*-----------------------------------------------------------*/
memset(&iaddr, 0x00, sizeof(struct sockaddr_in));
iaddr.sin_family = AF_INET;
iaddr.sin_port = htons(PORT); /* PORT no set*/
iaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* any address OK */
rc = connect(sockfd, (struct sockaddr *)&iaddr, sizeof(iaddr));
if(rc < 0){
perror("CONNECT"); getchar(); exit(0);
}
/*-----------------------------------------------------------*/
/* setup to call handshake , setting cipher */
/*-----------------------------------------------------------*/
sslh->protocol = 0;
sslh->timeout = 0;
sslh->cipherSuiteList = &cipher;
sslh->cipherSuiteListLen = 1;
/*-----------------------------------------------------------*/
/* initiate the SSL handshake as a CLIENT */
/*-----------------------------------------------------------*/
rc = SSL_Handshake(sslh, SSL_HANDSHAKE_AS_CLIENT);
if(rc != 0){
perror("SSL_HANDSHAKE");
close(sockfd);
getchar();
exit(0);
}
/*-----------------------------------------------------------*/
/* send a message to the server using secure session */
/*-----------------------------------------------------------*/
memset(buff, 0, sizeof(buff));
strcpy(buff, "* CLIENT 1ST MESSAGE USING SSL");
len = strlen(buff);
rc = SSL_Write(sslh, buff, len);
if(rc != len){
if(rc < 0){
perror("SSL_WRITE"); getchar(); exit(0);
}
else{
printf("SSL_WRITE did not all data・n");
getchar(); exit(0);
}
}
else{
printf("SSL_WRITE OK = %s・n", buff);
}
/*-----------------------------------------------------------*/
/* receive the message from the server using SSL */
/*-----------------------------------------------------------*/
memset(buff, 0, sizeof(buff));
rc = SSL_Read(sslh, buff, len);
if(rc < 0){
perror("SSL_READ"); getchar(); exit(0);
}
printf("SSL_READ OK = %s・n", buff);
SSL_Destroy(sslh);
close(sockfd);
printf("**************************************・n");
printf("* SSLCLT SUCCESSFULLY COMPLETE ! *・n");
printf("**************************************・n");
getchar();
}
/****************/
void INZSR(void)
/****************/
{
errcode.BYTESPRO = errcode.BYTESAVL = 0;
}
/********************/
int SSL_INZSR(void)
/********************/
{
int rc = 0;
char errmsg[128];
memset((char*)&sslinit, 0, sizeof(sslinit));
sslinit.applicationID = "MY_CLIENT_APP";
sslinit.applicationIDLen = 13;
sslinit.localCertificate = NULL;
sslinit.localCertificateLen = 0;
sslinit.cipherSuiteList = NULL;
sslinit.cipherSuiteListLen = 0;
malloc_ptr = (void*)malloc(malloc_size);
sslinit.localCertificate = (unsigned char*)malloc_ptr;
sslinit.localCertificateLen = malloc_size;
rc = SSL_Init_Application(&sslinit);
if(rc != 0){/* init App err */
memset(errmsg, 0, sizeof(errmsg));
sprintf(errmsg,
"SSL_INZSR:SSL_Init_App ERROR = %s・n", SSL_error(rc))
err_log(errmsg, FALSE, "SSL_INZSR", __LINE__);
return FALSE;
}/* init App err */
return TRUE;
}
/****************************/
int SSL_CREATE(int *sockfd)
/****************************/
{
sslh = SSL_Create(*sockfd, SSL_ENCRYPT);
if(sslh == NULL){
printf("SSL_Create failed with errno = %d・n", errno);
close(*sockfd);
return FALSE;
}
return TRUE;
}
/**********************/
char* SSL_error(int rc)
/**********************/
{
memset(ssl_msg, 0, sizeof(ssl_msg));
switch(rc){/*switch*/
case SSL_ERROR_NO_CIPHERS:
strcpy(ssl_msg,
"a cipher suite that is not valid was specified");
break;
case SSL_ERROR_CERT_EXPIRED:
strcpy(ssl_msg,
"the validity time period of certificate is expired.");
break;
case SSL_ERROR_KEYPASSWORD_EXPIRED:
strcpy(ssl_msg,
"the specified key ring pasword has expied.");
break;
case SSL_ERROR_NO_KEYRING:
strcpy(ssl_msg,
"No key ring filee was found.");
break;
case SSL_ERROR_NOT_REGISTERED:
strcpy(ssl_msg,
"The applicatin identifier is not registored width certifi・
cate registry facility.");
break;
case SSL_ERROR_NOT_TRUSTED_ROOT:
strcpy(ssl_msg,
"The certificate is not signed by a tructed certificate ・
authority.");
break;
case SSL_ERROR_NO_CERTIFICATE:
strcpy(ssl_msg,
"No certificate is available for SSL processing.");
break;
case SSL_ERROR_IO:
strcpy(ssl_msg,
"An error occurd in SSL processing; check the error value")
break;
case SSL_ERROR_SSL_NOT_AVAILABLE:
strcpy(ssl_msg,
"SSL が使用可能ではありません。 ");
break;
case SSL_ERROR_UNKNOWN:
strcpy(ssl_msg,
"An unknown oe unexpected error occued durering SSL ・
processing");
break;
default:
sprintf(ssl_msg, "rc = %d", rc);
}/*switch*/
return ssl_msg;
}
/********************************************************/
void err_log(char* msg, int opt, char* err_at, int line)
/********************************************************/
{
fprintf(stderr, "%s・n", msg);
fprintf(stderr, " ->ERR AT = %s, LINE = %d・n", err_at, line);
if(opt == TRUE)
fprintf(stderr, "%s・n", strerror(errno));
}
コンパイルは
CRTBNDC MYOBJLIB/SSLCLT SRCFILE(MYSRCLIB/QCSRC) AUT(*ALL)
クライアントの場合も
sslinit.applicationID = "MY_CLIENT_APP";
sslinit.applicationIDLen = 13;
によってアプリケーションが宣言されていることに注意されたい。