Skip to content

Commit 541a585

Browse files
committed
TCP input TLS - Add SslCtx, wrapper around SSL_CTX.
1 parent 9392836 commit 541a585

File tree

1 file changed

+188
-0
lines changed

1 file changed

+188
-0
lines changed
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
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 Sets path to folder with trusted certificates.
80+
* @param d Path to existing directory with certificates in the PEM format.
81+
* @throws On failure.
82+
*/
83+
void load_verify_dir(const char *d) {
84+
if (SSL_CTX_load_verify_dir(get(), d) <= 0) {
85+
throw_ssl_err("Failed to load verify directory.");
86+
}
87+
}
88+
89+
/**
90+
* @brief Sets path to trusted certificate file.
91+
* @param f Path to file with certificate in the PEM format.
92+
* @throws On failure.
93+
*/
94+
void load_verify_file(const char *f) {
95+
if (SSL_CTX_load_verify_file(get(), f) <= 0) {
96+
throw_ssl_err("Failed to load verify file.");
97+
}
98+
}
99+
100+
/**
101+
* @brief Set the minimum allowed TLS version.
102+
* @param version Minimum allowed tls version. `TLS1_2_VERSION` and higher is recommended.
103+
* @throws On failure.
104+
*/
105+
void set_min_proto_version(long version) {
106+
if (!SSL_CTX_set_min_proto_version(get(), version)) {
107+
throw_ssl_err("Failed to set minimum tls version.");
108+
}
109+
}
110+
111+
/**
112+
* @brief Set `SslCtx` flags.
113+
* @param opts Flags for `SSL_CTX`.
114+
*/
115+
void set_options(std::uint64_t opts) noexcept { SSL_CTX_set_options(get(), opts); }
116+
117+
/**
118+
* @brief Set file with certificate with which this will verify to peer.
119+
* @param f Path to file in PEM format with certificate (and parent certificate(s)).
120+
* @throws On failure.
121+
*/
122+
void use_certificate_chain_file(const char *f) {
123+
if (SSL_CTX_use_certificate_chain_file(get(), f) <= 0) {
124+
throw_ssl_err("Failed to load certificate chain file.");
125+
}
126+
}
127+
128+
/**
129+
* @brief Set private key of used certificate.
130+
*
131+
* This may prompt the user for password for the private key.
132+
* @param f Path to file with the private key.
133+
* @param type Format of the file (e.g. `SSL_FILETYPE_PEM`).
134+
* @throws On failure.
135+
*/
136+
void use_private_key_file(const char *f, int type) {
137+
if (SSL_CTX_use_PrivateKey_file(get(), f, type) <= 0) {
138+
throw_ssl_err("Failed to load private key file.");
139+
}
140+
}
141+
142+
/**
143+
* @brief Set cache id unique to aplication.
144+
* @param id_data Arbitrary cache id data.
145+
* @param id_len Length of `id_data`.
146+
*/
147+
void set_session_id_context(const char *id_data, unsigned id_len) noexcept {
148+
SSL_CTX_set_session_id_context(
149+
get(),
150+
reinterpret_cast<const unsigned char *>(id_data),
151+
id_len
152+
);
153+
}
154+
155+
/**
156+
* @brief Set the session caching mode. (Caching for connections from the same client.)
157+
* @param mode Caching mode (e.g. `SSL_SESS_CACHE_SERVER`).
158+
*/
159+
void set_session_cache_mode(long mode) noexcept {
160+
SSL_CTX_set_session_cache_mode(get(), mode);
161+
}
162+
163+
/**
164+
* @brief Sets the size of cache.
165+
* @param size Size of the cache.
166+
*/
167+
void sess_set_cache_size(long size) noexcept {
168+
SSL_CTX_sess_set_cache_size(get(), size);
169+
}
170+
171+
/**
172+
* @brief Timeout for cached connection data.
173+
* @param timeout Timeout for cached connection data.
174+
*/
175+
void sess_set_timeout(std::chrono::seconds timeout) noexcept {
176+
SSL_CTX_set_timeout(get(), long(timeout.count()));
177+
}
178+
179+
/**
180+
* @brief Uses this to create new `Ssl`.
181+
* @return Newly create ssl.
182+
* @throws On failure.
183+
*/
184+
Ssl create_ssl() { return { get() }; }
185+
};
186+
187+
} // namespace tls
188+
} // namespace tcp_in

0 commit comments

Comments
 (0)