src/corosio/src/tls/context.cpp

91.8% Lines (101/110) 92.9% List of functions (26/28)
context.cpp
f(x) Functions (28)
Function Calls Lines Blocks
boost::corosio::(anonymous namespace)::read_file_contents(std::basic_string_view<char, std::char_traits<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) :26 11x 100.0% 69.0% boost::corosio::tls_context::tls_context() :40 32x 100.0% 100.0% boost::corosio::tls_context::use_certificate(std::basic_string_view<char, std::char_traits<char> >, boost::corosio::tls_file_format) :47 3x 100.0% 81.0% boost::corosio::tls_context::use_certificate_file(std::basic_string_view<char, std::char_traits<char> >, boost::corosio::tls_file_format) :56 2x 100.0% 100.0% boost::corosio::tls_context::use_certificate_chain(std::basic_string_view<char, std::char_traits<char> >) :66 1x 100.0% 80.0% boost::corosio::tls_context::use_certificate_chain_file(std::basic_string_view<char, std::char_traits<char> >) :73 2x 100.0% 100.0% boost::corosio::tls_context::use_private_key(std::basic_string_view<char, std::char_traits<char> >, boost::corosio::tls_file_format) :79 2x 100.0% 81.0% boost::corosio::tls_context::use_private_key_file(std::basic_string_view<char, std::char_traits<char> >, boost::corosio::tls_file_format) :88 2x 100.0% 100.0% boost::corosio::tls_context::use_pkcs12(std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> >) :98 1x 100.0% 100.0% boost::corosio::tls_context::use_pkcs12_file(std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> >) :110 1x 60.0% 50.0% boost::corosio::tls_context::add_certificate_authority(std::basic_string_view<char, std::char_traits<char> >) :126 2x 100.0% 100.0% boost::corosio::tls_context::load_verify_file(std::basic_string_view<char, std::char_traits<char> >) :133 2x 100.0% 83.0% boost::corosio::tls_context::add_verify_path(std::basic_string_view<char, std::char_traits<char> >) :143 2x 100.0% 100.0% boost::corosio::tls_context::set_default_verify_paths() :150 1x 100.0% 100.0% boost::corosio::tls_context::set_min_protocol_version(boost::corosio::tls_version) :161 2x 100.0% 100.0% boost::corosio::tls_context::set_max_protocol_version(boost::corosio::tls_version) :168 2x 100.0% 100.0% boost::corosio::tls_context::set_ciphersuites(std::basic_string_view<char, std::char_traits<char> >) :175 2x 100.0% 80.0% boost::corosio::tls_context::set_ciphersuites_tls13(std::basic_string_view<char, std::char_traits<char> >) :182 0 0.0% 0.0% boost::corosio::tls_context::set_alpn(std::initializer_list<std::basic_string_view<char, std::char_traits<char> > >) :189 3x 88.9% 92.0% boost::corosio::tls_context::set_verify_mode(boost::corosio::tls_verify_mode) :211 2x 100.0% 100.0% boost::corosio::tls_context::set_verify_depth(int) :218 1x 100.0% 100.0% boost::corosio::tls_context::set_hostname(std::basic_string_view<char, std::char_traits<char> >) :225 2x 100.0% 75.0% boost::corosio::tls_context::set_servername_callback_impl(std::function<bool (std::basic_string_view<char, std::char_traits<char> >)>) :231 1x 100.0% 100.0% boost::corosio::tls_context::set_password_callback_impl(std::function<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > (unsigned long, boost::corosio::tls_password_purpose)>) :238 1x 100.0% 100.0% boost::corosio::tls_context::set_verify_callback_impl(std::function<bool (bool, boost::corosio::verify_context&)>) :245 0 0.0% 0.0% boost::corosio::tls_context::add_crl(std::basic_string_view<char, std::char_traits<char> >) :256 2x 100.0% 100.0% boost::corosio::tls_context::add_crl_file(std::basic_string_view<char, std::char_traits<char> >) :263 2x 100.0% 83.0% boost::corosio::tls_context::set_revocation_policy(boost::corosio::tls_revocation_policy) :273 3x 100.0% 100.0%
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2026 Steve Gerbino
4 // Copyright (c) 2026 Michael Vandeberg
5 //
6 // Distributed under the Boost Software License, Version 1.0. (See accompanying
7 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // Official repository: https://github.com/cppalliance/corosio
10 //
11
12 #include <boost/corosio/tls_context.hpp>
13 #include "detail/context_impl.hpp"
14
15 #include <cerrno>
16 #include <fstream>
17 #include <sstream>
18
19 namespace boost::corosio {
20
21 namespace {
22
23 // Read an entire file in binary mode into `out`, returning ENOENT if it
24 // cannot be opened. Shared by the file-based credential/trust loaders.
25 std::error_code
26 11x read_file_contents(std::string_view filename, std::string& out)
27 {
28 11x std::ifstream file(std::string(filename), std::ios::binary);
29 11x if (!file)
30 6x return std::error_code(ENOENT, std::generic_category());
31
32 5x std::ostringstream ss;
33 5x ss << file.rdbuf();
34 5x out = ss.str();
35 5x return {};
36 11x }
37
38 } // namespace
39
40 32x tls_context::tls_context() : impl_(std::make_shared<impl>()) {}
41
42 //
43 // Credential Loading
44 //
45
46 std::error_code
47 3x tls_context::use_certificate(
48 std::string_view certificate, tls_file_format format)
49 {
50 3x impl_->entity_certificate = std::string(certificate);
51 3x impl_->entity_cert_format = format;
52 3x return {};
53 }
54
55 std::error_code
56 2x tls_context::use_certificate_file(
57 std::string_view filename, tls_file_format format)
58 {
59 2x if (auto ec = read_file_contents(filename, impl_->entity_certificate); ec)
60 1x return ec;
61 1x impl_->entity_cert_format = format;
62 1x return {};
63 }
64
65 std::error_code
66 1x tls_context::use_certificate_chain(std::string_view chain)
67 {
68 1x impl_->certificate_chain = std::string(chain);
69 1x return {};
70 }
71
72 std::error_code
73 2x tls_context::use_certificate_chain_file(std::string_view filename)
74 {
75 2x return read_file_contents(filename, impl_->certificate_chain);
76 }
77
78 std::error_code
79 2x tls_context::use_private_key(
80 std::string_view private_key, tls_file_format format)
81 {
82 2x impl_->private_key = std::string(private_key);
83 2x impl_->private_key_format = format;
84 2x return {};
85 }
86
87 std::error_code
88 2x tls_context::use_private_key_file(
89 std::string_view filename, tls_file_format format)
90 {
91 2x if (auto ec = read_file_contents(filename, impl_->private_key); ec)
92 1x return ec;
93 1x impl_->private_key_format = format;
94 1x return {};
95 }
96
97 std::error_code
98 1x tls_context::use_pkcs12(std::string_view data, std::string_view passphrase)
99 {
100 // assign(ptr, len) rather than std::string(string_view): libstdc++'s
101 // basic_string(const char*, size_t) computes std::distance(s, s + n),
102 // whose one-past-the-end pointer ASan's detect_invalid_pointer_pairs
103 // rejects for a global buffer. assign copies without that subtraction.
104 1x impl_->pkcs12_data.assign(data.data(), data.size());
105 1x impl_->pkcs12_password.assign(passphrase.data(), passphrase.size());
106 1x return {};
107 }
108
109 std::error_code
110 1x tls_context::use_pkcs12_file(
111 std::string_view filename, std::string_view passphrase)
112 {
113 1x if (auto ec = read_file_contents(filename, impl_->pkcs12_data); ec)
114 1x return ec;
115 // assign(ptr, len), not std::string(passphrase): see the note in
116 // use_pkcs12.
117 impl_->pkcs12_password.assign(passphrase.data(), passphrase.size());
118 return {};
119 }
120
121 //
122 // Trust Anchors
123 //
124
125 std::error_code
126 2x tls_context::add_certificate_authority(std::string_view ca)
127 {
128 2x impl_->ca_certificates.emplace_back(ca);
129 2x return {};
130 }
131
132 std::error_code
133 2x tls_context::load_verify_file(std::string_view filename)
134 {
135 2x std::string contents;
136 2x if (auto ec = read_file_contents(filename, contents); ec)
137 1x return ec;
138 1x impl_->ca_certificates.push_back(std::move(contents));
139 1x return {};
140 2x }
141
142 std::error_code
143 2x tls_context::add_verify_path(std::string_view path)
144 {
145 2x impl_->verify_paths.emplace_back(path);
146 2x return {};
147 }
148
149 std::error_code
150 1x tls_context::set_default_verify_paths()
151 {
152 1x impl_->use_default_verify_paths = true;
153 1x return {};
154 }
155
156 //
157 // Protocol Configuration
158 //
159
160 std::error_code
161 2x tls_context::set_min_protocol_version(tls_version v)
162 {
163 2x impl_->min_version = v;
164 2x return {};
165 }
166
167 std::error_code
168 2x tls_context::set_max_protocol_version(tls_version v)
169 {
170 2x impl_->max_version = v;
171 2x return {};
172 }
173
174 std::error_code
175 2x tls_context::set_ciphersuites(std::string_view ciphers)
176 {
177 2x impl_->ciphersuites = std::string(ciphers);
178 2x return {};
179 }
180
181 std::error_code
182 tls_context::set_ciphersuites_tls13(std::string_view ciphers)
183 {
184 impl_->ciphersuites_tls13 = std::string(ciphers);
185 return {};
186 }
187
188 std::error_code
189 3x tls_context::set_alpn(std::initializer_list<std::string_view> protocols)
190 {
191 // Validate before mutating so a bad entry doesn't silently drop part of
192 // the list (or wipe a prior valid configuration). A name must be a
193 // non-empty token no longer than 255 bytes (the ALPN wire length field)
194 // and must not contain a comma (WolfSSL's list separator).
195 6x for (auto const& p : protocols)
196 6x if (p.empty() || p.size() > 255 ||
197 3x p.find(',') != std::string_view::npos)
198 return std::make_error_code(std::errc::invalid_argument);
199
200 3x impl_->alpn_protocols.clear();
201 6x for (auto const& p : protocols)
202 3x impl_->alpn_protocols.emplace_back(p);
203 3x return {};
204 }
205
206 //
207 // Certificate Verification
208 //
209
210 std::error_code
211 2x tls_context::set_verify_mode(tls_verify_mode mode)
212 {
213 2x impl_->verification_mode = mode;
214 2x return {};
215 }
216
217 std::error_code
218 1x tls_context::set_verify_depth(int depth)
219 {
220 1x impl_->verify_depth = depth;
221 1x return {};
222 }
223
224 void
225 2x tls_context::set_hostname(std::string_view hostname)
226 {
227 2x impl_->hostname = std::string(hostname);
228 2x }
229
230 void
231 1x tls_context::set_servername_callback_impl(
232 std::function<bool(std::string_view)> callback)
233 {
234 1x impl_->servername_callback = std::move(callback);
235 1x }
236
237 void
238 1x tls_context::set_password_callback_impl(
239 std::function<std::string(std::size_t, tls_password_purpose)> callback)
240 {
241 1x impl_->password_callback = std::move(callback);
242 1x }
243
244 void
245 tls_context::set_verify_callback_impl(
246 std::function<bool(bool, verify_context&)> callback)
247 {
248 impl_->verify_callback = std::move(callback);
249 }
250
251 //
252 // Revocation Checking
253 //
254
255 std::error_code
256 2x tls_context::add_crl(std::string_view crl)
257 {
258 2x impl_->crls.emplace_back(crl);
259 2x return {};
260 }
261
262 std::error_code
263 2x tls_context::add_crl_file(std::string_view filename)
264 {
265 2x std::string contents;
266 2x if (auto ec = read_file_contents(filename, contents); ec)
267 1x return ec;
268 1x impl_->crls.push_back(std::move(contents));
269 1x return {};
270 2x }
271
272 void
273 3x tls_context::set_revocation_policy(tls_revocation_policy policy)
274 {
275 3x impl_->revocation = policy;
276 3x }
277
278 } // namespace boost::corosio
279