Line data Source code
1 : //
2 : // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
3 : //
4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // Official repository: https://github.com/cppalliance/corosio
8 : //
9 :
10 : #include <boost/corosio/tls_context.hpp>
11 : #include "detail/context_impl.hpp"
12 :
13 : #include <cerrno>
14 : #include <fstream>
15 : #include <sstream>
16 :
17 : namespace boost::corosio {
18 :
19 : //------------------------------------------------------------------------------
20 :
21 0 : tls_context::
22 0 : tls_context()
23 0 : : impl_( std::make_shared<impl>() )
24 : {
25 0 : }
26 :
27 : //------------------------------------------------------------------------------
28 : //
29 : // Credential Loading
30 : //
31 : //------------------------------------------------------------------------------
32 :
33 : std::error_code
34 0 : tls_context::
35 : use_certificate(
36 : std::string_view certificate,
37 : tls_file_format format )
38 : {
39 0 : impl_->entity_certificate = std::string( certificate );
40 0 : impl_->entity_cert_format = format;
41 0 : return {};
42 : }
43 :
44 : std::error_code
45 0 : tls_context::
46 : use_certificate_file(
47 : std::string_view filename,
48 : tls_file_format format )
49 : {
50 0 : std::ifstream file( std::string( filename ), std::ios::binary );
51 0 : if( !file )
52 0 : return std::error_code( ENOENT, std::generic_category() );
53 :
54 0 : std::ostringstream ss;
55 0 : ss << file.rdbuf();
56 0 : impl_->entity_certificate = ss.str();
57 0 : impl_->entity_cert_format = format;
58 0 : return {};
59 0 : }
60 :
61 : std::error_code
62 0 : tls_context::
63 : use_certificate_chain( std::string_view chain )
64 : {
65 0 : impl_->certificate_chain = std::string( chain );
66 0 : return {};
67 : }
68 :
69 : std::error_code
70 0 : tls_context::
71 : use_certificate_chain_file( std::string_view filename )
72 : {
73 0 : std::ifstream file( std::string( filename ), std::ios::binary );
74 0 : if( !file )
75 0 : return std::error_code( ENOENT, std::generic_category() );
76 :
77 0 : std::ostringstream ss;
78 0 : ss << file.rdbuf();
79 0 : impl_->certificate_chain = ss.str();
80 0 : return {};
81 0 : }
82 :
83 : std::error_code
84 0 : tls_context::
85 : use_private_key(
86 : std::string_view private_key,
87 : tls_file_format format )
88 : {
89 0 : impl_->private_key = std::string( private_key );
90 0 : impl_->private_key_format = format;
91 0 : return {};
92 : }
93 :
94 : std::error_code
95 0 : tls_context::
96 : use_private_key_file(
97 : std::string_view filename,
98 : tls_file_format format )
99 : {
100 0 : std::ifstream file( std::string( filename ), std::ios::binary );
101 0 : if( !file )
102 0 : return std::error_code( ENOENT, std::generic_category() );
103 :
104 0 : std::ostringstream ss;
105 0 : ss << file.rdbuf();
106 0 : impl_->private_key = ss.str();
107 0 : impl_->private_key_format = format;
108 0 : return {};
109 0 : }
110 :
111 : std::error_code
112 0 : tls_context::
113 : use_pkcs12(
114 : std::string_view /*data*/,
115 : std::string_view /*passphrase*/ )
116 : {
117 : // TODO: Implement PKCS#12 parsing
118 0 : return std::error_code( ENOTSUP, std::generic_category() );
119 : }
120 :
121 : std::error_code
122 0 : tls_context::
123 : use_pkcs12_file(
124 : std::string_view /*filename*/,
125 : std::string_view /*passphrase*/ )
126 : {
127 : // TODO: Implement PKCS#12 file loading
128 0 : return std::error_code( ENOTSUP, std::generic_category() );
129 : }
130 :
131 : //------------------------------------------------------------------------------
132 : //
133 : // Trust Anchors
134 : //
135 : //------------------------------------------------------------------------------
136 :
137 : std::error_code
138 0 : tls_context::
139 : add_certificate_authority( std::string_view ca )
140 : {
141 0 : impl_->ca_certificates.emplace_back( ca );
142 0 : return {};
143 : }
144 :
145 : std::error_code
146 0 : tls_context::
147 : load_verify_file( std::string_view filename )
148 : {
149 0 : std::ifstream file( std::string( filename ), std::ios::binary );
150 0 : if( !file )
151 0 : return std::error_code( ENOENT, std::generic_category() );
152 :
153 0 : std::ostringstream ss;
154 0 : ss << file.rdbuf();
155 0 : impl_->ca_certificates.push_back( ss.str() );
156 0 : return {};
157 0 : }
158 :
159 : std::error_code
160 0 : tls_context::
161 : add_verify_path( std::string_view path )
162 : {
163 0 : impl_->verify_paths.emplace_back( path );
164 0 : return {};
165 : }
166 :
167 : std::error_code
168 0 : tls_context::
169 : set_default_verify_paths()
170 : {
171 0 : impl_->use_default_verify_paths = true;
172 0 : return {};
173 : }
174 :
175 : //------------------------------------------------------------------------------
176 : //
177 : // Protocol Configuration
178 : //
179 : //------------------------------------------------------------------------------
180 :
181 : std::error_code
182 0 : tls_context::
183 : set_min_protocol_version( tls_version v )
184 : {
185 0 : impl_->min_version = v;
186 0 : return {};
187 : }
188 :
189 : std::error_code
190 0 : tls_context::
191 : set_max_protocol_version( tls_version v )
192 : {
193 0 : impl_->max_version = v;
194 0 : return {};
195 : }
196 :
197 : std::error_code
198 0 : tls_context::
199 : set_ciphersuites( std::string_view ciphers )
200 : {
201 0 : impl_->ciphersuites = std::string( ciphers );
202 0 : return {};
203 : }
204 :
205 : std::error_code
206 0 : tls_context::
207 : set_alpn( std::initializer_list<std::string_view> protocols )
208 : {
209 0 : impl_->alpn_protocols.clear();
210 0 : for( auto const& p : protocols )
211 0 : impl_->alpn_protocols.emplace_back( p );
212 0 : return {};
213 : }
214 :
215 : //------------------------------------------------------------------------------
216 : //
217 : // Certificate Verification
218 : //
219 : //------------------------------------------------------------------------------
220 :
221 : std::error_code
222 0 : tls_context::
223 : set_verify_mode( tls_verify_mode mode )
224 : {
225 0 : impl_->verification_mode = mode;
226 0 : return {};
227 : }
228 :
229 : std::error_code
230 0 : tls_context::
231 : set_verify_depth( int depth )
232 : {
233 0 : impl_->verify_depth = depth;
234 0 : return {};
235 : }
236 :
237 : void
238 0 : tls_context::
239 : set_hostname( std::string_view hostname )
240 : {
241 0 : impl_->hostname = std::string( hostname );
242 0 : }
243 :
244 : void
245 0 : tls_context::
246 : set_servername_callback_impl(
247 : std::function<bool( std::string_view )> callback )
248 : {
249 0 : impl_->servername_callback = std::move( callback );
250 0 : }
251 :
252 : void
253 0 : tls_context::
254 : set_password_callback_impl(
255 : std::function<std::string( std::size_t, tls_password_purpose )> callback )
256 : {
257 0 : impl_->password_callback = std::move( callback );
258 0 : }
259 :
260 : //------------------------------------------------------------------------------
261 : //
262 : // Revocation Checking
263 : //
264 : //------------------------------------------------------------------------------
265 :
266 : std::error_code
267 0 : tls_context::
268 : add_crl( std::string_view crl )
269 : {
270 0 : impl_->crls.emplace_back( crl );
271 0 : return {};
272 : }
273 :
274 : std::error_code
275 0 : tls_context::
276 : add_crl_file( std::string_view filename )
277 : {
278 0 : std::ifstream file( std::string( filename ), std::ios::binary );
279 0 : if( !file )
280 0 : return std::error_code( ENOENT, std::generic_category() );
281 :
282 0 : std::ostringstream ss;
283 0 : ss << file.rdbuf();
284 0 : impl_->crls.push_back( ss.str() );
285 0 : return {};
286 0 : }
287 :
288 : std::error_code
289 0 : tls_context::
290 : set_ocsp_staple( std::string_view response )
291 : {
292 0 : impl_->ocsp_staple = std::string( response );
293 0 : return {};
294 : }
295 :
296 : void
297 0 : tls_context::
298 : set_require_ocsp_staple( bool require )
299 : {
300 0 : impl_->require_ocsp_staple = require;
301 0 : }
302 :
303 : void
304 0 : tls_context::
305 : set_revocation_policy( tls_revocation_policy policy )
306 : {
307 0 : impl_->revocation = policy;
308 0 : }
309 :
310 : } // namespace boost::corosio
|