Skip to content

Commit 5cd6906

Browse files
committed
TCP input TLS - Add DecoderFactory for TlsDecoders.
1 parent 0062b1d commit 5cd6906

File tree

3 files changed

+141
-0
lines changed

3 files changed

+141
-0
lines changed

src/plugins/input/tcp/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ add_library(tcp-input MODULE
1515
src/IpxPlugin.cpp
1616
src/tls/Ssl.cpp
1717
src/tls/TlsDecoder.cpp
18+
src/tls/DecoderFactory.cpp
1819
)
1920

2021
find_package(LibLz4 REQUIRED)
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/**
2+
* \file
3+
* \author Jakub Antonín Štigler <[email protected]>
4+
* \brief Factory for tls connections. (source file)
5+
* \date 2025
6+
*
7+
* Copyright: (C) 2023 CESNET, z.s.p.o.
8+
* SPDX-License-Identifier: BSD-3-Clause
9+
*/
10+
11+
#include "DecoderFactory.hpp"
12+
13+
#include "../Config.hpp"
14+
#include "TlsDecoder.hpp"
15+
16+
// OpenSSL v1.1.1 compatibility.
17+
// The flag SSL_OP_IGNORE_UNEXPECTED_EOF is not supported in v1.1.1. This will define it as flag
18+
// without effect if it is not supported so that it may be used in any case.
19+
// The flag is not neccesary, but with it if peer closes the connection without sending proper TLS
20+
// message, it will not be treated as error. This is OK because can check if IPFIX messages are
21+
// complete.
22+
#ifndef SSL_OP_IGNORE_UNEXPECTED_EOF
23+
#define SSL_OP_IGNORE_UNEXPECTED_EOF 0
24+
#endif // ifndef SSL_OP_IGNORE_UNEXPECTED_EOF
25+
26+
namespace tcp_in {
27+
namespace tls {
28+
29+
/**
30+
* @brief Load certificate authority based on the configuration.
31+
* @param conf Configuration of what should be load as certificate authority.
32+
* @param ctx Context to which will the ca load.
33+
*/
34+
static void load_ca(const Config &conf, SslCtx &ctx);
35+
36+
DecoderFactory::DecoderFactory(const Config &conf) : m_ctx(TLS_server_method()) {
37+
// Cache configuration. Cache is used to speed up initial handshake for clients that were
38+
// recently connected.
39+
constexpr long CACHE_TIMEOUT_SECONDS = 3600;
40+
const std::string cache_id = "ipfixcol2";
41+
constexpr std::size_t CACHE_SIZE = 1024;
42+
43+
m_ctx.set_min_proto_version(TLS1_2_VERSION);
44+
m_ctx.set_options(
45+
SSL_OP_IGNORE_UNEXPECTED_EOF | SSL_OP_NO_RENEGOTIATION | SSL_OP_CIPHER_SERVER_PREFERENCE
46+
);
47+
48+
sleep(1);
49+
50+
m_ctx.use_certificate_chain_file(conf.certificate_file.c_str());
51+
m_ctx.use_private_key_file(conf.private_key_file.c_str(), SSL_FILETYPE_PEM);
52+
53+
m_ctx.set_session_id_context(cache_id.data(), unsigned(cache_id.size()));
54+
m_ctx.set_session_cache_mode(SSL_SESS_CACHE_SERVER);
55+
m_ctx.sess_set_cache_size(CACHE_SIZE);
56+
m_ctx.sess_set_timeout(CACHE_TIMEOUT_SECONDS);
57+
58+
if (conf.verify_peer) {
59+
m_ctx.set_verify(SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
60+
load_ca(conf, m_ctx);
61+
} else {
62+
m_ctx.set_verify(SSL_VERIFY_NONE);
63+
}
64+
}
65+
66+
std::unique_ptr<Decoder> DecoderFactory::create(int fd) {
67+
return std::unique_ptr<Decoder>(new TlsDecoder(m_ctx, fd));
68+
}
69+
70+
static void load_ca(const Config &conf, SslCtx &ctx) {
71+
if (conf.use_default_ca) {
72+
ctx.set_default_verify_paths();
73+
return;
74+
}
75+
76+
if (conf.default_ca_file) {
77+
ctx.set_default_verify_file();
78+
} else if (!conf.ca_file.empty()) {
79+
ctx.load_verify_file(conf.ca_file.c_str());
80+
}
81+
82+
if (conf.default_ca_dir) {
83+
ctx.set_default_verify_dir();
84+
} else if (!conf.ca_dir.empty()) {
85+
ctx.load_verify_dir(conf.ca_dir.c_str());
86+
}
87+
88+
if (conf.default_ca_store) {
89+
ctx.set_default_verify_store();
90+
} else if (!conf.ca_store.empty()) {
91+
ctx.load_verify_store(conf.ca_store.c_str());
92+
}
93+
}
94+
95+
} // namespace tls
96+
} // namespace tcp_in
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* \file
3+
* \author Jakub Antonín Štigler <[email protected]>
4+
* \brief Factory for tls connections. (header file)
5+
* \date 2025
6+
*
7+
* Copyright: (C) 2023 CESNET, z.s.p.o.
8+
* SPDX-License-Identifier: BSD-3-Clause
9+
*/
10+
11+
#pragma once
12+
13+
#include "../Config.hpp"
14+
#include "../Decoder.hpp"
15+
#include "SslCtx.hpp"
16+
17+
namespace tcp_in {
18+
namespace tls {
19+
20+
/** Factory for `TlsDecoder`s. Holds shared data. */
21+
class DecoderFactory {
22+
public:
23+
/**
24+
* @brief Create new tls decoder factory using certificate and private key in the given file.
25+
* Note that this may prompt the user for password.
26+
* @throws `std::runtime_error` on failure.
27+
*/
28+
DecoderFactory(const Config &conf);
29+
30+
/**
31+
* @brief Create new tls decoder.
32+
* @param fd Stream for tls communication. (Usually TCP).
33+
* @return TLS decoder.
34+
* @throws `std::runtime_exception` if initialization of the decoder fails.
35+
*/
36+
std::unique_ptr<Decoder> create(int fd);
37+
38+
private:
39+
SslCtx m_ctx;
40+
};
41+
42+
} // namespace tls
43+
} // namespace tcp_in
44+

0 commit comments

Comments
 (0)