我有一个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
    }

最佳答案

仅供参考,解决此问题的另一种方法可能是在sslclient下运行C程序,该程序基本上类似于DJB的tcpclient,但使用SSL-即sslclient将生成程序并打开与服务器的SSL连接,并通过管道程序的标准输出到服务器,然后将服务器的输出通过管道传递到程序的标准输入。这样做的好处是,您可以让sslclient承担所有繁重的工作,与服务器协商SSL协议并进行实际的加密,并且可以专注于程序的核心功能。有关更多信息,请参见http://www.superscript.com/ucspi-ssl/sslclient.html

10-05 18:24