我有一个C tcp客户端,目前使用SSLV3
需要有关我缺少什么以及我需要在客户端做些什么的指导
我仍然不太清楚实施并尝试阅读文档和理解 要求人们展示一些亮点 (从原始代码中删除了很多东西)
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include "socketApp.h"
#include "stdio.h"
#include "string.h"
#include "functions.h"
#include "logger.h"
#include <errno.h>
#include <fcntl.h>
#include <malloc.h>
#include <resolv.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define TCP_KEEPALIVE 0x2
fd_set readSet, actualReadSet;
static int xSocket,ySocket,zSocket;
static char debugBuf[200];
char str[4][20] = {"INVALID","x","y","z"};
char xLogPrint=0;
#define FAIL -1
char CertFile[] = "SocketCert.pem";
char KeyFile[] = "SocketPrivateKey.pem"; //current no key implemetation is done
SSL_CTX *ctx;
int server;
static int sslStatus;
SSL *ssl;
SSL_CTX* InitCTX(void);
int setupSSL(int server){
SSL_library_init();
ctx = InitCTX();
LoadCertificates(ctx, CertFile, KeyFile);
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_y(stderr);
return -1;
}else{
sprintf(debugBuf,"Connected with %s encryption\n", SSL_get_cipher(ssl));
debug_log(debugBuf,TRACE_LOG);
setSSLContext(ssl,sslStatus);
return 0;
}
}
int LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile)
{
if ( SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM) <= 0 )/* set the local certificate from CertFile */
{
ERR_print_errors_y(stderr);
debug_log("Certificate Load error",TRACE_LOG);
return -1;
}
//printf("Server certificates:\n");
// line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
//printf("Subject: %s\n", line);
/* 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_y(stderr);
abort();
}*/
/* verify private key
if ( !SSL_CTX_check_private_key(ctx) )
{
yrintf(stderr, "Private key does not match the public certificate\n");
printf("abort at SSL_CTX_check_private_key");
abort();
}*/
debug_log("Certificate Load success",TRACE_LOG);
return 0;
}
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 = SSLv3_client_method(); /* Create new client-method instance */
ctx = SSL_CTX_new(method); /* Create new context */
if ( ctx == NULL )
{
//ERR_print_errors_y(stderr);
debug_log("SSL context load failure",TRACE_LOG);
sprintf(debugBuf,"SYSTEM:SSL_SOCKET:creation Failed: %d %s\n",stderr,ERR_print_errors_y(stderr));
debug_log(debugBuf,TRACE_LOG);
//abort();
return ctx;
}
SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL);
SSL_CTX_load_verify_locations(ctx,CertFile,NULL);
return ctx;
}
int socketfdInit(void)
{
FD_ZERO(&readSet);
return 0;
}
int connectToServer(int server,int serverIP, int serverPort)
{
long arg = 0;
int *serverSock= NULL;
int retVal, keepalive=5000,sockOpt=1;
struct sockaddr_in localAddr, serverAddr;
int valopt;
struct timeval tv;
socklen_t opt_len;
int sock_err =0;
fd_set tempSet;
sslStatus=getSSLEnableStatus();
sprintf(debugBuf,"SYSTEM:x_SOCKET:sslStatus: %d \n",sslStatus);
debug_log(debugBuf,TRACE_LOG);
if ((*serverSock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
sprintf(debugBuf,"SYSTEM:%s_SOCKET:creation Failed: %d %s\n",str[server],errno,strerror(errno));
debug_log(debugBuf,TRACE_LOG);
return -1;
}
if (sslStatus == 1){
retVal=setupSSL(*serverSock);
if (retVal != 0){
return retVal;
}
else{
FD_SET(*serverSock, &readSet);
FD_SET(*serverSock, &actualReadSet);
return 0;
}
}
}
int SendToSock( int msgLen,char *msg)
{
int i,numBytesSent;
int sock_err =0;
int sock_errl = sizeof(sock_err);
int serverSock = 0;
if (sslStatus == 1){
numBytesSent = SSL_write(ssl, msg,msgLen+2);
}
else{
numBytesSent = send(serverSock, msg,msgLen+2, MSG_NOSIGNAL);
}
}
int ReceiveFromSock(char *msg,int Rxtimeout)
{
// time val for select expiry
struct timeval tv;
int opt_len; // for querying getsocket opt -->value of length of result
int sock_err=0; // placeholder integer where result is passed by getsockOpt
int bytesRecvd=0;
int selectRetVal;
int tempBytesRecvd;
int status;
fd_set errSet ;
int serverSock = 0;
int len;
char lenStr[3];
if (sslStatus == 1){
bytesRecvd = SSL_read(ssl, (char *)lenStr, 2);
SSL_get_error(ssl,status);
sprintf(debugBuf,"SYSTEM:x_SOCKET:recv: get error value %d",bytesRecvd);
debug_log(debugBuf,TRACE_LOG);
}else
bytesRecvd = recv(serverSock, (char *)lenStr, 2, 0); //receive the length in EBCDIC
}
答案 0 :(得分:0)
只是一个FYI,解决这个问题的另一种方法可能是在sslclient下运行你的C程序,它基本上类似于DJB的tcpclient,但是使用SSL - 即sslclient将产生你的程序并打开到服务器的SSL连接,并将程序的stdout传递给服务器,并将服务器的输出管道输出到程序的stdin。这样做的好处在于,只要与服务器协商SSL协议并进行实际加密,就可以让sslclient完成所有繁重工作,并且您可以专注于程序的核心功能。有关详细信息,请参阅http://www.superscript.com/ucspi-ssl/sslclient.html。