From 24e2a4e4a97129cfeb939357153d32fe271b0ba6 Mon Sep 17 00:00:00 2001 From: marcelb Date: Tue, 27 Jun 2023 16:31:14 +0200 Subject: [PATCH] Fix SSL handshake error, set timeout and SSL prefun calls --- .vscode/tasks.json | 31 ++++++++++++++++++++++++++ lib/tcp_socket.hpp | 2 +- src/tcp_socket.cpp | 17 ++++++++++----- test/client.cpp | 18 ++++++++++----- test/client.o | Bin 40560 -> 40560 bytes test/server.cpp | 53 +++++++++++++++++++++++---------------------- test/server.o | Bin 40504 -> 40464 bytes 7 files changed, 84 insertions(+), 37 deletions(-) create mode 100644 .vscode/tasks.json diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..989190b --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,31 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: g++ build active file", + "command": "/usr/bin/g++", + "args": [ + "-g", + "${fileDirname}/client.cpp", + "${fileDirname}/../src/*.cpp", + // "${fileDirname}../include/*/src/*.cpp", + "-o", + "${fileDirname}/client.o", + "-lssl", + "-lcrypto" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "Task generated by Debugger." + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/lib/tcp_socket.hpp b/lib/tcp_socket.hpp index c732f4b..d19a52f 100644 --- a/lib/tcp_socket.hpp +++ b/lib/tcp_socket.hpp @@ -55,7 +55,7 @@ class client { struct sockaddr_in addr; SSL* ssl = NULL; - client (const string address, const ushort port, const uint timeout = 500, SSL_CTX* securefds = NULL); + client (const string address, const ushort port, const uint timeout = 100, SSL_CTX* securefds = NULL); ~client (); bool tell (const string msg); string obey (size_t byte_limit = 1024); diff --git a/src/tcp_socket.cpp b/src/tcp_socket.cpp index 2734743..2f2dad4 100644 --- a/src/tcp_socket.cpp +++ b/src/tcp_socket.cpp @@ -53,6 +53,11 @@ server::~server () { */ secure::secure() { + + SSL_library_init(); + SSL_load_error_strings(); + OpenSSL_add_all_algorithms(); + fds = SSL_CTX_new(SSLv23_client_method()); if (!fds) { throw string("[ERROR] Creating SSL context "); @@ -71,7 +76,7 @@ secure::secure(const string cert, const string priv) { SSL_load_error_strings(); OpenSSL_add_all_algorithms(); - // Create an SSL context + // Create an SSL context fds = SSL_CTX_new(SSLv23_server_method()); if (!fds) { throw string("[ERROR] Creating SSL context "); @@ -135,12 +140,13 @@ client::client(const string address, const ushort port, const uint timeout, SSL_ } SSL_set_fd(ssl, sock); - } // Perform the SSL handshake - if (SSL_connect(ssl) <= 0) { - SSL_free(ssl); - throw string("[ERROR] Performing SSL handshake "); + if (SSL_connect(ssl) <= 0) { + SSL_free(ssl); + throw string("[ERROR] Performing SSL handshake "); + } } + } @@ -234,6 +240,7 @@ comming::comming(const server *_srv, const uint timeout, SSL_CTX* securefds) { throw string("[ERROR] Creating SSL object "); } SSL_set_fd(ssl, conn); + // Perform SSL handshake if (SSL_accept(ssl) <= 0) { SSL_free(ssl); diff --git a/test/client.cpp b/test/client.cpp index 6584194..a026c56 100644 --- a/test/client.cpp +++ b/test/client.cpp @@ -8,11 +8,19 @@ int main() { try { - secure crypto; - client myserver("localhost", 5000, 500, crypto.fds); - string sends = "Hello world!"; - cout << myserver.tell(sends) << " " << sends.length() << endl; - cout << myserver.obey(); + secure crypto; + cout << "init cert " << endl; + + client myserver("127.0.0.1", 5000, 500, crypto.fds); + // client myserver("localhost", 5000); + cout << "init client " << endl; + + + string sends = "Hello world!"; + cout << myserver.tell(sends) << " " << sends.length() << endl; + cout << "wait client " << endl; + + cout << myserver.obey(); } catch (const string err) { diff --git a/test/client.o b/test/client.o index 5b42f43df9a659fe455d1bde9f00cd7ebaa14752..788827dced1cc56c65bf03f74d07d7cdfe8e6d29 100755 GIT binary patch delta 8229 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

-17%>d0-g^56I`cBhXdI}t8cstbmU3s3- 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 BXO#c| delta 10137 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