簡體   English   中英

OpenSSL客戶端驗證-需要客戶端驗證要求

[英]OpenSSL client verification - Need client side validation requirements

我有一個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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM