Skip to content

Commit 286545d

Browse files
committed
TCP input TLS - Add SslCtx, wrapper around SSL_CTX.
1 parent 5a1c686 commit 286545d

File tree

1 file changed

+166
-0
lines changed

1 file changed

+166
-0
lines changed
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/**
2+
* \file
3+
* \author Jakub Antonín Štigler <[email protected]>
4+
* \brief Wrapper around SSL_CTX from OpenSSL. (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 <array>
14+
#include <chrono>
15+
#include <memory>
16+
#include <stdexcept>
17+
#include <string>
18+
19+
#include <openssl/err.h>
20+
#include <openssl/ssl.h>
21+
22+
#include "Ssl.hpp"
23+
#include "throw_ssl_err.hpp"
24+
25+
namespace tcp_in {
26+
namespace tls {
27+
28+
namespace dealloc {
29+
30+
/** Deallocator for `SSL_CTX` from OpenSSL. Can be used for example in `std::unique_ptr` */
31+
class SslCtx {
32+
public:
33+
void operator()(SSL_CTX *ptr) { SSL_CTX_free(ptr); }
34+
};
35+
36+
} // namespace dealloc
37+
38+
/** Wrapper around `SSL_CTX` from OpenSSL. */
39+
class SslCtx : public std::unique_ptr<SSL_CTX, dealloc::SslCtx> {
40+
public:
41+
/** Unique pointer of `SSL_CTX`. This is base class for `SslCtx`. */
42+
using SelfPtr = std::unique_ptr<SSL_CTX, dealloc::SslCtx>;
43+
44+
/**
45+
* @brief Construct this with the given method.
46+
* @param method Method for creating `SSL_CTX`. Can be obtained for example with
47+
* `TLS_server_method()`.
48+
* @throws On failure.
49+
*/
50+
SslCtx(const SSL_METHOD *method) : SelfPtr(SSL_CTX_new(method)) {
51+
if (!get()) {
52+
throw_ssl_err("Failed to create ssl context.");
53+
}
54+
}
55+
56+
/**
57+
* @brief Set the verify mode. (What should be verified about peer)
58+
* @param mode Verify mode (e.g. SSL_VERIFY_NONE).
59+
* @param cb Verify callback.
60+
*/
61+
void set_verify(int mode, SSL_verify_cb cb = nullptr) noexcept {
62+
SSL_CTX_set_verify(get(), mode, cb);
63+
}
64+
65+
/**
66+
* @brief Sets the paths to trusted certificates to the default locations.
67+
*
68+
* This will try to set the paths from environment variables, and if that fails, it will use the
69+
* os defaults.
70+
* @throws On failure.
71+
*/
72+
void set_default_verify_paths() {
73+
if (!SSL_CTX_set_default_verify_paths(get())) {
74+
throw_ssl_err("Failed to set default trusted certificate store.");
75+
}
76+
}
77+
78+
/**
79+
* @brief Set the minimum allowed TLS version.
80+
* @param version Minimum allowed tls version. `TLS1_2_VERSION` and higher is recommended.
81+
* @throws On failure.
82+
*/
83+
void set_min_proto_version(long version) {
84+
if (!SSL_CTX_set_min_proto_version(get(), version)) {
85+
throw_ssl_err("Failed to set minimum tls version.");
86+
}
87+
}
88+
89+
/**
90+
* @brief Set `SslCtx` flags.
91+
* @param opts Flags for `SSL_CTX`.
92+
*/
93+
void set_options(std::uint64_t opts) noexcept { SSL_CTX_set_options(get(), opts); }
94+
95+
/**
96+
* @brief Set file with certificate with which this will verify to peer.
97+
* @param f Path to file in PEM format with certificate (and parent certificate(s)).
98+
* @throws On failure.
99+
*/
100+
void use_certificate_chain_file(const char *f) {
101+
if (SSL_CTX_use_certificate_chain_file(get(), f) <= 0) {
102+
throw_ssl_err("Failed to load certificate chain file.");
103+
}
104+
}
105+
106+
/**
107+
* @brief Set private key of used certificate.
108+
*
109+
* This may prompt the user for password for the private key.
110+
* @param f Path to file with the private key.
111+
* @param type Format of the file (e.g. `SSL_FILETYPE_PEM`).
112+
* @throws On failure.
113+
*/
114+
void use_private_key_file(const char *f, int type) {
115+
if (SSL_CTX_use_PrivateKey_file(get(), f, type) <= 0) {
116+
throw_ssl_err("Failed to load private key file.");
117+
}
118+
}
119+
120+
/**
121+
* @brief Set cache id unique to aplication.
122+
* @param id_data Arbitrary cache id data.
123+
* @param id_len Length of `id_data`.
124+
*/
125+
void set_session_id_context(const char *id_data, unsigned id_len) noexcept {
126+
SSL_CTX_set_session_id_context(
127+
get(),
128+
reinterpret_cast<const unsigned char *>(id_data),
129+
id_len
130+
);
131+
}
132+
133+
/**
134+
* @brief Set the session caching mode. (Caching for connections from the same client.)
135+
* @param mode Caching mode (e.g. `SSL_SESS_CACHE_SERVER`).
136+
*/
137+
void set_session_cache_mode(long mode) noexcept {
138+
SSL_CTX_set_session_cache_mode(get(), mode);
139+
}
140+
141+
/**
142+
* @brief Sets the size of cache.
143+
* @param size Size of the cache.
144+
*/
145+
void sess_set_cache_size(long size) noexcept {
146+
SSL_CTX_sess_set_cache_size(get(), size);
147+
}
148+
149+
/**
150+
* @brief Timeout for cached connection data.
151+
* @param timeout Timeout for cached connection data.
152+
*/
153+
void sess_set_timeout(std::chrono::seconds timeout) noexcept {
154+
SSL_CTX_set_timeout(get(), long(timeout.count()));
155+
}
156+
157+
/**
158+
* @brief Uses this to create new `Ssl`.
159+
* @return Newly create ssl.
160+
* @throws On failure.
161+
*/
162+
Ssl create_ssl() { return { get() }; }
163+
};
164+
165+
} // namespace tls
166+
} // namespace tcp_in

0 commit comments

Comments
 (0)