diff --git a/.vscode/settings.json b/.vscode/settings.json index 1507357..adb4a79 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,49 @@ { "files.associations": { - "functional": "cpp" + "functional": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "concepts": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "random": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp" } } \ No newline at end of file diff --git a/example/cert.pem b/example/cert.pem new file mode 100644 index 0000000..360eaa3 --- /dev/null +++ b/example/cert.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDazCCAlOgAwIBAgIUcmzC65mt2XxhXwskSJT7io+uesIwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMzA1MjMxNjQzMDNaFw0yNDA1 +MjIxNjQzMDNaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCykD9egLZJuJ+4vWScFZJye4MGkAI0JEBjirLd5wmU +lMVp5gNdQy5OlyEu0YY5HfYj15fXu3bdjBIdMvR5b64SvNpomej5G2BctvB4iFfi +9r440MARGzckKoUve7M3q9lKQDYIGT4uuF3YVrXocNXPPViTsQDQPkmGzSY2O1Ay +gbBcvBDR034K+Yu2dS8AQ84/yBUIQnbpg1myAAXp5PQxHW2fQrQbGY/vy+orx1hE +eHE62+0h4dgpmQFUFXT8tTwolvEm6kCkOmj9LoHSkXAcJwBnybN43vInyhyRuteM +PfaYLBE8gov+CKQiAcpUSnLzj/j5H47hfifRgudUuLORAgMBAAGjUzBRMB0GA1Ud +DgQWBBRCJrbSSAB7K4nKtLZ5hFLiPjdLQTAfBgNVHSMEGDAWgBRCJrbSSAB7K4nK +tLZ5hFLiPjdLQTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAi +CBwLMSqlB5uTlyjJMSbWw5qY1GKJtCGUAzHXlr6LnmqFgNl+BX4IDu8YaNilPqHZ +F4NhFwMZN9+FJZcyCG8lJ7sqIFge+KVG8jmP2SsA8qY/HyvzmDH0ZTDYxRGymzEH +ryVm8QXLR6ndqb75yK3CnN4tafuEz0ThObdzN1wIKRSUb+CjeuY2DFRqvrdmqnhg +tv3ZCW720yNOpaHTIzdObEM4BlqRBEXVXLJVWmY9vHWnZZMoiRnliv+y28Bh0pNH +JcMUvZfkJGPWBb50HucDziZLeGnEQjBMUW97OCSu6hx0nCDhK44ClmU6Eit+1xmu +MRoDLJeh59UFEvWylyXW +-----END CERTIFICATE----- diff --git a/example/privkey.pem b/example/privkey.pem new file mode 100644 index 0000000..01f76a0 --- /dev/null +++ b/example/privkey.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCykD9egLZJuJ+4 +vWScFZJye4MGkAI0JEBjirLd5wmUlMVp5gNdQy5OlyEu0YY5HfYj15fXu3bdjBId +MvR5b64SvNpomej5G2BctvB4iFfi9r440MARGzckKoUve7M3q9lKQDYIGT4uuF3Y +VrXocNXPPViTsQDQPkmGzSY2O1AygbBcvBDR034K+Yu2dS8AQ84/yBUIQnbpg1my +AAXp5PQxHW2fQrQbGY/vy+orx1hEeHE62+0h4dgpmQFUFXT8tTwolvEm6kCkOmj9 +LoHSkXAcJwBnybN43vInyhyRuteMPfaYLBE8gov+CKQiAcpUSnLzj/j5H47hfifR +gudUuLORAgMBAAECggEAS8QpH1A+CMnt+9Vg+1mr6ie+UOqKBNXc/F+9xapixkjZ ++zU9+DSpUW+PBO6ipVmxN0QjicZhiWAFz53vXhelJQ49HmUwFYMoQC7fmkVABW3t +CO6KkLebjhz8pkk2okioyni0dHtBh1FzgHhKd3ZpQqYlD4XrcnD7gddKf3hrbwIg +5pnr/QkPxeyli7hMUJJv2qWvaBtvqfhMqhjRH7T484CV6hEtURzuVAMgUB2hM4XP +Opjlp5pZAw/4eS2fXK7R4DypaiklOWo7K7u+twSvWTxNDqYRvmcKZ37zWuoKKAD0 +/rTl5VjtF3yRRv43cxu/6wxF/KGjbkJ5hszeQAMQgQKBgQC3mkGqh0tW7zEf8s5n +iotLznjIpY6VpEJ4ehTiVz1IJc7URxyn2H7/cRok19rbg904uQJhrPCOyLWnmMxb +tdKTNaR/LczMe/rgTlBRyN577VxriEXHuU1fSzig5wvZIo3ZCbIJ13T5EvPbcVIi +/VEIk4zyEroU9OSNKT4m/Stj8wKBgQD4+VHekVWo4qpEW/mh9w7SKA2DDXdFFlcP +cn3jtyDRFa1e6so29HFTpy/2pF2+4Kb6o6cq04GhfDPQqY3Opn8/pChEP6Vp0qyj +SegbidCmIpsYKPyzJUTmGN+Y40Tk6XA3e9OK1eR0uAcm7Tq3FpObNvONJtd7i6AD +ckyop/afawKBgCWF/zms4Pbpd67B3vFGXWWm0wSe4V8v7O3WdYI0ti+SmozD49Vh +58KpCODSxMXsU0AOf7AauidUWdvg3JM5u8meQvpDEAISrJk/KCcu2FmXjzXi6fAB +rRB2vSIVVlSQPVFIK/za7eshtnj41gKUpwULstiefy1dR4CaFzu8riuFAoGAIua4 +Xk3bRzB3E9wc02KRtk4dDsj9djbaf3TaRuit9gFm605YiHmdxU9Dfvytk4tkfPAi +B/PcUSnbDZ4nHdfjMKWva1nMs1fwEXfTzMB1+kQRn8JnIinQTb0g4wrA5qH+tBhs +oCK5ws7lWcSZnX7RtElwvNG8FTqOdM06B8572P8CgYBEZpdWLPKlS7cHnw506CaT +bZMgsI0RnXTgqlrlQR029/9zS3ocrmcOov+tOYDGLQnZjRJ1LxWUIIqPaJ5RvUua +pZu8tbvYNnyuI+Ugby6pUQIzFr6flQ2sJWVwoGEAX1f5LiffcXrkZ2F37c9ORCnA +g9V/U/i/RkSgH0cbouMPvg== +-----END PRIVATE KEY----- diff --git a/lib/tcp_socket.hpp b/lib/tcp_socket.hpp index b702bf6..f2d25af 100644 --- a/lib/tcp_socket.hpp +++ b/lib/tcp_socket.hpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include "ip.hpp" @@ -20,16 +22,25 @@ class server { server (const ushort port, const uint limit = 1000); ~server (); - }; +class secure { + public: + SSL_CTX* fds; + + secure(); // client + secure(const string cert, const string priv); //server + ~secure(); + +}; class client { public: int sock; struct sockaddr_in addr; + SSL* ssl = NULL; - client (const string address, const ushort port); + client (const string address, const ushort port, const uint timeout = 500, SSL_CTX* securefds = NULL); ~client (); bool tell (const string msg); string obey (size_t byte_limit = 1024); @@ -39,15 +50,18 @@ class client { class comming { public: const server *srv; + struct sockaddr_in addr; int conn; string ipv4; string ipv6; + SSL* ssl = NULL; - comming(const server *_srv, const uint timeout); + comming(const server *_srv, const uint timeout = 100, SSL_CTX* securefds = NULL); ~comming(); 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 b6606b4..7f6ae7e 100644 --- a/src/tcp_socket.cpp +++ b/src/tcp_socket.cpp @@ -40,7 +40,47 @@ server::~server () { } -client::client(const string address, const ushort port) { +secure::secure() { + fds = SSL_CTX_new(SSLv23_client_method()); + if (!fds) { + //throw "[ERROR] Creating SSL context "; + cout << endl << "[ERROR] Creating SSL context "; + + } +} + +secure::secure(const string cert, const string priv) { + + SSL_library_init(); + SSL_load_error_strings(); + OpenSSL_add_all_algorithms(); + + // Create an SSL context + fds = SSL_CTX_new(SSLv23_server_method()); + if (!fds) { + // throw "[ERROR] Creating SSL context "; + cout << endl << "[ERROR] Creating SSL context "; + } + + // Load the server's certificate and private key files + if (SSL_CTX_use_certificate_file(fds, cert.c_str(), SSL_FILETYPE_PEM) <= 0) { + // throw "[ERROR] Loading certificate file."; + cout << endl << "[ERROR] Loading certificate file."; + } + + if (SSL_CTX_use_PrivateKey_file(fds, priv.c_str(), SSL_FILETYPE_PEM) <= 0) { + //throw "[ERROR] Loading private key file."; + cout << endl << "[ERROR] Loading private key file."; + } + +} + +secure::~secure () { + SSL_CTX_free(fds); +} + + +client::client(const string address, const ushort port, const uint timeout, SSL_CTX* securefds) { sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { @@ -57,11 +97,41 @@ client::client(const string address, const ushort port) { printf("[EROR] Ne mogu se povezati s poslužiteljem!"); } + struct timeval tv; + tv.tv_sec = 0; // za sad 2 sekunde timeout, harkodirano + tv.tv_usec = timeout*1000; + + if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval))) { + printf ("[ERROR] 503 Ne mogu postaviti timeout!"); + sock = -1; + } + + if (securefds) { + ssl = SSL_new(securefds); + if (!ssl) { + //throw "[ERROR] Creating SSL object."; + cout << endl << "[ERROR] Creating SSL object."; + } + SSL_set_fd(ssl, sock); + + } + // Perform the SSL handshake + if (SSL_connect(ssl) <= 0) { + SSL_free(ssl); + // throw "[ERROR] Performing SSL handshake."; + cout << endl << "[ERROR] Performing SSL handshake."; + } + } client::~client () { + if (ssl) { + SSL_shutdown(ssl); + SSL_free(ssl); + } + if (sock <= 0) { printf ("[ERROR] Soket destruktor: već zatvoren soket!"); } @@ -74,19 +144,32 @@ client::~client () { bool client::tell (const string msg) { - ssize_t sended = send(sock, msg.c_str(), msg.length(),0); + size_t sended = 0; + if (ssl) { + sended = SSL_write(ssl, msg.c_str(), msg.length()); + } + else { + sended = write(sock, msg.c_str(), msg.length()); + } return sended == msg.length(); } string client::obey (size_t byte_limit) { - char res[byte_limit] = {0}; - ssize_t n = read ( sock , res, byte_limit); + char res[byte_limit] = {0}; + + if (ssl) { + SSL_read(ssl, res, byte_limit); + } + else { + read(sock , res, byte_limit); + } + return (string) res; } -comming::comming(const server *_srv, const uint timeout) { +comming::comming(const server *_srv, const uint timeout, SSL_CTX* securefds) { srv = _srv; socklen_t len = sizeof(struct sockaddr_in); @@ -94,6 +177,31 @@ comming::comming(const server *_srv, const uint timeout) { printf("[ERROR] Ne mogu preuzeti vezu klijenta!"); } + struct timeval tv; + tv.tv_sec = 1; // za sad 2 sekunde timeout, harkodirano + tv.tv_usec = 0; + + if (setsockopt(conn, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval))) { + printf("[ERROR] 503 Ne mogu postaviti timeout!"); + conn = -1; + } + + + if (securefds) { + ssl = SSL_new(securefds); + if (!ssl) { + // throw "[ERROR] Creating SSL object."; + cout << endl << "[ERROR] Creating SSL object."; + } + SSL_set_fd(ssl, conn); + // Perform SSL handshake + if (SSL_accept(ssl) <= 0) { + SSL_free(ssl); + // throw "[ERROR] Performing SSL handshake."; + cout << endl << "[ERROR] Performing SSL handshake."; + } + } + char ipv4_buff[INET_ADDRSTRLEN]; char ipv6_buff[INET6_ADDRSTRLEN]; @@ -106,6 +214,12 @@ comming::comming(const server *_srv, const uint timeout) { } comming::~comming() { + + if (ssl) { + SSL_shutdown(ssl); + SSL_free(ssl); + } + if (conn <= 0) { printf ("[ERROR] Comming destruktor: već zatvoren soket!"); } @@ -116,12 +230,25 @@ comming::~comming() { } bool comming::tell (const string msg) { - ssize_t sended = send(conn, msg.c_str(), msg.length(),0); + ssize_t sended = 0; + if (ssl) { + sended = SSL_write(ssl, msg.c_str(), msg.length()); + } + else { + sended = write(conn, msg.c_str(), msg.length()); + } return sended == msg.length(); } string comming::obey (size_t byte_limit) { char res[byte_limit] = {0}; - ssize_t n = read ( conn , res, byte_limit); + + if (ssl) { + SSL_read(ssl, res, byte_limit); + } + else { + read(conn , res, byte_limit); + } + return (string) res; } diff --git a/test/client.cpp b/test/client.cpp index 083c994..ca4a890 100644 --- a/test/client.cpp +++ b/test/client.cpp @@ -6,10 +6,12 @@ using namespace std; int main() { - client myserver("localhost", 5000); - string sends = "Hello wld!"; + secure crypto; + client myserver("localhost", 5000, 500, crypto.fds); + string sends = "Hello world!"; cout << myserver.tell(sends) << " " << sends.length() << endl; cout << myserver.obey(); + return 0; } \ No newline at end of file diff --git a/test/client.o b/test/client.o index 9254249..012ee4c 100755 Binary files a/test/client.o and b/test/client.o differ diff --git a/test/compile-client.sh b/test/compile-client.sh index c0b31c0..048551b 100644 --- a/test/compile-client.sh +++ b/test/compile-client.sh @@ -1 +1 @@ -g++ client.cpp ../src/* -o client.o \ No newline at end of file +g++ client.cpp ../src/* -o client.o -lssl -lcrypto \ No newline at end of file diff --git a/test/compile-server.sh b/test/compile-server.sh index e6bb7c9..9a9e315 100644 --- a/test/compile-server.sh +++ b/test/compile-server.sh @@ -1 +1 @@ -g++ server.cpp ../src/* -o server.o \ No newline at end of file +g++ server.cpp ../src/* -o server.o -lssl -lcrypto \ No newline at end of file diff --git a/test/server.cpp b/test/server.cpp index c0139ca..be48d89 100644 --- a/test/server.cpp +++ b/test/server.cpp @@ -6,21 +6,31 @@ using namespace std; int main() { + cout << "init server " << endl; server myserver(5000, 10); - comming myclient(&myserver, 1000); + cout << "init cert " << endl; + secure crypto ("../example/cert.pem", "../example/privkey.pem"); + cout << "init client " << endl; + + comming myclient(&myserver, 1000, crypto.fds); + cout << "wait client " << myclient.ipv4 << endl; string fromclient = myclient.obey(); + cout << "tell client " << fromclient << endl; + sleep(5); myclient.tell(fromclient); - myclient.~comming(); - - while (true) { - comming myclient(&myserver, 1000); - string fromclient = myclient.obey(); - cout << fromclient << " " << myclient.conn << endl; - cout << "Poslano: " << myclient.tell(fromclient) << "Veličin: " << fromclient.length() << endl; - // myclient.~comming(); - cout << "IPv4 " << myclient.ipv4 << " ipv6 " << myclient.ipv6; - } + // myclient.~comming(); + + // while (true) { + // comming myclient(&myserver, 1000); + // string fromclient = myclient.obey(); + // cout << fromclient << " " << myclient.conn << endl; + // cout << "Poslano: " << myclient.tell(fromclient) << "Veličin: " << fromclient.length() << endl; + // // myclient.~comming(); + // cout << "IPv4 " << myclient.ipv4 << " ipv6 " << myclient.ipv6; + // } + + // sleep(80); return 0; diff --git a/test/server.o b/test/server.o index 2a5703a..d571660 100755 Binary files a/test/server.o and b/test/server.o differ