Skip to content

Commit d1e872a

Browse files
committed
Improvements on version 3.2
- new features: - TLS client can now read subjects from server certificate as well as server can - improvements: - Improve the exception templates - When subject part can't be read from foreign certificate, throw exception instead returning nothing -> Return pattern is now guaranteed - bug fixes:
2 parents 904eb63 + 211f794 commit d1e872a

25 files changed

+616
-79
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ using namespace tcp; // The entire library is in the namespace tcp
146146

147147
The following linker flags are mandatory to be set depending on what sub-features are used:
148148

149-
* **-lssl** if the TLS encryption is used
149+
* **-lssl** if the TLS encryption is used (General OpenSSL library)
150+
* **-lcrypto** if the TLS encryption is used (OpenSSL cryptographic library)
150151

151152
### Message modes
152153

example/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.10)
55
set(CMAKE_CXX_STANDARD 17)
66
set(CMAKE_CXX_STANDARD_REQUIRED ON)
77

8-
project(example VERSION 3.2.0 DESCRIPTION "Example of using the TCP client and server classes")
8+
project(example VERSION 3.2.1 DESCRIPTION "Example of using the TCP client and server classes")
99

1010
add_executable(server server.cpp)
1111
add_executable(client client.cpp)

example/client.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
* @file server.cpp
33
* @author Nils Henrich
44
* @brief Example how to use the server part
5-
* @version 1.0
5+
* @version 3.2.1
66
* @date 2024-04-20
77
*
8-
* @copyright Copyright (c) 2024
8+
* @copyright Copyright (c) 2025
99
*/
1010

1111
#include <iostream>

example/server.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
* @file server.cpp
33
* @author Nils Henrich
44
* @brief Example how to use the server part
5-
* @version 1.0
5+
* @version 3.2.1
66
* @date 2024-04-20
77
*
8-
* @copyright Copyright (c) 2024
8+
* @copyright Copyright (c) 2025
99
*/
1010

1111
#include <iostream>

hooks/post-checkout

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,18 @@ then
2323
# ---------- Update version ----------
2424
version=$(echo $current_branch | sed "s/release\///g" | sed -E "s/^[a-zA-Z]+//g")
2525
find $root_dir/src/ -type f -exec sed -i -E "s/@version\s*[1234567890\.\+]+$/@version $version/g" {} \;
26+
find $root_dir/example/ -type f -exec sed -i -E "s/@version\s*[1234567890\.\+]+$/@version $version/g" {} \;
2627
find $root_dir/example/ -type f -name CMakeLists.txt -exec sed -i -E "s/project\((\w+)\s+VERSION\s+[1234567890\.\+]+/project(\1 VERSION $version/g" {} \;
28+
29+
# ---------- Update copyright year ----------
30+
year=$(date +"%Y")
31+
find $root_dir/src/ -type f -exec sed -i -E "s/@copyright.*/@copyright Copyright (c) $year/g" {} \;
32+
find $root_dir/example/ -type f -exec sed -i -E "s/@copyright.*/@copyright Copyright (c) $year/g" {} \;
33+
34+
# ---------- Commit changes ----------
2735
git add $root_dir
2836
git commit -m "<hook> Update to version $version"
37+
2938
else
3039
echo "Nothing to be done for branch '$current_branch'"
3140
fi

src/TcpClient.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
* @file TcpClient.hpp
33
* @author Nils Henrich
44
* @brief TCP client for unencrypted data transfer without authentication.
5-
* @version 3.2.0
5+
* @version 3.2.1
66
* @date 2021-12-27
77
*
8-
* @copyright Copyright (c) 2021
8+
* @copyright Copyright (c) 2025
99
*
1010
*/
1111

src/TcpServer.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
* @file TcpServer.hpp
33
* @author Nils Henrich
44
* @brief TCP server for unencrypted data transfer without authentication.
5-
* @version 3.2.0
5+
* @version 3.2.1
66
* @date 2021-12-27
77
*
8-
* @copyright Copyright (c) 2021
8+
* @copyright Copyright (c) 2025
99
*
1010
*/
1111

src/TlsClient.hpp

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
* @file TlsClient.hpp
33
* @author Nils Henrich
44
* @brief TLS client for encrypted data transfer with authentication.
5-
* @version 3.2.0
5+
* @version 3.2.1
66
* @date 2021-12-27
77
*
8-
* @copyright Copyright (c) 2021
8+
* @copyright Copyright (c) 2025
99
*
1010
*/
1111

@@ -67,6 +67,46 @@ namespace tcp
6767
*/
6868
virtual ~TlsClient() { stop(); }
6969

70+
/**
71+
* @brief Get specific subject part as string of the certificate of the server.
72+
* Throw Client_error if server not connected or NID is invalid.
73+
*
74+
* @param subjPart
75+
* @return string
76+
*/
77+
::std::string getSubjPartFromServerCert(const int subjPart)
78+
{
79+
char buf[256]{0};
80+
81+
// Check if server is connected
82+
if (!isRunning())
83+
{
84+
#ifdef DEVELOP
85+
::std::cerr << DEBUGINFO << ": Client is not running, means not connected to any server" << ::std::endl;
86+
#endif // DEVELOP
87+
88+
throw Client_error("Not connected to any server to read certificate subject part from");
89+
}
90+
91+
// Read server certificate from TLS channel
92+
::std::unique_ptr<X509, void (*)(X509 *)> remoteCert{SSL_get_peer_certificate(clientSocket.get()), X509_free};
93+
94+
// Get whole subject part from server certificate
95+
X509_NAME *remoteCertSubject{X509_get_subject_name(remoteCert.get())};
96+
97+
// Get specific part from subject
98+
if (-1 == X509_NAME_get_text_by_NID(remoteCertSubject, subjPart, buf, 256))
99+
{
100+
#ifdef DEVELOP
101+
::std::cerr << DEBUGINFO << ": Invalid NID " << subjPart << " for certificate subject" << ::std::endl;
102+
#endif // DEVELOP
103+
104+
throw Client_error("Invalid NID " + ::std::to_string(subjPart) + " for server certificate subject");
105+
}
106+
107+
return ::std::string(buf);
108+
}
109+
70110
/**
71111
* @brief Sets the file paths for the CA certificate, server certificate, and private key.
72112
*

src/TlsServer.hpp

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
* @file TlsServer.hpp
33
* @author Nils Henrich
44
* @brief TLS server for encrypted data transfer with authentication.
5-
* @version 3.2.0
5+
* @version 3.2.1
66
* @date 2021-12-27
77
*
8-
* @copyright Copyright (c) 2021
8+
* @copyright Copyright (c) 2025
99
*
1010
*/
1111

@@ -62,40 +62,42 @@ namespace tcp
6262

6363
/**
6464
* @brief Get specific subject part as string of the certificate of a specific connected client (Identified by its TCP ID).
65+
* Throw Server_error if client ID is not found or NID is invalid.
6566
*
6667
* @param clientId
67-
* @param tlsSocket
6868
* @param subjPart
6969
* @return string
7070
*/
71-
::std::string getSubjPartFromClientCert(const int clientId, const SSL *tlsSocket, const int subjPart)
71+
::std::string getSubjPartFromClientCert(const int clientId, const int subjPart)
7272
{
7373
char buf[256]{0};
74+
::std::lock_guard<::std::mutex> lck{activeConnections_m};
7475

75-
// If TLS socket is null, get socket from list of connected clients
76-
if (!tlsSocket)
76+
// Check if client is connected
77+
if (activeConnections.find(clientId) == activeConnections.end())
7778
{
78-
::std::lock_guard<::std::mutex> lck{activeConnections_m};
79-
if (activeConnections.find(clientId) == activeConnections.end())
80-
{
8179
#ifdef DEVELOP
82-
::std::cerr << DEBUGINFO << ": No connected client " << clientId << ::std::endl;
80+
::std::cerr << DEBUGINFO << ": No connected client " << clientId << ::std::endl;
8381
#endif // DEVELOP
8482

85-
return "";
86-
}
87-
88-
tlsSocket = activeConnections[clientId].get();
83+
throw Server_error("No connected client " + ::std::to_string(clientId) + " to read certificate subject part from");
8984
}
9085

9186
// Read client certificate from TLS channel
92-
::std::unique_ptr<X509, void (*)(X509 *)> remoteCert{SSL_get_peer_certificate(tlsSocket), X509_free};
87+
::std::unique_ptr<X509, void (*)(X509 *)> remoteCert{SSL_get_peer_certificate(activeConnections[clientId].get()), X509_free};
9388

94-
// Get wholw subject part from client certificate
89+
// Get whole subject part from client certificate
9590
X509_NAME *remoteCertSubject{X509_get_subject_name(remoteCert.get())};
9691

9792
// Get specific part from subject
98-
X509_NAME_get_text_by_NID(remoteCertSubject, subjPart, buf, 256);
93+
if (-1 == X509_NAME_get_text_by_NID(remoteCertSubject, subjPart, buf, 256))
94+
{
95+
#ifdef DEVELOP
96+
::std::cerr << DEBUGINFO << ": Invalid NID " << subjPart << " for certificate subject" << ::std::endl;
97+
#endif // DEVELOP
98+
99+
throw Server_error("Invalid NID " + ::std::to_string(subjPart) + " for client certificate subject");
100+
}
99101

100102
// Return subject part as string
101103
return ::std::string(buf);

src/template/Client.hpp

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
* @brief Base framework for all classes that build a network client based on TCP.
55
* This class contains no functionality, but serves a base framework for the creation of stable clients based on TCP.
66
* When compiling with the -DDEBUG flag, the class will print out all received messages to the console.
7-
* @version 3.2.0
7+
* @version 3.2.1
88
* @date 2021-12-28
99
*
10-
* @copyright Copyright (c) 2021
10+
* @copyright Copyright (c) 2025
1111
*
1212
*/
1313

@@ -20,14 +20,14 @@
2020
#include <cstring>
2121
#include <thread>
2222
#include <memory>
23-
#include <exception>
2423
#include <atomic>
2524
#include <functional>
2625
#include <unistd.h>
2726
#include <netinet/in.h>
2827
#include <arpa/inet.h>
2928
#include <netdb.h>
3029
#include <sys/socket.h>
30+
#include "exception.hpp"
3131

3232
// Debugging output
3333
#ifdef DEVELOP
@@ -65,29 +65,11 @@ namespace tcp
6565
}
6666
};
6767

68-
/**
69-
* @brief Exception class for the Client class.
70-
*/
71-
class Client_error : public ::std::exception
68+
// Client error
69+
class Client_error : public Error
7270
{
7371
public:
74-
Client_error(::std::string msg = "unexpected client error") : msg{msg} {}
75-
virtual ~Client_error() {}
76-
77-
const char *what()
78-
{
79-
return msg.c_str();
80-
}
81-
82-
private:
83-
const ::std::string msg;
84-
85-
// Delete default constructor
86-
Client_error() = delete;
87-
88-
// Disallow copy
89-
Client_error(const Client_error &) = delete;
90-
Client_error &operator=(const Client_error &) = delete;
72+
Client_error(::std::string msg = "unexpected client error") : Error{msg} {}
9173
};
9274

9375
/**

0 commit comments

Comments
 (0)