C++ SSLClient/Server cannot send and receive

Viewed 39

Hello I'm doing a SSL client / server application but I don't receive messages sent from the client to the server and vice-versa. I'm using 2 class to define the SSLClient and SSLServer. Also the server doesn't wait to get a message when I do SSL_read(....)

SSLServer.cpp:

#include "SSLServer.h"
#include <iostream>
SSLServer::SSLServer(char *host, int port, std::string pathCert, std::string pathKeyCert){
    mHostAddress = host;
    mPort = port;
    mPathCert = pathCert;
    mPathKeyCert = pathKeyCert;
}

bool SSLServer::start(int (*func)(SSL *ssl)){
    if(init()){
        if(bindSocket() && listenSocket()){
            while(true){
                mSockLenT = sizeof(mSockAddrStorage);
                int clientSocket = accept(mServerSocket, (struct sockaddr *) &mSockAddrIn, &mSockLenT);
                SSL *ssl = SSL_new(mCtx);
                SSL_set_fd(ssl, clientSocket);
                if(SSL_accept(ssl) != FAIL){
                    std::thread client(func, ssl);
                    client.detach();
                } else {
                    closeServerSocket();
                }
            }
        } else {
            return false;
        }
    }
    closeServerSocket();
    return true;
}

bool SSLServer::init(){
    SSL_library_init();
    initCtx();
    if(mCtx != NULL){
        if(loadCertificate() == SUCCESS){
            mServerSocket = socket(PF_INET, SOCK_STREAM, 0x0);
            mSockAddrIn.sin_family = AF_INET;
            mSockAddrIn.sin_port = htons(mPort);
            mSockAddrIn.sin_addr.s_addr = inet_addr(mHostAddress);
            memset(mSockAddrIn.sin_zero, '\0', sizeof(mSockAddrIn.sin_zero));
            return true;
        }
    }
    return false;
}

bool SSLServer::bindSocket(){
    if(bind(mServerSocket, (struct sockaddr *) &mSockAddrIn, sizeof(mSockAddrIn)) == FAIL){
        closeServerSocket();
        return false;
    }
    return true;
}

bool SSLServer::listenSocket(){
    if(listen(mServerSocket, MAX_OPEN_CONNECTIONS) == FAIL){
        closeServerSocket();
        return false;
    }
    return true;
}

void SSLServer::closeServerSocket(){
    close(mServerSocket);
    SSL_CTX_free(mCtx);
}

void SSLServer::initCtx(){
    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();
    const SSL_METHOD *method = SSLv23_client_method();
    mCtx = SSL_CTX_new(method);
}

int SSLServer::loadCertificate(){
    if(SSL_CTX_load_verify_locations(mCtx, mPathCert.c_str(), mPathKeyCert.c_str()) != 0x1){
        return FAIL;
    }
    if(SSL_CTX_set_default_verify_paths(mCtx) != 0x1){
        return FAIL;
    }
    if(SSL_CTX_use_certificate_file(mCtx, mPathCert.c_str(), SSL_FILETYPE_PEM) <= 0x0){
        return FAIL;
    }
    if(SSL_CTX_use_PrivateKey_file(mCtx, mPathKeyCert.c_str(), SSL_FILETYPE_PEM) <= 0x0){
        return FAIL;
    }
    if(!SSL_CTX_check_private_key(mCtx)){
        return FAIL;
    }
    return SUCCESS;
}

SSLServer.h:

#include <cstring>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>         // "close()"
#include <thread>
#include <string>
#include <openssl/ssl.h>
#include <openssl/types.h>

#define MAX_OPEN_CONNECTIONS    20
#define BUFFER_SIZE    1024

#define SUCCESS 0x0
#define FAIL    -0x1
#define SOCKET_CLOSED   -0x1

class SSLServer {

    public:
        SSLServer(char *host, int port, std::string pathCert, std::string pathKeyCert);
        bool start(int (*func)(SSL *ssl));

    private:
        char *mHostAddress;
        int mPort;
        struct sockaddr_in mSockAddrIn;
        struct sockaddr_storage mSockAddrStorage;
        socklen_t mSockLenT;
        int mServerSocket;

        SSL_CTX *mCtx;
        std::string mPathCert;
        std::string mPathKeyCert;

        bool init();
        bool bindSocket();
        bool listenSocket();
        void closeServerSocket();
        void initCtx();
        int loadCertificate();

};

SSLClient:

#include "SSLClient.h"

SLLClient::SLLClient(char * address, int port, std::string pathCert, std::string pathKeyCert) : ClientTCP(address, port) {
    mPathCertificate = pathCert;
    mKeyCertificate = pathKeyCert;
}

bool SLLClient::initSocket() {
    SSL_library_init();
    initCtx();
    if(mCtx != NULL && loadCertificates() == SUCCESS){
        ClientTCP::initSocket();
        mSSL = SSL_new(mCtx);
        SSL_set_fd(mSSL, mClientSocket);
        return true;
    }
    return false;
}

bool SLLClient::connectSocket(void){
    return ClientTCP::connectSocket() && SSL_connect(mSSL) != -0x1;
}

bool SLLClient::sendMsg(char * msg, int len){
    return SSL_write(mSSL, msg, len);
}

bool SLLClient::recvMsg(char *buffer, int len){
    return SSL_read(mSSL, buffer, len);
}

void SLLClient::closeSocket(void){
    SSL_free(mSSL);
    ClientTCP::closeSocket();
    SSL_CTX_free(mCtx);
}

int SLLClient::loadCertificates(){
    if(SSL_CTX_use_certificate_file(mCtx, mPathCertificate.c_str(), SSL_FILETYPE_PEM) <= 0x0){
        return ERROR;
    }
    if(SSL_CTX_use_PrivateKey_file(mCtx, mKeyCertificate.c_str(), SSL_FILETYPE_PEM) <= 0x0){
        return ERROR;
    }
    if(!SSL_CTX_check_private_key(mCtx)){
        return ERROR;
    }
    return SUCCESS;
}   

void SLLClient::initCtx(){
    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();

    const SSL_METHOD *method = SSLv23_client_method();
    mCtx = SSL_CTX_new(method);
}

SLLClient.h:

#include "ClientTCP/ClientTCP.h"
#include <string>
#include <openssl/ssl.h>
#include <openssl/err.h>

class SLLClient : public ClientTCP {

    public:
        SLLClient(char * address, int port, std::string pathCert, std::string pathKeyCert);
        virtual bool initSocket(void) override;
        bool connectSocket(void) override;
        virtual bool sendMsg(char *, int) override;
        virtual bool recvMsg(char *, int) override;
        virtual void closeSocket(void) override;

    private:
        SSL *mSSL;
        SSL_CTX *mCtx;
        std::string mPathCertificate;
        std::string mKeyCertificate;

        int loadCertificates();
        void initCtx();

};

TcpClient:

ClientTCP::ClientTCP(char *address, int port){
    mAddress = address;
    mPort = port;
}

bool ClientTCP::initSocket(){
    mClientSocket = socket(PF_INET, SOCK_STREAM, 0x0);
    m_server_addr.sin_family = AF_INET;
    m_server_addr.sin_port = htons(mPort);
    m_server_addr.sin_addr.s_addr = inet_addr(mAddress);
    memset(m_server_addr.sin_zero, '\0', sizeof m_server_addr.sin_zero);
    m_addr_size = sizeof m_server_addr;
    return true;
}

bool ClientTCP::connectSocket(){
    return connect(mClientSocket, (struct sockaddr *) &m_server_addr, m_addr_size) == SUCCESS;
}

bool ClientTCP::sendMsg(char *buffer, int size){
    return send(mClientSocket, buffer, size, 0x0) != ERROR;
}

bool ClientTCP::recvMsg(char *buffer, int size){
    return recv(mClientSocket, buffer, size, 0x0) != ERROR;
}

void ClientTCP::closeSocket(){
    close(mClientSocket);
}
1 Answers

Found the error, I was using SSLv23_client_method insteand of SSLv23_server_method LOOOL

Related