diff --git a/include/ehs/io/socket/SSL.h b/include/ehs/io/socket/SSL.h index 43074e4..fa7e87d 100644 --- a/include/ehs/io/socket/SSL.h +++ b/include/ehs/io/socket/SSL.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "ehs/EHS.h" #include "ehs/Str.h" #include "TCP.h" @@ -15,15 +17,18 @@ namespace ehs class EHS_LIB_IO SSL : public TCP { private: + bool server; SSL_CTX* ctx; ::SSL* sslHdl; + X509 *cert; + EVP_PKEY* pkey; public: ~SSL() override; SSL(); - SSL(const IP &type); + SSL(const IP &type, const bool &server); SSL(TCP&& tcp) noexcept; @@ -49,9 +54,9 @@ namespace ehs UInt_64 Receive(Byte* const buffer, const UInt_32 size) override; - void UseCertificate(const Byte* data, const UInt_64 size); + void UseCertificate(const Char_8* data, const UInt_32 &size); - void UsePrivateKey(const Byte* data, const UInt_64 size); + void UsePrivateKey(const Char_8* data, const UInt_32 &size); bool IsValid(); }; diff --git a/include/ehs/io/socket/Socket.h b/include/ehs/io/socket/Socket.h index 3d9561a..5051ece 100644 --- a/include/ehs/io/socket/Socket.h +++ b/include/ehs/io/socket/Socket.h @@ -41,6 +41,7 @@ namespace ehs TEXT_PLAIN, TEXT_HTML, TEXT_XML, + IMG_X_ICON, NONE }; diff --git a/src/io/socket/Request.cpp b/src/io/socket/Request.cpp index c61c7eb..ea976d4 100644 --- a/src/io/socket/Request.cpp +++ b/src/io/socket/Request.cpp @@ -264,6 +264,8 @@ namespace ehs return "text/html"; case ContentType::TEXT_XML: return "text/xml"; + case ContentType::IMG_X_ICON: + return "image/x-icon"; default: return ""; } @@ -287,6 +289,8 @@ namespace ehs return ContentType::TEXT_HTML; else if (value == "text/xml") return ContentType::TEXT_XML; + else if (value == "image/x-icon") + return ContentType::IMG_X_ICON; else return ContentType::NONE; } diff --git a/src/io/socket/Response.cpp b/src/io/socket/Response.cpp index c5065dd..eeafc69 100644 --- a/src/io/socket/Response.cpp +++ b/src/io/socket/Response.cpp @@ -343,6 +343,8 @@ namespace ehs return "text/html"; case ContentType::TEXT_XML: return "text/xml"; + case ContentType::IMG_X_ICON: + return "image/x-icon"; default: return ""; } @@ -366,6 +368,8 @@ namespace ehs return ContentType::TEXT_HTML; else if (value == "text/xml") return ContentType::TEXT_XML; + else if (value == "image/x-icon") + return ContentType::IMG_X_ICON; else return ContentType::NONE; } diff --git a/src/io/socket/SSL.cpp b/src/io/socket/SSL.cpp index 6c4134f..b6e1a6a 100644 --- a/src/io/socket/SSL.cpp +++ b/src/io/socket/SSL.cpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include namespace ehs { @@ -12,6 +14,11 @@ namespace ehs if (!IsValid()) return; + EVP_PKEY_free(pkey); + + X509_free(cert); + + if (sslHdl) { if (connection) @@ -25,28 +32,28 @@ namespace ehs } SSL::SSL() - : ctx(nullptr), sslHdl(nullptr) + : server(false), ctx(nullptr), sslHdl(nullptr), cert(nullptr), pkey(nullptr) { } - SSL::SSL(const IP &type) - : TCP(type), ctx(nullptr), sslHdl(nullptr) + SSL::SSL(const IP &type, const bool &server) + : TCP(type), server(server), ctx(nullptr), sslHdl(nullptr), cert(nullptr), pkey(nullptr) { SSL::Initialize(); } SSL::SSL(TCP&& tcp) noexcept - : TCP(std::move(tcp)), ctx(nullptr), sslHdl(nullptr) + : TCP(std::move(tcp)), server(false), ctx(nullptr), sslHdl(nullptr), cert(nullptr), pkey(nullptr) { } SSL::SSL(const TCP& tcp) - : TCP(tcp), ctx(nullptr), sslHdl(nullptr) + : TCP(tcp), server(false), ctx(nullptr), sslHdl(nullptr), cert(nullptr), pkey(nullptr) { } SSL::SSL(const SSL& ssl) - : TCP(ssl), ctx(nullptr), sslHdl(nullptr) + : TCP(ssl), server(ssl.server), ctx(nullptr), sslHdl(nullptr), cert(nullptr), pkey(nullptr) { } @@ -57,8 +64,11 @@ namespace ehs TCP::operator=(ssl); + server = ssl.server; ctx = nullptr; sslHdl = nullptr; + cert = nullptr; + pkey = nullptr; return *this; } @@ -71,6 +81,40 @@ namespace ehs return; SSL_library_init(); + OpenSSL_add_ssl_algorithms(); + SSL_load_error_strings(); + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, nullptr); + OSSL_PROVIDER_load(nullptr, "default"); + + SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); + + if (server) + { + ctx = SSL_CTX_new(TLS_server_method()); + if (!ctx) + { + UInt_32 code = ERR_get_error(); + EHS_LOG_INT(LogType::ERR, 0, ERR_error_string(code, nullptr)); + } + + SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL:!MD5"); + SSL_CTX_set_ciphersuites(ctx, + "TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:" + "TLS_CHACHA20_POLY1305_SHA256:ECDHE-RSA-AES128-GCM-SHA256" + ); + } + else + { + ctx = SSL_CTX_new(TLS_client_method()); + if (!ctx) + { + UInt_32 code = ERR_get_error(); + EHS_LOG_INT(LogType::ERR, 0, ERR_error_string(code, nullptr)); + } + + SSL_CTX_set_default_verify_paths(ctx); + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, nullptr); + } } void SSL::Release() @@ -80,6 +124,12 @@ namespace ehs if (!IsValid()) return; + EVP_PKEY_free(pkey); + pkey = nullptr; + + X509_free(cert); + cert = nullptr; + if (sslHdl) { if (connection) @@ -107,26 +157,12 @@ namespace ehs void SSL::Listen() { - OpenSSL_add_ssl_algorithms(); - SSL_load_error_strings(); - ctx = SSL_CTX_new(TLS_server_method()); - - SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); - - SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL:!MD5"); - SSL_CTX_set_ciphersuites(ctx, - "TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:" - "TLS_CHACHA20_POLY1305_SHA256:ECDHE-RSA-AES128-GCM-SHA256" - ); - - #if OPENSSL_VERSION_NUMBER < 0x10101000L - SSL_CTX_set_ecdh_auto(ctx, 1); - #endif - sslHdl = SSL_new(ctx); SSL_set_fd(sslHdl, hdl); TCP::Listen(); + + EHS_LOG_SUCCESS(); } SSL* SSL::Accept() @@ -142,8 +178,14 @@ namespace ehs delete tcp; - client->ctx = nullptr; - client->sslHdl = SSL_new(ctx); + client->sslHdl = SSL_new(this->ctx); + if (!client->sslHdl) + { + UInt_32 code = ERR_get_error(); + EHS_LOG_INT(LogType::ERR, 0, ERR_error_string(code, nullptr)); + return nullptr; + } + SSL_set_fd(client->sslHdl, client->hdl); int err = SSL_accept(client->sslHdl); @@ -153,6 +195,8 @@ namespace ehs return {}; } + EHS_LOG_SUCCESS(); + return client; } @@ -160,20 +204,6 @@ namespace ehs { TCP::Connect(address, port); - OpenSSL_add_ssl_algorithms(); - SSL_load_error_strings(); - - ctx = SSL_CTX_new(TLS_client_method()); - if (!ctx) - { - EHS_LOG_INT(LogType::ERR, 0, "Failed to creat SSL context."); - return; - } - - SSL_CTX_set_default_verify_paths(ctx); - SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, nullptr); - SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); - sslHdl = SSL_new(ctx); SSL_set_fd(sslHdl, hdl); @@ -226,40 +256,34 @@ namespace ehs return received; } - void SSL::UseCertificate(const Byte* data, const UInt_64 size) + void SSL::UseCertificate(const Char_8* data, const UInt_32 &size) { - X509 *cert = d2i_X509(nullptr, &data, (long)size); - if (!cert) - { - EHS_LOG_INT(LogType::ERR, 0, "Invalid certificate."); - return; - } + BIO* certBio = BIO_new_mem_buf(data, (int)size); + X509 *cert = PEM_read_bio_X509(certBio, nullptr, nullptr, nullptr); - if (SSL_CTX_use_certificate(ctx, cert) != 1) - { - EHS_LOG_INT(LogType::ERR, 1, "Failed to use certificate."); - return; - } + if (!SSL_CTX_use_certificate(ctx, cert)) + { + UInt_32 code = ERR_get_error(); + EHS_LOG_INT(LogType::ERR, 0, ERR_error_string(code, nullptr)); + return; + } - X509_free(cert); + BIO_free(certBio); } - void SSL::UsePrivateKey(const Byte* data, const UInt_64 size) + void SSL::UsePrivateKey(const Char_8* data, const UInt_32 &size) { - EVP_PKEY *key = d2i_PrivateKey(EVP_PKEY_RSA, nullptr, &data, (long)size); - if (!key) - { - EHS_LOG_INT(LogType::ERR, 0, "Invalid private key."); - return; - } + BIO* keyBio = BIO_new_mem_buf(data, (int)size); + EVP_PKEY* pkey = PEM_read_bio_PrivateKey(keyBio, nullptr, nullptr, nullptr); - if (SSL_CTX_use_PrivateKey(ctx, key) != 1) - { - EHS_LOG_INT(LogType::ERR, 1, "Failed to use private key."); - return; - } + if (!SSL_CTX_use_PrivateKey(ctx, pkey)) + { + UInt_32 code = ERR_get_error(); + EHS_LOG_INT(LogType::ERR, 0, ERR_error_string(code, nullptr)); + return; + } - EVP_PKEY_free(key); + BIO_free(keyBio); } bool SSL::IsValid()