]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/asio/include/boost/asio/ssl/old/detail/openssl_context_service.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / asio / include / boost / asio / ssl / old / detail / openssl_context_service.hpp
CommitLineData
7c673cae
FG
1//
2// ssl/old/detail/openssl_context_service.hpp
3// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
6// Copyright (c) 2005-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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_OLD_DETAIL_OPENSSL_CONTEXT_SERVICE_HPP
13#define BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_CONTEXT_SERVICE_HPP
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#include <cstring>
21#include <string>
22#include <boost/function.hpp>
23#include <boost/asio/detail/throw_error.hpp>
24#include <boost/asio/error.hpp>
25#include <boost/asio/io_service.hpp>
26#include <boost/asio/ssl/context_base.hpp>
27#include <boost/asio/ssl/detail/openssl_init.hpp>
28#include <boost/asio/ssl/detail/openssl_types.hpp>
29
30#include <boost/asio/detail/push_options.hpp>
31
32namespace boost {
33namespace asio {
34namespace ssl {
35namespace old {
36namespace detail {
37
38class openssl_context_service
39 : public boost::asio::detail::service_base<openssl_context_service>
40{
41public:
42 // The native type of the context.
43 typedef ::SSL_CTX* impl_type;
44
45 // The type for the password callback function object.
46 typedef boost::function<std::string(std::size_t,
47 context_base::password_purpose)> password_callback_type;
48
49 // Constructor.
50 openssl_context_service(boost::asio::io_service& io_service)
51 : boost::asio::detail::service_base<openssl_context_service>(io_service)
52 {
53 }
54
55 // Destroy all user-defined handler objects owned by the service.
56 void shutdown_service()
57 {
58 }
59
60 // Return a null context implementation.
61 static impl_type null()
62 {
63 return 0;
64 }
65
66 // Create a new context implementation.
67 void create(impl_type& impl, context_base::method m)
68 {
69 switch (m)
70 {
71#if defined(OPENSSL_NO_SSL2)
72 case context_base::sslv2:
73 case context_base::sslv2_client:
74 case context_base::sslv2_server:
75 boost::asio::detail::throw_error(boost::asio::error::invalid_argument);
76 break;
77#else // defined(OPENSSL_NO_SSL2)
78 case context_base::sslv2:
79 impl = ::SSL_CTX_new(::SSLv2_method());
80 break;
81 case context_base::sslv2_client:
82 impl = ::SSL_CTX_new(::SSLv2_client_method());
83 break;
84 case context_base::sslv2_server:
85 impl = ::SSL_CTX_new(::SSLv2_server_method());
86 break;
87#endif // defined(OPENSSL_NO_SSL2)
88#if defined(OPENSSL_NO_SSL3)
89 case context_base::sslv3:
90 case context_base::sslv3_client:
91 case context_base::sslv3_server:
92 boost::asio::detail::throw_error(boost::asio::error::invalid_argument);
93 break;
94#else // defined(OPENSSL_NO_SSL3)
95 case context_base::sslv3:
96 impl = ::SSL_CTX_new(::SSLv3_method());
97 break;
98 case context_base::sslv3_client:
99 impl = ::SSL_CTX_new(::SSLv3_client_method());
100 break;
101 case context_base::sslv3_server:
102 impl = ::SSL_CTX_new(::SSLv3_server_method());
103 break;
104#endif // defined(OPENSSL_NO_SSL3)
105 case context_base::tlsv1:
106 impl = ::SSL_CTX_new(::TLSv1_method());
107 break;
108 case context_base::tlsv1_client:
109 impl = ::SSL_CTX_new(::TLSv1_client_method());
110 break;
111 case context_base::tlsv1_server:
112 impl = ::SSL_CTX_new(::TLSv1_server_method());
113 break;
114 case context_base::sslv23:
115 impl = ::SSL_CTX_new(::SSLv23_method());
116 break;
117 case context_base::sslv23_client:
118 impl = ::SSL_CTX_new(::SSLv23_client_method());
119 break;
120 case context_base::sslv23_server:
121 impl = ::SSL_CTX_new(::SSLv23_server_method());
122 break;
123 default:
124 impl = ::SSL_CTX_new(0);
125 break;
126 }
127 }
128
129 // Destroy a context implementation.
130 void destroy(impl_type& impl)
131 {
132 if (impl != null())
133 {
134 if (impl->default_passwd_callback_userdata)
135 {
136 password_callback_type* callback =
137 static_cast<password_callback_type*>(
138 impl->default_passwd_callback_userdata);
139 delete callback;
140 impl->default_passwd_callback_userdata = 0;
141 }
142
143 ::SSL_CTX_free(impl);
144 impl = null();
145 }
146 }
147
148 // Set options on the context.
149 boost::system::error_code set_options(impl_type& impl,
150 context_base::options o, boost::system::error_code& ec)
151 {
152 ::SSL_CTX_set_options(impl, o);
153
154 ec = boost::system::error_code();
155 return ec;
156 }
157
158 // Set peer verification mode.
159 boost::system::error_code set_verify_mode(impl_type& impl,
160 context_base::verify_mode v, boost::system::error_code& ec)
161 {
162 ::SSL_CTX_set_verify(impl, v, 0);
163
164 ec = boost::system::error_code();
165 return ec;
166 }
167
168 // Load a certification authority file for performing verification.
169 boost::system::error_code load_verify_file(impl_type& impl,
170 const std::string& filename, boost::system::error_code& ec)
171 {
172 if (::SSL_CTX_load_verify_locations(impl, filename.c_str(), 0) != 1)
173 {
174 ec = boost::asio::error::invalid_argument;
175 return ec;
176 }
177
178 ec = boost::system::error_code();
179 return ec;
180 }
181
182 // Add a directory containing certification authority files to be used for
183 // performing verification.
184 boost::system::error_code add_verify_path(impl_type& impl,
185 const std::string& path, boost::system::error_code& ec)
186 {
187 if (::SSL_CTX_load_verify_locations(impl, 0, path.c_str()) != 1)
188 {
189 ec = boost::asio::error::invalid_argument;
190 return ec;
191 }
192
193 ec = boost::system::error_code();
194 return ec;
195 }
196
197 // Use a certificate from a file.
198 boost::system::error_code use_certificate_file(impl_type& impl,
199 const std::string& filename, context_base::file_format format,
200 boost::system::error_code& ec)
201 {
202 int file_type;
203 switch (format)
204 {
205 case context_base::asn1:
206 file_type = SSL_FILETYPE_ASN1;
207 break;
208 case context_base::pem:
209 file_type = SSL_FILETYPE_PEM;
210 break;
211 default:
212 {
213 ec = boost::asio::error::invalid_argument;
214 return ec;
215 }
216 }
217
218 if (::SSL_CTX_use_certificate_file(impl, filename.c_str(), file_type) != 1)
219 {
220 ec = boost::asio::error::invalid_argument;
221 return ec;
222 }
223
224 ec = boost::system::error_code();
225 return ec;
226 }
227
228 // Use a certificate chain from a file.
229 boost::system::error_code use_certificate_chain_file(impl_type& impl,
230 const std::string& filename, boost::system::error_code& ec)
231 {
232 if (::SSL_CTX_use_certificate_chain_file(impl, filename.c_str()) != 1)
233 {
234 ec = boost::asio::error::invalid_argument;
235 return ec;
236 }
237
238 ec = boost::system::error_code();
239 return ec;
240 }
241
242 // Use a private key from a file.
243 boost::system::error_code use_private_key_file(impl_type& impl,
244 const std::string& filename, context_base::file_format format,
245 boost::system::error_code& ec)
246 {
247 int file_type;
248 switch (format)
249 {
250 case context_base::asn1:
251 file_type = SSL_FILETYPE_ASN1;
252 break;
253 case context_base::pem:
254 file_type = SSL_FILETYPE_PEM;
255 break;
256 default:
257 {
258 ec = boost::asio::error::invalid_argument;
259 return ec;
260 }
261 }
262
263 if (::SSL_CTX_use_PrivateKey_file(impl, filename.c_str(), file_type) != 1)
264 {
265 ec = boost::asio::error::invalid_argument;
266 return ec;
267 }
268
269 ec = boost::system::error_code();
270 return ec;
271 }
272
273 // Use an RSA private key from a file.
274 boost::system::error_code use_rsa_private_key_file(impl_type& impl,
275 const std::string& filename, context_base::file_format format,
276 boost::system::error_code& ec)
277 {
278 int file_type;
279 switch (format)
280 {
281 case context_base::asn1:
282 file_type = SSL_FILETYPE_ASN1;
283 break;
284 case context_base::pem:
285 file_type = SSL_FILETYPE_PEM;
286 break;
287 default:
288 {
289 ec = boost::asio::error::invalid_argument;
290 return ec;
291 }
292 }
293
294 if (::SSL_CTX_use_RSAPrivateKey_file(
295 impl, filename.c_str(), file_type) != 1)
296 {
297 ec = boost::asio::error::invalid_argument;
298 return ec;
299 }
300
301 ec = boost::system::error_code();
302 return ec;
303 }
304
305 // Use the specified file to obtain the temporary Diffie-Hellman parameters.
306 boost::system::error_code use_tmp_dh_file(impl_type& impl,
307 const std::string& filename, boost::system::error_code& ec)
308 {
309 ::BIO* bio = ::BIO_new_file(filename.c_str(), "r");
310 if (!bio)
311 {
312 ec = boost::asio::error::invalid_argument;
313 return ec;
314 }
315
316 ::DH* dh = ::PEM_read_bio_DHparams(bio, 0, 0, 0);
317 if (!dh)
318 {
319 ::BIO_free(bio);
320 ec = boost::asio::error::invalid_argument;
321 return ec;
322 }
323
324 ::BIO_free(bio);
325 int result = ::SSL_CTX_set_tmp_dh(impl, dh);
326 ::DH_free(dh);
327 if (result != 1)
328 {
329 ec = boost::asio::error::invalid_argument;
330 return ec;
331 }
332
333 ec = boost::system::error_code();
334 return ec;
335 }
336
337 static int password_callback(char* buf, int size, int purpose, void* data)
338 {
339 using namespace std; // For strncat and strlen.
340
341 if (data)
342 {
343 password_callback_type* callback =
344 static_cast<password_callback_type*>(data);
345 std::string passwd = (*callback)(static_cast<std::size_t>(size),
346 purpose ? context_base::for_writing : context_base::for_reading);
347 *buf = '\0';
348 strncat(buf, passwd.c_str(), size);
349 return strlen(buf);
350 }
351
352 return 0;
353 }
354
355 // Set the password callback.
356 template <typename Password_Callback>
357 boost::system::error_code set_password_callback(impl_type& impl,
358 Password_Callback callback, boost::system::error_code& ec)
359 {
360 // Allocate callback function object if not already present.
361 if (impl->default_passwd_callback_userdata)
362 {
363 password_callback_type* callback_function =
364 static_cast<password_callback_type*>(
365 impl->default_passwd_callback_userdata);
366 *callback_function = callback;
367 }
368 else
369 {
370 password_callback_type* callback_function =
371 new password_callback_type(callback);
372 impl->default_passwd_callback_userdata = callback_function;
373 }
374
375 // Set the password callback.
376 SSL_CTX_set_default_passwd_cb(impl,
377 &openssl_context_service::password_callback);
378
379 ec = boost::system::error_code();
380 return ec;
381 }
382
383private:
384 // Ensure openssl is initialised.
385 boost::asio::ssl::detail::openssl_init<> init_;
386};
387
388} // namespace detail
389} // namespace old
390} // namespace ssl
391} // namespace asio
392} // namespace boost
393
394#include <boost/asio/detail/pop_options.hpp>
395
396#endif // BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_CONTEXT_SERVICE_HPP