Chris@16
|
1 //
|
Chris@16
|
2 // ssl/impl/context.ipp
|
Chris@16
|
3 // ~~~~~~~~~~~~~~~~~~~~
|
Chris@16
|
4 //
|
Chris@16
|
5 // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
|
Chris@16
|
6 // Copyright (c) 2005-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
Chris@16
|
7 //
|
Chris@16
|
8 // Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
9 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
10 //
|
Chris@16
|
11
|
Chris@16
|
12 #ifndef BOOST_ASIO_SSL_IMPL_CONTEXT_IPP
|
Chris@16
|
13 #define BOOST_ASIO_SSL_IMPL_CONTEXT_IPP
|
Chris@16
|
14
|
Chris@16
|
15 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
Chris@16
|
16 # pragma once
|
Chris@16
|
17 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
Chris@16
|
18
|
Chris@16
|
19 #include <boost/asio/detail/config.hpp>
|
Chris@16
|
20
|
Chris@16
|
21 #if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
|
Chris@16
|
22 # include <cstring>
|
Chris@16
|
23 # include <boost/asio/detail/throw_error.hpp>
|
Chris@16
|
24 # include <boost/asio/error.hpp>
|
Chris@16
|
25 # include <boost/asio/ssl/context.hpp>
|
Chris@16
|
26 # include <boost/asio/ssl/error.hpp>
|
Chris@16
|
27 #endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
|
Chris@16
|
28
|
Chris@16
|
29 #include <boost/asio/detail/push_options.hpp>
|
Chris@16
|
30
|
Chris@16
|
31 namespace boost {
|
Chris@16
|
32 namespace asio {
|
Chris@16
|
33 namespace ssl {
|
Chris@16
|
34
|
Chris@16
|
35 #if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
|
Chris@16
|
36
|
Chris@16
|
37 struct context::bio_cleanup
|
Chris@16
|
38 {
|
Chris@16
|
39 BIO* p;
|
Chris@16
|
40 ~bio_cleanup() { if (p) ::BIO_free(p); }
|
Chris@16
|
41 };
|
Chris@16
|
42
|
Chris@16
|
43 struct context::x509_cleanup
|
Chris@16
|
44 {
|
Chris@16
|
45 X509* p;
|
Chris@16
|
46 ~x509_cleanup() { if (p) ::X509_free(p); }
|
Chris@16
|
47 };
|
Chris@16
|
48
|
Chris@16
|
49 struct context::evp_pkey_cleanup
|
Chris@16
|
50 {
|
Chris@16
|
51 EVP_PKEY* p;
|
Chris@16
|
52 ~evp_pkey_cleanup() { if (p) ::EVP_PKEY_free(p); }
|
Chris@16
|
53 };
|
Chris@16
|
54
|
Chris@16
|
55 struct context::rsa_cleanup
|
Chris@16
|
56 {
|
Chris@16
|
57 RSA* p;
|
Chris@16
|
58 ~rsa_cleanup() { if (p) ::RSA_free(p); }
|
Chris@16
|
59 };
|
Chris@16
|
60
|
Chris@16
|
61 struct context::dh_cleanup
|
Chris@16
|
62 {
|
Chris@16
|
63 DH* p;
|
Chris@16
|
64 ~dh_cleanup() { if (p) ::DH_free(p); }
|
Chris@16
|
65 };
|
Chris@16
|
66
|
Chris@16
|
67 context::context(context::method m)
|
Chris@16
|
68 : handle_(0)
|
Chris@16
|
69 {
|
Chris@16
|
70 switch (m)
|
Chris@16
|
71 {
|
Chris@16
|
72 #if defined(OPENSSL_NO_SSL2)
|
Chris@16
|
73 case context::sslv2:
|
Chris@16
|
74 case context::sslv2_client:
|
Chris@16
|
75 case context::sslv2_server:
|
Chris@16
|
76 boost::asio::detail::throw_error(
|
Chris@16
|
77 boost::asio::error::invalid_argument, "context");
|
Chris@16
|
78 break;
|
Chris@16
|
79 #else // defined(OPENSSL_NO_SSL2)
|
Chris@16
|
80 case context::sslv2:
|
Chris@16
|
81 handle_ = ::SSL_CTX_new(::SSLv2_method());
|
Chris@16
|
82 break;
|
Chris@16
|
83 case context::sslv2_client:
|
Chris@16
|
84 handle_ = ::SSL_CTX_new(::SSLv2_client_method());
|
Chris@16
|
85 break;
|
Chris@16
|
86 case context::sslv2_server:
|
Chris@16
|
87 handle_ = ::SSL_CTX_new(::SSLv2_server_method());
|
Chris@16
|
88 break;
|
Chris@16
|
89 #endif // defined(OPENSSL_NO_SSL2)
|
Chris@16
|
90 case context::sslv3:
|
Chris@16
|
91 handle_ = ::SSL_CTX_new(::SSLv3_method());
|
Chris@16
|
92 break;
|
Chris@16
|
93 case context::sslv3_client:
|
Chris@16
|
94 handle_ = ::SSL_CTX_new(::SSLv3_client_method());
|
Chris@16
|
95 break;
|
Chris@16
|
96 case context::sslv3_server:
|
Chris@16
|
97 handle_ = ::SSL_CTX_new(::SSLv3_server_method());
|
Chris@16
|
98 break;
|
Chris@16
|
99 case context::tlsv1:
|
Chris@16
|
100 handle_ = ::SSL_CTX_new(::TLSv1_method());
|
Chris@16
|
101 break;
|
Chris@16
|
102 case context::tlsv1_client:
|
Chris@16
|
103 handle_ = ::SSL_CTX_new(::TLSv1_client_method());
|
Chris@16
|
104 break;
|
Chris@16
|
105 case context::tlsv1_server:
|
Chris@16
|
106 handle_ = ::SSL_CTX_new(::TLSv1_server_method());
|
Chris@16
|
107 break;
|
Chris@16
|
108 case context::sslv23:
|
Chris@16
|
109 handle_ = ::SSL_CTX_new(::SSLv23_method());
|
Chris@16
|
110 break;
|
Chris@16
|
111 case context::sslv23_client:
|
Chris@16
|
112 handle_ = ::SSL_CTX_new(::SSLv23_client_method());
|
Chris@16
|
113 break;
|
Chris@16
|
114 case context::sslv23_server:
|
Chris@16
|
115 handle_ = ::SSL_CTX_new(::SSLv23_server_method());
|
Chris@16
|
116 break;
|
Chris@16
|
117 #if defined(SSL_TXT_TLSV1_1)
|
Chris@16
|
118 case context::tlsv11:
|
Chris@16
|
119 handle_ = ::SSL_CTX_new(::TLSv1_1_method());
|
Chris@16
|
120 break;
|
Chris@16
|
121 case context::tlsv11_client:
|
Chris@16
|
122 handle_ = ::SSL_CTX_new(::TLSv1_1_client_method());
|
Chris@16
|
123 break;
|
Chris@16
|
124 case context::tlsv11_server:
|
Chris@16
|
125 handle_ = ::SSL_CTX_new(::TLSv1_1_server_method());
|
Chris@16
|
126 break;
|
Chris@16
|
127 #else // defined(SSL_TXT_TLSV1_1)
|
Chris@16
|
128 case context::tlsv11:
|
Chris@16
|
129 case context::tlsv11_client:
|
Chris@16
|
130 case context::tlsv11_server:
|
Chris@16
|
131 boost::asio::detail::throw_error(
|
Chris@16
|
132 boost::asio::error::invalid_argument, "context");
|
Chris@16
|
133 break;
|
Chris@16
|
134 #endif // defined(SSL_TXT_TLSV1_1)
|
Chris@16
|
135 #if defined(SSL_TXT_TLSV1_2)
|
Chris@16
|
136 case context::tlsv12:
|
Chris@16
|
137 handle_ = ::SSL_CTX_new(::TLSv1_2_method());
|
Chris@16
|
138 break;
|
Chris@16
|
139 case context::tlsv12_client:
|
Chris@16
|
140 handle_ = ::SSL_CTX_new(::TLSv1_2_client_method());
|
Chris@16
|
141 break;
|
Chris@16
|
142 case context::tlsv12_server:
|
Chris@16
|
143 handle_ = ::SSL_CTX_new(::TLSv1_2_server_method());
|
Chris@16
|
144 break;
|
Chris@16
|
145 #else // defined(SSL_TXT_TLSV1_2)
|
Chris@16
|
146 case context::tlsv12:
|
Chris@16
|
147 case context::tlsv12_client:
|
Chris@16
|
148 case context::tlsv12_server:
|
Chris@16
|
149 boost::asio::detail::throw_error(
|
Chris@16
|
150 boost::asio::error::invalid_argument, "context");
|
Chris@16
|
151 break;
|
Chris@16
|
152 #endif // defined(SSL_TXT_TLSV1_2)
|
Chris@16
|
153 default:
|
Chris@16
|
154 handle_ = ::SSL_CTX_new(0);
|
Chris@16
|
155 break;
|
Chris@16
|
156 }
|
Chris@16
|
157
|
Chris@16
|
158 if (handle_ == 0)
|
Chris@16
|
159 {
|
Chris@16
|
160 boost::system::error_code ec(
|
Chris@16
|
161 static_cast<int>(::ERR_get_error()),
|
Chris@16
|
162 boost::asio::error::get_ssl_category());
|
Chris@16
|
163 boost::asio::detail::throw_error(ec, "context");
|
Chris@16
|
164 }
|
Chris@16
|
165
|
Chris@16
|
166 set_options(no_compression);
|
Chris@16
|
167 }
|
Chris@16
|
168
|
Chris@16
|
169 context::context(boost::asio::io_service&, context::method m)
|
Chris@16
|
170 : handle_(0)
|
Chris@16
|
171 {
|
Chris@16
|
172 context tmp(m);
|
Chris@16
|
173 handle_ = tmp.handle_;
|
Chris@16
|
174 tmp.handle_ = 0;
|
Chris@16
|
175 }
|
Chris@16
|
176
|
Chris@16
|
177 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
Chris@16
|
178 context::context(context&& other)
|
Chris@16
|
179 {
|
Chris@16
|
180 handle_ = other.handle_;
|
Chris@16
|
181 other.handle_ = 0;
|
Chris@16
|
182 }
|
Chris@16
|
183
|
Chris@16
|
184 context& context::operator=(context&& other)
|
Chris@16
|
185 {
|
Chris@16
|
186 context tmp(BOOST_ASIO_MOVE_CAST(context)(*this));
|
Chris@16
|
187 handle_ = other.handle_;
|
Chris@16
|
188 other.handle_ = 0;
|
Chris@16
|
189 return *this;
|
Chris@16
|
190 }
|
Chris@16
|
191 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
Chris@16
|
192
|
Chris@16
|
193 context::~context()
|
Chris@16
|
194 {
|
Chris@16
|
195 if (handle_)
|
Chris@16
|
196 {
|
Chris@16
|
197 if (handle_->default_passwd_callback_userdata)
|
Chris@16
|
198 {
|
Chris@16
|
199 detail::password_callback_base* callback =
|
Chris@16
|
200 static_cast<detail::password_callback_base*>(
|
Chris@16
|
201 handle_->default_passwd_callback_userdata);
|
Chris@16
|
202 delete callback;
|
Chris@16
|
203 handle_->default_passwd_callback_userdata = 0;
|
Chris@16
|
204 }
|
Chris@16
|
205
|
Chris@16
|
206 if (SSL_CTX_get_app_data(handle_))
|
Chris@16
|
207 {
|
Chris@16
|
208 detail::verify_callback_base* callback =
|
Chris@16
|
209 static_cast<detail::verify_callback_base*>(
|
Chris@16
|
210 SSL_CTX_get_app_data(handle_));
|
Chris@16
|
211 delete callback;
|
Chris@16
|
212 SSL_CTX_set_app_data(handle_, 0);
|
Chris@16
|
213 }
|
Chris@16
|
214
|
Chris@16
|
215 ::SSL_CTX_free(handle_);
|
Chris@16
|
216 }
|
Chris@16
|
217 }
|
Chris@16
|
218
|
Chris@16
|
219 context::native_handle_type context::native_handle()
|
Chris@16
|
220 {
|
Chris@16
|
221 return handle_;
|
Chris@16
|
222 }
|
Chris@16
|
223
|
Chris@16
|
224 context::impl_type context::impl()
|
Chris@16
|
225 {
|
Chris@16
|
226 return handle_;
|
Chris@16
|
227 }
|
Chris@16
|
228
|
Chris@16
|
229 void context::clear_options(context::options o)
|
Chris@16
|
230 {
|
Chris@16
|
231 boost::system::error_code ec;
|
Chris@16
|
232 clear_options(o, ec);
|
Chris@16
|
233 boost::asio::detail::throw_error(ec, "clear_options");
|
Chris@16
|
234 }
|
Chris@16
|
235
|
Chris@16
|
236 boost::system::error_code context::clear_options(
|
Chris@16
|
237 context::options o, boost::system::error_code& ec)
|
Chris@16
|
238 {
|
Chris@16
|
239 #if (OPENSSL_VERSION_NUMBER >= 0x009080DFL) \
|
Chris@16
|
240 && (OPENSSL_VERSION_NUMBER != 0x00909000L)
|
Chris@16
|
241 # if !defined(SSL_OP_NO_COMPRESSION)
|
Chris@16
|
242 if ((o & context::no_compression) != 0)
|
Chris@16
|
243 {
|
Chris@16
|
244 # if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
|
Chris@16
|
245 handle_->comp_methods = SSL_COMP_get_compression_methods();
|
Chris@16
|
246 # endif // (OPENSSL_VERSION_NUMBER >= 0x00908000L)
|
Chris@16
|
247 o ^= context::no_compression;
|
Chris@16
|
248 }
|
Chris@16
|
249 # endif // !defined(SSL_OP_NO_COMPRESSION)
|
Chris@16
|
250
|
Chris@16
|
251 ::SSL_CTX_clear_options(handle_, o);
|
Chris@16
|
252
|
Chris@16
|
253 ec = boost::system::error_code();
|
Chris@16
|
254 #else // (OPENSSL_VERSION_NUMBER >= 0x009080DFL)
|
Chris@16
|
255 // && (OPENSSL_VERSION_NUMBER != 0x00909000L)
|
Chris@16
|
256 (void)o;
|
Chris@16
|
257 ec = boost::asio::error::operation_not_supported;
|
Chris@16
|
258 #endif // (OPENSSL_VERSION_NUMBER >= 0x009080DFL)
|
Chris@16
|
259 // && (OPENSSL_VERSION_NUMBER != 0x00909000L)
|
Chris@16
|
260 return ec;
|
Chris@16
|
261 }
|
Chris@16
|
262
|
Chris@16
|
263 void context::set_options(context::options o)
|
Chris@16
|
264 {
|
Chris@16
|
265 boost::system::error_code ec;
|
Chris@16
|
266 set_options(o, ec);
|
Chris@16
|
267 boost::asio::detail::throw_error(ec, "set_options");
|
Chris@16
|
268 }
|
Chris@16
|
269
|
Chris@16
|
270 boost::system::error_code context::set_options(
|
Chris@16
|
271 context::options o, boost::system::error_code& ec)
|
Chris@16
|
272 {
|
Chris@16
|
273 #if !defined(SSL_OP_NO_COMPRESSION)
|
Chris@16
|
274 if ((o & context::no_compression) != 0)
|
Chris@16
|
275 {
|
Chris@16
|
276 #if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
|
Chris@16
|
277 handle_->comp_methods =
|
Chris@16
|
278 boost::asio::ssl::detail::openssl_init<>::get_null_compression_methods();
|
Chris@16
|
279 #endif // (OPENSSL_VERSION_NUMBER >= 0x00908000L)
|
Chris@16
|
280 o ^= context::no_compression;
|
Chris@16
|
281 }
|
Chris@16
|
282 #endif // !defined(SSL_OP_NO_COMPRESSION)
|
Chris@16
|
283
|
Chris@16
|
284 ::SSL_CTX_set_options(handle_, o);
|
Chris@16
|
285
|
Chris@16
|
286 ec = boost::system::error_code();
|
Chris@16
|
287 return ec;
|
Chris@16
|
288 }
|
Chris@16
|
289
|
Chris@16
|
290 void context::set_verify_mode(verify_mode v)
|
Chris@16
|
291 {
|
Chris@16
|
292 boost::system::error_code ec;
|
Chris@16
|
293 set_verify_mode(v, ec);
|
Chris@16
|
294 boost::asio::detail::throw_error(ec, "set_verify_mode");
|
Chris@16
|
295 }
|
Chris@16
|
296
|
Chris@16
|
297 boost::system::error_code context::set_verify_mode(
|
Chris@16
|
298 verify_mode v, boost::system::error_code& ec)
|
Chris@16
|
299 {
|
Chris@16
|
300 ::SSL_CTX_set_verify(handle_, v, ::SSL_CTX_get_verify_callback(handle_));
|
Chris@16
|
301
|
Chris@16
|
302 ec = boost::system::error_code();
|
Chris@16
|
303 return ec;
|
Chris@16
|
304 }
|
Chris@16
|
305
|
Chris@16
|
306 void context::set_verify_depth(int depth)
|
Chris@16
|
307 {
|
Chris@16
|
308 boost::system::error_code ec;
|
Chris@16
|
309 set_verify_depth(depth, ec);
|
Chris@16
|
310 boost::asio::detail::throw_error(ec, "set_verify_depth");
|
Chris@16
|
311 }
|
Chris@16
|
312
|
Chris@16
|
313 boost::system::error_code context::set_verify_depth(
|
Chris@16
|
314 int depth, boost::system::error_code& ec)
|
Chris@16
|
315 {
|
Chris@16
|
316 ::SSL_CTX_set_verify_depth(handle_, depth);
|
Chris@16
|
317
|
Chris@16
|
318 ec = boost::system::error_code();
|
Chris@16
|
319 return ec;
|
Chris@16
|
320 }
|
Chris@16
|
321
|
Chris@16
|
322 void context::load_verify_file(const std::string& filename)
|
Chris@16
|
323 {
|
Chris@16
|
324 boost::system::error_code ec;
|
Chris@16
|
325 load_verify_file(filename, ec);
|
Chris@16
|
326 boost::asio::detail::throw_error(ec, "load_verify_file");
|
Chris@16
|
327 }
|
Chris@16
|
328
|
Chris@16
|
329 boost::system::error_code context::load_verify_file(
|
Chris@16
|
330 const std::string& filename, boost::system::error_code& ec)
|
Chris@16
|
331 {
|
Chris@16
|
332 if (::SSL_CTX_load_verify_locations(handle_, filename.c_str(), 0) != 1)
|
Chris@16
|
333 {
|
Chris@16
|
334 ec = boost::system::error_code(
|
Chris@16
|
335 static_cast<int>(::ERR_get_error()),
|
Chris@16
|
336 boost::asio::error::get_ssl_category());
|
Chris@16
|
337 return ec;
|
Chris@16
|
338 }
|
Chris@16
|
339
|
Chris@16
|
340 ec = boost::system::error_code();
|
Chris@16
|
341 return ec;
|
Chris@16
|
342 }
|
Chris@16
|
343
|
Chris@16
|
344 void context::add_certificate_authority(const const_buffer& ca)
|
Chris@16
|
345 {
|
Chris@16
|
346 boost::system::error_code ec;
|
Chris@16
|
347 add_certificate_authority(ca, ec);
|
Chris@16
|
348 boost::asio::detail::throw_error(ec, "add_certificate_authority");
|
Chris@16
|
349 }
|
Chris@16
|
350
|
Chris@16
|
351 boost::system::error_code context::add_certificate_authority(
|
Chris@16
|
352 const const_buffer& ca, boost::system::error_code& ec)
|
Chris@16
|
353 {
|
Chris@16
|
354 ::ERR_clear_error();
|
Chris@16
|
355
|
Chris@16
|
356 bio_cleanup bio = { make_buffer_bio(ca) };
|
Chris@16
|
357 if (bio.p)
|
Chris@16
|
358 {
|
Chris@16
|
359 x509_cleanup cert = { ::PEM_read_bio_X509(bio.p, 0, 0, 0) };
|
Chris@16
|
360 if (cert.p)
|
Chris@16
|
361 {
|
Chris@16
|
362 if (X509_STORE* store = ::SSL_CTX_get_cert_store(handle_))
|
Chris@16
|
363 {
|
Chris@16
|
364 if (::X509_STORE_add_cert(store, cert.p) == 1)
|
Chris@16
|
365 {
|
Chris@16
|
366 ec = boost::system::error_code();
|
Chris@16
|
367 return ec;
|
Chris@16
|
368 }
|
Chris@16
|
369 }
|
Chris@16
|
370 }
|
Chris@16
|
371 }
|
Chris@16
|
372
|
Chris@16
|
373 ec = boost::system::error_code(
|
Chris@16
|
374 static_cast<int>(::ERR_get_error()),
|
Chris@16
|
375 boost::asio::error::get_ssl_category());
|
Chris@16
|
376 return ec;
|
Chris@16
|
377 }
|
Chris@16
|
378
|
Chris@16
|
379 void context::set_default_verify_paths()
|
Chris@16
|
380 {
|
Chris@16
|
381 boost::system::error_code ec;
|
Chris@16
|
382 set_default_verify_paths(ec);
|
Chris@16
|
383 boost::asio::detail::throw_error(ec, "set_default_verify_paths");
|
Chris@16
|
384 }
|
Chris@16
|
385
|
Chris@16
|
386 boost::system::error_code context::set_default_verify_paths(
|
Chris@16
|
387 boost::system::error_code& ec)
|
Chris@16
|
388 {
|
Chris@16
|
389 if (::SSL_CTX_set_default_verify_paths(handle_) != 1)
|
Chris@16
|
390 {
|
Chris@16
|
391 ec = boost::system::error_code(
|
Chris@16
|
392 static_cast<int>(::ERR_get_error()),
|
Chris@16
|
393 boost::asio::error::get_ssl_category());
|
Chris@16
|
394 return ec;
|
Chris@16
|
395 }
|
Chris@16
|
396
|
Chris@16
|
397 ec = boost::system::error_code();
|
Chris@16
|
398 return ec;
|
Chris@16
|
399 }
|
Chris@16
|
400
|
Chris@16
|
401 void context::add_verify_path(const std::string& path)
|
Chris@16
|
402 {
|
Chris@16
|
403 boost::system::error_code ec;
|
Chris@16
|
404 add_verify_path(path, ec);
|
Chris@16
|
405 boost::asio::detail::throw_error(ec, "add_verify_path");
|
Chris@16
|
406 }
|
Chris@16
|
407
|
Chris@16
|
408 boost::system::error_code context::add_verify_path(
|
Chris@16
|
409 const std::string& path, boost::system::error_code& ec)
|
Chris@16
|
410 {
|
Chris@16
|
411 if (::SSL_CTX_load_verify_locations(handle_, 0, path.c_str()) != 1)
|
Chris@16
|
412 {
|
Chris@16
|
413 ec = boost::system::error_code(
|
Chris@16
|
414 static_cast<int>(::ERR_get_error()),
|
Chris@16
|
415 boost::asio::error::get_ssl_category());
|
Chris@16
|
416 return ec;
|
Chris@16
|
417 }
|
Chris@16
|
418
|
Chris@16
|
419 ec = boost::system::error_code();
|
Chris@16
|
420 return ec;
|
Chris@16
|
421 }
|
Chris@16
|
422
|
Chris@16
|
423 void context::use_certificate(
|
Chris@16
|
424 const const_buffer& certificate, file_format format)
|
Chris@16
|
425 {
|
Chris@16
|
426 boost::system::error_code ec;
|
Chris@16
|
427 use_certificate(certificate, format, ec);
|
Chris@16
|
428 boost::asio::detail::throw_error(ec, "use_certificate");
|
Chris@16
|
429 }
|
Chris@16
|
430
|
Chris@16
|
431 boost::system::error_code context::use_certificate(
|
Chris@16
|
432 const const_buffer& certificate, file_format format,
|
Chris@16
|
433 boost::system::error_code& ec)
|
Chris@16
|
434 {
|
Chris@16
|
435 ::ERR_clear_error();
|
Chris@16
|
436
|
Chris@16
|
437 if (format == context_base::asn1)
|
Chris@16
|
438 {
|
Chris@16
|
439 if (::SSL_CTX_use_certificate_ASN1(handle_,
|
Chris@16
|
440 static_cast<int>(buffer_size(certificate)),
|
Chris@16
|
441 buffer_cast<const unsigned char*>(certificate)) == 1)
|
Chris@16
|
442 {
|
Chris@16
|
443 ec = boost::system::error_code();
|
Chris@16
|
444 return ec;
|
Chris@16
|
445 }
|
Chris@16
|
446 }
|
Chris@16
|
447 else if (format == context_base::pem)
|
Chris@16
|
448 {
|
Chris@16
|
449 bio_cleanup bio = { make_buffer_bio(certificate) };
|
Chris@16
|
450 if (bio.p)
|
Chris@16
|
451 {
|
Chris@16
|
452 x509_cleanup cert = { ::PEM_read_bio_X509(bio.p, 0, 0, 0) };
|
Chris@16
|
453 if (cert.p)
|
Chris@16
|
454 {
|
Chris@16
|
455 if (::SSL_CTX_use_certificate(handle_, cert.p) == 1)
|
Chris@16
|
456 {
|
Chris@16
|
457 ec = boost::system::error_code();
|
Chris@16
|
458 return ec;
|
Chris@16
|
459 }
|
Chris@16
|
460 }
|
Chris@16
|
461 }
|
Chris@16
|
462 }
|
Chris@16
|
463 else
|
Chris@16
|
464 {
|
Chris@16
|
465 ec = boost::asio::error::invalid_argument;
|
Chris@16
|
466 return ec;
|
Chris@16
|
467 }
|
Chris@16
|
468
|
Chris@16
|
469 ec = boost::system::error_code(
|
Chris@16
|
470 static_cast<int>(::ERR_get_error()),
|
Chris@16
|
471 boost::asio::error::get_ssl_category());
|
Chris@16
|
472 return ec;
|
Chris@16
|
473 }
|
Chris@16
|
474
|
Chris@16
|
475 void context::use_certificate_file(
|
Chris@16
|
476 const std::string& filename, file_format format)
|
Chris@16
|
477 {
|
Chris@16
|
478 boost::system::error_code ec;
|
Chris@16
|
479 use_certificate_file(filename, format, ec);
|
Chris@16
|
480 boost::asio::detail::throw_error(ec, "use_certificate_file");
|
Chris@16
|
481 }
|
Chris@16
|
482
|
Chris@16
|
483 boost::system::error_code context::use_certificate_file(
|
Chris@16
|
484 const std::string& filename, file_format format,
|
Chris@16
|
485 boost::system::error_code& ec)
|
Chris@16
|
486 {
|
Chris@16
|
487 int file_type;
|
Chris@16
|
488 switch (format)
|
Chris@16
|
489 {
|
Chris@16
|
490 case context_base::asn1:
|
Chris@16
|
491 file_type = SSL_FILETYPE_ASN1;
|
Chris@16
|
492 break;
|
Chris@16
|
493 case context_base::pem:
|
Chris@16
|
494 file_type = SSL_FILETYPE_PEM;
|
Chris@16
|
495 break;
|
Chris@16
|
496 default:
|
Chris@16
|
497 {
|
Chris@16
|
498 ec = boost::asio::error::invalid_argument;
|
Chris@16
|
499 return ec;
|
Chris@16
|
500 }
|
Chris@16
|
501 }
|
Chris@16
|
502
|
Chris@16
|
503 if (::SSL_CTX_use_certificate_file(handle_, filename.c_str(), file_type) != 1)
|
Chris@16
|
504 {
|
Chris@16
|
505 ec = boost::system::error_code(
|
Chris@16
|
506 static_cast<int>(::ERR_get_error()),
|
Chris@16
|
507 boost::asio::error::get_ssl_category());
|
Chris@16
|
508 return ec;
|
Chris@16
|
509 }
|
Chris@16
|
510
|
Chris@16
|
511 ec = boost::system::error_code();
|
Chris@16
|
512 return ec;
|
Chris@16
|
513 }
|
Chris@16
|
514
|
Chris@16
|
515 void context::use_certificate_chain(const const_buffer& chain)
|
Chris@16
|
516 {
|
Chris@16
|
517 boost::system::error_code ec;
|
Chris@16
|
518 use_certificate_chain(chain, ec);
|
Chris@16
|
519 boost::asio::detail::throw_error(ec, "use_certificate_chain");
|
Chris@16
|
520 }
|
Chris@16
|
521
|
Chris@16
|
522 boost::system::error_code context::use_certificate_chain(
|
Chris@16
|
523 const const_buffer& chain, boost::system::error_code& ec)
|
Chris@16
|
524 {
|
Chris@16
|
525 ::ERR_clear_error();
|
Chris@16
|
526
|
Chris@16
|
527 bio_cleanup bio = { make_buffer_bio(chain) };
|
Chris@16
|
528 if (bio.p)
|
Chris@16
|
529 {
|
Chris@16
|
530 x509_cleanup cert = {
|
Chris@16
|
531 ::PEM_read_bio_X509_AUX(bio.p, 0,
|
Chris@16
|
532 handle_->default_passwd_callback,
|
Chris@16
|
533 handle_->default_passwd_callback_userdata) };
|
Chris@16
|
534 if (!cert.p)
|
Chris@16
|
535 {
|
Chris@16
|
536 ec = boost::system::error_code(ERR_R_PEM_LIB,
|
Chris@16
|
537 boost::asio::error::get_ssl_category());
|
Chris@16
|
538 return ec;
|
Chris@16
|
539 }
|
Chris@16
|
540
|
Chris@16
|
541 int result = ::SSL_CTX_use_certificate(handle_, cert.p);
|
Chris@16
|
542 if (result == 0 || ::ERR_peek_error() != 0)
|
Chris@16
|
543 {
|
Chris@16
|
544 ec = boost::system::error_code(
|
Chris@16
|
545 static_cast<int>(::ERR_get_error()),
|
Chris@16
|
546 boost::asio::error::get_ssl_category());
|
Chris@16
|
547 return ec;
|
Chris@16
|
548 }
|
Chris@16
|
549
|
Chris@16
|
550 if (handle_->extra_certs)
|
Chris@16
|
551 {
|
Chris@16
|
552 ::sk_X509_pop_free(handle_->extra_certs, X509_free);
|
Chris@16
|
553 handle_->extra_certs = 0;
|
Chris@16
|
554 }
|
Chris@16
|
555
|
Chris@16
|
556 while (X509* cacert = ::PEM_read_bio_X509(bio.p, 0,
|
Chris@16
|
557 handle_->default_passwd_callback,
|
Chris@16
|
558 handle_->default_passwd_callback_userdata))
|
Chris@16
|
559 {
|
Chris@16
|
560 if (!::SSL_CTX_add_extra_chain_cert(handle_, cacert))
|
Chris@16
|
561 {
|
Chris@16
|
562 ec = boost::system::error_code(
|
Chris@16
|
563 static_cast<int>(::ERR_get_error()),
|
Chris@16
|
564 boost::asio::error::get_ssl_category());
|
Chris@16
|
565 return ec;
|
Chris@16
|
566 }
|
Chris@16
|
567 }
|
Chris@16
|
568
|
Chris@16
|
569 result = ::ERR_peek_last_error();
|
Chris@16
|
570 if ((ERR_GET_LIB(result) == ERR_LIB_PEM)
|
Chris@16
|
571 && (ERR_GET_REASON(result) == PEM_R_NO_START_LINE))
|
Chris@16
|
572 {
|
Chris@16
|
573 ::ERR_clear_error();
|
Chris@16
|
574 ec = boost::system::error_code();
|
Chris@16
|
575 return ec;
|
Chris@16
|
576 }
|
Chris@16
|
577 }
|
Chris@16
|
578
|
Chris@16
|
579 ec = boost::system::error_code(
|
Chris@16
|
580 static_cast<int>(::ERR_get_error()),
|
Chris@16
|
581 boost::asio::error::get_ssl_category());
|
Chris@16
|
582 return ec;
|
Chris@16
|
583 }
|
Chris@16
|
584
|
Chris@16
|
585 void context::use_certificate_chain_file(const std::string& filename)
|
Chris@16
|
586 {
|
Chris@16
|
587 boost::system::error_code ec;
|
Chris@16
|
588 use_certificate_chain_file(filename, ec);
|
Chris@16
|
589 boost::asio::detail::throw_error(ec, "use_certificate_chain_file");
|
Chris@16
|
590 }
|
Chris@16
|
591
|
Chris@16
|
592 boost::system::error_code context::use_certificate_chain_file(
|
Chris@16
|
593 const std::string& filename, boost::system::error_code& ec)
|
Chris@16
|
594 {
|
Chris@16
|
595 if (::SSL_CTX_use_certificate_chain_file(handle_, filename.c_str()) != 1)
|
Chris@16
|
596 {
|
Chris@16
|
597 ec = boost::system::error_code(
|
Chris@16
|
598 static_cast<int>(::ERR_get_error()),
|
Chris@16
|
599 boost::asio::error::get_ssl_category());
|
Chris@16
|
600 return ec;
|
Chris@16
|
601 }
|
Chris@16
|
602
|
Chris@16
|
603 ec = boost::system::error_code();
|
Chris@16
|
604 return ec;
|
Chris@16
|
605 }
|
Chris@16
|
606
|
Chris@16
|
607 void context::use_private_key(
|
Chris@16
|
608 const const_buffer& private_key, context::file_format format)
|
Chris@16
|
609 {
|
Chris@16
|
610 boost::system::error_code ec;
|
Chris@16
|
611 use_private_key(private_key, format, ec);
|
Chris@16
|
612 boost::asio::detail::throw_error(ec, "use_private_key");
|
Chris@16
|
613 }
|
Chris@16
|
614
|
Chris@16
|
615 boost::system::error_code context::use_private_key(
|
Chris@16
|
616 const const_buffer& private_key, context::file_format format,
|
Chris@16
|
617 boost::system::error_code& ec)
|
Chris@16
|
618 {
|
Chris@16
|
619 ::ERR_clear_error();
|
Chris@16
|
620
|
Chris@16
|
621 bio_cleanup bio = { make_buffer_bio(private_key) };
|
Chris@16
|
622 if (bio.p)
|
Chris@16
|
623 {
|
Chris@16
|
624 evp_pkey_cleanup evp_private_key = { 0 };
|
Chris@16
|
625 switch (format)
|
Chris@16
|
626 {
|
Chris@16
|
627 case context_base::asn1:
|
Chris@16
|
628 evp_private_key.p = ::d2i_PrivateKey_bio(bio.p, 0);
|
Chris@16
|
629 break;
|
Chris@16
|
630 case context_base::pem:
|
Chris@16
|
631 evp_private_key.p = ::PEM_read_bio_PrivateKey(bio.p, 0, 0, 0);
|
Chris@16
|
632 break;
|
Chris@16
|
633 default:
|
Chris@16
|
634 {
|
Chris@16
|
635 ec = boost::asio::error::invalid_argument;
|
Chris@16
|
636 return ec;
|
Chris@16
|
637 }
|
Chris@16
|
638 }
|
Chris@16
|
639
|
Chris@16
|
640 if (evp_private_key.p)
|
Chris@16
|
641 {
|
Chris@16
|
642 if (::SSL_CTX_use_PrivateKey(handle_, evp_private_key.p) == 1)
|
Chris@16
|
643 {
|
Chris@16
|
644 ec = boost::system::error_code();
|
Chris@16
|
645 return ec;
|
Chris@16
|
646 }
|
Chris@16
|
647 }
|
Chris@16
|
648 }
|
Chris@16
|
649
|
Chris@16
|
650 ec = boost::system::error_code(
|
Chris@16
|
651 static_cast<int>(::ERR_get_error()),
|
Chris@16
|
652 boost::asio::error::get_ssl_category());
|
Chris@16
|
653 return ec;
|
Chris@16
|
654 }
|
Chris@16
|
655
|
Chris@16
|
656 void context::use_private_key_file(
|
Chris@16
|
657 const std::string& filename, context::file_format format)
|
Chris@16
|
658 {
|
Chris@16
|
659 boost::system::error_code ec;
|
Chris@16
|
660 use_private_key_file(filename, format, ec);
|
Chris@16
|
661 boost::asio::detail::throw_error(ec, "use_private_key_file");
|
Chris@16
|
662 }
|
Chris@16
|
663
|
Chris@16
|
664 void context::use_rsa_private_key(
|
Chris@16
|
665 const const_buffer& private_key, context::file_format format)
|
Chris@16
|
666 {
|
Chris@16
|
667 boost::system::error_code ec;
|
Chris@16
|
668 use_rsa_private_key(private_key, format, ec);
|
Chris@16
|
669 boost::asio::detail::throw_error(ec, "use_rsa_private_key");
|
Chris@16
|
670 }
|
Chris@16
|
671
|
Chris@16
|
672 boost::system::error_code context::use_rsa_private_key(
|
Chris@16
|
673 const const_buffer& private_key, context::file_format format,
|
Chris@16
|
674 boost::system::error_code& ec)
|
Chris@16
|
675 {
|
Chris@16
|
676 ::ERR_clear_error();
|
Chris@16
|
677
|
Chris@16
|
678 bio_cleanup bio = { make_buffer_bio(private_key) };
|
Chris@16
|
679 if (bio.p)
|
Chris@16
|
680 {
|
Chris@16
|
681 rsa_cleanup rsa_private_key = { 0 };
|
Chris@16
|
682 switch (format)
|
Chris@16
|
683 {
|
Chris@16
|
684 case context_base::asn1:
|
Chris@16
|
685 rsa_private_key.p = ::d2i_RSAPrivateKey_bio(bio.p, 0);
|
Chris@16
|
686 break;
|
Chris@16
|
687 case context_base::pem:
|
Chris@16
|
688 rsa_private_key.p = ::PEM_read_bio_RSAPrivateKey(bio.p, 0, 0, 0);
|
Chris@16
|
689 break;
|
Chris@16
|
690 default:
|
Chris@16
|
691 {
|
Chris@16
|
692 ec = boost::asio::error::invalid_argument;
|
Chris@16
|
693 return ec;
|
Chris@16
|
694 }
|
Chris@16
|
695 }
|
Chris@16
|
696
|
Chris@16
|
697 if (rsa_private_key.p)
|
Chris@16
|
698 {
|
Chris@16
|
699 if (::SSL_CTX_use_RSAPrivateKey(handle_, rsa_private_key.p) == 1)
|
Chris@16
|
700 {
|
Chris@16
|
701 ec = boost::system::error_code();
|
Chris@16
|
702 return ec;
|
Chris@16
|
703 }
|
Chris@16
|
704 }
|
Chris@16
|
705 }
|
Chris@16
|
706
|
Chris@16
|
707 ec = boost::system::error_code(
|
Chris@16
|
708 static_cast<int>(::ERR_get_error()),
|
Chris@16
|
709 boost::asio::error::get_ssl_category());
|
Chris@16
|
710 return ec;
|
Chris@16
|
711 }
|
Chris@16
|
712
|
Chris@16
|
713 boost::system::error_code context::use_private_key_file(
|
Chris@16
|
714 const std::string& filename, context::file_format format,
|
Chris@16
|
715 boost::system::error_code& ec)
|
Chris@16
|
716 {
|
Chris@16
|
717 int file_type;
|
Chris@16
|
718 switch (format)
|
Chris@16
|
719 {
|
Chris@16
|
720 case context_base::asn1:
|
Chris@16
|
721 file_type = SSL_FILETYPE_ASN1;
|
Chris@16
|
722 break;
|
Chris@16
|
723 case context_base::pem:
|
Chris@16
|
724 file_type = SSL_FILETYPE_PEM;
|
Chris@16
|
725 break;
|
Chris@16
|
726 default:
|
Chris@16
|
727 {
|
Chris@16
|
728 ec = boost::asio::error::invalid_argument;
|
Chris@16
|
729 return ec;
|
Chris@16
|
730 }
|
Chris@16
|
731 }
|
Chris@16
|
732
|
Chris@16
|
733 if (::SSL_CTX_use_PrivateKey_file(handle_, filename.c_str(), file_type) != 1)
|
Chris@16
|
734 {
|
Chris@16
|
735 ec = boost::system::error_code(
|
Chris@16
|
736 static_cast<int>(::ERR_get_error()),
|
Chris@16
|
737 boost::asio::error::get_ssl_category());
|
Chris@16
|
738 return ec;
|
Chris@16
|
739 }
|
Chris@16
|
740
|
Chris@16
|
741 ec = boost::system::error_code();
|
Chris@16
|
742 return ec;
|
Chris@16
|
743 }
|
Chris@16
|
744
|
Chris@16
|
745 void context::use_rsa_private_key_file(
|
Chris@16
|
746 const std::string& filename, context::file_format format)
|
Chris@16
|
747 {
|
Chris@16
|
748 boost::system::error_code ec;
|
Chris@16
|
749 use_rsa_private_key_file(filename, format, ec);
|
Chris@16
|
750 boost::asio::detail::throw_error(ec, "use_rsa_private_key_file");
|
Chris@16
|
751 }
|
Chris@16
|
752
|
Chris@16
|
753 boost::system::error_code context::use_rsa_private_key_file(
|
Chris@16
|
754 const std::string& filename, context::file_format format,
|
Chris@16
|
755 boost::system::error_code& ec)
|
Chris@16
|
756 {
|
Chris@16
|
757 int file_type;
|
Chris@16
|
758 switch (format)
|
Chris@16
|
759 {
|
Chris@16
|
760 case context_base::asn1:
|
Chris@16
|
761 file_type = SSL_FILETYPE_ASN1;
|
Chris@16
|
762 break;
|
Chris@16
|
763 case context_base::pem:
|
Chris@16
|
764 file_type = SSL_FILETYPE_PEM;
|
Chris@16
|
765 break;
|
Chris@16
|
766 default:
|
Chris@16
|
767 {
|
Chris@16
|
768 ec = boost::asio::error::invalid_argument;
|
Chris@16
|
769 return ec;
|
Chris@16
|
770 }
|
Chris@16
|
771 }
|
Chris@16
|
772
|
Chris@16
|
773 if (::SSL_CTX_use_RSAPrivateKey_file(
|
Chris@16
|
774 handle_, filename.c_str(), file_type) != 1)
|
Chris@16
|
775 {
|
Chris@16
|
776 ec = boost::system::error_code(
|
Chris@16
|
777 static_cast<int>(::ERR_get_error()),
|
Chris@16
|
778 boost::asio::error::get_ssl_category());
|
Chris@16
|
779 return ec;
|
Chris@16
|
780 }
|
Chris@16
|
781
|
Chris@16
|
782 ec = boost::system::error_code();
|
Chris@16
|
783 return ec;
|
Chris@16
|
784 }
|
Chris@16
|
785
|
Chris@16
|
786 void context::use_tmp_dh(const const_buffer& dh)
|
Chris@16
|
787 {
|
Chris@16
|
788 boost::system::error_code ec;
|
Chris@16
|
789 use_tmp_dh(dh, ec);
|
Chris@16
|
790 boost::asio::detail::throw_error(ec, "use_tmp_dh");
|
Chris@16
|
791 }
|
Chris@16
|
792
|
Chris@16
|
793 boost::system::error_code context::use_tmp_dh(
|
Chris@16
|
794 const const_buffer& dh, boost::system::error_code& ec)
|
Chris@16
|
795 {
|
Chris@16
|
796 bio_cleanup bio = { make_buffer_bio(dh) };
|
Chris@16
|
797 if (bio.p)
|
Chris@16
|
798 {
|
Chris@16
|
799 return do_use_tmp_dh(bio.p, ec);
|
Chris@16
|
800 }
|
Chris@16
|
801
|
Chris@16
|
802 ec = boost::system::error_code(
|
Chris@16
|
803 static_cast<int>(::ERR_get_error()),
|
Chris@16
|
804 boost::asio::error::get_ssl_category());
|
Chris@16
|
805 return ec;
|
Chris@16
|
806 }
|
Chris@16
|
807
|
Chris@16
|
808 void context::use_tmp_dh_file(const std::string& filename)
|
Chris@16
|
809 {
|
Chris@16
|
810 boost::system::error_code ec;
|
Chris@16
|
811 use_tmp_dh_file(filename, ec);
|
Chris@16
|
812 boost::asio::detail::throw_error(ec, "use_tmp_dh_file");
|
Chris@16
|
813 }
|
Chris@16
|
814
|
Chris@16
|
815 boost::system::error_code context::use_tmp_dh_file(
|
Chris@16
|
816 const std::string& filename, boost::system::error_code& ec)
|
Chris@16
|
817 {
|
Chris@16
|
818 bio_cleanup bio = { ::BIO_new_file(filename.c_str(), "r") };
|
Chris@16
|
819 if (bio.p)
|
Chris@16
|
820 {
|
Chris@16
|
821 return do_use_tmp_dh(bio.p, ec);
|
Chris@16
|
822 }
|
Chris@16
|
823
|
Chris@16
|
824 ec = boost::system::error_code(
|
Chris@16
|
825 static_cast<int>(::ERR_get_error()),
|
Chris@16
|
826 boost::asio::error::get_ssl_category());
|
Chris@16
|
827 return ec;
|
Chris@16
|
828 }
|
Chris@16
|
829
|
Chris@16
|
830 boost::system::error_code context::do_use_tmp_dh(
|
Chris@16
|
831 BIO* bio, boost::system::error_code& ec)
|
Chris@16
|
832 {
|
Chris@16
|
833 ::ERR_clear_error();
|
Chris@16
|
834
|
Chris@16
|
835 dh_cleanup dh = { ::PEM_read_bio_DHparams(bio, 0, 0, 0) };
|
Chris@16
|
836 if (dh.p)
|
Chris@16
|
837 {
|
Chris@16
|
838 if (::SSL_CTX_set_tmp_dh(handle_, dh.p) == 1)
|
Chris@16
|
839 {
|
Chris@16
|
840 ec = boost::system::error_code();
|
Chris@16
|
841 return ec;
|
Chris@16
|
842 }
|
Chris@16
|
843 }
|
Chris@16
|
844
|
Chris@16
|
845 ec = boost::system::error_code(
|
Chris@16
|
846 static_cast<int>(::ERR_get_error()),
|
Chris@16
|
847 boost::asio::error::get_ssl_category());
|
Chris@16
|
848 return ec;
|
Chris@16
|
849 }
|
Chris@16
|
850
|
Chris@16
|
851 boost::system::error_code context::do_set_verify_callback(
|
Chris@16
|
852 detail::verify_callback_base* callback, boost::system::error_code& ec)
|
Chris@16
|
853 {
|
Chris@16
|
854 if (SSL_CTX_get_app_data(handle_))
|
Chris@16
|
855 {
|
Chris@16
|
856 delete static_cast<detail::verify_callback_base*>(
|
Chris@16
|
857 SSL_CTX_get_app_data(handle_));
|
Chris@16
|
858 }
|
Chris@16
|
859
|
Chris@16
|
860 SSL_CTX_set_app_data(handle_, callback);
|
Chris@16
|
861
|
Chris@16
|
862 ::SSL_CTX_set_verify(handle_,
|
Chris@16
|
863 ::SSL_CTX_get_verify_mode(handle_),
|
Chris@16
|
864 &context::verify_callback_function);
|
Chris@16
|
865
|
Chris@16
|
866 ec = boost::system::error_code();
|
Chris@16
|
867 return ec;
|
Chris@16
|
868 }
|
Chris@16
|
869
|
Chris@16
|
870 int context::verify_callback_function(int preverified, X509_STORE_CTX* ctx)
|
Chris@16
|
871 {
|
Chris@16
|
872 if (ctx)
|
Chris@16
|
873 {
|
Chris@16
|
874 if (SSL* ssl = static_cast<SSL*>(
|
Chris@16
|
875 ::X509_STORE_CTX_get_ex_data(
|
Chris@16
|
876 ctx, ::SSL_get_ex_data_X509_STORE_CTX_idx())))
|
Chris@16
|
877 {
|
Chris@16
|
878 if (SSL_CTX* handle = ::SSL_get_SSL_CTX(ssl))
|
Chris@16
|
879 {
|
Chris@16
|
880 if (SSL_CTX_get_app_data(handle))
|
Chris@16
|
881 {
|
Chris@16
|
882 detail::verify_callback_base* callback =
|
Chris@16
|
883 static_cast<detail::verify_callback_base*>(
|
Chris@16
|
884 SSL_CTX_get_app_data(handle));
|
Chris@16
|
885
|
Chris@16
|
886 verify_context verify_ctx(ctx);
|
Chris@16
|
887 return callback->call(preverified != 0, verify_ctx) ? 1 : 0;
|
Chris@16
|
888 }
|
Chris@16
|
889 }
|
Chris@16
|
890 }
|
Chris@16
|
891 }
|
Chris@16
|
892
|
Chris@16
|
893 return 0;
|
Chris@16
|
894 }
|
Chris@16
|
895
|
Chris@16
|
896 boost::system::error_code context::do_set_password_callback(
|
Chris@16
|
897 detail::password_callback_base* callback, boost::system::error_code& ec)
|
Chris@16
|
898 {
|
Chris@16
|
899 if (handle_->default_passwd_callback_userdata)
|
Chris@16
|
900 delete static_cast<detail::password_callback_base*>(
|
Chris@16
|
901 handle_->default_passwd_callback_userdata);
|
Chris@16
|
902
|
Chris@16
|
903 handle_->default_passwd_callback_userdata = callback;
|
Chris@16
|
904
|
Chris@16
|
905 SSL_CTX_set_default_passwd_cb(handle_, &context::password_callback_function);
|
Chris@16
|
906
|
Chris@16
|
907 ec = boost::system::error_code();
|
Chris@16
|
908 return ec;
|
Chris@16
|
909 }
|
Chris@16
|
910
|
Chris@16
|
911 int context::password_callback_function(
|
Chris@16
|
912 char* buf, int size, int purpose, void* data)
|
Chris@16
|
913 {
|
Chris@16
|
914 using namespace std; // For strncat and strlen.
|
Chris@16
|
915
|
Chris@16
|
916 if (data)
|
Chris@16
|
917 {
|
Chris@16
|
918 detail::password_callback_base* callback =
|
Chris@16
|
919 static_cast<detail::password_callback_base*>(data);
|
Chris@16
|
920
|
Chris@16
|
921 std::string passwd = callback->call(static_cast<std::size_t>(size),
|
Chris@16
|
922 purpose ? context_base::for_writing : context_base::for_reading);
|
Chris@16
|
923
|
Chris@16
|
924 #if defined(BOOST_ASIO_HAS_SECURE_RTL)
|
Chris@16
|
925 strcpy_s(buf, size, passwd.c_str());
|
Chris@16
|
926 #else // defined(BOOST_ASIO_HAS_SECURE_RTL)
|
Chris@16
|
927 *buf = '\0';
|
Chris@16
|
928 strncat(buf, passwd.c_str(), size);
|
Chris@16
|
929 #endif // defined(BOOST_ASIO_HAS_SECURE_RTL)
|
Chris@16
|
930
|
Chris@16
|
931 return static_cast<int>(strlen(buf));
|
Chris@16
|
932 }
|
Chris@16
|
933
|
Chris@16
|
934 return 0;
|
Chris@16
|
935 }
|
Chris@16
|
936
|
Chris@16
|
937 BIO* context::make_buffer_bio(const const_buffer& b)
|
Chris@16
|
938 {
|
Chris@16
|
939 return ::BIO_new_mem_buf(
|
Chris@16
|
940 const_cast<void*>(buffer_cast<const void*>(b)),
|
Chris@16
|
941 static_cast<int>(buffer_size(b)));
|
Chris@16
|
942 }
|
Chris@16
|
943
|
Chris@16
|
944 #endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
|
Chris@16
|
945
|
Chris@16
|
946 } // namespace ssl
|
Chris@16
|
947 } // namespace asio
|
Chris@16
|
948 } // namespace boost
|
Chris@16
|
949
|
Chris@16
|
950 #include <boost/asio/detail/pop_options.hpp>
|
Chris@16
|
951
|
Chris@16
|
952 #endif // BOOST_ASIO_SSL_IMPL_CONTEXT_IPP
|