Don't understand, what I'm doing wrong...
Please, look at my source code, I post it down here.
On server side, function wolfSSL_accept return error, after function wolfSSL_connect at client side.
Also don't understand how to work with cipher's and certificate's, with functions wolfSSL_CTX_set_cipher_list and wolfSSL_CTX_SetTmpDH.
I was readed manuals, looked samples, but still cannot make it work...
Can you fix my source code, please?
Tell me, please, what I'm doing wrong?
There is simple echo client-server:
SERVER
#include <iostream>
#include <string>
#include <algorithm>
#include <conio.h>
#include <wolfssl/ssl.h>
#define CERT_SERVER_PATH "Certs/server-cert.pem"
#define KEY_SERVER_PATH "Certs/server-key.pem"
#define PORT 1234
#define Assert(expr) _ASSERT_EXPR((expr), _CRT_WIDE(#expr))
#define _WINSOCKAPI_
#include <Windows.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
void Exit(WOLFSSL* ssl)
{
std::string err_str(80, 0);
int err = wolfSSL_get_error(ssl, 0);
wolfSSL_ERR_error_string(err, &err_str[0]);
std::cerr << err_str << "\n";
Assert(false && "Error");
exit(-1);
}
WOLFSSL_CTX* Init()
{
WSADATA wsa_data;
WORD version;
version = MAKEWORD(2, 0);
WSAStartup(version, &wsa_data);
wolfSSL_Init();
auto ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method());
const char* cipher_list = "DHE-RSA-AES128-SHA256";
if (wolfSSL_CTX_set_cipher_list(ctx, cipher_list) != SSL_SUCCESS)
Exit(nullptr);
return ctx;
}
void LoadCerts(WOLFSSL_CTX* ctx)
{
if (wolfSSL_CTX_use_certificate_file(ctx, CERT_SERVER_PATH, SSL_FILETYPE_PEM) != SSL_SUCCESS)
Exit(nullptr);
if (wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_SERVER_PATH, SSL_FILETYPE_PEM) != SSL_SUCCESS)
Exit(nullptr);
}
int Send(WOLFSSL* ssl, const std::string& data)
{
return wolfSSL_write(ssl, (char*)data.c_str(), data.size());
}
int Recv(WOLFSSL* ssl, std::string& data, int size)
{
return wolfSSL_read(ssl, (char*)&data[0], size);
}
void Clean(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
{
wolfSSL_shutdown(ssl);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
wolfSSL_Cleanup();
WSACleanup();
}
int main()
{
int yes = 1;
SOCKET server_socket = INVALID_SOCKET;
struct sockaddr_in sockaddr;
WOLFSSL_CTX* ctx = nullptr;
WOLFSSL* ssl = nullptr;
if (!(ctx = Init()))
Exit(nullptr);
LoadCerts(ctx);
server_socket = ::WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, 0);
memset(&sockaddr, 0x00, sizeof(sockaddr_in));
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(PORT);
sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
::setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&yes, sizeof(int));
::bind(server_socket, (struct sockaddr*)&sockaddr, sizeof(struct sockaddr));
::listen(server_socket, 1);
std::cout << "Waiting connection...\n";
SOCKET client_socket = ::accept(server_socket, nullptr, nullptr);
std::cout << "Got new connection\n";
if (!(ssl = wolfSSL_new(ctx)))
Exit(ssl);
wolfSSL_set_fd(ssl, client_socket);
if (wolfSSL_accept(ssl) != SSL_SUCCESS)
Exit(ssl);
std::cout << "Secure socket ready\n";
std::string data(80, 0);
if (!Recv(ssl, data, data.size()))
Exit(ssl);
std::cout << "Recv: " << data << "\n";
data.erase(std::remove(data.begin(), data.end(), '\0'), data.end());
data += " <---> ECHO\n";
if (!Send(ssl, data))
Exit(ssl);
Clean(ssl, ctx);
std::cout << "\nDone\n";
_getch();
return 0;
}
CLIENT
#include <iostream>
#include <string>
#include <algorithm>
#include <conio.h>
#include <wolfssl/ssl.h>
#define CERT_CLIENT_PATH "Certs/client-cert.pem"
#define IP "127.0.0.1"
#define PORT 1234
#define Assert(expr) _ASSERT_EXPR((expr), _CRT_WIDE(#expr))
#define _WINSOCKAPI_
#include <Windows.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
void Exit(WOLFSSL* ssl)
{
std::string err_str(80, 0);
int err = wolfSSL_get_error(ssl, 0);
wolfSSL_ERR_error_string(err, &err_str[0]);
std::cerr << err_str << "\n";
Assert(false && "Error");
exit(-1);
}
WOLFSSL_CTX* Init()
{
WSADATA wsa_data;
WORD version;
version = MAKEWORD(2, 0);
WSAStartup(version, &wsa_data);
wolfSSL_Init();
auto ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
const char* cipher_list = "DHE-RSA-AES128-SHA256";
if (wolfSSL_CTX_set_cipher_list(ctx, cipher_list) != SSL_SUCCESS)
Exit(nullptr);
return ctx;
}
int Send(WOLFSSL* ssl, const std::string& data)
{
return wolfSSL_write(ssl, (char*)data.c_str(), data.size());
}
int Recv(WOLFSSL* ssl, std::string& data, int size)
{
return wolfSSL_read(ssl, (char*)&data[0], size);
}
void Clean(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
{
wolfSSL_shutdown(ssl);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
wolfSSL_Cleanup();
WSACleanup();
}
int main()
{
int yes = 1;
SOCKET socket = INVALID_SOCKET;
struct sockaddr_in sockaddr;
WOLFSSL_CTX* ctx = nullptr;
WOLFSSL* ssl = nullptr;
if (!(ctx = Init()))
Exit(nullptr);
struct hostent* target = nullptr;
socket = ::WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, 0);
target = gethostbyname(IP);
memset(&sockaddr, 0x00, sizeof(sockaddr_in));
sockaddr.sin_family = AF_INET;
((u_long*)&sockaddr.sin_addr)[0] = ((u_long**)target->h_addr_list)[0][0];
sockaddr.sin_port = htons(PORT);
std::cout << "Connecting... ";
if (::connect(socket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
Exit(nullptr);
if (!(ssl = wolfSSL_new(ctx)))
Exit(ssl);
wolfSSL_set_fd(ssl, socket);
if (wolfSSL_connect(ssl) == SSL_SUCCESS)
Exit(ssl);
std::cout << " Done\n";
std::string data = "hello";
if (!Send(ssl, data))
Exit(ssl);
if (!Recv(ssl, data, data.size()))
Exit(ssl);
std::cout << "Respone: " << data;
Clean(ssl, ctx);
std::cout << "\nDone\n";
_getch();
return 0;
}