сертификат клиента запроса openssl - PullRequest
0 голосов
/ 31 мая 2018

Мой сервер не может получить сертификат однорангового узла. Это работает, когда SSL_CTX_set_verify (ctx, SSL_VERIFY_PEER, 0);удаляется. Добавление приводит к тому, что клиент и сервер не обмениваются данными. Запрос сертификата клиента с сервера всегда дает NULL

Ниже приведен следующий код: - Заголовочный файл socket.h, используемый в примере сервера и клиента

#ifndef SOCKET_H
#define SOCKET_H

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <set>

#include <openssl/ssl.h>
#include <openssl/err.h>
#include <thread>

int g_start=[]()->int{
        system("../Servercert.sh");  /*create the certificates*/
        SSL_load_error_strings(); /* load all error messages */
        SSL_library_init(); /* load & register all cryptos, etc for TLS 1.2. */
        return 0;
        }();  //initialize this for all who use TLS 1.2

/*---------------------------------------------------------------------*/
/*--- LoadCertificates - load from files.                           ---*/
/*---------------------------------------------------------------------*/
void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile)
{
    /* set the local certificate from CertFile */
    if ( SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM) <= 0 )
    {
        ERR_print_errors_fp(stderr);
        abort();
    }
    /* 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_fp(stderr);
        abort();
    }
    /* verify private key */
    if ( !SSL_CTX_check_private_key(ctx) )
    {
        fprintf(stderr, "Private key does not match the public certificate\n");
        abort();
    }
}

SSL_CTX* InitCTX(void)
{   const SSL_METHOD *method;
    SSL_CTX *ctx;

    method = SSLv23_method(); /* Create new client-method instance */
    ctx = SSL_CTX_new(method); /* Create new context */
    if ( ctx == NULL )
    {
        ERR_print_errors_fp(stderr);
        abort();
    }
    return ctx;
}


#endif // SOCKET_H

исходный файл моего сервера

#include <iostream>
using namespace std;

#include "socket.h"

SSL *socketsInListenMode(SSL_CTX * &ctx,int portno)
{
    ctx = InitCTX(); /* initialize SSL */
    LoadCertificates(ctx, "server.cert","server.key");
    SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,0);

    sockaddr_in serv_addr={},cli_addr={};
    int sockListenfd = socket(AF_INET, SOCK_STREAM, 0);

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);

    int bindret=bind(sockListenfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
    cout<<bindret<<endl;
    if(bindret < 0) return 0;

    listen(sockListenfd,10);

    socklen_t s=0;
    int newsockfd = accept(sockListenfd, (struct sockaddr *)&cli_addr, &s);

    SSL *ssl = SSL_new(ctx);         /* get new SSL state with context */
    SSL_set_fd(ssl, newsockfd); /* set connection socket to SSL state */
    SSL_accept(ssl);

    close( sockListenfd );
    sockListenfd = 0;   //this will cause Accept to return
    return ssl;
}

#include<string>
int main()
{
    SSL_CTX *ctx=0;
    SSL *ssl = socketsInListenMode(ctx,5000);

    string s="asif";
    SSL_write(ssl,s.c_str(),s.length());  //may no write the full string (but thats okay for our sample)

    close(SSL_get_fd(ssl));
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    return 0;
}

исходный файл моего клиента

#include <iostream>
#include "../server/socket.h"

using namespace std;

int SocketConnect(int portno, string strIP)
{
    struct sockaddr_in serv_addr={};

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr(strIP.c_str());
    serv_addr.sin_port = htons(portno);

    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    int ret=connect(sockfd,(struct sockaddr *) &serv_addr, sizeof(serv_addr));
    if(-1 == ret)
    {
        return -1;
    }
    return sockfd;
}

SSL *secureConnect(SSL_CTX * &ctx,int portno, string strIP)
{
    ctx = InitCTX();

    LoadCertificates(ctx, "server.cert","server.key");
    SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,0);

    SSL *ssl = SSL_new(ctx); /* create new SSL connection state */

    int sfd=SocketConnect(portno,strIP);  //socketConnect

    if(-1 == sfd)
        return NULL;

    SSL_set_fd(ssl, sfd);
    SSL_connect(ssl);         //SSL connect

    return ssl;
}

int main()
{
    SSL_CTX *ctx=0;
    SSL *ssl = secureConnect(ctx,5000,"127.0.0.1");

    char buff[100]={};
    SSL_read(ssl,buff,sizeof(buff));
    cout<<buff<<endl<<flush;

    close(SSL_get_fd(ssl));
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    return 0;
}

1 Ответ

0 голосов
/ 31 мая 2018

На самом деле это не должно работать без SSL_CTX_set_verify также, поскольку вы не указали, где искать сертификаты CA, когда сертификат однорангового узла проверяется во время рукопожатия, может быть, это работает, если вы использовали самозаверяющий сертификат

Вы должны использовать SSL_CTX_load_verify_locations для установки сертификатов CA

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...