]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/asio/ssl/impl/context.ipp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / asio / ssl / impl / context.ipp
CommitLineData
7c673cae
FG
1//
2// ssl/impl/context.ipp
3// ~~~~~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
92f5a8d4 6// Copyright (c) 2005-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7c673cae
FG
7//
8// Distributed under the Boost Software License, Version 1.0. (See accompanying
9// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10//
11
12#ifndef BOOST_ASIO_SSL_IMPL_CONTEXT_IPP
13#define BOOST_ASIO_SSL_IMPL_CONTEXT_IPP
14
15#if defined(_MSC_VER) && (_MSC_VER >= 1200)
16# pragma once
17#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18
19#include <boost/asio/detail/config.hpp>
20
b32b8144
FG
21#include <cstring>
22#include <boost/asio/detail/throw_error.hpp>
23#include <boost/asio/error.hpp>
24#include <boost/asio/ssl/context.hpp>
25#include <boost/asio/ssl/error.hpp>
7c673cae
FG
26
27#include <boost/asio/detail/push_options.hpp>
28
29namespace boost {
30namespace asio {
31namespace ssl {
32
7c673cae
FG
33struct context::bio_cleanup
34{
35 BIO* p;
36 ~bio_cleanup() { if (p) ::BIO_free(p); }
37};
38
39struct context::x509_cleanup
40{
41 X509* p;
42 ~x509_cleanup() { if (p) ::X509_free(p); }
43};
44
45struct context::evp_pkey_cleanup
46{
47 EVP_PKEY* p;
48 ~evp_pkey_cleanup() { if (p) ::EVP_PKEY_free(p); }
49};
50
51struct context::rsa_cleanup
52{
53 RSA* p;
54 ~rsa_cleanup() { if (p) ::RSA_free(p); }
55};
56
57struct context::dh_cleanup
58{
59 DH* p;
60 ~dh_cleanup() { if (p) ::DH_free(p); }
61};
62
63context::context(context::method m)
64 : handle_(0)
65{
66 ::ERR_clear_error();
67
68 switch (m)
69 {
b32b8144
FG
70 // SSL v2.
71#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) || defined(OPENSSL_NO_SSL2)
7c673cae
FG
72 case context::sslv2:
73 case context::sslv2_client:
74 case context::sslv2_server:
75 boost::asio::detail::throw_error(
76 boost::asio::error::invalid_argument, "context");
77 break;
b32b8144 78#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L) || defined(OPENSSL_NO_SSL2)
7c673cae
FG
79 case context::sslv2:
80 handle_ = ::SSL_CTX_new(::SSLv2_method());
81 break;
82 case context::sslv2_client:
83 handle_ = ::SSL_CTX_new(::SSLv2_client_method());
84 break;
85 case context::sslv2_server:
86 handle_ = ::SSL_CTX_new(::SSLv2_server_method());
87 break;
b32b8144
FG
88#endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L) || defined(OPENSSL_NO_SSL2)
89
90 // SSL v3.
91#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
92 case context::sslv3:
93 handle_ = ::SSL_CTX_new(::TLS_method());
94 if (handle_)
95 {
96 SSL_CTX_set_min_proto_version(handle_, SSL3_VERSION);
97 SSL_CTX_set_max_proto_version(handle_, SSL3_VERSION);
98 }
99 break;
100 case context::sslv3_client:
101 handle_ = ::SSL_CTX_new(::TLS_client_method());
102 if (handle_)
103 {
104 SSL_CTX_set_min_proto_version(handle_, SSL3_VERSION);
105 SSL_CTX_set_max_proto_version(handle_, SSL3_VERSION);
106 }
107 break;
108 case context::sslv3_server:
109 handle_ = ::SSL_CTX_new(::TLS_server_method());
110 if (handle_)
111 {
112 SSL_CTX_set_min_proto_version(handle_, SSL3_VERSION);
113 SSL_CTX_set_max_proto_version(handle_, SSL3_VERSION);
114 }
115 break;
116#elif defined(OPENSSL_NO_SSL3)
7c673cae
FG
117 case context::sslv3:
118 case context::sslv3_client:
119 case context::sslv3_server:
120 boost::asio::detail::throw_error(
121 boost::asio::error::invalid_argument, "context");
122 break;
123#else // defined(OPENSSL_NO_SSL3)
124 case context::sslv3:
125 handle_ = ::SSL_CTX_new(::SSLv3_method());
126 break;
127 case context::sslv3_client:
128 handle_ = ::SSL_CTX_new(::SSLv3_client_method());
129 break;
130 case context::sslv3_server:
131 handle_ = ::SSL_CTX_new(::SSLv3_server_method());
132 break;
133#endif // defined(OPENSSL_NO_SSL3)
b32b8144
FG
134
135 // TLS v1.0.
136#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
137 case context::tlsv1:
138 handle_ = ::SSL_CTX_new(::TLS_method());
139 if (handle_)
140 {
141 SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION);
142 SSL_CTX_set_max_proto_version(handle_, TLS1_VERSION);
143 }
144 break;
145 case context::tlsv1_client:
146 handle_ = ::SSL_CTX_new(::TLS_client_method());
147 if (handle_)
148 {
149 SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION);
150 SSL_CTX_set_max_proto_version(handle_, TLS1_VERSION);
151 }
152 break;
153 case context::tlsv1_server:
154 handle_ = ::SSL_CTX_new(::TLS_server_method());
155 if (handle_)
156 {
157 SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION);
158 SSL_CTX_set_max_proto_version(handle_, TLS1_VERSION);
159 }
160 break;
92f5a8d4 161#elif defined(SSL_TXT_TLSV1)
7c673cae
FG
162 case context::tlsv1:
163 handle_ = ::SSL_CTX_new(::TLSv1_method());
164 break;
165 case context::tlsv1_client:
166 handle_ = ::SSL_CTX_new(::TLSv1_client_method());
167 break;
168 case context::tlsv1_server:
169 handle_ = ::SSL_CTX_new(::TLSv1_server_method());
170 break;
92f5a8d4
TL
171#else // defined(SSL_TXT_TLSV1)
172 case context::tlsv1:
173 case context::tlsv1_client:
174 case context::tlsv1_server:
175 boost::asio::detail::throw_error(
176 boost::asio::error::invalid_argument, "context");
177 break;
178#endif // defined(SSL_TXT_TLSV1)
b32b8144
FG
179
180 // TLS v1.1.
181#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
182 case context::tlsv11:
183 handle_ = ::SSL_CTX_new(::TLS_method());
184 if (handle_)
185 {
186 SSL_CTX_set_min_proto_version(handle_, TLS1_1_VERSION);
187 SSL_CTX_set_max_proto_version(handle_, TLS1_1_VERSION);
188 }
7c673cae 189 break;
b32b8144
FG
190 case context::tlsv11_client:
191 handle_ = ::SSL_CTX_new(::TLS_client_method());
192 if (handle_)
193 {
194 SSL_CTX_set_min_proto_version(handle_, TLS1_1_VERSION);
195 SSL_CTX_set_max_proto_version(handle_, TLS1_1_VERSION);
196 }
7c673cae 197 break;
b32b8144
FG
198 case context::tlsv11_server:
199 handle_ = ::SSL_CTX_new(::TLS_server_method());
200 if (handle_)
201 {
202 SSL_CTX_set_min_proto_version(handle_, TLS1_1_VERSION);
203 SSL_CTX_set_max_proto_version(handle_, TLS1_1_VERSION);
204 }
7c673cae 205 break;
b32b8144 206#elif defined(SSL_TXT_TLSV1_1)
7c673cae
FG
207 case context::tlsv11:
208 handle_ = ::SSL_CTX_new(::TLSv1_1_method());
209 break;
210 case context::tlsv11_client:
211 handle_ = ::SSL_CTX_new(::TLSv1_1_client_method());
212 break;
213 case context::tlsv11_server:
214 handle_ = ::SSL_CTX_new(::TLSv1_1_server_method());
215 break;
216#else // defined(SSL_TXT_TLSV1_1)
217 case context::tlsv11:
218 case context::tlsv11_client:
219 case context::tlsv11_server:
220 boost::asio::detail::throw_error(
221 boost::asio::error::invalid_argument, "context");
222 break;
223#endif // defined(SSL_TXT_TLSV1_1)
b32b8144
FG
224
225 // TLS v1.2.
226#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
227 case context::tlsv12:
228 handle_ = ::SSL_CTX_new(::TLS_method());
229 if (handle_)
230 {
231 SSL_CTX_set_min_proto_version(handle_, TLS1_2_VERSION);
232 SSL_CTX_set_max_proto_version(handle_, TLS1_2_VERSION);
233 }
234 break;
235 case context::tlsv12_client:
236 handle_ = ::SSL_CTX_new(::TLS_client_method());
237 if (handle_)
238 {
239 SSL_CTX_set_min_proto_version(handle_, TLS1_2_VERSION);
240 SSL_CTX_set_max_proto_version(handle_, TLS1_2_VERSION);
241 }
242 break;
243 case context::tlsv12_server:
244 handle_ = ::SSL_CTX_new(::TLS_server_method());
245 if (handle_)
246 {
247 SSL_CTX_set_min_proto_version(handle_, TLS1_2_VERSION);
248 SSL_CTX_set_max_proto_version(handle_, TLS1_2_VERSION);
249 }
250 break;
92f5a8d4 251#elif defined(SSL_TXT_TLSV1_2)
7c673cae
FG
252 case context::tlsv12:
253 handle_ = ::SSL_CTX_new(::TLSv1_2_method());
254 break;
255 case context::tlsv12_client:
256 handle_ = ::SSL_CTX_new(::TLSv1_2_client_method());
257 break;
258 case context::tlsv12_server:
259 handle_ = ::SSL_CTX_new(::TLSv1_2_server_method());
260 break;
92f5a8d4 261#else // defined(SSL_TXT_TLSV1_2)
7c673cae
FG
262 case context::tlsv12:
263 case context::tlsv12_client:
264 case context::tlsv12_server:
265 boost::asio::detail::throw_error(
266 boost::asio::error::invalid_argument, "context");
267 break;
92f5a8d4
TL
268#endif // defined(SSL_TXT_TLSV1_2)
269
270 // TLS v1.3.
271#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) \
272 && !defined(LIBRESSL_VERSION_NUMBER)
273 case context::tlsv13:
274 handle_ = ::SSL_CTX_new(::TLS_method());
275 if (handle_)
276 {
277 SSL_CTX_set_min_proto_version(handle_, TLS1_3_VERSION);
278 SSL_CTX_set_max_proto_version(handle_, TLS1_3_VERSION);
279 }
280 break;
281 case context::tlsv13_client:
282 handle_ = ::SSL_CTX_new(::TLS_client_method());
283 if (handle_)
284 {
285 SSL_CTX_set_min_proto_version(handle_, TLS1_3_VERSION);
286 SSL_CTX_set_max_proto_version(handle_, TLS1_3_VERSION);
287 }
288 break;
289 case context::tlsv13_server:
290 handle_ = ::SSL_CTX_new(::TLS_server_method());
291 if (handle_)
292 {
293 SSL_CTX_set_min_proto_version(handle_, TLS1_3_VERSION);
294 SSL_CTX_set_max_proto_version(handle_, TLS1_3_VERSION);
295 }
296 break;
297#else // (OPENSSL_VERSION_NUMBER >= 0x10101000L)
298 // && !defined(LIBRESSL_VERSION_NUMBER)
299 case context::tlsv13:
300 case context::tlsv13_client:
301 case context::tlsv13_server:
302 boost::asio::detail::throw_error(
303 boost::asio::error::invalid_argument, "context");
304 break;
305#endif // (OPENSSL_VERSION_NUMBER >= 0x10101000L)
306 // && !defined(LIBRESSL_VERSION_NUMBER)
b32b8144
FG
307
308 // Any supported SSL/TLS version.
309 case context::sslv23:
310 handle_ = ::SSL_CTX_new(::SSLv23_method());
311 break;
312 case context::sslv23_client:
313 handle_ = ::SSL_CTX_new(::SSLv23_client_method());
314 break;
315 case context::sslv23_server:
316 handle_ = ::SSL_CTX_new(::SSLv23_server_method());
317 break;
318
319 // Any supported TLS version.
320#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
321 case context::tls:
7c673cae 322 handle_ = ::SSL_CTX_new(::TLS_method());
b32b8144
FG
323 if (handle_)
324 SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION);
7c673cae 325 break;
b32b8144 326 case context::tls_client:
7c673cae 327 handle_ = ::SSL_CTX_new(::TLS_client_method());
b32b8144
FG
328 if (handle_)
329 SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION);
7c673cae 330 break;
b32b8144 331 case context::tls_server:
7c673cae 332 handle_ = ::SSL_CTX_new(::TLS_server_method());
b32b8144
FG
333 if (handle_)
334 SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION);
335 break;
336#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
337 case context::tls:
338 handle_ = ::SSL_CTX_new(::SSLv23_method());
339 if (handle_)
340 SSL_CTX_set_options(handle_, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
341 break;
342 case context::tls_client:
343 handle_ = ::SSL_CTX_new(::SSLv23_client_method());
344 if (handle_)
345 SSL_CTX_set_options(handle_, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
7c673cae 346 break;
b32b8144
FG
347 case context::tls_server:
348 handle_ = ::SSL_CTX_new(::SSLv23_server_method());
349 if (handle_)
350 SSL_CTX_set_options(handle_, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
351 break;
352#endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
353
7c673cae
FG
354 default:
355 handle_ = ::SSL_CTX_new(0);
356 break;
357 }
358
359 if (handle_ == 0)
360 {
361 boost::system::error_code ec(
362 static_cast<int>(::ERR_get_error()),
363 boost::asio::error::get_ssl_category());
364 boost::asio::detail::throw_error(ec, "context");
365 }
366
367 set_options(no_compression);
368}
369
7c673cae
FG
370#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
371context::context(context&& other)
372{
373 handle_ = other.handle_;
374 other.handle_ = 0;
375}
376
377context& context::operator=(context&& other)
378{
379 context tmp(BOOST_ASIO_MOVE_CAST(context)(*this));
380 handle_ = other.handle_;
381 other.handle_ = 0;
382 return *this;
383}
384#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
385
386context::~context()
387{
388 if (handle_)
389 {
92f5a8d4
TL
390#if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \
391 && !defined(LIBRESSL_VERSION_NUMBER)) \
392 || defined(BOOST_ASIO_USE_WOLFSSL)
7c673cae
FG
393 void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
394#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
395 void* cb_userdata = handle_->default_passwd_callback_userdata;
396#endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
397 if (cb_userdata)
398 {
399 detail::password_callback_base* callback =
400 static_cast<detail::password_callback_base*>(
401 cb_userdata);
402 delete callback;
92f5a8d4
TL
403#if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \
404 && !defined(LIBRESSL_VERSION_NUMBER)) \
405 || defined(BOOST_ASIO_USE_WOLFSSL)
7c673cae
FG
406 ::SSL_CTX_set_default_passwd_cb_userdata(handle_, 0);
407#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
408 handle_->default_passwd_callback_userdata = 0;
409#endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
410 }
411
412 if (SSL_CTX_get_app_data(handle_))
413 {
414 detail::verify_callback_base* callback =
415 static_cast<detail::verify_callback_base*>(
416 SSL_CTX_get_app_data(handle_));
417 delete callback;
418 SSL_CTX_set_app_data(handle_, 0);
419 }
420
421 ::SSL_CTX_free(handle_);
422 }
423}
424
425context::native_handle_type context::native_handle()
426{
427 return handle_;
428}
429
7c673cae
FG
430void context::clear_options(context::options o)
431{
432 boost::system::error_code ec;
433 clear_options(o, ec);
434 boost::asio::detail::throw_error(ec, "clear_options");
435}
436
b32b8144 437BOOST_ASIO_SYNC_OP_VOID context::clear_options(
7c673cae
FG
438 context::options o, boost::system::error_code& ec)
439{
440#if (OPENSSL_VERSION_NUMBER >= 0x009080DFL) \
441 && (OPENSSL_VERSION_NUMBER != 0x00909000L)
442# if !defined(SSL_OP_NO_COMPRESSION)
443 if ((o & context::no_compression) != 0)
444 {
445# if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
446 handle_->comp_methods = SSL_COMP_get_compression_methods();
447# endif // (OPENSSL_VERSION_NUMBER >= 0x00908000L)
448 o ^= context::no_compression;
449 }
450# endif // !defined(SSL_OP_NO_COMPRESSION)
451
452 ::SSL_CTX_clear_options(handle_, o);
453
454 ec = boost::system::error_code();
455#else // (OPENSSL_VERSION_NUMBER >= 0x009080DFL)
456 // && (OPENSSL_VERSION_NUMBER != 0x00909000L)
457 (void)o;
458 ec = boost::asio::error::operation_not_supported;
459#endif // (OPENSSL_VERSION_NUMBER >= 0x009080DFL)
460 // && (OPENSSL_VERSION_NUMBER != 0x00909000L)
b32b8144 461 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
462}
463
464void context::set_options(context::options o)
465{
466 boost::system::error_code ec;
467 set_options(o, ec);
468 boost::asio::detail::throw_error(ec, "set_options");
469}
470
b32b8144 471BOOST_ASIO_SYNC_OP_VOID context::set_options(
7c673cae
FG
472 context::options o, boost::system::error_code& ec)
473{
474#if !defined(SSL_OP_NO_COMPRESSION)
475 if ((o & context::no_compression) != 0)
476 {
477#if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
478 handle_->comp_methods =
479 boost::asio::ssl::detail::openssl_init<>::get_null_compression_methods();
480#endif // (OPENSSL_VERSION_NUMBER >= 0x00908000L)
481 o ^= context::no_compression;
482 }
483#endif // !defined(SSL_OP_NO_COMPRESSION)
484
485 ::SSL_CTX_set_options(handle_, o);
486
487 ec = boost::system::error_code();
b32b8144 488 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
489}
490
491void context::set_verify_mode(verify_mode v)
492{
493 boost::system::error_code ec;
494 set_verify_mode(v, ec);
495 boost::asio::detail::throw_error(ec, "set_verify_mode");
496}
497
b32b8144 498BOOST_ASIO_SYNC_OP_VOID context::set_verify_mode(
7c673cae
FG
499 verify_mode v, boost::system::error_code& ec)
500{
501 ::SSL_CTX_set_verify(handle_, v, ::SSL_CTX_get_verify_callback(handle_));
502
503 ec = boost::system::error_code();
b32b8144 504 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
505}
506
507void context::set_verify_depth(int depth)
508{
509 boost::system::error_code ec;
510 set_verify_depth(depth, ec);
511 boost::asio::detail::throw_error(ec, "set_verify_depth");
512}
513
b32b8144 514BOOST_ASIO_SYNC_OP_VOID context::set_verify_depth(
7c673cae
FG
515 int depth, boost::system::error_code& ec)
516{
517 ::SSL_CTX_set_verify_depth(handle_, depth);
518
519 ec = boost::system::error_code();
b32b8144 520 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
521}
522
523void context::load_verify_file(const std::string& filename)
524{
525 boost::system::error_code ec;
526 load_verify_file(filename, ec);
527 boost::asio::detail::throw_error(ec, "load_verify_file");
528}
529
b32b8144 530BOOST_ASIO_SYNC_OP_VOID context::load_verify_file(
7c673cae
FG
531 const std::string& filename, boost::system::error_code& ec)
532{
533 ::ERR_clear_error();
534
535 if (::SSL_CTX_load_verify_locations(handle_, filename.c_str(), 0) != 1)
536 {
537 ec = boost::system::error_code(
538 static_cast<int>(::ERR_get_error()),
539 boost::asio::error::get_ssl_category());
b32b8144 540 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
541 }
542
543 ec = boost::system::error_code();
b32b8144 544 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
545}
546
547void context::add_certificate_authority(const const_buffer& ca)
548{
549 boost::system::error_code ec;
550 add_certificate_authority(ca, ec);
551 boost::asio::detail::throw_error(ec, "add_certificate_authority");
552}
553
b32b8144 554BOOST_ASIO_SYNC_OP_VOID context::add_certificate_authority(
7c673cae
FG
555 const const_buffer& ca, boost::system::error_code& ec)
556{
557 ::ERR_clear_error();
558
559 bio_cleanup bio = { make_buffer_bio(ca) };
560 if (bio.p)
561 {
11fdf7f2 562 if (X509_STORE* store = ::SSL_CTX_get_cert_store(handle_))
7c673cae 563 {
11fdf7f2 564 for (;;)
7c673cae 565 {
11fdf7f2
TL
566 x509_cleanup cert = { ::PEM_read_bio_X509(bio.p, 0, 0, 0) };
567 if (!cert.p)
568 break;
569
570 if (::X509_STORE_add_cert(store, cert.p) != 1)
7c673cae 571 {
11fdf7f2
TL
572 ec = boost::system::error_code(
573 static_cast<int>(::ERR_get_error()),
574 boost::asio::error::get_ssl_category());
b32b8144 575 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
576 }
577 }
578 }
579 }
580
11fdf7f2 581 ec = boost::system::error_code();
b32b8144 582 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
583}
584
585void context::set_default_verify_paths()
586{
587 boost::system::error_code ec;
588 set_default_verify_paths(ec);
589 boost::asio::detail::throw_error(ec, "set_default_verify_paths");
590}
591
b32b8144 592BOOST_ASIO_SYNC_OP_VOID context::set_default_verify_paths(
7c673cae
FG
593 boost::system::error_code& ec)
594{
595 ::ERR_clear_error();
596
597 if (::SSL_CTX_set_default_verify_paths(handle_) != 1)
598 {
599 ec = boost::system::error_code(
600 static_cast<int>(::ERR_get_error()),
601 boost::asio::error::get_ssl_category());
b32b8144 602 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
603 }
604
605 ec = boost::system::error_code();
b32b8144 606 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
607}
608
609void context::add_verify_path(const std::string& path)
610{
611 boost::system::error_code ec;
612 add_verify_path(path, ec);
613 boost::asio::detail::throw_error(ec, "add_verify_path");
614}
615
b32b8144 616BOOST_ASIO_SYNC_OP_VOID context::add_verify_path(
7c673cae
FG
617 const std::string& path, boost::system::error_code& ec)
618{
619 ::ERR_clear_error();
620
621 if (::SSL_CTX_load_verify_locations(handle_, 0, path.c_str()) != 1)
622 {
623 ec = boost::system::error_code(
624 static_cast<int>(::ERR_get_error()),
625 boost::asio::error::get_ssl_category());
b32b8144 626 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
627 }
628
629 ec = boost::system::error_code();
b32b8144 630 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
631}
632
633void context::use_certificate(
634 const const_buffer& certificate, file_format format)
635{
636 boost::system::error_code ec;
637 use_certificate(certificate, format, ec);
638 boost::asio::detail::throw_error(ec, "use_certificate");
639}
640
b32b8144 641BOOST_ASIO_SYNC_OP_VOID context::use_certificate(
7c673cae
FG
642 const const_buffer& certificate, file_format format,
643 boost::system::error_code& ec)
644{
645 ::ERR_clear_error();
646
647 if (format == context_base::asn1)
648 {
649 if (::SSL_CTX_use_certificate_ASN1(handle_,
b32b8144
FG
650 static_cast<int>(certificate.size()),
651 static_cast<const unsigned char*>(certificate.data())) == 1)
7c673cae
FG
652 {
653 ec = boost::system::error_code();
b32b8144 654 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
655 }
656 }
657 else if (format == context_base::pem)
658 {
659 bio_cleanup bio = { make_buffer_bio(certificate) };
660 if (bio.p)
661 {
662 x509_cleanup cert = { ::PEM_read_bio_X509(bio.p, 0, 0, 0) };
663 if (cert.p)
664 {
665 if (::SSL_CTX_use_certificate(handle_, cert.p) == 1)
666 {
667 ec = boost::system::error_code();
b32b8144 668 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
669 }
670 }
671 }
672 }
673 else
674 {
675 ec = boost::asio::error::invalid_argument;
b32b8144 676 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
677 }
678
679 ec = boost::system::error_code(
680 static_cast<int>(::ERR_get_error()),
681 boost::asio::error::get_ssl_category());
b32b8144 682 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
683}
684
685void context::use_certificate_file(
686 const std::string& filename, file_format format)
687{
688 boost::system::error_code ec;
689 use_certificate_file(filename, format, ec);
690 boost::asio::detail::throw_error(ec, "use_certificate_file");
691}
692
b32b8144 693BOOST_ASIO_SYNC_OP_VOID context::use_certificate_file(
7c673cae
FG
694 const std::string& filename, file_format format,
695 boost::system::error_code& ec)
696{
697 int file_type;
698 switch (format)
699 {
700 case context_base::asn1:
701 file_type = SSL_FILETYPE_ASN1;
702 break;
703 case context_base::pem:
704 file_type = SSL_FILETYPE_PEM;
705 break;
706 default:
707 {
708 ec = boost::asio::error::invalid_argument;
b32b8144 709 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
710 }
711 }
712
713 ::ERR_clear_error();
714
715 if (::SSL_CTX_use_certificate_file(handle_, filename.c_str(), file_type) != 1)
716 {
717 ec = boost::system::error_code(
718 static_cast<int>(::ERR_get_error()),
719 boost::asio::error::get_ssl_category());
b32b8144 720 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
721 }
722
723 ec = boost::system::error_code();
b32b8144 724 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
725}
726
727void context::use_certificate_chain(const const_buffer& chain)
728{
729 boost::system::error_code ec;
730 use_certificate_chain(chain, ec);
731 boost::asio::detail::throw_error(ec, "use_certificate_chain");
732}
733
b32b8144 734BOOST_ASIO_SYNC_OP_VOID context::use_certificate_chain(
7c673cae
FG
735 const const_buffer& chain, boost::system::error_code& ec)
736{
737 ::ERR_clear_error();
738
739 bio_cleanup bio = { make_buffer_bio(chain) };
740 if (bio.p)
741 {
92f5a8d4
TL
742#if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \
743 && !defined(LIBRESSL_VERSION_NUMBER)) \
744 || defined(BOOST_ASIO_USE_WOLFSSL)
7c673cae
FG
745 pem_password_cb* callback = ::SSL_CTX_get_default_passwd_cb(handle_);
746 void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
747#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
748 pem_password_cb* callback = handle_->default_passwd_callback;
749 void* cb_userdata = handle_->default_passwd_callback_userdata;
750#endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
751 x509_cleanup cert = {
752 ::PEM_read_bio_X509_AUX(bio.p, 0,
753 callback,
754 cb_userdata) };
755 if (!cert.p)
756 {
757 ec = boost::system::error_code(ERR_R_PEM_LIB,
758 boost::asio::error::get_ssl_category());
b32b8144 759 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
760 }
761
762 int result = ::SSL_CTX_use_certificate(handle_, cert.p);
763 if (result == 0 || ::ERR_peek_error() != 0)
764 {
765 ec = boost::system::error_code(
766 static_cast<int>(::ERR_get_error()),
767 boost::asio::error::get_ssl_category());
b32b8144 768 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
769 }
770
92f5a8d4
TL
771#if ((OPENSSL_VERSION_NUMBER >= 0x10002000L) \
772 && !defined(LIBRESSL_VERSION_NUMBER)) \
773 || defined(BOOST_ASIO_USE_WOLFSSL)
7c673cae
FG
774 ::SSL_CTX_clear_chain_certs(handle_);
775#else
776 if (handle_->extra_certs)
777 {
778 ::sk_X509_pop_free(handle_->extra_certs, X509_free);
779 handle_->extra_certs = 0;
780 }
781#endif // (OPENSSL_VERSION_NUMBER >= 0x10002000L)
782
783 while (X509* cacert = ::PEM_read_bio_X509(bio.p, 0,
784 callback,
785 cb_userdata))
786 {
787 if (!::SSL_CTX_add_extra_chain_cert(handle_, cacert))
788 {
789 ec = boost::system::error_code(
790 static_cast<int>(::ERR_get_error()),
791 boost::asio::error::get_ssl_category());
b32b8144 792 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
793 }
794 }
795
796 result = ::ERR_peek_last_error();
797 if ((ERR_GET_LIB(result) == ERR_LIB_PEM)
798 && (ERR_GET_REASON(result) == PEM_R_NO_START_LINE))
799 {
800 ::ERR_clear_error();
801 ec = boost::system::error_code();
b32b8144 802 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
803 }
804 }
805
806 ec = boost::system::error_code(
807 static_cast<int>(::ERR_get_error()),
808 boost::asio::error::get_ssl_category());
b32b8144 809 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
810}
811
812void context::use_certificate_chain_file(const std::string& filename)
813{
814 boost::system::error_code ec;
815 use_certificate_chain_file(filename, ec);
816 boost::asio::detail::throw_error(ec, "use_certificate_chain_file");
817}
818
b32b8144 819BOOST_ASIO_SYNC_OP_VOID context::use_certificate_chain_file(
7c673cae
FG
820 const std::string& filename, boost::system::error_code& ec)
821{
822 ::ERR_clear_error();
823
824 if (::SSL_CTX_use_certificate_chain_file(handle_, filename.c_str()) != 1)
825 {
826 ec = boost::system::error_code(
827 static_cast<int>(::ERR_get_error()),
828 boost::asio::error::get_ssl_category());
b32b8144 829 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
830 }
831
832 ec = boost::system::error_code();
b32b8144 833 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
834}
835
836void context::use_private_key(
837 const const_buffer& private_key, context::file_format format)
838{
839 boost::system::error_code ec;
840 use_private_key(private_key, format, ec);
841 boost::asio::detail::throw_error(ec, "use_private_key");
842}
843
b32b8144 844BOOST_ASIO_SYNC_OP_VOID context::use_private_key(
7c673cae
FG
845 const const_buffer& private_key, context::file_format format,
846 boost::system::error_code& ec)
847{
848 ::ERR_clear_error();
849
92f5a8d4
TL
850#if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \
851 && !defined(LIBRESSL_VERSION_NUMBER)) \
852 || defined(BOOST_ASIO_USE_WOLFSSL)
7c673cae
FG
853 pem_password_cb* callback = ::SSL_CTX_get_default_passwd_cb(handle_);
854 void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
855#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
856 pem_password_cb* callback = handle_->default_passwd_callback;
857 void* cb_userdata = handle_->default_passwd_callback_userdata;
858#endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
859
860 bio_cleanup bio = { make_buffer_bio(private_key) };
861 if (bio.p)
862 {
863 evp_pkey_cleanup evp_private_key = { 0 };
864 switch (format)
865 {
866 case context_base::asn1:
867 evp_private_key.p = ::d2i_PrivateKey_bio(bio.p, 0);
868 break;
869 case context_base::pem:
870 evp_private_key.p = ::PEM_read_bio_PrivateKey(
871 bio.p, 0, callback,
872 cb_userdata);
873 break;
874 default:
875 {
876 ec = boost::asio::error::invalid_argument;
b32b8144 877 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
878 }
879 }
880
881 if (evp_private_key.p)
882 {
883 if (::SSL_CTX_use_PrivateKey(handle_, evp_private_key.p) == 1)
884 {
885 ec = boost::system::error_code();
b32b8144 886 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
887 }
888 }
889 }
890
891 ec = boost::system::error_code(
892 static_cast<int>(::ERR_get_error()),
893 boost::asio::error::get_ssl_category());
b32b8144 894 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
895}
896
897void context::use_private_key_file(
898 const std::string& filename, context::file_format format)
899{
900 boost::system::error_code ec;
901 use_private_key_file(filename, format, ec);
902 boost::asio::detail::throw_error(ec, "use_private_key_file");
903}
904
905void context::use_rsa_private_key(
906 const const_buffer& private_key, context::file_format format)
907{
908 boost::system::error_code ec;
909 use_rsa_private_key(private_key, format, ec);
910 boost::asio::detail::throw_error(ec, "use_rsa_private_key");
911}
912
b32b8144 913BOOST_ASIO_SYNC_OP_VOID context::use_rsa_private_key(
7c673cae
FG
914 const const_buffer& private_key, context::file_format format,
915 boost::system::error_code& ec)
916{
917 ::ERR_clear_error();
918
92f5a8d4
TL
919#if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \
920 && !defined(LIBRESSL_VERSION_NUMBER)) \
921 || defined(BOOST_ASIO_USE_WOLFSSL)
7c673cae
FG
922 pem_password_cb* callback = ::SSL_CTX_get_default_passwd_cb(handle_);
923 void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
924#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
925 pem_password_cb* callback = handle_->default_passwd_callback;
926 void* cb_userdata = handle_->default_passwd_callback_userdata;
927#endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
928
929 bio_cleanup bio = { make_buffer_bio(private_key) };
930 if (bio.p)
931 {
932 rsa_cleanup rsa_private_key = { 0 };
933 switch (format)
934 {
935 case context_base::asn1:
936 rsa_private_key.p = ::d2i_RSAPrivateKey_bio(bio.p, 0);
937 break;
938 case context_base::pem:
939 rsa_private_key.p = ::PEM_read_bio_RSAPrivateKey(
940 bio.p, 0, callback,
941 cb_userdata);
942 break;
943 default:
944 {
945 ec = boost::asio::error::invalid_argument;
b32b8144 946 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
947 }
948 }
949
950 if (rsa_private_key.p)
951 {
952 if (::SSL_CTX_use_RSAPrivateKey(handle_, rsa_private_key.p) == 1)
953 {
954 ec = boost::system::error_code();
b32b8144 955 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
956 }
957 }
958 }
959
960 ec = boost::system::error_code(
961 static_cast<int>(::ERR_get_error()),
962 boost::asio::error::get_ssl_category());
b32b8144 963 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
964}
965
b32b8144 966BOOST_ASIO_SYNC_OP_VOID context::use_private_key_file(
7c673cae
FG
967 const std::string& filename, context::file_format format,
968 boost::system::error_code& ec)
969{
970 int file_type;
971 switch (format)
972 {
973 case context_base::asn1:
974 file_type = SSL_FILETYPE_ASN1;
975 break;
976 case context_base::pem:
977 file_type = SSL_FILETYPE_PEM;
978 break;
979 default:
980 {
981 ec = boost::asio::error::invalid_argument;
b32b8144 982 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
983 }
984 }
985
986 ::ERR_clear_error();
987
988 if (::SSL_CTX_use_PrivateKey_file(handle_, filename.c_str(), file_type) != 1)
989 {
990 ec = boost::system::error_code(
991 static_cast<int>(::ERR_get_error()),
992 boost::asio::error::get_ssl_category());
b32b8144 993 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
994 }
995
996 ec = boost::system::error_code();
b32b8144 997 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
998}
999
1000void context::use_rsa_private_key_file(
1001 const std::string& filename, context::file_format format)
1002{
1003 boost::system::error_code ec;
1004 use_rsa_private_key_file(filename, format, ec);
1005 boost::asio::detail::throw_error(ec, "use_rsa_private_key_file");
1006}
1007
b32b8144 1008BOOST_ASIO_SYNC_OP_VOID context::use_rsa_private_key_file(
7c673cae
FG
1009 const std::string& filename, context::file_format format,
1010 boost::system::error_code& ec)
1011{
1012 int file_type;
1013 switch (format)
1014 {
1015 case context_base::asn1:
1016 file_type = SSL_FILETYPE_ASN1;
1017 break;
1018 case context_base::pem:
1019 file_type = SSL_FILETYPE_PEM;
1020 break;
1021 default:
1022 {
1023 ec = boost::asio::error::invalid_argument;
b32b8144 1024 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
1025 }
1026 }
1027
1028 ::ERR_clear_error();
1029
1030 if (::SSL_CTX_use_RSAPrivateKey_file(
1031 handle_, filename.c_str(), file_type) != 1)
1032 {
1033 ec = boost::system::error_code(
1034 static_cast<int>(::ERR_get_error()),
1035 boost::asio::error::get_ssl_category());
b32b8144 1036 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
1037 }
1038
1039 ec = boost::system::error_code();
b32b8144 1040 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
1041}
1042
1043void context::use_tmp_dh(const const_buffer& dh)
1044{
1045 boost::system::error_code ec;
1046 use_tmp_dh(dh, ec);
1047 boost::asio::detail::throw_error(ec, "use_tmp_dh");
1048}
1049
b32b8144 1050BOOST_ASIO_SYNC_OP_VOID context::use_tmp_dh(
7c673cae
FG
1051 const const_buffer& dh, boost::system::error_code& ec)
1052{
1053 ::ERR_clear_error();
1054
1055 bio_cleanup bio = { make_buffer_bio(dh) };
1056 if (bio.p)
1057 {
1058 return do_use_tmp_dh(bio.p, ec);
1059 }
1060
1061 ec = boost::system::error_code(
1062 static_cast<int>(::ERR_get_error()),
1063 boost::asio::error::get_ssl_category());
b32b8144 1064 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
1065}
1066
1067void context::use_tmp_dh_file(const std::string& filename)
1068{
1069 boost::system::error_code ec;
1070 use_tmp_dh_file(filename, ec);
1071 boost::asio::detail::throw_error(ec, "use_tmp_dh_file");
1072}
1073
b32b8144 1074BOOST_ASIO_SYNC_OP_VOID context::use_tmp_dh_file(
7c673cae
FG
1075 const std::string& filename, boost::system::error_code& ec)
1076{
1077 ::ERR_clear_error();
1078
1079 bio_cleanup bio = { ::BIO_new_file(filename.c_str(), "r") };
1080 if (bio.p)
1081 {
1082 return do_use_tmp_dh(bio.p, ec);
1083 }
1084
1085 ec = boost::system::error_code(
1086 static_cast<int>(::ERR_get_error()),
1087 boost::asio::error::get_ssl_category());
b32b8144 1088 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
1089}
1090
b32b8144 1091BOOST_ASIO_SYNC_OP_VOID context::do_use_tmp_dh(
7c673cae
FG
1092 BIO* bio, boost::system::error_code& ec)
1093{
1094 ::ERR_clear_error();
1095
1096 dh_cleanup dh = { ::PEM_read_bio_DHparams(bio, 0, 0, 0) };
1097 if (dh.p)
1098 {
1099 if (::SSL_CTX_set_tmp_dh(handle_, dh.p) == 1)
1100 {
1101 ec = boost::system::error_code();
b32b8144 1102 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
1103 }
1104 }
1105
1106 ec = boost::system::error_code(
1107 static_cast<int>(::ERR_get_error()),
1108 boost::asio::error::get_ssl_category());
b32b8144 1109 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
1110}
1111
b32b8144 1112BOOST_ASIO_SYNC_OP_VOID context::do_set_verify_callback(
7c673cae
FG
1113 detail::verify_callback_base* callback, boost::system::error_code& ec)
1114{
1115 if (SSL_CTX_get_app_data(handle_))
1116 {
1117 delete static_cast<detail::verify_callback_base*>(
1118 SSL_CTX_get_app_data(handle_));
1119 }
1120
1121 SSL_CTX_set_app_data(handle_, callback);
1122
1123 ::SSL_CTX_set_verify(handle_,
1124 ::SSL_CTX_get_verify_mode(handle_),
1125 &context::verify_callback_function);
1126
1127 ec = boost::system::error_code();
b32b8144 1128 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
1129}
1130
1131int context::verify_callback_function(int preverified, X509_STORE_CTX* ctx)
1132{
1133 if (ctx)
1134 {
1135 if (SSL* ssl = static_cast<SSL*>(
1136 ::X509_STORE_CTX_get_ex_data(
1137 ctx, ::SSL_get_ex_data_X509_STORE_CTX_idx())))
1138 {
1139 if (SSL_CTX* handle = ::SSL_get_SSL_CTX(ssl))
1140 {
1141 if (SSL_CTX_get_app_data(handle))
1142 {
1143 detail::verify_callback_base* callback =
1144 static_cast<detail::verify_callback_base*>(
1145 SSL_CTX_get_app_data(handle));
1146
1147 verify_context verify_ctx(ctx);
1148 return callback->call(preverified != 0, verify_ctx) ? 1 : 0;
1149 }
1150 }
1151 }
1152 }
1153
1154 return 0;
1155}
1156
b32b8144 1157BOOST_ASIO_SYNC_OP_VOID context::do_set_password_callback(
7c673cae
FG
1158 detail::password_callback_base* callback, boost::system::error_code& ec)
1159{
92f5a8d4
TL
1160#if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \
1161 && !defined(LIBRESSL_VERSION_NUMBER)) \
1162 || defined(BOOST_ASIO_USE_WOLFSSL)
7c673cae
FG
1163 void* old_callback = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
1164 ::SSL_CTX_set_default_passwd_cb_userdata(handle_, callback);
1165#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
1166 void* old_callback = handle_->default_passwd_callback_userdata;
1167 handle_->default_passwd_callback_userdata = callback;
1168#endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
1169
1170 if (old_callback)
1171 delete static_cast<detail::password_callback_base*>(
1172 old_callback);
1173
1174 SSL_CTX_set_default_passwd_cb(handle_, &context::password_callback_function);
1175
1176 ec = boost::system::error_code();
b32b8144 1177 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
1178}
1179
1180int context::password_callback_function(
1181 char* buf, int size, int purpose, void* data)
1182{
1183 using namespace std; // For strncat and strlen.
1184
1185 if (data)
1186 {
1187 detail::password_callback_base* callback =
1188 static_cast<detail::password_callback_base*>(data);
1189
1190 std::string passwd = callback->call(static_cast<std::size_t>(size),
1191 purpose ? context_base::for_writing : context_base::for_reading);
1192
1193#if defined(BOOST_ASIO_HAS_SECURE_RTL)
1194 strcpy_s(buf, size, passwd.c_str());
1195#else // defined(BOOST_ASIO_HAS_SECURE_RTL)
1196 *buf = '\0';
1197 if (size > 0)
1198 strncat(buf, passwd.c_str(), size - 1);
1199#endif // defined(BOOST_ASIO_HAS_SECURE_RTL)
1200
1201 return static_cast<int>(strlen(buf));
1202 }
1203
1204 return 0;
1205}
1206
1207BIO* context::make_buffer_bio(const const_buffer& b)
1208{
1209 return ::BIO_new_mem_buf(
b32b8144
FG
1210 const_cast<void*>(b.data()),
1211 static_cast<int>(b.size()));
7c673cae
FG
1212}
1213
7c673cae
FG
1214} // namespace ssl
1215} // namespace asio
1216} // namespace boost
1217
1218#include <boost/asio/detail/pop_options.hpp>
1219
1220#endif // BOOST_ASIO_SSL_IMPL_CONTEXT_IPP