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);
}