src/corosio/src/tls/context.cpp

97.3% Lines (107/110) 100.0% List of functions (28/28) 87.5% Branches (35/40)
context.cpp
f(x) Functions (28)
Function Calls Lines Branches 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% 100.0% 65.6% boost::corosio::tls_context::tls_context() :40 2220x 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 1094x 100.0% 100.0% 78.6% 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% 100.0% boost::corosio::tls_context::use_certificate_chain(std::basic_string_view<char, std::char_traits<char> >) :66 2x 100.0% 100.0% 76.9% 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 1094x 100.0% 100.0% 78.6% 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% 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 6x 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% 54.5% boost::corosio::tls_context::add_certificate_authority(std::basic_string_view<char, std::char_traits<char> >) :126 1105x 100.0% 100.0% boost::corosio::tls_context::load_verify_file(std::basic_string_view<char, std::char_traits<char> >) :133 2x 100.0% 100.0% 86.7% boost::corosio::tls_context::add_verify_path(std::basic_string_view<char, std::char_traits<char> >) :143 3x 100.0% 100.0% boost::corosio::tls_context::set_default_verify_paths() :150 2x 100.0% 100.0% boost::corosio::tls_context::set_min_protocol_version(boost::corosio::tls_version) :161 11x 100.0% 100.0% boost::corosio::tls_context::set_max_protocol_version(boost::corosio::tls_version) :168 4x 100.0% 100.0% boost::corosio::tls_context::set_ciphersuites(std::basic_string_view<char, std::char_traits<char> >) :175 8x 100.0% 100.0% 76.9% boost::corosio::tls_context::set_ciphersuites_tls13(std::basic_string_view<char, std::char_traits<char> >) :182 5x 100.0% 100.0% 76.9% boost::corosio::tls_context::set_alpn(std::initializer_list<std::basic_string_view<char, std::char_traits<char> > >) :189 7x 88.9% 66.7% 91.7% boost::corosio::tls_context::set_verify_mode(boost::corosio::tls_verify_mode) :211 2190x 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 6x 100.0% 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 4x 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 long, boost::corosio::tls_password_purpose)>) :238 2x 100.0% 100.0% boost::corosio::tls_context::set_verify_callback_impl(std::function<bool (bool, boost::corosio::verify_context&)>) :245 5x 100.0% 100.0% boost::corosio::tls_context::add_crl(std::basic_string_view<char, std::char_traits<char> >) :256 5x 100.0% 100.0% boost::corosio::tls_context::add_crl_file(std::basic_string_view<char, std::char_traits<char> >) :263 2x 100.0% 100.0% 86.7% boost::corosio::tls_context::set_revocation_policy(boost::corosio::tls_revocation_policy) :273 6x 100.0% 100.0%
Line Branch TLA Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco ([email protected])
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
2/2
✓ Branch 4 → 5 taken 11 times.
✓ Branch 5 → 6 taken 11 times.
11x std::ifstream file(std::string(filename), std::ios::binary);
29
3/3
✓ Branch 8 → 9 taken 11 times.
✓ Branch 9 → 10 taken 6 times.
✓ Branch 9 → 11 taken 5 times.
11x if (!file)
30 6x return std::error_code(ENOENT, std::generic_category());
31
32
1/1
✓ Branch 11 → 12 taken 5 times.
5x std::ostringstream ss;
33
1/1
✓ Branch 13 → 14 taken 5 times.
5x ss << file.rdbuf();
34
1/1
✓ Branch 14 → 15 taken 5 times.
5x out = ss.str();
35 5x return {};
36 11x }
37
38 } // namespace
39
40 2220x tls_context::tls_context() : impl_(std::make_shared<impl>()) {}
41
42 //
43 // Credential Loading
44 //
45
46 std::error_code
47 1094x tls_context::use_certificate(
48 std::string_view certificate, tls_file_format format)
49 {
50
1/1
✓ Branch 4 → 5 taken 1094 times.
1094x impl_->entity_certificate = std::string(certificate);
51 1094x impl_->entity_cert_format = format;
52 1094x 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
2/2
✓ Branch 5 → 6 taken 1 time.
✓ Branch 5 → 7 taken 1 time.
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 2x tls_context::use_certificate_chain(std::string_view chain)
67 {
68
1/1
✓ Branch 4 → 5 taken 2 times.
2x impl_->certificate_chain = std::string(chain);
69 2x 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 1094x tls_context::use_private_key(
80 std::string_view private_key, tls_file_format format)
81 {
82
1/1
✓ Branch 4 → 5 taken 1094 times.
1094x impl_->private_key = std::string(private_key);
83 1094x impl_->private_key_format = format;
84 1094x 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
2/2
✓ Branch 5 → 6 taken 1 time.
✓ Branch 5 → 7 taken 1 time.
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 6x 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 6x impl_->pkcs12_data.assign(data.data(), data.size());
105 6x impl_->pkcs12_password.assign(passphrase.data(), passphrase.size());
106 6x 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
1/2
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 7 not taken.
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 1105x tls_context::add_certificate_authority(std::string_view ca)
127 {
128 1105x impl_->ca_certificates.emplace_back(ca);
129 1105x 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
3/3
✓ Branch 3 → 4 taken 2 times.
✓ Branch 5 → 6 taken 1 time.
✓ Branch 5 → 7 taken 1 time.
2x if (auto ec = read_file_contents(filename, contents); ec)
137 1x return ec;
138
1/1
✓ Branch 9 → 10 taken 1 time.
1x impl_->ca_certificates.push_back(std::move(contents));
139 1x return {};
140 2x }
141
142 std::error_code
143 3x tls_context::add_verify_path(std::string_view path)
144 {
145 3x impl_->verify_paths.emplace_back(path);
146 3x return {};
147 }
148
149 std::error_code
150 2x tls_context::set_default_verify_paths()
151 {
152 2x impl_->use_default_verify_paths = true;
153 2x return {};
154 }
155
156 //
157 // Protocol Configuration
158 //
159
160 std::error_code
161 11x tls_context::set_min_protocol_version(tls_version v)
162 {
163 11x impl_->min_version = v;
164 11x return {};
165 }
166
167 std::error_code
168 4x tls_context::set_max_protocol_version(tls_version v)
169 {
170 4x impl_->max_version = v;
171 4x return {};
172 }
173
174 std::error_code
175 8x tls_context::set_ciphersuites(std::string_view ciphers)
176 {
177
1/1
✓ Branch 4 → 5 taken 8 times.
8x impl_->ciphersuites = std::string(ciphers);
178 8x return {};
179 }
180
181 std::error_code
182 5x tls_context::set_ciphersuites_tls13(std::string_view ciphers)
183 {
184
1/1
✓ Branch 4 → 5 taken 5 times.
5x impl_->ciphersuites_tls13 = std::string(ciphers);
185 5x return {};
186 }
187
188 std::error_code
189 7x 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
2/2
✓ Branch 15 → 4 taken 9 times.
✓ Branch 15 → 16 taken 7 times.
16x for (auto const& p : protocols)
196
4/8
✓ Branch 5 → 6 taken 9 times.
✗ Branch 5 → 10 not taken.
✓ Branch 7 → 8 taken 9 times.
✗ Branch 7 → 10 not taken.
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 9 times.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 9 times.
18x if (p.empty() || p.size() > 255 ||
197 9x p.find(',') != std::string_view::npos)
198 return std::make_error_code(std::errc::invalid_argument);
199
200 7x impl_->alpn_protocols.clear();
201
2/2
✓ Branch 23 → 20 taken 9 times.
✓ Branch 23 → 24 taken 7 times.
16x for (auto const& p : protocols)
202 9x impl_->alpn_protocols.emplace_back(p);
203 7x return {};
204 }
205
206 //
207 // Certificate Verification
208 //
209
210 std::error_code
211 2190x tls_context::set_verify_mode(tls_verify_mode mode)
212 {
213 2190x impl_->verification_mode = mode;
214 2190x 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 6x tls_context::set_hostname(std::string_view hostname)
226 {
227
1/1
✓ Branch 4 → 5 taken 6 times.
6x impl_->hostname = std::string(hostname);
228 6x }
229
230 void
231 4x tls_context::set_servername_callback_impl(
232 std::function<bool(std::string_view)> callback)
233 {
234 4x impl_->servername_callback = std::move(callback);
235 4x }
236
237 void
238 2x tls_context::set_password_callback_impl(
239 std::function<std::string(std::size_t, tls_password_purpose)> callback)
240 {
241 2x impl_->password_callback = std::move(callback);
242 2x }
243
244 void
245 5x tls_context::set_verify_callback_impl(
246 std::function<bool(bool, verify_context&)> callback)
247 {
248 5x impl_->verify_callback = std::move(callback);
249 5x }
250
251 //
252 // Revocation Checking
253 //
254
255 std::error_code
256 5x tls_context::add_crl(std::string_view crl)
257 {
258 5x impl_->crls.emplace_back(crl);
259 5x 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
3/3
✓ Branch 3 → 4 taken 2 times.
✓ Branch 5 → 6 taken 1 time.
✓ Branch 5 → 7 taken 1 time.
2x if (auto ec = read_file_contents(filename, contents); ec)
267 1x return ec;
268
1/1
✓ Branch 9 → 10 taken 1 time.
1x impl_->crls.push_back(std::move(contents));
269 1x return {};
270 2x }
271
272 void
273 6x tls_context::set_revocation_policy(tls_revocation_policy policy)
274 {
275 6x impl_->revocation = policy;
276 6x }
277
278 } // namespace boost::corosio
279