Skip to content

Commit 5087679

Browse files
committed
TCP input TLS - Add TlsDecoder.
1 parent 286545d commit 5087679

File tree

3 files changed

+111
-0
lines changed

3 files changed

+111
-0
lines changed

src/plugins/input/tcp/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ add_library(tcp-input MODULE
1414
src/Plugin.cpp
1515
src/IpxPlugin.cpp
1616
src/tls/Ssl.cpp
17+
src/tls/TlsDecoder.cpp
1718
)
1819

1920
find_package(LibLz4 REQUIRED)
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* \file
3+
* \author Jakub Antonín Štigler <[email protected]>
4+
* \brief TLS decoder for IPFIX plugin. (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 "TlsDecoder.hpp"
12+
13+
namespace tcp_in {
14+
namespace tls {
15+
16+
// Size of buffer for copying data from OpenSSL to DecodeBuffer.
17+
constexpr std::size_t BUFFER_SIZE = 4096;
18+
19+
TlsDecoder::TlsDecoder(SslCtx &ctx, int fd) :
20+
m_ssl(ctx.create_ssl()),
21+
m_buffer(BUFFER_SIZE)
22+
{
23+
SslBio bio(BIO_s_socket());
24+
bio.set_fd(fd);
25+
m_ssl.set_bio(std::move(bio));
26+
27+
// m_ssl.set_tlsext_host_name(host); // SNI hostname
28+
// m_ssl.set1_host(host); // DNS names
29+
30+
m_handshake_complete = m_ssl.accept();
31+
}
32+
33+
DecodeBuffer &TlsDecoder::decode() {
34+
if (!m_handshake_complete) {
35+
m_handshake_complete = m_ssl.accept();
36+
if (!m_handshake_complete) {
37+
return m_decoded;
38+
}
39+
}
40+
41+
// XXX: The copy to intermidiate `m_buffer` can be avoided by extending `DecodeBuffer` to be
42+
// able to read with generic read function.
43+
44+
while (!m_decoded.enough_data()) {
45+
auto res = m_ssl.read_ex(m_buffer);
46+
m_decoded.read_from(m_buffer.data(), m_buffer.size());
47+
switch (res) {
48+
case ReadResult::READ:
49+
break;
50+
case ReadResult::WAIT:
51+
return m_decoded;
52+
case ReadResult::FINISHED:
53+
// FIXME: properly check that the shutdown is complete.
54+
m_ssl.shutdown();
55+
// Intentional falltrough
56+
case ReadResult::CLOSED:
57+
m_decoded.signal_eof();
58+
return m_decoded;
59+
}
60+
}
61+
62+
return m_decoded;
63+
}
64+
65+
} // namespace tls
66+
} // 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 TLS decoder for IPFIX plugin. (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 <vector>
14+
15+
#include "../Decoder.hpp"
16+
#include "../UniqueFd.hpp"
17+
#include "SslCtx.hpp"
18+
#include "Ssl.hpp"
19+
20+
namespace tcp_in {
21+
namespace tls {
22+
23+
// TLS content type handshake
24+
/** Identifies data for which `TlsDecoder` should be used. */
25+
constexpr std::uint8_t TLS_MAGIC = 22;
26+
27+
/** Decoder for TLS connections. */
28+
class TlsDecoder : public Decoder {
29+
public:
30+
TlsDecoder(SslCtx &ctx, int fd);
31+
32+
virtual DecodeBuffer &decode() override;
33+
34+
virtual const char *get_name() const override { return "TLS"; }
35+
36+
private:
37+
Ssl m_ssl;
38+
bool m_handshake_complete = false;
39+
DecodeBuffer m_decoded;
40+
std::vector<std::uint8_t> m_buffer;
41+
};
42+
43+
} // namespace tls
44+
} // namespace tcp_in

0 commit comments

Comments
 (0)