Added boost header

This commit is contained in:
Christophe Riccio
2012-01-08 01:26:07 +00:00
parent 9c3faaca40
commit c7d752cdf8
8946 changed files with 1732316 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
//
// ssl/basic_context.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_BASIC_CONTEXT_HPP
#define BOOST_ASIO_SSL_BASIC_CONTEXT_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <boost/asio/ssl/old/basic_context.hpp>
#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
using boost::asio::ssl::old::basic_context;
#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_BASIC_CONTEXT_HPP

533
test/external/boost/asio/ssl/context.hpp vendored Normal file
View File

@@ -0,0 +1,533 @@
//
// ssl/context.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_CONTEXT_HPP
#define BOOST_ASIO_SSL_CONTEXT_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <boost/asio/ssl/basic_context.hpp>
# include <boost/asio/ssl/context_service.hpp>
#else // defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <string>
# include <boost/asio/io_service.hpp>
# include <boost/asio/ssl/context_base.hpp>
# include <boost/asio/ssl/detail/openssl_types.hpp>
# include <boost/asio/ssl/detail/openssl_init.hpp>
# include <boost/asio/ssl/detail/password_callback.hpp>
# include <boost/asio/ssl/detail/verify_callback.hpp>
# include <boost/asio/ssl/verify_mode.hpp>
#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
/// Typedef for the typical usage of context.
typedef basic_context<context_service> context;
#else // defined(BOOST_ASIO_ENABLE_OLD_SSL)
class context
: public context_base,
private noncopyable
{
public:
/// The native handle type of the SSL context.
typedef SSL_CTX* native_handle_type;
/// (Deprecated: Use native_handle_type.) The native type of the SSL context.
typedef SSL_CTX* impl_type;
/// Constructor.
BOOST_ASIO_DECL explicit context(method m);
/// Deprecated constructor taking a reference to an io_service object.
BOOST_ASIO_DECL context(boost::asio::io_service&, method m);
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Move-construct a context from another.
/**
* This constructor moves an SSL context from one object to another.
*
* @param other The other context object from which the move will occur.
*
* @note Following the move, the following operations only are valid for the
* moved-from object:
* @li Destruction.
* @li As a target for move-assignment.
*/
BOOST_ASIO_DECL context(context&& other);
/// Move-assign a context from another.
/**
* This assignment operator moves an SSL context from one object to another.
*
* @param other The other context object from which the move will occur.
*
* @note Following the move, the following operations only are valid for the
* moved-from object:
* @li Destruction.
* @li As a target for move-assignment.
*/
BOOST_ASIO_DECL context& operator=(context&& other);
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Destructor.
BOOST_ASIO_DECL ~context();
/// Get the underlying implementation in the native type.
/**
* This function may be used to obtain the underlying implementation of the
* context. This is intended to allow access to context functionality that is
* not otherwise provided.
*/
BOOST_ASIO_DECL native_handle_type native_handle();
/// (Deprecated: Use native_handle().) Get the underlying implementation in
/// the native type.
/**
* This function may be used to obtain the underlying implementation of the
* context. This is intended to allow access to context functionality that is
* not otherwise provided.
*/
BOOST_ASIO_DECL impl_type impl();
/// Set options on the context.
/**
* This function may be used to configure the SSL options used by the context.
*
* @param o A bitmask of options. The available option values are defined in
* the context_base class. The options are bitwise-ored with any existing
* value for the options.
*
* @throws boost::system::system_error Thrown on failure.
*
* @note Calls @c SSL_CTX_set_options.
*/
BOOST_ASIO_DECL void set_options(options o);
/// Set options on the context.
/**
* This function may be used to configure the SSL options used by the context.
*
* @param o A bitmask of options. The available option values are defined in
* the context_base class. The options are bitwise-ored with any existing
* value for the options.
*
* @param ec Set to indicate what error occurred, if any.
*
* @note Calls @c SSL_CTX_set_options.
*/
BOOST_ASIO_DECL boost::system::error_code set_options(options o,
boost::system::error_code& ec);
/// Set the peer verification mode.
/**
* This function may be used to configure the peer verification mode used by
* the context.
*
* @param v A bitmask of peer verification modes. See @ref verify_mode for
* available values.
*
* @throws boost::system::system_error Thrown on failure.
*
* @note Calls @c SSL_CTX_set_verify.
*/
BOOST_ASIO_DECL void set_verify_mode(verify_mode v);
/// Set the peer verification mode.
/**
* This function may be used to configure the peer verification mode used by
* the context.
*
* @param v A bitmask of peer verification modes. See @ref verify_mode for
* available values.
*
* @param ec Set to indicate what error occurred, if any.
*
* @note Calls @c SSL_CTX_set_verify.
*/
BOOST_ASIO_DECL boost::system::error_code set_verify_mode(
verify_mode v, boost::system::error_code& ec);
/// Set the callback used to verify peer certificates.
/**
* This function is used to specify a callback function that will be called
* by the implementation when it needs to verify a peer certificate.
*
* @param callback The function object to be used for verifying a certificate.
* The function signature of the handler must be:
* @code bool verify_callback(
* bool preverified, // True if the certificate passed pre-verification.
* verify_context& ctx // The peer certificate and other context.
* ); @endcode
* The return value of the callback is true if the certificate has passed
* verification, false otherwise.
*
* @throws boost::system::system_error Thrown on failure.
*
* @note Calls @c SSL_CTX_set_verify.
*/
template <typename VerifyCallback>
void set_verify_callback(VerifyCallback callback);
/// Set the callback used to verify peer certificates.
/**
* This function is used to specify a callback function that will be called
* by the implementation when it needs to verify a peer certificate.
*
* @param callback The function object to be used for verifying a certificate.
* The function signature of the handler must be:
* @code bool verify_callback(
* bool preverified, // True if the certificate passed pre-verification.
* verify_context& ctx // The peer certificate and other context.
* ); @endcode
* The return value of the callback is true if the certificate has passed
* verification, false otherwise.
*
* @param ec Set to indicate what error occurred, if any.
*
* @note Calls @c SSL_CTX_set_verify.
*/
template <typename VerifyCallback>
boost::system::error_code set_verify_callback(VerifyCallback callback,
boost::system::error_code& ec);
/// Load a certification authority file for performing verification.
/**
* This function is used to load one or more trusted certification authorities
* from a file.
*
* @param filename The name of a file containing certification authority
* certificates in PEM format.
*
* @throws boost::system::system_error Thrown on failure.
*
* @note Calls @c SSL_CTX_load_verify_locations.
*/
BOOST_ASIO_DECL void load_verify_file(const std::string& filename);
/// Load a certification authority file for performing verification.
/**
* This function is used to load the certificates for one or more trusted
* certification authorities from a file.
*
* @param filename The name of a file containing certification authority
* certificates in PEM format.
*
* @param ec Set to indicate what error occurred, if any.
*
* @note Calls @c SSL_CTX_load_verify_locations.
*/
BOOST_ASIO_DECL boost::system::error_code load_verify_file(
const std::string& filename, boost::system::error_code& ec);
/// Configures the context to use the default directories for finding
/// certification authority certificates.
/**
* This function specifies that the context should use the default,
* system-dependent directories for locating certification authority
* certificates.
*
* @throws boost::system::system_error Thrown on failure.
*
* @note Calls @c SSL_CTX_set_default_verify_paths.
*/
BOOST_ASIO_DECL void set_default_verify_paths();
/// Configures the context to use the default directories for finding
/// certification authority certificates.
/**
* This function specifies that the context should use the default,
* system-dependent directories for locating certification authority
* certificates.
*
* @param ec Set to indicate what error occurred, if any.
*
* @note Calls @c SSL_CTX_set_default_verify_paths.
*/
BOOST_ASIO_DECL boost::system::error_code set_default_verify_paths(
boost::system::error_code& ec);
/// Add a directory containing certificate authority files to be used for
/// performing verification.
/**
* This function is used to specify the name of a directory containing
* certification authority certificates. Each file in the directory must
* contain a single certificate. The files must be named using the subject
* name's hash and an extension of ".0".
*
* @param path The name of a directory containing the certificates.
*
* @throws boost::system::system_error Thrown on failure.
*
* @note Calls @c SSL_CTX_load_verify_locations.
*/
BOOST_ASIO_DECL void add_verify_path(const std::string& path);
/// Add a directory containing certificate authority files to be used for
/// performing verification.
/**
* This function is used to specify the name of a directory containing
* certification authority certificates. Each file in the directory must
* contain a single certificate. The files must be named using the subject
* name's hash and an extension of ".0".
*
* @param path The name of a directory containing the certificates.
*
* @param ec Set to indicate what error occurred, if any.
*
* @note Calls @c SSL_CTX_load_verify_locations.
*/
BOOST_ASIO_DECL boost::system::error_code add_verify_path(
const std::string& path, boost::system::error_code& ec);
/// Use a certificate from a file.
/**
* This function is used to load a certificate into the context from a file.
*
* @param filename The name of the file containing the certificate.
*
* @param format The file format (ASN.1 or PEM).
*
* @throws boost::system::system_error Thrown on failure.
*
* @note Calls @c SSL_CTX_use_certificate_file.
*/
BOOST_ASIO_DECL void use_certificate_file(
const std::string& filename, file_format format);
/// Use a certificate from a file.
/**
* This function is used to load a certificate into the context from a file.
*
* @param filename The name of the file containing the certificate.
*
* @param format The file format (ASN.1 or PEM).
*
* @param ec Set to indicate what error occurred, if any.
*
* @note Calls @c SSL_CTX_use_certificate_file.
*/
BOOST_ASIO_DECL boost::system::error_code use_certificate_file(
const std::string& filename, file_format format,
boost::system::error_code& ec);
/// Use a certificate chain from a file.
/**
* This function is used to load a certificate chain into the context from a
* file.
*
* @param filename The name of the file containing the certificate. The file
* must use the PEM format.
*
* @throws boost::system::system_error Thrown on failure.
*
* @note Calls @c SSL_CTX_use_certificate_chain_file.
*/
BOOST_ASIO_DECL void use_certificate_chain_file(const std::string& filename);
/// Use a certificate chain from a file.
/**
* This function is used to load a certificate chain into the context from a
* file.
*
* @param filename The name of the file containing the certificate. The file
* must use the PEM format.
*
* @param ec Set to indicate what error occurred, if any.
*
* @note Calls @c SSL_CTX_use_certificate_chain_file.
*/
BOOST_ASIO_DECL boost::system::error_code use_certificate_chain_file(
const std::string& filename, boost::system::error_code& ec);
/// Use a private key from a file.
/**
* This function is used to load a private key into the context from a file.
*
* @param filename The name of the file containing the private key.
*
* @param format The file format (ASN.1 or PEM).
*
* @throws boost::system::system_error Thrown on failure.
*
* @note Calls @c SSL_CTX_use_PrivateKey_file.
*/
BOOST_ASIO_DECL void use_private_key_file(
const std::string& filename, file_format format);
/// Use a private key from a file.
/**
* This function is used to load a private key into the context from a file.
*
* @param filename The name of the file containing the private key.
*
* @param format The file format (ASN.1 or PEM).
*
* @param ec Set to indicate what error occurred, if any.
*
* @note Calls @c SSL_CTX_use_PrivateKey_file.
*/
BOOST_ASIO_DECL boost::system::error_code use_private_key_file(
const std::string& filename, file_format format,
boost::system::error_code& ec);
/// Use an RSA private key from a file.
/**
* This function is used to load an RSA private key into the context from a
* file.
*
* @param filename The name of the file containing the RSA private key.
*
* @param format The file format (ASN.1 or PEM).
*
* @throws boost::system::system_error Thrown on failure.
*
* @note Calls @c SSL_CTX_use_RSAPrivateKey_file.
*/
BOOST_ASIO_DECL void use_rsa_private_key_file(
const std::string& filename, file_format format);
/// Use an RSA private key from a file.
/**
* This function is used to load an RSA private key into the context from a
* file.
*
* @param filename The name of the file containing the RSA private key.
*
* @param format The file format (ASN.1 or PEM).
*
* @param ec Set to indicate what error occurred, if any.
*
* @note Calls @c SSL_CTX_use_RSAPrivateKey_file.
*/
BOOST_ASIO_DECL boost::system::error_code use_rsa_private_key_file(
const std::string& filename, file_format format,
boost::system::error_code& ec);
/// Use the specified file to obtain the temporary Diffie-Hellman parameters.
/**
* This function is used to load Diffie-Hellman parameters into the context
* from a file.
*
* @param filename The name of the file containing the Diffie-Hellman
* parameters. The file must use the PEM format.
*
* @throws boost::system::system_error Thrown on failure.
*
* @note Calls @c SSL_CTX_set_tmp_dh.
*/
BOOST_ASIO_DECL void use_tmp_dh_file(const std::string& filename);
/// Use the specified file to obtain the temporary Diffie-Hellman parameters.
/**
* This function is used to load Diffie-Hellman parameters into the context
* from a file.
*
* @param filename The name of the file containing the Diffie-Hellman
* parameters. The file must use the PEM format.
*
* @param ec Set to indicate what error occurred, if any.
*
* @note Calls @c SSL_CTX_set_tmp_dh.
*/
BOOST_ASIO_DECL boost::system::error_code use_tmp_dh_file(
const std::string& filename, boost::system::error_code& ec);
/// Set the password callback.
/**
* This function is used to specify a callback function to obtain password
* information about an encrypted key in PEM format.
*
* @param callback The function object to be used for obtaining the password.
* The function signature of the handler must be:
* @code std::string password_callback(
* std::size_t max_length, // The maximum size for a password.
* password_purpose purpose // Whether password is for reading or writing.
* ); @endcode
* The return value of the callback is a string containing the password.
*
* @throws boost::system::system_error Thrown on failure.
*
* @note Calls @c SSL_CTX_set_default_passwd_cb.
*/
template <typename PasswordCallback>
void set_password_callback(PasswordCallback callback);
/// Set the password callback.
/**
* This function is used to specify a callback function to obtain password
* information about an encrypted key in PEM format.
*
* @param callback The function object to be used for obtaining the password.
* The function signature of the handler must be:
* @code std::string password_callback(
* std::size_t max_length, // The maximum size for a password.
* password_purpose purpose // Whether password is for reading or writing.
* ); @endcode
* The return value of the callback is a string containing the password.
*
* @param ec Set to indicate what error occurred, if any.
*
* @note Calls @c SSL_CTX_set_default_passwd_cb.
*/
template <typename PasswordCallback>
boost::system::error_code set_password_callback(PasswordCallback callback,
boost::system::error_code& ec);
private:
// Helper function used to set a peer certificate verification callback.
BOOST_ASIO_DECL boost::system::error_code do_set_verify_callback(
detail::verify_callback_base* callback, boost::system::error_code& ec);
// Callback used when the SSL implementation wants to verify a certificate.
BOOST_ASIO_DECL static int verify_callback_function(
int preverified, X509_STORE_CTX* ctx);
// Helper function used to set a password callback.
BOOST_ASIO_DECL boost::system::error_code do_set_password_callback(
detail::password_callback_base* callback, boost::system::error_code& ec);
// Callback used when the SSL implementation wants a password.
BOOST_ASIO_DECL static int password_callback_function(
char* buf, int size, int purpose, void* data);
// The underlying native implementation.
native_handle_type handle_;
// Ensure openssl is initialised.
boost::asio::ssl::detail::openssl_init<> init_;
};
#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#include <boost/asio/ssl/impl/context.hpp>
#if defined(BOOST_ASIO_HEADER_ONLY)
# include <boost/asio/ssl/impl/context.ipp>
#endif // defined(BOOST_ASIO_HEADER_ONLY)
#endif // BOOST_ASIO_SSL_CONTEXT_HPP

View File

@@ -0,0 +1,150 @@
//
// ssl/context_base.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_CONTEXT_BASE_HPP
#define BOOST_ASIO_SSL_CONTEXT_BASE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/asio/ssl/detail/openssl_types.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
/// The context_base class is used as a base for the basic_context class
/// template so that we have a common place to define various enums.
class context_base
{
public:
/// Different methods supported by a context.
enum method
{
/// Generic SSL version 2.
sslv2,
/// SSL version 2 client.
sslv2_client,
/// SSL version 2 server.
sslv2_server,
/// Generic SSL version 3.
sslv3,
/// SSL version 3 client.
sslv3_client,
/// SSL version 3 server.
sslv3_server,
/// Generic TLS version 1.
tlsv1,
/// TLS version 1 client.
tlsv1_client,
/// TLS version 1 server.
tlsv1_server,
/// Generic SSL/TLS.
sslv23,
/// SSL/TLS client.
sslv23_client,
/// SSL/TLS server.
sslv23_server
};
/// Bitmask type for SSL options.
typedef int options;
#if defined(GENERATING_DOCUMENTATION)
/// Implement various bug workarounds.
static const int default_workarounds = implementation_defined;
/// Always create a new key when using tmp_dh parameters.
static const int single_dh_use = implementation_defined;
/// Disable SSL v2.
static const int no_sslv2 = implementation_defined;
/// Disable SSL v3.
static const int no_sslv3 = implementation_defined;
/// Disable TLS v1.
static const int no_tlsv1 = implementation_defined;
#else
BOOST_STATIC_CONSTANT(int, default_workarounds = SSL_OP_ALL);
BOOST_STATIC_CONSTANT(int, single_dh_use = SSL_OP_SINGLE_DH_USE);
BOOST_STATIC_CONSTANT(int, no_sslv2 = SSL_OP_NO_SSLv2);
BOOST_STATIC_CONSTANT(int, no_sslv3 = SSL_OP_NO_SSLv3);
BOOST_STATIC_CONSTANT(int, no_tlsv1 = SSL_OP_NO_TLSv1);
#endif
/// File format types.
enum file_format
{
/// ASN.1 file.
asn1,
/// PEM file.
pem
};
#if !defined(GENERATING_DOCUMENTATION)
// The following types and constants are preserved for backward compatibility.
// New programs should use the equivalents of the same names that are defined
// in the boost::asio::ssl namespace.
typedef int verify_mode;
BOOST_STATIC_CONSTANT(int, verify_none = SSL_VERIFY_NONE);
BOOST_STATIC_CONSTANT(int, verify_peer = SSL_VERIFY_PEER);
BOOST_STATIC_CONSTANT(int,
verify_fail_if_no_peer_cert = SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
BOOST_STATIC_CONSTANT(int, verify_client_once = SSL_VERIFY_CLIENT_ONCE);
#endif
/// Purpose of PEM password.
enum password_purpose
{
/// The password is needed for reading/decryption.
for_reading,
/// The password is needed for writing/encryption.
for_writing
};
protected:
/// Protected destructor to prevent deletion through this type.
~context_base()
{
}
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
private:
// Workaround to enable the empty base optimisation with Borland C++.
char dummy_;
#endif
};
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_CONTEXT_BASE_HPP

View File

@@ -0,0 +1,42 @@
//
// ssl/context_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_CONTEXT_SERVICE_HPP
#define BOOST_ASIO_SSL_CONTEXT_SERVICE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <boost/asio/ssl/old/context_service.hpp>
#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
using boost::asio::ssl::old::context_service;
#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_CONTEXT_SERVICE_HPP

View File

@@ -0,0 +1,162 @@
//
// ssl/detail/engine.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_DETAIL_ENGINE_HPP
#define BOOST_ASIO_SSL_DETAIL_ENGINE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <boost/asio/buffer.hpp>
# include <boost/asio/detail/static_mutex.hpp>
# include <boost/asio/ssl/detail/openssl_types.hpp>
# include <boost/asio/ssl/detail/verify_callback.hpp>
# include <boost/asio/ssl/stream_base.hpp>
# include <boost/asio/ssl/verify_mode.hpp>
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
namespace detail {
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
class engine
{
public:
enum want
{
// Returned by functions to indicate that the engine wants input. The input
// buffer should be updated to point to the data. The engine then needs to
// be called again to retry the operation.
want_input_and_retry = -2,
// Returned by functions to indicate that the engine wants to write output.
// The output buffer points to the data to be written. The engine then
// needs to be called again to retry the operation.
want_output_and_retry = -1,
// Returned by functions to indicate that the engine doesn't need input or
// output.
want_nothing = 0,
// Returned by functions to indicate that the engine wants to write output.
// The output buffer points to the data to be written. After that the
// operation is complete, and the engine does not need to be called again.
want_output = 1
};
// Construct a new engine for the specified context.
BOOST_ASIO_DECL explicit engine(SSL_CTX* context);
// Destructor.
BOOST_ASIO_DECL ~engine();
// Get the underlying implementation in the native type.
BOOST_ASIO_DECL SSL* native_handle();
// Set the peer verification mode.
BOOST_ASIO_DECL boost::system::error_code set_verify_mode(
verify_mode v, boost::system::error_code& ec);
// Set a peer certificate verification callback.
BOOST_ASIO_DECL boost::system::error_code set_verify_callback(
verify_callback_base* callback, boost::system::error_code& ec);
// Perform an SSL handshake using either SSL_connect (client-side) or
// SSL_accept (server-side).
BOOST_ASIO_DECL want handshake(
stream_base::handshake_type type, boost::system::error_code& ec);
// Perform a graceful shutdown of the SSL session.
BOOST_ASIO_DECL want shutdown(boost::system::error_code& ec);
// Write bytes to the SSL session.
BOOST_ASIO_DECL want write(const boost::asio::const_buffer& data,
boost::system::error_code& ec, std::size_t& bytes_transferred);
// Read bytes from the SSL session.
BOOST_ASIO_DECL want read(const boost::asio::mutable_buffer& data,
boost::system::error_code& ec, std::size_t& bytes_transferred);
// Get output data to be written to the transport.
BOOST_ASIO_DECL boost::asio::mutable_buffers_1 get_output(
const boost::asio::mutable_buffer& data);
// Put input data that was read from the transport.
BOOST_ASIO_DECL boost::asio::const_buffer put_input(
const boost::asio::const_buffer& data);
// Map an error::eof code returned by the underlying transport according to
// the type and state of the SSL session. Returns a const reference to the
// error code object, suitable for passing to a completion handler.
BOOST_ASIO_DECL const boost::system::error_code& map_error_code(
boost::system::error_code& ec) const;
private:
// Disallow copying and assignment.
engine(const engine&);
engine& operator=(const engine&);
// Callback used when the SSL implementation wants to verify a certificate.
BOOST_ASIO_DECL static int verify_callback_function(
int preverified, X509_STORE_CTX* ctx);
// The SSL_accept function may not be thread safe. This mutex is used to
// protect all calls to the SSL_accept function.
BOOST_ASIO_DECL static boost::asio::detail::static_mutex& accept_mutex();
// Perform one operation. Returns >= 0 on success or error, want_read if the
// operation needs more input, or want_write if it needs to write some output
// before the operation can complete.
BOOST_ASIO_DECL want perform(int (engine::* op)(void*, std::size_t),
void* data, std::size_t length, boost::system::error_code& ec,
std::size_t* bytes_transferred);
// Adapt the SSL_accept function to the signature needed for perform().
BOOST_ASIO_DECL int do_accept(void*, std::size_t);
// Adapt the SSL_connect function to the signature needed for perform().
BOOST_ASIO_DECL int do_connect(void*, std::size_t);
// Adapt the SSL_shutdown function to the signature needed for perform().
BOOST_ASIO_DECL int do_shutdown(void*, std::size_t);
// Adapt the SSL_read function to the signature needed for perform().
BOOST_ASIO_DECL int do_read(void* data, std::size_t length);
// Adapt the SSL_write function to the signature needed for perform().
BOOST_ASIO_DECL int do_write(void* data, std::size_t length);
SSL* ssl_;
BIO* ext_bio_;
};
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace detail
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#if defined(BOOST_ASIO_HEADER_ONLY)
# include <boost/asio/ssl/detail/impl/engine.ipp>
#endif // defined(BOOST_ASIO_HEADER_ONLY)
#endif // BOOST_ASIO_SSL_DETAIL_ENGINE_HPP

View File

@@ -0,0 +1,70 @@
//
// ssl/detail/handshake_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_DETAIL_HANDSHAKE_OP_HPP
#define BOOST_ASIO_SSL_DETAIL_HANDSHAKE_OP_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <boost/asio/ssl/detail/engine.hpp>
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
namespace detail {
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
class handshake_op
{
public:
handshake_op(stream_base::handshake_type type)
: type_(type)
{
}
engine::want operator()(engine& eng,
boost::system::error_code& ec,
std::size_t& bytes_transferred) const
{
bytes_transferred = 0;
return eng.handshake(type_, ec);
}
template <typename Handler>
void call_handler(Handler& handler,
const boost::system::error_code& ec,
const std::size_t&) const
{
handler(ec);
}
private:
stream_base::handshake_type type_;
};
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace detail
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_DETAIL_HANDSHAKE_OP_HPP

View File

@@ -0,0 +1,306 @@
//
// ssl/detail/impl/engine.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_DETAIL_IMPL_ENGINE_IPP
#define BOOST_ASIO_SSL_DETAIL_IMPL_ENGINE_IPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <boost/asio/ssl/detail/engine.hpp>
# include <boost/asio/ssl/verify_context.hpp>
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
namespace detail {
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
engine::engine(SSL_CTX* context)
: ssl_(::SSL_new(context))
{
accept_mutex().init();
::SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE);
::SSL_set_mode(ssl_, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
#if defined(SSL_MODE_RELEASE_BUFFERS)
::SSL_set_mode(ssl_, SSL_MODE_RELEASE_BUFFERS);
#endif // defined(SSL_MODE_RELEASE_BUFFERS)
::BIO* int_bio = 0;
::BIO_new_bio_pair(&int_bio, 0, &ext_bio_, 0);
::SSL_set_bio(ssl_, int_bio, int_bio);
}
engine::~engine()
{
if (SSL_get_app_data(ssl_))
{
delete static_cast<verify_callback_base*>(SSL_get_app_data(ssl_));
SSL_set_app_data(ssl_, 0);
}
::BIO_free(ext_bio_);
::SSL_free(ssl_);
}
SSL* engine::native_handle()
{
return ssl_;
}
boost::system::error_code engine::set_verify_mode(
verify_mode v, boost::system::error_code& ec)
{
::SSL_set_verify(ssl_, v, ::SSL_get_verify_callback(ssl_));
ec = boost::system::error_code();
return ec;
}
boost::system::error_code engine::set_verify_callback(
verify_callback_base* callback, boost::system::error_code& ec)
{
if (SSL_get_app_data(ssl_))
delete static_cast<verify_callback_base*>(SSL_get_app_data(ssl_));
SSL_set_app_data(ssl_, callback);
::SSL_set_verify(ssl_, ::SSL_get_verify_mode(ssl_),
&engine::verify_callback_function);
ec = boost::system::error_code();
return ec;
}
int engine::verify_callback_function(int preverified, X509_STORE_CTX* ctx)
{
if (ctx)
{
if (SSL* ssl = static_cast<SSL*>(
::X509_STORE_CTX_get_ex_data(
ctx, ::SSL_get_ex_data_X509_STORE_CTX_idx())))
{
if (SSL_get_app_data(ssl))
{
verify_callback_base* callback =
static_cast<verify_callback_base*>(
SSL_get_app_data(ssl));
verify_context verify_ctx(ctx);
return callback->call(preverified != 0, verify_ctx) ? 1 : 0;
}
}
}
return 0;
}
engine::want engine::handshake(
stream_base::handshake_type type, boost::system::error_code& ec)
{
return perform((type == boost::asio::ssl::stream_base::client)
? &engine::do_connect : &engine::do_accept, 0, 0, ec, 0);
}
engine::want engine::shutdown(boost::system::error_code& ec)
{
return perform(&engine::do_shutdown, 0, 0, ec, 0);
}
engine::want engine::write(const boost::asio::const_buffer& data,
boost::system::error_code& ec, std::size_t& bytes_transferred)
{
if (boost::asio::buffer_size(data) == 0)
{
ec = boost::system::error_code();
return engine::want_nothing;
}
return perform(&engine::do_write,
const_cast<void*>(boost::asio::buffer_cast<const void*>(data)),
boost::asio::buffer_size(data), ec, &bytes_transferred);
}
engine::want engine::read(const boost::asio::mutable_buffer& data,
boost::system::error_code& ec, std::size_t& bytes_transferred)
{
if (boost::asio::buffer_size(data) == 0)
{
ec = boost::system::error_code();
return engine::want_nothing;
}
return perform(&engine::do_read,
boost::asio::buffer_cast<void*>(data),
boost::asio::buffer_size(data), ec, &bytes_transferred);
}
boost::asio::mutable_buffers_1 engine::get_output(
const boost::asio::mutable_buffer& data)
{
int length = ::BIO_read(ext_bio_,
boost::asio::buffer_cast<void*>(data),
boost::asio::buffer_size(data));
return boost::asio::buffer(data,
length > 0 ? static_cast<std::size_t>(length) : 0);
}
boost::asio::const_buffer engine::put_input(
const boost::asio::const_buffer& data)
{
int length = ::BIO_write(ext_bio_,
boost::asio::buffer_cast<const void*>(data),
boost::asio::buffer_size(data));
return boost::asio::buffer(data +
(length > 0 ? static_cast<std::size_t>(length) : 0));
}
const boost::system::error_code& engine::map_error_code(
boost::system::error_code& ec) const
{
// We only want to map the error::eof code.
if (ec != boost::asio::error::eof)
return ec;
// If there's data yet to be read, it's an error.
if (BIO_wpending(ext_bio_))
{
ec = boost::system::error_code(
ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ),
boost::asio::error::get_ssl_category());
return ec;
}
// SSL v2 doesn't provide a protocol-level shutdown, so an eof on the
// underlying transport is passed through.
if (ssl_ && ssl_->version == SSL2_VERSION)
return ec;
// Otherwise, the peer should have negotiated a proper shutdown.
if ((::SSL_get_shutdown(ssl_) & SSL_RECEIVED_SHUTDOWN) == 0)
{
ec = boost::system::error_code(
ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ),
boost::asio::error::get_ssl_category());
}
return ec;
}
boost::asio::detail::static_mutex& engine::accept_mutex()
{
static boost::asio::detail::static_mutex mutex = BOOST_ASIO_STATIC_MUTEX_INIT;
return mutex;
}
engine::want engine::perform(int (engine::* op)(void*, std::size_t),
void* data, std::size_t length, boost::system::error_code& ec,
std::size_t* bytes_transferred)
{
std::size_t pending_output_before = ::BIO_ctrl_pending(ext_bio_);
int result = (this->*op)(data, length);
int ssl_error = ::SSL_get_error(ssl_, result);
int sys_error = ::ERR_get_error();
std::size_t pending_output_after = ::BIO_ctrl_pending(ext_bio_);
if (ssl_error == SSL_ERROR_SSL)
{
ec = boost::system::error_code(sys_error,
boost::asio::error::get_ssl_category());
return want_nothing;
}
if (ssl_error == SSL_ERROR_SYSCALL)
{
ec = boost::system::error_code(sys_error,
boost::asio::error::get_system_category());
return want_nothing;
}
if (result > 0 && bytes_transferred)
*bytes_transferred = static_cast<std::size_t>(result);
if (ssl_error == SSL_ERROR_WANT_WRITE)
{
ec = boost::system::error_code();
return want_output_and_retry;
}
else if (pending_output_after > pending_output_before)
{
ec = boost::system::error_code();
return result > 0 ? want_output : want_output_and_retry;
}
else if (ssl_error == SSL_ERROR_WANT_READ)
{
ec = boost::system::error_code();
return want_input_and_retry;
}
else if (::SSL_get_shutdown(ssl_) & SSL_RECEIVED_SHUTDOWN)
{
ec = boost::asio::error::eof;
return want_nothing;
}
else
{
ec = boost::system::error_code();
return want_nothing;
}
}
int engine::do_accept(void*, std::size_t)
{
boost::asio::detail::static_mutex::scoped_lock lock(accept_mutex());
return ::SSL_accept(ssl_);
}
int engine::do_connect(void*, std::size_t)
{
return ::SSL_connect(ssl_);
}
int engine::do_shutdown(void*, std::size_t)
{
int result = ::SSL_shutdown(ssl_);
if (result == 0)
result = ::SSL_shutdown(ssl_);
return result;
}
int engine::do_read(void* data, std::size_t length)
{
return ::SSL_read(ssl_, data, length < INT_MAX ? length : INT_MAX);
}
int engine::do_write(void* data, std::size_t length)
{
return ::SSL_write(ssl_, data, length < INT_MAX ? length : INT_MAX);
}
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace detail
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_DETAIL_IMPL_ENGINE_IPP

View File

@@ -0,0 +1,109 @@
//
// ssl/detail/impl/openssl_init.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
// Copyright (c) 2005-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP
#define BOOST_ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <vector>
#include <boost/assert.hpp>
#include <boost/asio/detail/mutex.hpp>
#include <boost/asio/detail/tss_ptr.hpp>
#include <boost/asio/ssl/detail/openssl_init.hpp>
#include <boost/asio/ssl/detail/openssl_types.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
namespace detail {
class openssl_init_base::do_init
{
public:
do_init()
{
::SSL_library_init();
::SSL_load_error_strings();
::OpenSSL_add_all_algorithms();
mutexes_.resize(::CRYPTO_num_locks());
for (size_t i = 0; i < mutexes_.size(); ++i)
mutexes_[i].reset(new boost::asio::detail::mutex);
::CRYPTO_set_locking_callback(&do_init::openssl_locking_func);
::CRYPTO_set_id_callback(&do_init::openssl_id_func);
}
~do_init()
{
::CRYPTO_set_id_callback(0);
::CRYPTO_set_locking_callback(0);
::ERR_free_strings();
::ERR_remove_state(0);
::EVP_cleanup();
::CRYPTO_cleanup_all_ex_data();
::CONF_modules_unload(1);
::ENGINE_cleanup();
}
private:
static unsigned long openssl_id_func()
{
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
return ::GetCurrentThreadId();
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
void* id = instance()->thread_id_;
if (id == 0)
instance()->thread_id_ = id = &id; // Ugh.
BOOST_ASSERT(sizeof(unsigned long) >= sizeof(void*));
return reinterpret_cast<unsigned long>(id);
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
}
static void openssl_locking_func(int mode, int n,
const char* /*file*/, int /*line*/)
{
if (mode & CRYPTO_LOCK)
instance()->mutexes_[n]->lock();
else
instance()->mutexes_[n]->unlock();
}
// Mutexes to be used in locking callbacks.
std::vector<boost::asio::detail::shared_ptr<
boost::asio::detail::mutex> > mutexes_;
#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
// The thread identifiers to be used by openssl.
boost::asio::detail::tss_ptr<void> thread_id_;
#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
};
boost::asio::detail::shared_ptr<openssl_init_base::do_init>
openssl_init_base::instance()
{
static boost::asio::detail::shared_ptr<do_init> init(new do_init);
return init;
}
} // namespace detail
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP

View File

@@ -0,0 +1,336 @@
//
// ssl/detail/io.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_DETAIL_IO_HPP
#define BOOST_ASIO_SSL_DETAIL_IO_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <boost/asio/ssl/detail/engine.hpp>
# include <boost/asio/ssl/detail/stream_core.hpp>
# include <boost/asio/write.hpp>
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
namespace detail {
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
template <typename Stream, typename Operation>
std::size_t io(Stream& next_layer, stream_core& core,
const Operation& op, boost::system::error_code& ec)
{
std::size_t bytes_transferred = 0;
do switch (op(core.engine_, ec, bytes_transferred))
{
case engine::want_input_and_retry:
// If the input buffer is empty then we need to read some more data from
// the underlying transport.
if (boost::asio::buffer_size(core.input_) == 0)
core.input_ = boost::asio::buffer(core.input_buffer_,
next_layer.read_some(core.input_buffer_, ec));
// Pass the new input data to the engine.
core.input_ = core.engine_.put_input(core.input_);
// Try the operation again.
continue;
case engine::want_output_and_retry:
// Get output data from the engine and write it to the underlying
// transport.
boost::asio::write(next_layer,
core.engine_.get_output(core.output_buffer_), ec);
// Try the operation again.
continue;
case engine::want_output:
// Get output data from the engine and write it to the underlying
// transport.
boost::asio::write(next_layer,
core.engine_.get_output(core.output_buffer_), ec);
// Operation is complete. Return result to caller.
core.engine_.map_error_code(ec);
return bytes_transferred;
default:
// Operation is complete. Return result to caller.
core.engine_.map_error_code(ec);
return bytes_transferred;
} while (!ec);
// Operation failed. Return result to caller.
core.engine_.map_error_code(ec);
return 0;
}
template <typename Stream, typename Operation, typename Handler>
class io_op
{
public:
io_op(Stream& next_layer, stream_core& core,
const Operation& op, Handler& handler)
: next_layer_(next_layer),
core_(core),
op_(op),
bytes_transferred_(0),
handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
io_op(const io_op& other)
: next_layer_(other.next_layer_),
core_(other.core_),
op_(other.op_),
want_(other.want_),
ec_(other.ec_),
bytes_transferred_(other.bytes_transferred_),
handler_(other.handler_)
{
}
io_op(io_op&& other)
: next_layer_(other.next_layer_),
core_(other.core_),
op_(other.op_),
want_(other.want_),
ec_(other.ec_),
bytes_transferred_(other.bytes_transferred_),
handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_))
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
void operator()(boost::system::error_code ec,
std::size_t bytes_transferred = ~std::size_t(0), int start = 0)
{
switch (start)
{
case 1: // Called after at least one async operation.
do
{
switch (want_ = op_(core_.engine_, ec_, bytes_transferred_))
{
case engine::want_input_and_retry:
// If the input buffer already has data in it we can pass it to the
// engine and then retry the operation immediately.
if (boost::asio::buffer_size(core_.input_) != 0)
{
core_.input_ = core_.engine_.put_input(core_.input_);
continue;
}
// The engine wants more data to be read from input. However, we
// cannot allow more than one read operation at a time on the
// underlying transport. The pending_read_ timer's expiry is set to
// pos_infin if a read is in progress, and neg_infin otherwise.
if (core_.pending_read_.expires_at() == boost::posix_time::neg_infin)
{
// Prevent other read operations from being started.
core_.pending_read_.expires_at(boost::posix_time::pos_infin);
// Start reading some data from the underlying transport.
next_layer_.async_read_some(
boost::asio::buffer(core_.input_buffer_),
BOOST_ASIO_MOVE_CAST(io_op)(*this));
}
else
{
// Wait until the current read operation completes.
core_.pending_read_.async_wait(BOOST_ASIO_MOVE_CAST(io_op)(*this));
}
// Yield control until asynchronous operation completes. Control
// resumes at the "default:" label below.
return;
case engine::want_output_and_retry:
case engine::want_output:
// The engine wants some data to be written to the output. However, we
// cannot allow more than one write operation at a time on the
// underlying transport. The pending_write_ timer's expiry is set to
// pos_infin if a write is in progress, and neg_infin otherwise.
if (core_.pending_write_.expires_at() == boost::posix_time::neg_infin)
{
// Prevent other write operations from being started.
core_.pending_write_.expires_at(boost::posix_time::pos_infin);
// Start writing all the data to the underlying transport.
boost::asio::async_write(next_layer_,
core_.engine_.get_output(core_.output_buffer_),
BOOST_ASIO_MOVE_CAST(io_op)(*this));
}
else
{
// Wait until the current write operation completes.
core_.pending_write_.async_wait(BOOST_ASIO_MOVE_CAST(io_op)(*this));
}
// Yield control until asynchronous operation completes. Control
// resumes at the "default:" label below.
return;
default:
// The SSL operation is done and we can invoke the handler, but we
// have to keep in mind that this function might be being called from
// the async operation's initiating function. In this case we're not
// allowed to call the handler directly. Instead, issue a zero-sized
// read so the handler runs "as-if" posted using io_service::post().
if (start)
{
next_layer_.async_read_some(
boost::asio::buffer(core_.input_buffer_, 0),
BOOST_ASIO_MOVE_CAST(io_op)(*this));
// Yield control until asynchronous operation completes. Control
// resumes at the "default:" label below.
return;
}
else
{
// Continue on to run handler directly.
break;
}
}
default:
if (bytes_transferred != ~std::size_t(0) && !ec_)
ec_ = ec;
switch (want_)
{
case engine::want_input_and_retry:
// Add received data to the engine's input.
core_.input_ = boost::asio::buffer(
core_.input_buffer_, bytes_transferred);
core_.input_ = core_.engine_.put_input(core_.input_);
// Release any waiting read operations.
core_.pending_read_.expires_at(boost::posix_time::neg_infin);
// Try the operation again.
continue;
case engine::want_output_and_retry:
// Release any waiting write operations.
core_.pending_write_.expires_at(boost::posix_time::neg_infin);
// Try the operation again.
continue;
case engine::want_output:
// Release any waiting write operations.
core_.pending_write_.expires_at(boost::posix_time::neg_infin);
// Fall through to call handler.
default:
// Pass the result to the handler.
op_.call_handler(handler_,
core_.engine_.map_error_code(ec_),
ec_ ? 0 : bytes_transferred_);
// Our work here is done.
return;
}
} while (!ec_);
// Operation failed. Pass the result to the handler.
op_.call_handler(handler_, core_.engine_.map_error_code(ec_), 0);
}
}
//private:
Stream& next_layer_;
stream_core& core_;
Operation op_;
engine::want want_;
boost::system::error_code ec_;
std::size_t bytes_transferred_;
Handler handler_;
};
template <typename Stream, typename Operation, typename Handler>
inline void* asio_handler_allocate(std::size_t size,
io_op<Stream, Operation, Handler>* this_handler)
{
return boost_asio_handler_alloc_helpers::allocate(
size, this_handler->handler_);
}
template <typename Stream, typename Operation, typename Handler>
inline void asio_handler_deallocate(void* pointer, std::size_t size,
io_op<Stream, Operation, Handler>* this_handler)
{
boost_asio_handler_alloc_helpers::deallocate(
pointer, size, this_handler->handler_);
}
template <typename Function, typename Stream,
typename Operation, typename Handler>
inline void asio_handler_invoke(Function& function,
io_op<Stream, Operation, Handler>* this_handler)
{
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
template <typename Function, typename Stream,
typename Operation, typename Handler>
inline void asio_handler_invoke(const Function& function,
io_op<Stream, Operation, Handler>* this_handler)
{
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
template <typename Stream, typename Operation, typename Handler>
inline void async_io(Stream& next_layer, stream_core& core,
const Operation& op, Handler handler)
{
io_op<Stream, Operation, Handler>(
next_layer, core, op, handler)(
boost::system::error_code(), 0, 1);
}
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace detail
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_DETAIL_IO_HPP

View File

@@ -0,0 +1,88 @@
//
// ssl/detail/openssl_init.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_DETAIL_OPENSSL_INIT_HPP
#define BOOST_ASIO_SSL_DETAIL_OPENSSL_INIT_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <cstring>
#include <boost/asio/detail/noncopyable.hpp>
#include <boost/asio/detail/shared_ptr.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
namespace detail {
class openssl_init_base
: private noncopyable
{
protected:
// Class that performs the actual initialisation.
class do_init;
// Helper function to manage a do_init singleton. The static instance of the
// openssl_init object ensures that this function is always called before
// main, and therefore before any other threads can get started. The do_init
// instance must be static in this function to ensure that it gets
// initialised before any other global objects try to use it.
BOOST_ASIO_DECL static boost::asio::detail::shared_ptr<do_init> instance();
};
template <bool Do_Init = true>
class openssl_init : private openssl_init_base
{
public:
// Constructor.
openssl_init()
: ref_(instance())
{
using namespace std; // For memmove.
// Ensure openssl_init::instance_ is linked in.
openssl_init* tmp = &instance_;
memmove(&tmp, &tmp, sizeof(openssl_init*));
}
// Destructor.
~openssl_init()
{
}
private:
// Instance to force initialisation of openssl at global scope.
static openssl_init instance_;
// Reference to singleton do_init object to ensure that openssl does not get
// cleaned up until the last user has finished with it.
boost::asio::detail::shared_ptr<do_init> ref_;
};
template <bool Do_Init>
openssl_init<Do_Init> openssl_init<Do_Init>::instance_;
} // namespace detail
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#if defined(BOOST_ASIO_HEADER_ONLY)
# include <boost/asio/ssl/detail/impl/openssl_init.ipp>
#endif // defined(BOOST_ASIO_HEADER_ONLY)
#endif // BOOST_ASIO_SSL_DETAIL_OPENSSL_INIT_HPP

View File

@@ -0,0 +1,26 @@
//
// ssl/detail/openssl_types.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP
#define BOOST_ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <openssl/conf.h>
#include <openssl/ssl.h>
#include <openssl/engine.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
#include <boost/asio/detail/socket_types.hpp>
#endif // BOOST_ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP

View File

@@ -0,0 +1,74 @@
//
// ssl/detail/password_callback.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_DETAIL_PASSWORD_CALLBACK_HPP
#define BOOST_ASIO_SSL_DETAIL_PASSWORD_CALLBACK_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <cstddef>
# include <string>
# include <boost/asio/ssl/context_base.hpp>
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
namespace detail {
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
class password_callback_base
{
public:
virtual ~password_callback_base()
{
}
virtual std::string call(std::size_t size,
context_base::password_purpose purpose) = 0;
};
template <typename PasswordCallback>
class password_callback : public password_callback_base
{
public:
explicit password_callback(PasswordCallback callback)
: callback_(callback)
{
}
virtual std::string call(std::size_t size,
context_base::password_purpose purpose)
{
return callback_(size, purpose);
}
private:
PasswordCallback callback_;
};
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace detail
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_DETAIL_PASSWORD_CALLBACK_HPP

View File

@@ -0,0 +1,75 @@
//
// ssl/detail/read_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_DETAIL_READ_OP_HPP
#define BOOST_ASIO_SSL_DETAIL_READ_OP_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <boost/asio/detail/buffer_sequence_adapter.hpp>
# include <boost/asio/ssl/detail/engine.hpp>
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
namespace detail {
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
template <typename MutableBufferSequence>
class read_op
{
public:
read_op(const MutableBufferSequence& buffers)
: buffers_(buffers)
{
}
engine::want operator()(engine& eng,
boost::system::error_code& ec,
std::size_t& bytes_transferred) const
{
boost::asio::mutable_buffer buffer =
boost::asio::detail::buffer_sequence_adapter<boost::asio::mutable_buffer,
MutableBufferSequence>::first(buffers_);
return eng.read(buffer, ec, bytes_transferred);
}
template <typename Handler>
void call_handler(Handler& handler,
const boost::system::error_code& ec,
const std::size_t& bytes_transferred) const
{
handler(ec, bytes_transferred);
}
private:
MutableBufferSequence buffers_;
};
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace detail
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_DETAIL_READ_OP_HPP

View File

@@ -0,0 +1,62 @@
//
// ssl/detail/shutdown_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_DETAIL_SHUTDOWN_OP_HPP
#define BOOST_ASIO_SSL_DETAIL_SHUTDOWN_OP_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <boost/asio/ssl/detail/engine.hpp>
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
namespace detail {
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
class shutdown_op
{
public:
engine::want operator()(engine& eng,
boost::system::error_code& ec,
std::size_t& bytes_transferred) const
{
bytes_transferred = 0;
return eng.shutdown(ec);
}
template <typename Handler>
void call_handler(Handler& handler,
const boost::system::error_code& ec,
const std::size_t&) const
{
handler(ec);
}
};
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace detail
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_DETAIL_SHUTDOWN_OP_HPP

View File

@@ -0,0 +1,92 @@
//
// ssl/detail/stream_core.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_DETAIL_STREAM_CORE_HPP
#define BOOST_ASIO_SSL_DETAIL_STREAM_CORE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <boost/asio/deadline_timer.hpp>
# include <boost/asio/ssl/detail/engine.hpp>
# include <boost/asio/buffer.hpp>
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
namespace detail {
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
struct stream_core
{
// According to the OpenSSL documentation, this is the buffer size that is is
// sufficient to hold the largest possible TLS record.
enum { max_tls_record_size = 17 * 1024 };
stream_core(SSL_CTX* context, boost::asio::io_service& io_service)
: engine_(context),
pending_read_(io_service),
pending_write_(io_service),
output_buffer_space_(max_tls_record_size),
output_buffer_(boost::asio::buffer(output_buffer_space_)),
input_buffer_space_(max_tls_record_size),
input_buffer_(boost::asio::buffer(input_buffer_space_))
{
pending_read_.expires_at(boost::posix_time::neg_infin);
pending_write_.expires_at(boost::posix_time::neg_infin);
}
~stream_core()
{
}
// The SSL engine.
engine engine_;
// Timer used for storing queued read operations.
boost::asio::deadline_timer pending_read_;
// Timer used for storing queued write operations.
boost::asio::deadline_timer pending_write_;
// Buffer space used to prepare output intended for the transport.
std::vector<unsigned char> output_buffer_space_;
// A buffer that may be used to prepare output intended for the transport.
const boost::asio::mutable_buffers_1 output_buffer_;
// Buffer space used to read input intended for the engine.
std::vector<unsigned char> input_buffer_space_;
// A buffer that may be used to read input intended for the engine.
const boost::asio::mutable_buffers_1 input_buffer_;
// The buffer pointing to the engine's unconsumed input.
boost::asio::const_buffer input_;
};
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace detail
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_DETAIL_STREAM_CORE_HPP

View File

@@ -0,0 +1,70 @@
//
// ssl/detail/verify_callback.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_DETAIL_VERIFY_CALLBACK_HPP
#define BOOST_ASIO_SSL_DETAIL_VERIFY_CALLBACK_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <boost/asio/ssl/verify_context.hpp>
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
namespace detail {
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
class verify_callback_base
{
public:
virtual ~verify_callback_base()
{
}
virtual bool call(bool preverified, verify_context& ctx) = 0;
};
template <typename VerifyCallback>
class verify_callback : public verify_callback_base
{
public:
explicit verify_callback(VerifyCallback callback)
: callback_(callback)
{
}
virtual bool call(bool preverified, verify_context& ctx)
{
return callback_(preverified, ctx);
}
private:
VerifyCallback callback_;
};
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace detail
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_DETAIL_VERIFY_CALLBACK_HPP

View File

@@ -0,0 +1,75 @@
//
// ssl/detail/write_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_DETAIL_WRITE_OP_HPP
#define BOOST_ASIO_SSL_DETAIL_WRITE_OP_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <boost/asio/detail/buffer_sequence_adapter.hpp>
# include <boost/asio/ssl/detail/engine.hpp>
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
namespace detail {
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
template <typename ConstBufferSequence>
class write_op
{
public:
write_op(const ConstBufferSequence& buffers)
: buffers_(buffers)
{
}
engine::want operator()(engine& eng,
boost::system::error_code& ec,
std::size_t& bytes_transferred) const
{
boost::asio::const_buffer buffer =
boost::asio::detail::buffer_sequence_adapter<boost::asio::const_buffer,
ConstBufferSequence>::first(buffers_);
return eng.write(buffer, ec, bytes_transferred);
}
template <typename Handler>
void call_handler(Handler& handler,
const boost::system::error_code& ec,
const std::size_t& bytes_transferred) const
{
handler(ec, bytes_transferred);
}
private:
ConstBufferSequence buffers_;
};
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace detail
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_DETAIL_WRITE_OP_HPP

72
test/external/boost/asio/ssl/error.hpp vendored Normal file
View File

@@ -0,0 +1,72 @@
//
// ssl/error.hpp
// ~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_ERROR_HPP
#define BOOST_ASIO_SSL_ERROR_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <boost/system/error_code.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace error {
enum ssl_errors
{
};
extern BOOST_ASIO_DECL
const boost::system::error_category& get_ssl_category();
static const boost::system::error_category& ssl_category
= boost::asio::error::get_ssl_category();
} // namespace error
} // namespace asio
} // namespace boost
namespace boost {
namespace system {
template<> struct is_error_code_enum<boost::asio::error::ssl_errors>
{
static const bool value = true;
};
} // namespace system
} // namespace boost
namespace boost {
namespace asio {
namespace error {
inline boost::system::error_code make_error_code(ssl_errors e)
{
return boost::system::error_code(
static_cast<int>(e), get_ssl_category());
}
} // namespace error
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#if defined(BOOST_ASIO_HEADER_ONLY)
# include <boost/asio/ssl/impl/error.ipp>
#endif // defined(BOOST_ASIO_HEADER_ONLY)
#endif // BOOST_ASIO_SSL_ERROR_HPP

View File

@@ -0,0 +1,73 @@
//
// ssl/impl/context.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
// Copyright (c) 2005-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_IMPL_CONTEXT_HPP
#define BOOST_ASIO_SSL_IMPL_CONTEXT_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <boost/asio/detail/throw_error.hpp>
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
template <typename VerifyCallback>
void context::set_verify_callback(VerifyCallback callback)
{
boost::system::error_code ec;
this->set_verify_callback(callback, ec);
boost::asio::detail::throw_error(ec, "set_verify_callback");
}
template <typename VerifyCallback>
boost::system::error_code context::set_verify_callback(
VerifyCallback callback, boost::system::error_code& ec)
{
return do_set_verify_callback(
new detail::verify_callback<VerifyCallback>(callback), ec);
}
template <typename PasswordCallback>
void context::set_password_callback(PasswordCallback callback)
{
boost::system::error_code ec;
this->set_password_callback(callback, ec);
boost::asio::detail::throw_error(ec, "set_password_callback");
}
template <typename PasswordCallback>
boost::system::error_code context::set_password_callback(
PasswordCallback callback, boost::system::error_code& ec)
{
return do_set_password_callback(
new detail::password_callback<PasswordCallback>(callback), ec);
}
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_IMPL_CONTEXT_HPP

View File

@@ -0,0 +1,527 @@
//
// ssl/impl/context.ipp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
// Copyright (c) 2005-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_IMPL_CONTEXT_IPP
#define BOOST_ASIO_SSL_IMPL_CONTEXT_IPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <cstring>
# include <boost/asio/detail/throw_error.hpp>
# include <boost/asio/error.hpp>
# include <boost/asio/ssl/context.hpp>
# include <boost/asio/ssl/error.hpp>
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
context::context(context::method m)
: handle_(0)
{
switch (m)
{
#if defined(OPENSSL_NO_SSL2)
case context::sslv2:
case context::sslv2_client:
case context::sslv2_server:
boost::asio::detail::throw_error(
boost::asio::error::invalid_argument, "context");
break;
#else // defined(OPENSSL_NO_SSL2)
case context::sslv2:
handle_ = ::SSL_CTX_new(::SSLv2_method());
break;
case context::sslv2_client:
handle_ = ::SSL_CTX_new(::SSLv2_client_method());
break;
case context::sslv2_server:
handle_ = ::SSL_CTX_new(::SSLv2_server_method());
break;
#endif // defined(OPENSSL_NO_SSL2)
case context::sslv3:
handle_ = ::SSL_CTX_new(::SSLv3_method());
break;
case context::sslv3_client:
handle_ = ::SSL_CTX_new(::SSLv3_client_method());
break;
case context::sslv3_server:
handle_ = ::SSL_CTX_new(::SSLv3_server_method());
break;
case context::tlsv1:
handle_ = ::SSL_CTX_new(::TLSv1_method());
break;
case context::tlsv1_client:
handle_ = ::SSL_CTX_new(::TLSv1_client_method());
break;
case context::tlsv1_server:
handle_ = ::SSL_CTX_new(::TLSv1_server_method());
break;
case context::sslv23:
handle_ = ::SSL_CTX_new(::SSLv23_method());
break;
case context::sslv23_client:
handle_ = ::SSL_CTX_new(::SSLv23_client_method());
break;
case context::sslv23_server:
handle_ = ::SSL_CTX_new(::SSLv23_server_method());
break;
default:
handle_ = ::SSL_CTX_new(0);
break;
}
if (handle_ == 0)
{
boost::system::error_code ec(::ERR_get_error(),
boost::asio::error::get_ssl_category());
boost::asio::detail::throw_error(ec, "context");
}
}
context::context(boost::asio::io_service&, context::method m)
: handle_(0)
{
context tmp(m);
handle_ = tmp.handle_;
tmp.handle_ = 0;
}
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
context::context(context&& other)
{
handle_ = other.handle_;
other.handle_ = 0;
}
context& context::operator=(context&& other)
{
context tmp(BOOST_ASIO_MOVE_CAST(context)(*this));
handle_ = other.handle_;
other.handle_ = 0;
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
context::~context()
{
if (handle_)
{
if (handle_->default_passwd_callback_userdata)
{
detail::password_callback_base* callback =
static_cast<detail::password_callback_base*>(
handle_->default_passwd_callback_userdata);
delete callback;
handle_->default_passwd_callback_userdata = 0;
}
if (SSL_CTX_get_app_data(handle_))
{
detail::verify_callback_base* callback =
static_cast<detail::verify_callback_base*>(
SSL_CTX_get_app_data(handle_));
delete callback;
SSL_CTX_set_app_data(handle_, 0);
}
::SSL_CTX_free(handle_);
}
}
context::native_handle_type context::native_handle()
{
return handle_;
}
context::impl_type context::impl()
{
return handle_;
}
void context::set_options(context::options o)
{
boost::system::error_code ec;
set_options(o, ec);
boost::asio::detail::throw_error(ec, "set_options");
}
boost::system::error_code context::set_options(
context::options o, boost::system::error_code& ec)
{
::SSL_CTX_set_options(handle_, o);
ec = boost::system::error_code();
return ec;
}
void context::set_verify_mode(verify_mode v)
{
boost::system::error_code ec;
set_verify_mode(v, ec);
boost::asio::detail::throw_error(ec, "set_verify_mode");
}
boost::system::error_code context::set_verify_mode(
verify_mode v, boost::system::error_code& ec)
{
::SSL_CTX_set_verify(handle_, v, ::SSL_CTX_get_verify_callback(handle_));
ec = boost::system::error_code();
return ec;
}
void context::load_verify_file(const std::string& filename)
{
boost::system::error_code ec;
load_verify_file(filename, ec);
boost::asio::detail::throw_error(ec, "load_verify_file");
}
boost::system::error_code context::load_verify_file(
const std::string& filename, boost::system::error_code& ec)
{
if (::SSL_CTX_load_verify_locations(handle_, filename.c_str(), 0) != 1)
{
ec = boost::system::error_code(::ERR_get_error(),
boost::asio::error::get_ssl_category());
return ec;
}
ec = boost::system::error_code();
return ec;
}
void context::set_default_verify_paths()
{
boost::system::error_code ec;
set_default_verify_paths(ec);
boost::asio::detail::throw_error(ec, "set_default_verify_paths");
}
boost::system::error_code context::set_default_verify_paths(
boost::system::error_code& ec)
{
if (::SSL_CTX_set_default_verify_paths(handle_) != 1)
{
ec = boost::system::error_code(::ERR_get_error(),
boost::asio::error::get_ssl_category());
return ec;
}
ec = boost::system::error_code();
return ec;
}
void context::add_verify_path(const std::string& path)
{
boost::system::error_code ec;
add_verify_path(path, ec);
boost::asio::detail::throw_error(ec, "add_verify_path");
}
boost::system::error_code context::add_verify_path(
const std::string& path, boost::system::error_code& ec)
{
if (::SSL_CTX_load_verify_locations(handle_, 0, path.c_str()) != 1)
{
ec = boost::system::error_code(::ERR_get_error(),
boost::asio::error::get_ssl_category());
return ec;
}
ec = boost::system::error_code();
return ec;
}
void context::use_certificate_file(
const std::string& filename, file_format format)
{
boost::system::error_code ec;
use_certificate_file(filename, format, ec);
boost::asio::detail::throw_error(ec, "use_certificate_file");
}
boost::system::error_code context::use_certificate_file(
const std::string& filename, file_format format,
boost::system::error_code& ec)
{
int file_type;
switch (format)
{
case context_base::asn1:
file_type = SSL_FILETYPE_ASN1;
break;
case context_base::pem:
file_type = SSL_FILETYPE_PEM;
break;
default:
{
ec = boost::asio::error::invalid_argument;
return ec;
}
}
if (::SSL_CTX_use_certificate_file(handle_, filename.c_str(), file_type) != 1)
{
ec = boost::system::error_code(::ERR_get_error(),
boost::asio::error::get_ssl_category());
return ec;
}
ec = boost::system::error_code();
return ec;
}
void context::use_certificate_chain_file(const std::string& filename)
{
boost::system::error_code ec;
use_certificate_chain_file(filename, ec);
boost::asio::detail::throw_error(ec, "use_certificate_chain_file");
}
boost::system::error_code context::use_certificate_chain_file(
const std::string& filename, boost::system::error_code& ec)
{
if (::SSL_CTX_use_certificate_chain_file(handle_, filename.c_str()) != 1)
{
ec = boost::system::error_code(::ERR_get_error(),
boost::asio::error::get_ssl_category());
return ec;
}
ec = boost::system::error_code();
return ec;
}
void context::use_private_key_file(
const std::string& filename, context::file_format format)
{
boost::system::error_code ec;
use_private_key_file(filename, format, ec);
boost::asio::detail::throw_error(ec, "use_private_key_file");
}
boost::system::error_code context::use_private_key_file(
const std::string& filename, context::file_format format,
boost::system::error_code& ec)
{
int file_type;
switch (format)
{
case context_base::asn1:
file_type = SSL_FILETYPE_ASN1;
break;
case context_base::pem:
file_type = SSL_FILETYPE_PEM;
break;
default:
{
ec = boost::asio::error::invalid_argument;
return ec;
}
}
if (::SSL_CTX_use_PrivateKey_file(handle_, filename.c_str(), file_type) != 1)
{
ec = boost::system::error_code(::ERR_get_error(),
boost::asio::error::get_ssl_category());
return ec;
}
ec = boost::system::error_code();
return ec;
}
void context::use_rsa_private_key_file(
const std::string& filename, context::file_format format)
{
boost::system::error_code ec;
use_rsa_private_key_file(filename, format, ec);
boost::asio::detail::throw_error(ec, "use_rsa_private_key_file");
}
boost::system::error_code context::use_rsa_private_key_file(
const std::string& filename, context::file_format format,
boost::system::error_code& ec)
{
int file_type;
switch (format)
{
case context_base::asn1:
file_type = SSL_FILETYPE_ASN1;
break;
case context_base::pem:
file_type = SSL_FILETYPE_PEM;
break;
default:
{
ec = boost::asio::error::invalid_argument;
return ec;
}
}
if (::SSL_CTX_use_RSAPrivateKey_file(
handle_, filename.c_str(), file_type) != 1)
{
ec = boost::system::error_code(::ERR_get_error(),
boost::asio::error::get_ssl_category());
return ec;
}
ec = boost::system::error_code();
return ec;
}
void context::use_tmp_dh_file(const std::string& filename)
{
boost::system::error_code ec;
use_tmp_dh_file(filename, ec);
boost::asio::detail::throw_error(ec, "use_tmp_dh_file");
}
boost::system::error_code context::use_tmp_dh_file(
const std::string& filename, boost::system::error_code& ec)
{
::BIO* bio = ::BIO_new_file(filename.c_str(), "r");
if (!bio)
{
ec = boost::asio::error::invalid_argument;
return ec;
}
::DH* dh = ::PEM_read_bio_DHparams(bio, 0, 0, 0);
if (!dh)
{
::BIO_free(bio);
ec = boost::asio::error::invalid_argument;
return ec;
}
::BIO_free(bio);
int result = ::SSL_CTX_set_tmp_dh(handle_, dh);
::DH_free(dh);
if (result != 1)
{
ec = boost::system::error_code(::ERR_get_error(),
boost::asio::error::get_ssl_category());
return ec;
}
ec = boost::system::error_code();
return ec;
}
boost::system::error_code context::do_set_verify_callback(
detail::verify_callback_base* callback, boost::system::error_code& ec)
{
if (SSL_CTX_get_app_data(handle_))
{
delete static_cast<detail::verify_callback_base*>(
SSL_CTX_get_app_data(handle_));
}
SSL_CTX_set_app_data(handle_, callback);
::SSL_CTX_set_verify(handle_,
::SSL_CTX_get_verify_mode(handle_),
&context::verify_callback_function);
ec = boost::system::error_code();
return ec;
}
int context::verify_callback_function(int preverified, X509_STORE_CTX* ctx)
{
if (ctx)
{
if (SSL* ssl = static_cast<SSL*>(
::X509_STORE_CTX_get_ex_data(
ctx, ::SSL_get_ex_data_X509_STORE_CTX_idx())))
{
if (SSL_CTX* handle = ::SSL_get_SSL_CTX(ssl))
{
if (SSL_CTX_get_app_data(handle))
{
detail::verify_callback_base* callback =
static_cast<detail::verify_callback_base*>(
SSL_CTX_get_app_data(handle));
verify_context verify_ctx(ctx);
return callback->call(preverified != 0, verify_ctx) ? 1 : 0;
}
}
}
}
return 0;
}
boost::system::error_code context::do_set_password_callback(
detail::password_callback_base* callback, boost::system::error_code& ec)
{
if (handle_->default_passwd_callback_userdata)
delete static_cast<detail::password_callback_base*>(
handle_->default_passwd_callback_userdata);
handle_->default_passwd_callback_userdata = callback;
SSL_CTX_set_default_passwd_cb(handle_, &context::password_callback_function);
ec = boost::system::error_code();
return ec;
}
int context::password_callback_function(
char* buf, int size, int purpose, void* data)
{
using namespace std; // For strncat and strlen.
if (data)
{
detail::password_callback_base* callback =
static_cast<detail::password_callback_base*>(data);
std::string passwd = callback->call(static_cast<std::size_t>(size),
purpose ? context_base::for_writing : context_base::for_reading);
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE)
strcpy_s(buf, size, passwd.c_str());
#else
*buf = '\0';
strncat(buf, passwd.c_str(), size);
#endif
return strlen(buf);
}
return 0;
}
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_IMPL_CONTEXT_IPP

View File

@@ -0,0 +1,59 @@
//
// ssl/impl/error.ipp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_IMPL_ERROR_IPP
#define BOOST_ASIO_SSL_IMPL_ERROR_IPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <boost/asio/ssl/error.hpp>
#include <boost/asio/ssl/detail/openssl_init.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace error {
namespace detail {
class ssl_category : public boost::system::error_category
{
public:
const char* name() const
{
return "asio.ssl";
}
std::string message(int value) const
{
const char* s = ::ERR_reason_error_string(value);
return s ? s : "asio.ssl error";
}
};
} // namespace detail
const boost::system::error_category& get_ssl_category()
{
static detail::ssl_category instance;
return instance;
}
} // namespace error
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_IMPL_ERROR_IPP

View File

@@ -0,0 +1,158 @@
//
// ssl/impl/rfc2818_verification.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_IMPL_RFC2818_VERIFICATION_IPP
#define BOOST_ASIO_SSL_IMPL_RFC2818_VERIFICATION_IPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <cctype>
# include <cstring>
# include <boost/asio/ip/address.hpp>
# include <boost/asio/ssl/rfc2818_verification.hpp>
# include <boost/asio/ssl/detail/openssl_types.hpp>
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
bool rfc2818_verification::operator()(
bool preverified, verify_context& ctx) const
{
using namespace std; // For memcmp.
// Don't bother looking at certificates that have failed pre-verification.
if (!preverified)
return false;
// We're only interested in checking the certificate at the end of the chain.
int depth = X509_STORE_CTX_get_error_depth(ctx.native_handle());
if (depth > 0)
return true;
// Try converting the host name to an address. If it is an address then we
// need to look for an IP address in the certificate rather than a host name.
boost::system::error_code ec;
ip::address address = ip::address::from_string(host_, ec);
bool is_address = !ec;
X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
// Go through the alternate names in the certificate looking for matching DNS
// or IP address entries.
GENERAL_NAMES* gens = static_cast<GENERAL_NAMES*>(
X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0));
for (int i = 0; i < sk_GENERAL_NAME_num(gens); ++i)
{
GENERAL_NAME* gen = sk_GENERAL_NAME_value(gens, i);
if (gen->type == GEN_DNS && !is_address)
{
ASN1_IA5STRING* domain = gen->d.dNSName;
if (domain->type == V_ASN1_IA5STRING && domain->data && domain->length)
{
const char* pattern = reinterpret_cast<const char*>(domain->data);
std::size_t pattern_length = domain->length;
if (match_pattern(pattern, pattern_length, host_.c_str()))
return true;
}
}
else if (gen->type == GEN_IPADD && is_address)
{
ASN1_OCTET_STRING* ip_address = gen->d.iPAddress;
if (ip_address->type == V_ASN1_OCTET_STRING && ip_address->data)
{
if (address.is_v4() && ip_address->length == 4)
{
ip::address_v4::bytes_type bytes = address.to_v4().to_bytes();
if (memcmp(bytes.data(), ip_address->data, 4) == 0)
return true;
}
else if (address.is_v6() && ip_address->length == 16)
{
ip::address_v6::bytes_type bytes = address.to_v6().to_bytes();
if (memcmp(bytes.data(), ip_address->data, 16) == 0)
return true;
}
}
}
}
// No match in the alternate names, so try the common names. We should only
// use the "most specific" common name, which is the last one in the list.
X509_NAME* name = X509_get_subject_name(cert);
int i = -1;
ASN1_STRING* common_name = 0;
while ((i = X509_NAME_get_index_by_NID(name, NID_commonName, i)) >= 0)
{
X509_NAME_ENTRY* name_entry = X509_NAME_get_entry(name, i);
common_name = X509_NAME_ENTRY_get_data(name_entry);
}
if (common_name && common_name->data && common_name->length)
{
const char* pattern = reinterpret_cast<const char*>(common_name->data);
std::size_t pattern_length = common_name->length;
if (match_pattern(pattern, pattern_length, host_.c_str()))
return true;
}
return false;
}
bool rfc2818_verification::match_pattern(const char* pattern,
std::size_t pattern_length, const char* host)
{
using namespace std; // For tolower.
const char* p = pattern;
const char* p_end = p + pattern_length;
const char* h = host;
while (p != p_end && *h)
{
if (*p == '*')
{
++p;
while (*h && *h != '.')
if (match_pattern(p, p_end - p, h++))
return true;
}
else if (tolower(*p) == tolower(*h))
{
++p;
++h;
}
else
{
return false;
}
}
return p == p_end && !*h;
}
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_IMPL_RFC2818_VERIFICATION_IPP

View File

@@ -0,0 +1,28 @@
//
// impl/ssl/src.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_IMPL_SRC_HPP
#define BOOST_ASIO_SSL_IMPL_SRC_HPP
#define BOOST_ASIO_SOURCE
#include <boost/asio/detail/config.hpp>
#if defined(BOOST_ASIO_HEADER_ONLY)
# error Do not compile Asio library source with BOOST_ASIO_HEADER_ONLY defined
#endif
#include <boost/asio/ssl/impl/context.ipp>
#include <boost/asio/ssl/impl/error.ipp>
#include <boost/asio/ssl/detail/impl/engine.ipp>
#include <boost/asio/ssl/detail/impl/openssl_init.ipp>
#include <boost/asio/ssl/impl/rfc2818_verification.ipp>
#endif // BOOST_ASIO_SSL_IMPL_SRC_HPP

View File

@@ -0,0 +1,436 @@
//
// ssl/old/basic_context.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
// Copyright (c) 2005-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_OLD_BASIC_CONTEXT_HPP
#define BOOST_ASIO_SSL_OLD_BASIC_CONTEXT_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <string>
#include <boost/noncopyable.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/ssl/context_base.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
namespace old {
/// SSL context.
template <typename Service>
class basic_context
: public context_base,
private boost::noncopyable
{
public:
/// The type of the service that will be used to provide context operations.
typedef Service service_type;
/// The native implementation type of the SSL context.
typedef typename service_type::impl_type impl_type;
/// Constructor.
basic_context(boost::asio::io_service& io_service, method m)
: service_(boost::asio::use_service<Service>(io_service)),
impl_(service_.null())
{
service_.create(impl_, m);
}
/// Destructor.
~basic_context()
{
service_.destroy(impl_);
}
/// Get the underlying implementation in the native type.
/**
* This function may be used to obtain the underlying implementation of the
* context. This is intended to allow access to context functionality that is
* not otherwise provided.
*/
impl_type impl()
{
return impl_;
}
/// Set options on the context.
/**
* This function may be used to configure the SSL options used by the context.
*
* @param o A bitmask of options. The available option values are defined in
* the context_base class. The options are bitwise-ored with any existing
* value for the options.
*
* @throws boost::system::system_error Thrown on failure.
*/
void set_options(options o)
{
boost::system::error_code ec;
service_.set_options(impl_, o, ec);
boost::asio::detail::throw_error(ec);
}
/// Set options on the context.
/**
* This function may be used to configure the SSL options used by the context.
*
* @param o A bitmask of options. The available option values are defined in
* the context_base class. The options are bitwise-ored with any existing
* value for the options.
*
* @param ec Set to indicate what error occurred, if any.
*/
boost::system::error_code set_options(options o,
boost::system::error_code& ec)
{
return service_.set_options(impl_, o, ec);
}
/// Set the peer verification mode.
/**
* This function may be used to configure the peer verification mode used by
* the context.
*
* @param v A bitmask of peer verification modes. The available verify_mode
* values are defined in the context_base class.
*
* @throws boost::system::system_error Thrown on failure.
*/
void set_verify_mode(verify_mode v)
{
boost::system::error_code ec;
service_.set_verify_mode(impl_, v, ec);
boost::asio::detail::throw_error(ec);
}
/// Set the peer verification mode.
/**
* This function may be used to configure the peer verification mode used by
* the context.
*
* @param v A bitmask of peer verification modes. The available verify_mode
* values are defined in the context_base class.
*
* @param ec Set to indicate what error occurred, if any.
*/
boost::system::error_code set_verify_mode(verify_mode v,
boost::system::error_code& ec)
{
return service_.set_verify_mode(impl_, v, ec);
}
/// Load a certification authority file for performing verification.
/**
* This function is used to load one or more trusted certification authorities
* from a file.
*
* @param filename The name of a file containing certification authority
* certificates in PEM format.
*
* @throws boost::system::system_error Thrown on failure.
*/
void load_verify_file(const std::string& filename)
{
boost::system::error_code ec;
service_.load_verify_file(impl_, filename, ec);
boost::asio::detail::throw_error(ec);
}
/// Load a certification authority file for performing verification.
/**
* This function is used to load the certificates for one or more trusted
* certification authorities from a file.
*
* @param filename The name of a file containing certification authority
* certificates in PEM format.
*
* @param ec Set to indicate what error occurred, if any.
*/
boost::system::error_code load_verify_file(const std::string& filename,
boost::system::error_code& ec)
{
return service_.load_verify_file(impl_, filename, ec);
}
/// Add a directory containing certificate authority files to be used for
/// performing verification.
/**
* This function is used to specify the name of a directory containing
* certification authority certificates. Each file in the directory must
* contain a single certificate. The files must be named using the subject
* name's hash and an extension of ".0".
*
* @param path The name of a directory containing the certificates.
*
* @throws boost::system::system_error Thrown on failure.
*/
void add_verify_path(const std::string& path)
{
boost::system::error_code ec;
service_.add_verify_path(impl_, path, ec);
boost::asio::detail::throw_error(ec);
}
/// Add a directory containing certificate authority files to be used for
/// performing verification.
/**
* This function is used to specify the name of a directory containing
* certification authority certificates. Each file in the directory must
* contain a single certificate. The files must be named using the subject
* name's hash and an extension of ".0".
*
* @param path The name of a directory containing the certificates.
*
* @param ec Set to indicate what error occurred, if any.
*/
boost::system::error_code add_verify_path(const std::string& path,
boost::system::error_code& ec)
{
return service_.add_verify_path(impl_, path, ec);
}
/// Use a certificate from a file.
/**
* This function is used to load a certificate into the context from a file.
*
* @param filename The name of the file containing the certificate.
*
* @param format The file format (ASN.1 or PEM).
*
* @throws boost::system::system_error Thrown on failure.
*/
void use_certificate_file(const std::string& filename, file_format format)
{
boost::system::error_code ec;
service_.use_certificate_file(impl_, filename, format, ec);
boost::asio::detail::throw_error(ec);
}
/// Use a certificate from a file.
/**
* This function is used to load a certificate into the context from a file.
*
* @param filename The name of the file containing the certificate.
*
* @param format The file format (ASN.1 or PEM).
*
* @param ec Set to indicate what error occurred, if any.
*/
boost::system::error_code use_certificate_file(const std::string& filename,
file_format format, boost::system::error_code& ec)
{
return service_.use_certificate_file(impl_, filename, format, ec);
}
/// Use a certificate chain from a file.
/**
* This function is used to load a certificate chain into the context from a
* file.
*
* @param filename The name of the file containing the certificate. The file
* must use the PEM format.
*
* @throws boost::system::system_error Thrown on failure.
*/
void use_certificate_chain_file(const std::string& filename)
{
boost::system::error_code ec;
service_.use_certificate_chain_file(impl_, filename, ec);
boost::asio::detail::throw_error(ec);
}
/// Use a certificate chain from a file.
/**
* This function is used to load a certificate chain into the context from a
* file.
*
* @param filename The name of the file containing the certificate. The file
* must use the PEM format.
*
* @param ec Set to indicate what error occurred, if any.
*/
boost::system::error_code use_certificate_chain_file(
const std::string& filename, boost::system::error_code& ec)
{
return service_.use_certificate_chain_file(impl_, filename, ec);
}
/// Use a private key from a file.
/**
* This function is used to load a private key into the context from a file.
*
* @param filename The name of the file containing the private key.
*
* @param format The file format (ASN.1 or PEM).
*
* @throws boost::system::system_error Thrown on failure.
*/
void use_private_key_file(const std::string& filename, file_format format)
{
boost::system::error_code ec;
service_.use_private_key_file(impl_, filename, format, ec);
boost::asio::detail::throw_error(ec);
}
/// Use a private key from a file.
/**
* This function is used to load a private key into the context from a file.
*
* @param filename The name of the file containing the private key.
*
* @param format The file format (ASN.1 or PEM).
*
* @param ec Set to indicate what error occurred, if any.
*/
boost::system::error_code use_private_key_file(const std::string& filename,
file_format format, boost::system::error_code& ec)
{
return service_.use_private_key_file(impl_, filename, format, ec);
}
/// Use an RSA private key from a file.
/**
* This function is used to load an RSA private key into the context from a
* file.
*
* @param filename The name of the file containing the RSA private key.
*
* @param format The file format (ASN.1 or PEM).
*
* @throws boost::system::system_error Thrown on failure.
*/
void use_rsa_private_key_file(const std::string& filename, file_format format)
{
boost::system::error_code ec;
service_.use_rsa_private_key_file(impl_, filename, format, ec);
boost::asio::detail::throw_error(ec);
}
/// Use an RSA private key from a file.
/**
* This function is used to load an RSA private key into the context from a
* file.
*
* @param filename The name of the file containing the RSA private key.
*
* @param format The file format (ASN.1 or PEM).
*
* @param ec Set to indicate what error occurred, if any.
*/
boost::system::error_code use_rsa_private_key_file(
const std::string& filename, file_format format,
boost::system::error_code& ec)
{
return service_.use_rsa_private_key_file(impl_, filename, format, ec);
}
/// Use the specified file to obtain the temporary Diffie-Hellman parameters.
/**
* This function is used to load Diffie-Hellman parameters into the context
* from a file.
*
* @param filename The name of the file containing the Diffie-Hellman
* parameters. The file must use the PEM format.
*
* @throws boost::system::system_error Thrown on failure.
*/
void use_tmp_dh_file(const std::string& filename)
{
boost::system::error_code ec;
service_.use_tmp_dh_file(impl_, filename, ec);
boost::asio::detail::throw_error(ec);
}
/// Use the specified file to obtain the temporary Diffie-Hellman parameters.
/**
* This function is used to load Diffie-Hellman parameters into the context
* from a file.
*
* @param filename The name of the file containing the Diffie-Hellman
* parameters. The file must use the PEM format.
*
* @param ec Set to indicate what error occurred, if any.
*/
boost::system::error_code use_tmp_dh_file(const std::string& filename,
boost::system::error_code& ec)
{
return service_.use_tmp_dh_file(impl_, filename, ec);
}
/// Set the password callback.
/**
* This function is used to specify a callback function to obtain password
* information about an encrypted key in PEM format.
*
* @param callback The function object to be used for obtaining the password.
* The function signature of the handler must be:
* @code std::string password_callback(
* std::size_t max_length, // The maximum size for a password.
* password_purpose purpose // Whether password is for reading or writing.
* ); @endcode
* The return value of the callback is a string containing the password.
*
* @throws boost::system::system_error Thrown on failure.
*/
template <typename PasswordCallback>
void set_password_callback(PasswordCallback callback)
{
boost::system::error_code ec;
service_.set_password_callback(impl_, callback, ec);
boost::asio::detail::throw_error(ec);
}
/// Set the password callback.
/**
* This function is used to specify a callback function to obtain password
* information about an encrypted key in PEM format.
*
* @param callback The function object to be used for obtaining the password.
* The function signature of the handler must be:
* @code std::string password_callback(
* std::size_t max_length, // The maximum size for a password.
* password_purpose purpose // Whether password is for reading or writing.
* ); @endcode
* The return value of the callback is a string containing the password.
*
* @param ec Set to indicate what error occurred, if any.
*/
template <typename PasswordCallback>
boost::system::error_code set_password_callback(PasswordCallback callback,
boost::system::error_code& ec)
{
return service_.set_password_callback(impl_, callback, ec);
}
private:
/// The backend service implementation.
service_type& service_;
/// The underlying native implementation.
impl_type impl_;
};
} // namespace old
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_OLD_BASIC_CONTEXT_HPP

View File

@@ -0,0 +1,176 @@
//
// ssl/old/context_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
// Copyright (c) 2005-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_OLD_CONTEXT_SERVICE_HPP
#define BOOST_ASIO_SSL_OLD_CONTEXT_SERVICE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <string>
#include <boost/noncopyable.hpp>
#include <boost/asio/error.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/ssl/context_base.hpp>
#include <boost/asio/ssl/old/detail/openssl_context_service.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
namespace old {
/// Default service implementation for a context.
class context_service
#if defined(GENERATING_DOCUMENTATION)
: public boost::asio::io_service::service
#else
: public boost::asio::detail::service_base<context_service>
#endif
{
private:
// The type of the platform-specific implementation.
typedef old::detail::openssl_context_service service_impl_type;
public:
#if defined(GENERATING_DOCUMENTATION)
/// The unique service identifier.
static boost::asio::io_service::id id;
#endif
/// The type of the context.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined impl_type;
#else
typedef service_impl_type::impl_type impl_type;
#endif
/// Constructor.
explicit context_service(boost::asio::io_service& io_service)
: boost::asio::detail::service_base<context_service>(io_service),
service_impl_(boost::asio::use_service<service_impl_type>(io_service))
{
}
/// Return a null context implementation.
impl_type null() const
{
return service_impl_.null();
}
/// Create a new context implementation.
void create(impl_type& impl, context_base::method m)
{
service_impl_.create(impl, m);
}
/// Destroy a context implementation.
void destroy(impl_type& impl)
{
service_impl_.destroy(impl);
}
/// Set options on the context.
boost::system::error_code set_options(impl_type& impl,
context_base::options o, boost::system::error_code& ec)
{
return service_impl_.set_options(impl, o, ec);
}
/// Set peer verification mode.
boost::system::error_code set_verify_mode(impl_type& impl,
context_base::verify_mode v, boost::system::error_code& ec)
{
return service_impl_.set_verify_mode(impl, v, ec);
}
/// Load a certification authority file for performing verification.
boost::system::error_code load_verify_file(impl_type& impl,
const std::string& filename, boost::system::error_code& ec)
{
return service_impl_.load_verify_file(impl, filename, ec);
}
/// Add a directory containing certification authority files to be used for
/// performing verification.
boost::system::error_code add_verify_path(impl_type& impl,
const std::string& path, boost::system::error_code& ec)
{
return service_impl_.add_verify_path(impl, path, ec);
}
/// Use a certificate from a file.
boost::system::error_code use_certificate_file(impl_type& impl,
const std::string& filename, context_base::file_format format,
boost::system::error_code& ec)
{
return service_impl_.use_certificate_file(impl, filename, format, ec);
}
/// Use a certificate chain from a file.
boost::system::error_code use_certificate_chain_file(impl_type& impl,
const std::string& filename, boost::system::error_code& ec)
{
return service_impl_.use_certificate_chain_file(impl, filename, ec);
}
/// Use a private key from a file.
boost::system::error_code use_private_key_file(impl_type& impl,
const std::string& filename, context_base::file_format format,
boost::system::error_code& ec)
{
return service_impl_.use_private_key_file(impl, filename, format, ec);
}
/// Use an RSA private key from a file.
boost::system::error_code use_rsa_private_key_file(impl_type& impl,
const std::string& filename, context_base::file_format format,
boost::system::error_code& ec)
{
return service_impl_.use_rsa_private_key_file(impl, filename, format, ec);
}
/// Use the specified file to obtain the temporary Diffie-Hellman parameters.
boost::system::error_code use_tmp_dh_file(impl_type& impl,
const std::string& filename, boost::system::error_code& ec)
{
return service_impl_.use_tmp_dh_file(impl, filename, ec);
}
/// Set the password callback.
template <typename PasswordCallback>
boost::system::error_code set_password_callback(impl_type& impl,
PasswordCallback callback, boost::system::error_code& ec)
{
return service_impl_.set_password_callback(impl, callback, ec);
}
private:
// Destroy all user-defined handler objects owned by the service.
void shutdown_service()
{
}
// The service that provides the platform-specific implementation.
service_impl_type& service_impl_;
};
} // namespace old
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_OLD_CONTEXT_SERVICE_HPP

View File

@@ -0,0 +1,388 @@
//
// ssl/old/detail/openssl_context_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
// Copyright (c) 2005-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_CONTEXT_SERVICE_HPP
#define BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_CONTEXT_SERVICE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <cstring>
#include <string>
#include <boost/function.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/ssl/context_base.hpp>
#include <boost/asio/ssl/detail/openssl_init.hpp>
#include <boost/asio/ssl/detail/openssl_types.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
namespace old {
namespace detail {
class openssl_context_service
: public boost::asio::detail::service_base<openssl_context_service>
{
public:
// The native type of the context.
typedef ::SSL_CTX* impl_type;
// The type for the password callback function object.
typedef boost::function<std::string(std::size_t,
context_base::password_purpose)> password_callback_type;
// Constructor.
openssl_context_service(boost::asio::io_service& io_service)
: boost::asio::detail::service_base<openssl_context_service>(io_service)
{
}
// Destroy all user-defined handler objects owned by the service.
void shutdown_service()
{
}
// Return a null context implementation.
static impl_type null()
{
return 0;
}
// Create a new context implementation.
void create(impl_type& impl, context_base::method m)
{
switch (m)
{
#if defined(OPENSSL_NO_SSL2)
case context_base::sslv2:
case context_base::sslv2_client:
case context_base::sslv2_server:
boost::asio::detail::throw_error(boost::asio::error::invalid_argument);
break;
#else // defined(OPENSSL_NO_SSL2)
case context_base::sslv2:
impl = ::SSL_CTX_new(::SSLv2_method());
break;
case context_base::sslv2_client:
impl = ::SSL_CTX_new(::SSLv2_client_method());
break;
case context_base::sslv2_server:
impl = ::SSL_CTX_new(::SSLv2_server_method());
break;
#endif // defined(OPENSSL_NO_SSL2)
case context_base::sslv3:
impl = ::SSL_CTX_new(::SSLv3_method());
break;
case context_base::sslv3_client:
impl = ::SSL_CTX_new(::SSLv3_client_method());
break;
case context_base::sslv3_server:
impl = ::SSL_CTX_new(::SSLv3_server_method());
break;
case context_base::tlsv1:
impl = ::SSL_CTX_new(::TLSv1_method());
break;
case context_base::tlsv1_client:
impl = ::SSL_CTX_new(::TLSv1_client_method());
break;
case context_base::tlsv1_server:
impl = ::SSL_CTX_new(::TLSv1_server_method());
break;
case context_base::sslv23:
impl = ::SSL_CTX_new(::SSLv23_method());
break;
case context_base::sslv23_client:
impl = ::SSL_CTX_new(::SSLv23_client_method());
break;
case context_base::sslv23_server:
impl = ::SSL_CTX_new(::SSLv23_server_method());
break;
default:
impl = ::SSL_CTX_new(0);
break;
}
}
// Destroy a context implementation.
void destroy(impl_type& impl)
{
if (impl != null())
{
if (impl->default_passwd_callback_userdata)
{
password_callback_type* callback =
static_cast<password_callback_type*>(
impl->default_passwd_callback_userdata);
delete callback;
impl->default_passwd_callback_userdata = 0;
}
::SSL_CTX_free(impl);
impl = null();
}
}
// Set options on the context.
boost::system::error_code set_options(impl_type& impl,
context_base::options o, boost::system::error_code& ec)
{
::SSL_CTX_set_options(impl, o);
ec = boost::system::error_code();
return ec;
}
// Set peer verification mode.
boost::system::error_code set_verify_mode(impl_type& impl,
context_base::verify_mode v, boost::system::error_code& ec)
{
::SSL_CTX_set_verify(impl, v, 0);
ec = boost::system::error_code();
return ec;
}
// Load a certification authority file for performing verification.
boost::system::error_code load_verify_file(impl_type& impl,
const std::string& filename, boost::system::error_code& ec)
{
if (::SSL_CTX_load_verify_locations(impl, filename.c_str(), 0) != 1)
{
ec = boost::asio::error::invalid_argument;
return ec;
}
ec = boost::system::error_code();
return ec;
}
// Add a directory containing certification authority files to be used for
// performing verification.
boost::system::error_code add_verify_path(impl_type& impl,
const std::string& path, boost::system::error_code& ec)
{
if (::SSL_CTX_load_verify_locations(impl, 0, path.c_str()) != 1)
{
ec = boost::asio::error::invalid_argument;
return ec;
}
ec = boost::system::error_code();
return ec;
}
// Use a certificate from a file.
boost::system::error_code use_certificate_file(impl_type& impl,
const std::string& filename, context_base::file_format format,
boost::system::error_code& ec)
{
int file_type;
switch (format)
{
case context_base::asn1:
file_type = SSL_FILETYPE_ASN1;
break;
case context_base::pem:
file_type = SSL_FILETYPE_PEM;
break;
default:
{
ec = boost::asio::error::invalid_argument;
return ec;
}
}
if (::SSL_CTX_use_certificate_file(impl, filename.c_str(), file_type) != 1)
{
ec = boost::asio::error::invalid_argument;
return ec;
}
ec = boost::system::error_code();
return ec;
}
// Use a certificate chain from a file.
boost::system::error_code use_certificate_chain_file(impl_type& impl,
const std::string& filename, boost::system::error_code& ec)
{
if (::SSL_CTX_use_certificate_chain_file(impl, filename.c_str()) != 1)
{
ec = boost::asio::error::invalid_argument;
return ec;
}
ec = boost::system::error_code();
return ec;
}
// Use a private key from a file.
boost::system::error_code use_private_key_file(impl_type& impl,
const std::string& filename, context_base::file_format format,
boost::system::error_code& ec)
{
int file_type;
switch (format)
{
case context_base::asn1:
file_type = SSL_FILETYPE_ASN1;
break;
case context_base::pem:
file_type = SSL_FILETYPE_PEM;
break;
default:
{
ec = boost::asio::error::invalid_argument;
return ec;
}
}
if (::SSL_CTX_use_PrivateKey_file(impl, filename.c_str(), file_type) != 1)
{
ec = boost::asio::error::invalid_argument;
return ec;
}
ec = boost::system::error_code();
return ec;
}
// Use an RSA private key from a file.
boost::system::error_code use_rsa_private_key_file(impl_type& impl,
const std::string& filename, context_base::file_format format,
boost::system::error_code& ec)
{
int file_type;
switch (format)
{
case context_base::asn1:
file_type = SSL_FILETYPE_ASN1;
break;
case context_base::pem:
file_type = SSL_FILETYPE_PEM;
break;
default:
{
ec = boost::asio::error::invalid_argument;
return ec;
}
}
if (::SSL_CTX_use_RSAPrivateKey_file(
impl, filename.c_str(), file_type) != 1)
{
ec = boost::asio::error::invalid_argument;
return ec;
}
ec = boost::system::error_code();
return ec;
}
// Use the specified file to obtain the temporary Diffie-Hellman parameters.
boost::system::error_code use_tmp_dh_file(impl_type& impl,
const std::string& filename, boost::system::error_code& ec)
{
::BIO* bio = ::BIO_new_file(filename.c_str(), "r");
if (!bio)
{
ec = boost::asio::error::invalid_argument;
return ec;
}
::DH* dh = ::PEM_read_bio_DHparams(bio, 0, 0, 0);
if (!dh)
{
::BIO_free(bio);
ec = boost::asio::error::invalid_argument;
return ec;
}
::BIO_free(bio);
int result = ::SSL_CTX_set_tmp_dh(impl, dh);
::DH_free(dh);
if (result != 1)
{
ec = boost::asio::error::invalid_argument;
return ec;
}
ec = boost::system::error_code();
return ec;
}
static int password_callback(char* buf, int size, int purpose, void* data)
{
using namespace std; // For strncat and strlen.
if (data)
{
password_callback_type* callback =
static_cast<password_callback_type*>(data);
std::string passwd = (*callback)(static_cast<std::size_t>(size),
purpose ? context_base::for_writing : context_base::for_reading);
*buf = '\0';
strncat(buf, passwd.c_str(), size);
return strlen(buf);
}
return 0;
}
// Set the password callback.
template <typename Password_Callback>
boost::system::error_code set_password_callback(impl_type& impl,
Password_Callback callback, boost::system::error_code& ec)
{
// Allocate callback function object if not already present.
if (impl->default_passwd_callback_userdata)
{
password_callback_type* callback_function =
static_cast<password_callback_type*>(
impl->default_passwd_callback_userdata);
*callback_function = callback;
}
else
{
password_callback_type* callback_function =
new password_callback_type(callback);
impl->default_passwd_callback_userdata = callback_function;
}
// Set the password callback.
SSL_CTX_set_default_passwd_cb(impl,
&openssl_context_service::password_callback);
ec = boost::system::error_code();
return ec;
}
private:
// Ensure openssl is initialised.
boost::asio::ssl::detail::openssl_init<> init_;
};
} // namespace detail
} // namespace old
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_CONTEXT_SERVICE_HPP

View File

@@ -0,0 +1,526 @@
//
// ssl/old/detail/openssl_operation.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_OPERATION_HPP
#define BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_OPERATION_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <boost/function.hpp>
#include <boost/assert.hpp>
#include <boost/bind.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/asio/detail/socket_ops.hpp>
#include <boost/asio/placeholders.hpp>
#include <boost/asio/ssl/detail/openssl_types.hpp>
#include <boost/asio/ssl/error.hpp>
#include <boost/asio/strand.hpp>
#include <boost/system/system_error.hpp>
#include <boost/asio/write.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
namespace old {
namespace detail {
typedef boost::function<int (::SSL*)> ssl_primitive_func;
typedef boost::function<void (const boost::system::error_code&, int)>
user_handler_func;
// Network send_/recv buffer implementation
//
//
class net_buffer
{
static const int NET_BUF_SIZE = 16*1024 + 256; // SSL record size + spare
unsigned char buf_[NET_BUF_SIZE];
unsigned char* data_start_;
unsigned char* data_end_;
public:
net_buffer()
{
data_start_ = data_end_ = buf_;
}
unsigned char* get_unused_start() { return data_end_; }
unsigned char* get_data_start() { return data_start_; }
size_t get_unused_len() { return (NET_BUF_SIZE - (data_end_ - buf_)); }
size_t get_data_len() { return (data_end_ - data_start_); }
void data_added(size_t count)
{
data_end_ += count;
data_end_ = data_end_ > (buf_ + NET_BUF_SIZE)?
(buf_ + NET_BUF_SIZE):
data_end_;
}
void data_removed(size_t count)
{
data_start_ += count;
if (data_start_ >= data_end_) reset();
}
void reset() { data_start_ = buf_; data_end_ = buf_; }
bool has_data() { return (data_start_ < data_end_); }
}; // class net_buffer
//
// Operation class
//
//
template <typename Stream>
class openssl_operation
{
public:
// Constructor for asynchronous operations
openssl_operation(ssl_primitive_func primitive,
Stream& socket,
net_buffer& recv_buf,
SSL* session,
BIO* ssl_bio,
user_handler_func handler,
boost::asio::io_service::strand& strand
)
: primitive_(primitive)
, user_handler_(handler)
, strand_(&strand)
, recv_buf_(recv_buf)
, socket_(socket)
, ssl_bio_(ssl_bio)
, session_(session)
{
write_ = boost::bind(
&openssl_operation::do_async_write,
this, boost::arg<1>(), boost::arg<2>()
);
read_ = boost::bind(
&openssl_operation::do_async_read,
this
);
handler_= boost::bind(
&openssl_operation::async_user_handler,
this, boost::arg<1>(), boost::arg<2>()
);
}
// Constructor for synchronous operations
openssl_operation(ssl_primitive_func primitive,
Stream& socket,
net_buffer& recv_buf,
SSL* session,
BIO* ssl_bio)
: primitive_(primitive)
, strand_(0)
, recv_buf_(recv_buf)
, socket_(socket)
, ssl_bio_(ssl_bio)
, session_(session)
{
write_ = boost::bind(
&openssl_operation::do_sync_write,
this, boost::arg<1>(), boost::arg<2>()
);
read_ = boost::bind(
&openssl_operation::do_sync_read,
this
);
handler_ = boost::bind(
&openssl_operation::sync_user_handler,
this, boost::arg<1>(), boost::arg<2>()
);
}
// Start operation
// In case of asynchronous it returns 0, in sync mode returns success code
// or throws an error...
int start()
{
int rc = primitive_( session_ );
bool is_operation_done = (rc > 0);
// For connect/accept/shutdown, the operation
// is done, when return code is 1
// for write, it is done, when is retcode > 0
// for read, is is done when retcode > 0
int error_code = !is_operation_done ?
::SSL_get_error( session_, rc ) :
0;
int sys_error_code = ERR_get_error();
if (error_code == SSL_ERROR_SSL)
return handler_(boost::system::error_code(
sys_error_code, boost::asio::error::get_ssl_category()), rc);
bool is_read_needed = (error_code == SSL_ERROR_WANT_READ);
bool is_write_needed = (error_code == SSL_ERROR_WANT_WRITE ||
::BIO_ctrl_pending( ssl_bio_ ));
bool is_shut_down_received =
((::SSL_get_shutdown( session_ ) & SSL_RECEIVED_SHUTDOWN) ==
SSL_RECEIVED_SHUTDOWN);
bool is_shut_down_sent =
((::SSL_get_shutdown( session_ ) & SSL_SENT_SHUTDOWN) ==
SSL_SENT_SHUTDOWN);
if (is_shut_down_sent && is_shut_down_received
&& is_operation_done && !is_write_needed)
// SSL connection is shut down cleanly
return handler_(boost::system::error_code(), 1);
if (is_shut_down_received && !is_operation_done)
// Shutdown has been requested, while we were reading or writing...
// abort our action...
return handler_(boost::asio::error::shut_down, 0);
if (!is_operation_done && !is_read_needed && !is_write_needed
&& !is_shut_down_sent)
{
// The operation has failed... It is not completed and does
// not want network communication nor does want to send shutdown out...
if (error_code == SSL_ERROR_SYSCALL)
{
return handler_(boost::system::error_code(
sys_error_code, boost::asio::error::system_category), rc);
}
else
{
return handler_(boost::system::error_code(
sys_error_code, boost::asio::error::get_ssl_category()), rc);
}
}
if (!is_operation_done && !is_write_needed)
{
// We may have left over data that we can pass to SSL immediately
if (recv_buf_.get_data_len() > 0)
{
// Pass the buffered data to SSL
int written = ::BIO_write
(
ssl_bio_,
recv_buf_.get_data_start(),
recv_buf_.get_data_len()
);
if (written > 0)
{
recv_buf_.data_removed(written);
}
else if (written < 0)
{
if (!BIO_should_retry(ssl_bio_))
{
// Some serios error with BIO....
return handler_(boost::asio::error::no_recovery, 0);
}
}
return start();
}
else if (is_read_needed || (is_shut_down_sent && !is_shut_down_received))
{
return read_();
}
}
// Continue with operation, flush any SSL data out to network...
return write_(is_operation_done, rc);
}
// Private implementation
private:
typedef boost::function<int (const boost::system::error_code&, int)>
int_handler_func;
typedef boost::function<int (bool, int)> write_func;
typedef boost::function<int ()> read_func;
ssl_primitive_func primitive_;
user_handler_func user_handler_;
boost::asio::io_service::strand* strand_;
write_func write_;
read_func read_;
int_handler_func handler_;
net_buffer send_buf_; // buffers for network IO
// The recv buffer is owned by the stream, not the operation, since there can
// be left over bytes after passing the data up to the application, and these
// bytes need to be kept around for the next read operation issued by the
// application.
net_buffer& recv_buf_;
Stream& socket_;
BIO* ssl_bio_;
SSL* session_;
//
int sync_user_handler(const boost::system::error_code& error, int rc)
{
if (!error)
return rc;
throw boost::system::system_error(error);
}
int async_user_handler(boost::system::error_code error, int rc)
{
if (rc < 0)
{
if (!error)
error = boost::asio::error::no_recovery;
rc = 0;
}
user_handler_(error, rc);
return 0;
}
// Writes bytes asynchronously from SSL to NET
int do_async_write(bool is_operation_done, int rc)
{
int len = ::BIO_ctrl_pending( ssl_bio_ );
if ( len )
{
// There is something to write into net, do it...
len = (int)send_buf_.get_unused_len() > len?
len:
send_buf_.get_unused_len();
if (len == 0)
{
// In case our send buffer is full, we have just to wait until
// previous send to complete...
return 0;
}
// Read outgoing data from bio
len = ::BIO_read( ssl_bio_, send_buf_.get_unused_start(), len);
if (len > 0)
{
unsigned char *data_start = send_buf_.get_unused_start();
send_buf_.data_added(len);
BOOST_ASSERT(strand_);
boost::asio::async_write
(
socket_,
boost::asio::buffer(data_start, len),
strand_->wrap
(
boost::bind
(
&openssl_operation::async_write_handler,
this,
is_operation_done,
rc,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
)
);
return 0;
}
else if (!BIO_should_retry(ssl_bio_))
{
// Seems like fatal error
// reading from SSL BIO has failed...
handler_(boost::asio::error::no_recovery, 0);
return 0;
}
}
if (is_operation_done)
{
// Finish the operation, with success
handler_(boost::system::error_code(), rc);
return 0;
}
// OPeration is not done and writing to net has been made...
// start operation again
start();
return 0;
}
void async_write_handler(bool is_operation_done, int rc,
const boost::system::error_code& error, size_t bytes_sent)
{
if (!error)
{
// Remove data from send buffer
send_buf_.data_removed(bytes_sent);
if (is_operation_done)
handler_(boost::system::error_code(), rc);
else
// Since the operation was not completed, try it again...
start();
}
else
handler_(error, rc);
}
int do_async_read()
{
// Wait for new data
BOOST_ASSERT(strand_);
socket_.async_read_some
(
boost::asio::buffer(recv_buf_.get_unused_start(),
recv_buf_.get_unused_len()),
strand_->wrap
(
boost::bind
(
&openssl_operation::async_read_handler,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
)
);
return 0;
}
void async_read_handler(const boost::system::error_code& error,
size_t bytes_recvd)
{
if (!error)
{
recv_buf_.data_added(bytes_recvd);
// Pass the received data to SSL
int written = ::BIO_write
(
ssl_bio_,
recv_buf_.get_data_start(),
recv_buf_.get_data_len()
);
if (written > 0)
{
recv_buf_.data_removed(written);
}
else if (written < 0)
{
if (!BIO_should_retry(ssl_bio_))
{
// Some serios error with BIO....
handler_(boost::asio::error::no_recovery, 0);
return;
}
}
// and try the SSL primitive again
start();
}
else
{
// Error in network level...
// SSL can't continue either...
handler_(error, 0);
}
}
// Syncronous functions...
int do_sync_write(bool is_operation_done, int rc)
{
int len = ::BIO_ctrl_pending( ssl_bio_ );
if ( len )
{
// There is something to write into net, do it...
len = (int)send_buf_.get_unused_len() > len?
len:
send_buf_.get_unused_len();
// Read outgoing data from bio
len = ::BIO_read( ssl_bio_, send_buf_.get_unused_start(), len);
if (len > 0)
{
size_t sent_len = boost::asio::write(
socket_,
boost::asio::buffer(send_buf_.get_unused_start(), len)
);
send_buf_.data_added(len);
send_buf_.data_removed(sent_len);
}
else if (!BIO_should_retry(ssl_bio_))
{
// Seems like fatal error
// reading from SSL BIO has failed...
throw boost::system::system_error(boost::asio::error::no_recovery);
}
}
if (is_operation_done)
// Finish the operation, with success
return rc;
// Operation is not finished, start again.
return start();
}
int do_sync_read()
{
size_t len = socket_.read_some
(
boost::asio::buffer(recv_buf_.get_unused_start(),
recv_buf_.get_unused_len())
);
// Write data to ssl
recv_buf_.data_added(len);
// Pass the received data to SSL
int written = ::BIO_write
(
ssl_bio_,
recv_buf_.get_data_start(),
recv_buf_.get_data_len()
);
if (written > 0)
{
recv_buf_.data_removed(written);
}
else if (written < 0)
{
if (!BIO_should_retry(ssl_bio_))
{
// Some serios error with BIO....
throw boost::system::system_error(boost::asio::error::no_recovery);
}
}
// Try the operation again
return start();
}
}; // class openssl_operation
} // namespace detail
} // namespace old
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_OPERATION_HPP

View File

@@ -0,0 +1,573 @@
//
// ssl/old/detail/stream_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
// Copyright (c) 2005-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_STREAM_SERVICE_HPP
#define BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_STREAM_SERVICE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <cstddef>
#include <climits>
#include <memory>
#include <boost/config.hpp>
#include <boost/noncopyable.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/asio/detail/buffer_sequence_adapter.hpp>
#include <boost/asio/error.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/ssl/basic_context.hpp>
#include <boost/asio/ssl/stream_base.hpp>
#include <boost/asio/ssl/old/detail/openssl_operation.hpp>
#include <boost/asio/ssl/detail/openssl_types.hpp>
#include <boost/asio/strand.hpp>
#include <boost/system/system_error.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
namespace old {
namespace detail {
class openssl_stream_service
: public boost::asio::detail::service_base<openssl_stream_service>
{
private:
enum { max_buffer_size = INT_MAX };
//Base handler for asyncrhonous operations
template <typename Stream>
class base_handler
{
public:
typedef boost::function<
void (const boost::system::error_code&, size_t)> func_t;
base_handler(boost::asio::io_service& io_service)
: op_(NULL)
, io_service_(io_service)
, work_(io_service)
{}
void do_func(const boost::system::error_code& error, size_t size)
{
func_(error, size);
}
void set_operation(openssl_operation<Stream>* op) { op_ = op; }
void set_func(func_t func) { func_ = func; }
~base_handler()
{
delete op_;
}
private:
func_t func_;
openssl_operation<Stream>* op_;
boost::asio::io_service& io_service_;
boost::asio::io_service::work work_;
}; // class base_handler
// Handler for asynchronous IO (write/read) operations
template<typename Stream, typename Handler>
class io_handler
: public base_handler<Stream>
{
public:
io_handler(Handler handler, boost::asio::io_service& io_service)
: base_handler<Stream>(io_service)
, handler_(handler)
{
this->set_func(boost::bind(
&io_handler<Stream, Handler>::handler_impl,
this, boost::arg<1>(), boost::arg<2>() ));
}
private:
Handler handler_;
void handler_impl(const boost::system::error_code& error, size_t size)
{
std::auto_ptr<io_handler<Stream, Handler> > this_ptr(this);
handler_(error, size);
}
}; // class io_handler
// Handler for asyncrhonous handshake (connect, accept) functions
template <typename Stream, typename Handler>
class handshake_handler
: public base_handler<Stream>
{
public:
handshake_handler(Handler handler, boost::asio::io_service& io_service)
: base_handler<Stream>(io_service)
, handler_(handler)
{
this->set_func(boost::bind(
&handshake_handler<Stream, Handler>::handler_impl,
this, boost::arg<1>(), boost::arg<2>() ));
}
private:
Handler handler_;
void handler_impl(const boost::system::error_code& error, size_t)
{
std::auto_ptr<handshake_handler<Stream, Handler> > this_ptr(this);
handler_(error);
}
}; // class handshake_handler
// Handler for asyncrhonous shutdown
template <typename Stream, typename Handler>
class shutdown_handler
: public base_handler<Stream>
{
public:
shutdown_handler(Handler handler, boost::asio::io_service& io_service)
: base_handler<Stream>(io_service),
handler_(handler)
{
this->set_func(boost::bind(
&shutdown_handler<Stream, Handler>::handler_impl,
this, boost::arg<1>(), boost::arg<2>() ));
}
private:
Handler handler_;
void handler_impl(const boost::system::error_code& error, size_t)
{
std::auto_ptr<shutdown_handler<Stream, Handler> > this_ptr(this);
handler_(error);
}
}; // class shutdown_handler
public:
// The implementation type.
typedef struct impl_struct
{
::SSL* ssl;
::BIO* ext_bio;
net_buffer recv_buf;
} * impl_type;
// Construct a new stream socket service for the specified io_service.
explicit openssl_stream_service(boost::asio::io_service& io_service)
: boost::asio::detail::service_base<openssl_stream_service>(io_service),
strand_(io_service)
{
}
// Destroy all user-defined handler objects owned by the service.
void shutdown_service()
{
}
// Return a null stream implementation.
impl_type null() const
{
return 0;
}
// Create a new stream implementation.
template <typename Stream, typename Context_Service>
void create(impl_type& impl, Stream& /*next_layer*/,
basic_context<Context_Service>& context)
{
impl = new impl_struct;
impl->ssl = ::SSL_new(context.impl());
::SSL_set_mode(impl->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
::SSL_set_mode(impl->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
::BIO* int_bio = 0;
impl->ext_bio = 0;
::BIO_new_bio_pair(&int_bio, 8192, &impl->ext_bio, 8192);
::SSL_set_bio(impl->ssl, int_bio, int_bio);
}
// Destroy a stream implementation.
template <typename Stream>
void destroy(impl_type& impl, Stream& /*next_layer*/)
{
if (impl != 0)
{
::BIO_free(impl->ext_bio);
::SSL_free(impl->ssl);
delete impl;
impl = 0;
}
}
// Perform SSL handshaking.
template <typename Stream>
boost::system::error_code handshake(impl_type& impl, Stream& next_layer,
stream_base::handshake_type type, boost::system::error_code& ec)
{
try
{
openssl_operation<Stream> op(
type == stream_base::client ?
&ssl_wrap<mutex_type>::SSL_connect:
&ssl_wrap<mutex_type>::SSL_accept,
next_layer,
impl->recv_buf,
impl->ssl,
impl->ext_bio);
op.start();
}
catch (boost::system::system_error& e)
{
ec = e.code();
return ec;
}
ec = boost::system::error_code();
return ec;
}
// Start an asynchronous SSL handshake.
template <typename Stream, typename Handler>
void async_handshake(impl_type& impl, Stream& next_layer,
stream_base::handshake_type type, Handler handler)
{
typedef handshake_handler<Stream, Handler> connect_handler;
connect_handler* local_handler =
new connect_handler(handler, get_io_service());
openssl_operation<Stream>* op = new openssl_operation<Stream>
(
type == stream_base::client ?
&ssl_wrap<mutex_type>::SSL_connect:
&ssl_wrap<mutex_type>::SSL_accept,
next_layer,
impl->recv_buf,
impl->ssl,
impl->ext_bio,
boost::bind
(
&base_handler<Stream>::do_func,
local_handler,
boost::arg<1>(),
boost::arg<2>()
),
strand_
);
local_handler->set_operation(op);
strand_.post(boost::bind(&openssl_operation<Stream>::start, op));
}
// Shut down SSL on the stream.
template <typename Stream>
boost::system::error_code shutdown(impl_type& impl, Stream& next_layer,
boost::system::error_code& ec)
{
try
{
openssl_operation<Stream> op(
&ssl_wrap<mutex_type>::SSL_shutdown,
next_layer,
impl->recv_buf,
impl->ssl,
impl->ext_bio);
op.start();
}
catch (boost::system::system_error& e)
{
ec = e.code();
return ec;
}
ec = boost::system::error_code();
return ec;
}
// Asynchronously shut down SSL on the stream.
template <typename Stream, typename Handler>
void async_shutdown(impl_type& impl, Stream& next_layer, Handler handler)
{
typedef shutdown_handler<Stream, Handler> disconnect_handler;
disconnect_handler* local_handler =
new disconnect_handler(handler, get_io_service());
openssl_operation<Stream>* op = new openssl_operation<Stream>
(
&ssl_wrap<mutex_type>::SSL_shutdown,
next_layer,
impl->recv_buf,
impl->ssl,
impl->ext_bio,
boost::bind
(
&base_handler<Stream>::do_func,
local_handler,
boost::arg<1>(),
boost::arg<2>()
),
strand_
);
local_handler->set_operation(op);
strand_.post(boost::bind(&openssl_operation<Stream>::start, op));
}
// Write some data to the stream.
template <typename Stream, typename Const_Buffers>
std::size_t write_some(impl_type& impl, Stream& next_layer,
const Const_Buffers& buffers, boost::system::error_code& ec)
{
size_t bytes_transferred = 0;
try
{
boost::asio::const_buffer buffer =
boost::asio::detail::buffer_sequence_adapter<
boost::asio::const_buffer, Const_Buffers>::first(buffers);
std::size_t buffer_size = boost::asio::buffer_size(buffer);
if (buffer_size > max_buffer_size)
buffer_size = max_buffer_size;
else if (buffer_size == 0)
{
ec = boost::system::error_code();
return 0;
}
boost::function<int (SSL*)> send_func =
boost::bind(boost::type<int>(), &::SSL_write, boost::arg<1>(),
boost::asio::buffer_cast<const void*>(buffer),
static_cast<int>(buffer_size));
openssl_operation<Stream> op(
send_func,
next_layer,
impl->recv_buf,
impl->ssl,
impl->ext_bio
);
bytes_transferred = static_cast<size_t>(op.start());
}
catch (boost::system::system_error& e)
{
ec = e.code();
return 0;
}
ec = boost::system::error_code();
return bytes_transferred;
}
// Start an asynchronous write.
template <typename Stream, typename Const_Buffers, typename Handler>
void async_write_some(impl_type& impl, Stream& next_layer,
const Const_Buffers& buffers, Handler handler)
{
typedef io_handler<Stream, Handler> send_handler;
boost::asio::const_buffer buffer =
boost::asio::detail::buffer_sequence_adapter<
boost::asio::const_buffer, Const_Buffers>::first(buffers);
std::size_t buffer_size = boost::asio::buffer_size(buffer);
if (buffer_size > max_buffer_size)
buffer_size = max_buffer_size;
else if (buffer_size == 0)
{
get_io_service().post(boost::asio::detail::bind_handler(
handler, boost::system::error_code(), 0));
return;
}
send_handler* local_handler = new send_handler(handler, get_io_service());
boost::function<int (SSL*)> send_func =
boost::bind(boost::type<int>(), &::SSL_write, boost::arg<1>(),
boost::asio::buffer_cast<const void*>(buffer),
static_cast<int>(buffer_size));
openssl_operation<Stream>* op = new openssl_operation<Stream>
(
send_func,
next_layer,
impl->recv_buf,
impl->ssl,
impl->ext_bio,
boost::bind
(
&base_handler<Stream>::do_func,
local_handler,
boost::arg<1>(),
boost::arg<2>()
),
strand_
);
local_handler->set_operation(op);
strand_.post(boost::bind(&openssl_operation<Stream>::start, op));
}
// Read some data from the stream.
template <typename Stream, typename Mutable_Buffers>
std::size_t read_some(impl_type& impl, Stream& next_layer,
const Mutable_Buffers& buffers, boost::system::error_code& ec)
{
size_t bytes_transferred = 0;
try
{
boost::asio::mutable_buffer buffer =
boost::asio::detail::buffer_sequence_adapter<
boost::asio::mutable_buffer, Mutable_Buffers>::first(buffers);
std::size_t buffer_size = boost::asio::buffer_size(buffer);
if (buffer_size > max_buffer_size)
buffer_size = max_buffer_size;
else if (buffer_size == 0)
{
ec = boost::system::error_code();
return 0;
}
boost::function<int (SSL*)> recv_func =
boost::bind(boost::type<int>(), &::SSL_read, boost::arg<1>(),
boost::asio::buffer_cast<void*>(buffer),
static_cast<int>(buffer_size));
openssl_operation<Stream> op(recv_func,
next_layer,
impl->recv_buf,
impl->ssl,
impl->ext_bio
);
bytes_transferred = static_cast<size_t>(op.start());
}
catch (boost::system::system_error& e)
{
ec = e.code();
return 0;
}
ec = boost::system::error_code();
return bytes_transferred;
}
// Start an asynchronous read.
template <typename Stream, typename Mutable_Buffers, typename Handler>
void async_read_some(impl_type& impl, Stream& next_layer,
const Mutable_Buffers& buffers, Handler handler)
{
typedef io_handler<Stream, Handler> recv_handler;
boost::asio::mutable_buffer buffer =
boost::asio::detail::buffer_sequence_adapter<
boost::asio::mutable_buffer, Mutable_Buffers>::first(buffers);
std::size_t buffer_size = boost::asio::buffer_size(buffer);
if (buffer_size > max_buffer_size)
buffer_size = max_buffer_size;
else if (buffer_size == 0)
{
get_io_service().post(boost::asio::detail::bind_handler(
handler, boost::system::error_code(), 0));
return;
}
recv_handler* local_handler = new recv_handler(handler, get_io_service());
boost::function<int (SSL*)> recv_func =
boost::bind(boost::type<int>(), &::SSL_read, boost::arg<1>(),
boost::asio::buffer_cast<void*>(buffer),
static_cast<int>(buffer_size));
openssl_operation<Stream>* op = new openssl_operation<Stream>
(
recv_func,
next_layer,
impl->recv_buf,
impl->ssl,
impl->ext_bio,
boost::bind
(
&base_handler<Stream>::do_func,
local_handler,
boost::arg<1>(),
boost::arg<2>()
),
strand_
);
local_handler->set_operation(op);
strand_.post(boost::bind(&openssl_operation<Stream>::start, op));
}
// Peek at the incoming data on the stream.
template <typename Stream, typename Mutable_Buffers>
std::size_t peek(impl_type& /*impl*/, Stream& /*next_layer*/,
const Mutable_Buffers& /*buffers*/, boost::system::error_code& ec)
{
ec = boost::system::error_code();
return 0;
}
// Determine the amount of data that may be read without blocking.
template <typename Stream>
std::size_t in_avail(impl_type& /*impl*/, Stream& /*next_layer*/,
boost::system::error_code& ec)
{
ec = boost::system::error_code();
return 0;
}
private:
boost::asio::io_service::strand strand_;
typedef boost::asio::detail::mutex mutex_type;
template<typename Mutex>
struct ssl_wrap
{
static Mutex ssl_mutex_;
static int SSL_accept(SSL *ssl)
{
typename Mutex::scoped_lock lock(ssl_mutex_);
return ::SSL_accept(ssl);
}
static int SSL_connect(SSL *ssl)
{
typename Mutex::scoped_lock lock(ssl_mutex_);
return ::SSL_connect(ssl);
}
static int SSL_shutdown(SSL *ssl)
{
typename Mutex::scoped_lock lock(ssl_mutex_);
return ::SSL_shutdown(ssl);
}
};
};
template<typename Mutex>
Mutex openssl_stream_service::ssl_wrap<Mutex>::ssl_mutex_;
} // namespace detail
} // namespace old
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_OLD_DETAIL_OPENSSL_STREAM_SERVICE_HPP

View File

@@ -0,0 +1,503 @@
//
// ssl/old/stream.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
// Copyright (c) 2005-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_OLD_STREAM_HPP
#define BOOST_ASIO_SSL_OLD_STREAM_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <cstddef>
#include <boost/noncopyable.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
#include <boost/asio/ssl/basic_context.hpp>
#include <boost/asio/ssl/stream_base.hpp>
#include <boost/asio/ssl/stream_service.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
namespace old {
/// Provides stream-oriented functionality using SSL.
/**
* The stream class template provides asynchronous and blocking stream-oriented
* functionality using SSL.
*
* @par Thread Safety
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*
* @par Example
* To use the SSL stream template with an ip::tcp::socket, you would write:
* @code
* boost::asio::io_service io_service;
* boost::asio::ssl::context context(io_service, boost::asio::ssl::context::sslv23);
* boost::asio::ssl::stream<boost::asio::ip::tcp::socket> sock(io_service, context);
* @endcode
*
* @par Concepts:
* AsyncReadStream, AsyncWriteStream, Stream, SyncRead_Stream, SyncWriteStream.
*/
template <typename Stream, typename Service = old::stream_service>
class stream
: public stream_base,
private boost::noncopyable
{
public:
/// The type of the next layer.
typedef typename boost::remove_reference<Stream>::type next_layer_type;
/// The type of the lowest layer.
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
/// The type of the service that will be used to provide stream operations.
typedef Service service_type;
/// The native implementation type of the stream.
typedef typename service_type::impl_type impl_type;
/// Construct a stream.
/**
* This constructor creates a stream and initialises the underlying stream
* object.
*
* @param arg The argument to be passed to initialise the underlying stream.
*
* @param context The SSL context to be used for the stream.
*/
template <typename Arg, typename Context_Service>
explicit stream(Arg& arg, basic_context<Context_Service>& context)
: next_layer_(arg),
service_(boost::asio::use_service<Service>(next_layer_.get_io_service())),
impl_(service_.null())
{
service_.create(impl_, next_layer_, context);
}
/// Destructor.
~stream()
{
service_.destroy(impl_, next_layer_);
}
/// Get the io_service associated with the object.
/**
* This function may be used to obtain the io_service object that the stream
* uses to dispatch handlers for asynchronous operations.
*
* @return A reference to the io_service object that stream will use to
* dispatch handlers. Ownership is not transferred to the caller.
*/
boost::asio::io_service& get_io_service()
{
return next_layer_.get_io_service();
}
/// Get a reference to the next layer.
/**
* This function returns a reference to the next layer in a stack of stream
* layers.
*
* @return A reference to the next layer in the stack of stream layers.
* Ownership is not transferred to the caller.
*/
next_layer_type& next_layer()
{
return next_layer_;
}
/// Get a reference to the lowest layer.
/**
* This function returns a reference to the lowest layer in a stack of
* stream layers.
*
* @return A reference to the lowest layer in the stack of stream layers.
* Ownership is not transferred to the caller.
*/
lowest_layer_type& lowest_layer()
{
return next_layer_.lowest_layer();
}
/// Get a const reference to the lowest layer.
/**
* This function returns a const reference to the lowest layer in a stack of
* stream layers.
*
* @return A const reference to the lowest layer in the stack of stream
* layers. Ownership is not transferred to the caller.
*/
const lowest_layer_type& lowest_layer() const
{
return next_layer_.lowest_layer();
}
/// Get the underlying implementation in the native type.
/**
* This function may be used to obtain the underlying implementation of the
* context. This is intended to allow access to stream functionality that is
* not otherwise provided.
*/
impl_type impl()
{
return impl_;
}
/// Perform SSL handshaking.
/**
* This function is used to perform SSL handshaking on the stream. The
* function call will block until handshaking is complete or an error occurs.
*
* @param type The type of handshaking to be performed, i.e. as a client or as
* a server.
*
* @throws boost::system::system_error Thrown on failure.
*/
void handshake(handshake_type type)
{
boost::system::error_code ec;
service_.handshake(impl_, next_layer_, type, ec);
boost::asio::detail::throw_error(ec);
}
/// Perform SSL handshaking.
/**
* This function is used to perform SSL handshaking on the stream. The
* function call will block until handshaking is complete or an error occurs.
*
* @param type The type of handshaking to be performed, i.e. as a client or as
* a server.
*
* @param ec Set to indicate what error occurred, if any.
*/
boost::system::error_code handshake(handshake_type type,
boost::system::error_code& ec)
{
return service_.handshake(impl_, next_layer_, type, ec);
}
/// Start an asynchronous SSL handshake.
/**
* This function is used to asynchronously perform an SSL handshake on the
* stream. This function call always returns immediately.
*
* @param type The type of handshaking to be performed, i.e. as a client or as
* a server.
*
* @param handler The handler to be called when the handshake operation
* completes. Copies will be made of the handler as required. The equivalent
* function signature of the handler must be:
* @code void handler(
* const boost::system::error_code& error // Result of operation.
* ); @endcode
*/
template <typename HandshakeHandler>
void async_handshake(handshake_type type, HandshakeHandler handler)
{
service_.async_handshake(impl_, next_layer_, type, handler);
}
/// Shut down SSL on the stream.
/**
* This function is used to shut down SSL on the stream. The function call
* will block until SSL has been shut down or an error occurs.
*
* @throws boost::system::system_error Thrown on failure.
*/
void shutdown()
{
boost::system::error_code ec;
service_.shutdown(impl_, next_layer_, ec);
boost::asio::detail::throw_error(ec);
}
/// Shut down SSL on the stream.
/**
* This function is used to shut down SSL on the stream. The function call
* will block until SSL has been shut down or an error occurs.
*
* @param ec Set to indicate what error occurred, if any.
*/
boost::system::error_code shutdown(boost::system::error_code& ec)
{
return service_.shutdown(impl_, next_layer_, ec);
}
/// Asynchronously shut down SSL on the stream.
/**
* This function is used to asynchronously shut down SSL on the stream. This
* function call always returns immediately.
*
* @param handler The handler to be called when the handshake operation
* completes. Copies will be made of the handler as required. The equivalent
* function signature of the handler must be:
* @code void handler(
* const boost::system::error_code& error // Result of operation.
* ); @endcode
*/
template <typename ShutdownHandler>
void async_shutdown(ShutdownHandler handler)
{
service_.async_shutdown(impl_, next_layer_, handler);
}
/// Write some data to the stream.
/**
* This function is used to write data on the stream. The function call will
* block until one or more bytes of data has been written successfully, or
* until an error occurs.
*
* @param buffers The data to be written.
*
* @returns The number of bytes written.
*
* @throws boost::system::system_error Thrown on failure.
*
* @note The write_some operation may not transmit all of the data to the
* peer. Consider using the @ref write function if you need to ensure that all
* data is written before the blocking operation completes.
*/
template <typename ConstBufferSequence>
std::size_t write_some(const ConstBufferSequence& buffers)
{
boost::system::error_code ec;
std::size_t s = service_.write_some(impl_, next_layer_, buffers, ec);
boost::asio::detail::throw_error(ec);
return s;
}
/// Write some data to the stream.
/**
* This function is used to write data on the stream. The function call will
* block until one or more bytes of data has been written successfully, or
* until an error occurs.
*
* @param buffers The data to be written to the stream.
*
* @param ec Set to indicate what error occurred, if any.
*
* @returns The number of bytes written. Returns 0 if an error occurred.
*
* @note The write_some operation may not transmit all of the data to the
* peer. Consider using the @ref write function if you need to ensure that all
* data is written before the blocking operation completes.
*/
template <typename ConstBufferSequence>
std::size_t write_some(const ConstBufferSequence& buffers,
boost::system::error_code& ec)
{
return service_.write_some(impl_, next_layer_, buffers, ec);
}
/// Start an asynchronous write.
/**
* This function is used to asynchronously write one or more bytes of data to
* the stream. The function call always returns immediately.
*
* @param buffers The data to be written to the stream. Although the buffers
* object may be copied as necessary, ownership of the underlying buffers is
* retained by the caller, which must guarantee that they remain valid until
* the handler is called.
*
* @param handler The handler to be called when the write operation completes.
* Copies will be made of the handler as required. The equivalent function
* signature of the handler must be:
* @code void handler(
* const boost::system::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes written.
* ); @endcode
*
* @note The async_write_some operation may not transmit all of the data to
* the peer. Consider using the @ref async_write function if you need to
* ensure that all data is written before the blocking operation completes.
*/
template <typename ConstBufferSequence, typename WriteHandler>
void async_write_some(const ConstBufferSequence& buffers,
WriteHandler handler)
{
service_.async_write_some(impl_, next_layer_, buffers, handler);
}
/// Read some data from the stream.
/**
* This function is used to read data from the stream. The function call will
* block until one or more bytes of data has been read successfully, or until
* an error occurs.
*
* @param buffers The buffers into which the data will be read.
*
* @returns The number of bytes read.
*
* @throws boost::system::system_error Thrown on failure.
*
* @note The read_some operation may not read all of the requested number of
* bytes. Consider using the @ref read function if you need to ensure that the
* requested amount of data is read before the blocking operation completes.
*/
template <typename MutableBufferSequence>
std::size_t read_some(const MutableBufferSequence& buffers)
{
boost::system::error_code ec;
std::size_t s = service_.read_some(impl_, next_layer_, buffers, ec);
boost::asio::detail::throw_error(ec);
return s;
}
/// Read some data from the stream.
/**
* This function is used to read data from the stream. The function call will
* block until one or more bytes of data has been read successfully, or until
* an error occurs.
*
* @param buffers The buffers into which the data will be read.
*
* @param ec Set to indicate what error occurred, if any.
*
* @returns The number of bytes read. Returns 0 if an error occurred.
*
* @note The read_some operation may not read all of the requested number of
* bytes. Consider using the @ref read function if you need to ensure that the
* requested amount of data is read before the blocking operation completes.
*/
template <typename MutableBufferSequence>
std::size_t read_some(const MutableBufferSequence& buffers,
boost::system::error_code& ec)
{
return service_.read_some(impl_, next_layer_, buffers, ec);
}
/// Start an asynchronous read.
/**
* This function is used to asynchronously read one or more bytes of data from
* the stream. The function call always returns immediately.
*
* @param buffers The buffers into which the data will be read. Although the
* buffers object may be copied as necessary, ownership of the underlying
* buffers is retained by the caller, which must guarantee that they remain
* valid until the handler is called.
*
* @param handler The handler to be called when the read operation completes.
* Copies will be made of the handler as required. The equivalent function
* signature of the handler must be:
* @code void handler(
* const boost::system::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes read.
* ); @endcode
*
* @note The async_read_some operation may not read all of the requested
* number of bytes. Consider using the @ref async_read function if you need to
* ensure that the requested amount of data is read before the asynchronous
* operation completes.
*/
template <typename MutableBufferSequence, typename ReadHandler>
void async_read_some(const MutableBufferSequence& buffers,
ReadHandler handler)
{
service_.async_read_some(impl_, next_layer_, buffers, handler);
}
/// Peek at the incoming data on the stream.
/**
* This function is used to peek at the incoming data on the stream, without
* removing it from the input queue. The function call will block until data
* has been read successfully or an error occurs.
*
* @param buffers The buffers into which the data will be read.
*
* @returns The number of bytes read.
*
* @throws boost::system::system_error Thrown on failure.
*/
template <typename MutableBufferSequence>
std::size_t peek(const MutableBufferSequence& buffers)
{
boost::system::error_code ec;
std::size_t s = service_.peek(impl_, next_layer_, buffers, ec);
boost::asio::detail::throw_error(ec);
return s;
}
/// Peek at the incoming data on the stream.
/**
* This function is used to peek at the incoming data on the stream, withoutxi
* removing it from the input queue. The function call will block until data
* has been read successfully or an error occurs.
*
* @param buffers The buffers into which the data will be read.
*
* @param ec Set to indicate what error occurred, if any.
*
* @returns The number of bytes read. Returns 0 if an error occurred.
*/
template <typename MutableBufferSequence>
std::size_t peek(const MutableBufferSequence& buffers,
boost::system::error_code& ec)
{
return service_.peek(impl_, next_layer_, buffers, ec);
}
/// Determine the amount of data that may be read without blocking.
/**
* This function is used to determine the amount of data, in bytes, that may
* be read from the stream without blocking.
*
* @returns The number of bytes of data that can be read without blocking.
*
* @throws boost::system::system_error Thrown on failure.
*/
std::size_t in_avail()
{
boost::system::error_code ec;
std::size_t s = service_.in_avail(impl_, next_layer_, ec);
boost::asio::detail::throw_error(ec);
return s;
}
/// Determine the amount of data that may be read without blocking.
/**
* This function is used to determine the amount of data, in bytes, that may
* be read from the stream without blocking.
*
* @param ec Set to indicate what error occurred, if any.
*
* @returns The number of bytes of data that can be read without blocking.
*/
std::size_t in_avail(boost::system::error_code& ec)
{
return service_.in_avail(impl_, next_layer_, ec);
}
private:
/// The next layer.
Stream next_layer_;
/// The backend service implementation.
service_type& service_;
/// The underlying native implementation.
impl_type impl_;
};
} // namespace old
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_OLD_STREAM_HPP

View File

@@ -0,0 +1,186 @@
//
// ssl/old/stream_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
// Copyright (c) 2005-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_OLD_STREAM_SERVICE_HPP
#define BOOST_ASIO_SSL_OLD_STREAM_SERVICE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <cstddef>
#include <boost/noncopyable.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/ssl/basic_context.hpp>
#include <boost/asio/ssl/old/detail/openssl_stream_service.hpp>
#include <boost/asio/ssl/stream_base.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
namespace old {
/// Default service implementation for an SSL stream.
class stream_service
#if defined(GENERATING_DOCUMENTATION)
: public boost::asio::io_service::service
#else
: public boost::asio::detail::service_base<stream_service>
#endif
{
private:
// The type of the platform-specific implementation.
typedef old::detail::openssl_stream_service service_impl_type;
public:
#if defined(GENERATING_DOCUMENTATION)
/// The unique service identifier.
static boost::asio::io_service::id id;
#endif
/// The type of a stream implementation.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined impl_type;
#else
typedef service_impl_type::impl_type impl_type;
#endif
/// Construct a new stream service for the specified io_service.
explicit stream_service(boost::asio::io_service& io_service)
: boost::asio::detail::service_base<stream_service>(io_service),
service_impl_(boost::asio::use_service<service_impl_type>(io_service))
{
}
/// Return a null stream implementation.
impl_type null() const
{
return service_impl_.null();
}
/// Create a new stream implementation.
template <typename Stream, typename Context_Service>
void create(impl_type& impl, Stream& next_layer,
basic_context<Context_Service>& context)
{
service_impl_.create(impl, next_layer, context);
}
/// Destroy a stream implementation.
template <typename Stream>
void destroy(impl_type& impl, Stream& next_layer)
{
service_impl_.destroy(impl, next_layer);
}
/// Perform SSL handshaking.
template <typename Stream>
boost::system::error_code handshake(impl_type& impl, Stream& next_layer,
stream_base::handshake_type type, boost::system::error_code& ec)
{
return service_impl_.handshake(impl, next_layer, type, ec);
}
/// Start an asynchronous SSL handshake.
template <typename Stream, typename HandshakeHandler>
void async_handshake(impl_type& impl, Stream& next_layer,
stream_base::handshake_type type, HandshakeHandler handler)
{
service_impl_.async_handshake(impl, next_layer, type, handler);
}
/// Shut down SSL on the stream.
template <typename Stream>
boost::system::error_code shutdown(impl_type& impl, Stream& next_layer,
boost::system::error_code& ec)
{
return service_impl_.shutdown(impl, next_layer, ec);
}
/// Asynchronously shut down SSL on the stream.
template <typename Stream, typename ShutdownHandler>
void async_shutdown(impl_type& impl, Stream& next_layer,
ShutdownHandler handler)
{
service_impl_.async_shutdown(impl, next_layer, handler);
}
/// Write some data to the stream.
template <typename Stream, typename ConstBufferSequence>
std::size_t write_some(impl_type& impl, Stream& next_layer,
const ConstBufferSequence& buffers, boost::system::error_code& ec)
{
return service_impl_.write_some(impl, next_layer, buffers, ec);
}
/// Start an asynchronous write.
template <typename Stream, typename ConstBufferSequence,
typename WriteHandler>
void async_write_some(impl_type& impl, Stream& next_layer,
const ConstBufferSequence& buffers, WriteHandler handler)
{
service_impl_.async_write_some(impl, next_layer, buffers, handler);
}
/// Read some data from the stream.
template <typename Stream, typename MutableBufferSequence>
std::size_t read_some(impl_type& impl, Stream& next_layer,
const MutableBufferSequence& buffers, boost::system::error_code& ec)
{
return service_impl_.read_some(impl, next_layer, buffers, ec);
}
/// Start an asynchronous read.
template <typename Stream, typename MutableBufferSequence,
typename ReadHandler>
void async_read_some(impl_type& impl, Stream& next_layer,
const MutableBufferSequence& buffers, ReadHandler handler)
{
service_impl_.async_read_some(impl, next_layer, buffers, handler);
}
/// Peek at the incoming data on the stream.
template <typename Stream, typename MutableBufferSequence>
std::size_t peek(impl_type& impl, Stream& next_layer,
const MutableBufferSequence& buffers, boost::system::error_code& ec)
{
return service_impl_.peek(impl, next_layer, buffers, ec);
}
/// Determine the amount of data that may be read without blocking.
template <typename Stream>
std::size_t in_avail(impl_type& impl, Stream& next_layer,
boost::system::error_code& ec)
{
return service_impl_.in_avail(impl, next_layer, ec);
}
private:
// Destroy all user-defined handler objects owned by the service.
void shutdown_service()
{
}
// The service that provides the platform-specific implementation.
service_impl_type& service_impl_;
};
} // namespace old
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_OLD_STREAM_SERVICE_HPP

View File

@@ -0,0 +1,102 @@
//
// ssl/rfc2818_verification.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_RFC2818_VERIFICATION_HPP
#define BOOST_ASIO_SSL_RFC2818_VERIFICATION_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <string>
# include <boost/asio/ssl/detail/openssl_types.hpp>
# include <boost/asio/ssl/verify_context.hpp>
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
/// Verifies a certificate against a hostname according to the rules described
/// in RFC 2818.
/**
* @par Example
* The following example shows how to synchronously open a secure connection to
* a given host name:
* @code
* using boost::asio::ip::tcp;
* namespace ssl = boost::asio::ssl;
* typedef ssl::stream<tcp::socket> ssl_socket;
*
* // Create a context that uses the default paths for finding CA certificates.
* ssl::context ctx(ssl::context::sslv23);
* ctx.set_default_verify_paths();
*
* // Open a socket and connect it to the remote host.
* boost::asio::io_service io_service;
* ssl_socket sock(io_service, ctx);
* tcp::resolver resolver(io_service);
* tcp::resolver::query query("host.name", "https");
* boost::asio::connect(sock.lowest_layer(), resolver.resolve(query));
* sock.lowest_layer().set_option(tcp::no_delay(true));
*
* // Perform SSL handshake and verify the remote host's certificate.
* sock.set_verify_mode(ssl::verify_peer);
* sock.set_verify_callback(ssl::rfc2818_verification("host.name"));
* sock.handshake(ssl_socket::client);
*
* // ... read and write as normal ...
* @endcode
*/
class rfc2818_verification
{
public:
/// The type of the function object's result.
typedef bool result_type;
/// Constructor.
explicit rfc2818_verification(const std::string& host)
: host_(host)
{
}
/// Perform certificate verification.
BOOST_ASIO_DECL bool operator()(bool preverified, verify_context& ctx) const;
private:
// Helper function to check a host name against a pattern.
BOOST_ASIO_DECL static bool match_pattern(const char* pattern,
std::size_t pattern_length, const char* host);
// Helper function to check a host name against an IPv4 address
// The host name to be checked.
std::string host_;
};
#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#if defined(BOOST_ASIO_HEADER_ONLY)
# include <boost/asio/ssl/impl/rfc2818_verification.ipp>
#endif // defined(BOOST_ASIO_HEADER_ONLY)
#endif // BOOST_ASIO_SSL_RFC2818_VERIFICATION_HPP

606
test/external/boost/asio/ssl/stream.hpp vendored Normal file
View File

@@ -0,0 +1,606 @@
//
// ssl/stream.hpp
// ~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_STREAM_HPP
#define BOOST_ASIO_SSL_STREAM_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <boost/asio/ssl/old/stream.hpp>
#else // defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <boost/asio/detail/buffer_sequence_adapter.hpp>
# include <boost/asio/detail/handler_type_requirements.hpp>
# include <boost/asio/detail/noncopyable.hpp>
# include <boost/asio/ssl/context.hpp>
# include <boost/asio/ssl/detail/handshake_op.hpp>
# include <boost/asio/ssl/detail/io.hpp>
# include <boost/asio/ssl/detail/read_op.hpp>
# include <boost/asio/ssl/detail/shutdown_op.hpp>
# include <boost/asio/ssl/detail/stream_core.hpp>
# include <boost/asio/ssl/detail/write_op.hpp>
# include <boost/asio/ssl/stream_base.hpp>
# include <boost/type_traits/remove_reference.hpp>
#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
using boost::asio::ssl::old::stream;
#else // defined(BOOST_ASIO_ENABLE_OLD_SSL)
/// Provides stream-oriented functionality using SSL.
/**
* The stream class template provides asynchronous and blocking stream-oriented
* functionality using SSL.
*
* @par Thread Safety
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe. The application must also ensure that all
* asynchronous operations are performed within the same implicit or explicit
* strand.
*
* @par Example
* To use the SSL stream template with an ip::tcp::socket, you would write:
* @code
* boost::asio::io_service io_service;
* boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
* boost::asio::ssl::stream<asio:ip::tcp::socket> sock(io_service, ctx);
* @endcode
*
* @par Concepts:
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
*/
template <typename Stream>
class stream :
public stream_base,
private noncopyable
{
public:
/// The native handle type of the SSL stream.
typedef SSL* native_handle_type;
/// Structure for use with deprecated impl_type.
struct impl_struct
{
SSL* ssl;
};
/// (Deprecated: Use native_handle_type.) The underlying implementation type.
typedef impl_struct* impl_type;
/// The type of the next layer.
typedef typename boost::remove_reference<Stream>::type next_layer_type;
/// The type of the lowest layer.
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
/// Construct a stream.
/**
* This constructor creates a stream and initialises the underlying stream
* object.
*
* @param arg The argument to be passed to initialise the underlying stream.
*
* @param ctx The SSL context to be used for the stream.
*/
template <typename Arg>
stream(Arg& arg, context& ctx)
: next_layer_(arg),
core_(ctx.native_handle(), next_layer_.lowest_layer().get_io_service())
{
backwards_compatible_impl_.ssl = core_.engine_.native_handle();
}
/// Destructor.
~stream()
{
}
/// Get the io_service associated with the object.
/**
* This function may be used to obtain the io_service object that the stream
* uses to dispatch handlers for asynchronous operations.
*
* @return A reference to the io_service object that stream will use to
* dispatch handlers. Ownership is not transferred to the caller.
*/
boost::asio::io_service& get_io_service()
{
return next_layer_.lowest_layer().get_io_service();
}
/// Get the underlying implementation in the native type.
/**
* This function may be used to obtain the underlying implementation of the
* context. This is intended to allow access to context functionality that is
* not otherwise provided.
*
* @par Example
* The native_handle() function returns a pointer of type @c SSL* that is
* suitable for passing to functions such as @c SSL_get_verify_result and
* @c SSL_get_peer_certificate:
* @code
* boost::asio::ssl::stream<asio:ip::tcp::socket> sock(io_service, ctx);
*
* // ... establish connection and perform handshake ...
*
* if (X509* cert = SSL_get_peer_certificate(sock.native_handle()))
* {
* if (SSL_get_verify_result(sock.native_handle()) == X509_V_OK)
* {
* // ...
* }
* }
* @endcode
*/
native_handle_type native_handle()
{
return core_.engine_.native_handle();
}
/// (Deprecated: Use native_handle().) Get the underlying implementation in
/// the native type.
/**
* This function may be used to obtain the underlying implementation of the
* context. This is intended to allow access to stream functionality that is
* not otherwise provided.
*/
impl_type impl()
{
return &backwards_compatible_impl_;
}
/// Get a reference to the next layer.
/**
* This function returns a reference to the next layer in a stack of stream
* layers.
*
* @return A reference to the next layer in the stack of stream layers.
* Ownership is not transferred to the caller.
*/
const next_layer_type& next_layer() const
{
return next_layer_;
}
/// Get a reference to the next layer.
/**
* This function returns a reference to the next layer in a stack of stream
* layers.
*
* @return A reference to the next layer in the stack of stream layers.
* Ownership is not transferred to the caller.
*/
next_layer_type& next_layer()
{
return next_layer_;
}
/// Get a reference to the lowest layer.
/**
* This function returns a reference to the lowest layer in a stack of
* stream layers.
*
* @return A reference to the lowest layer in the stack of stream layers.
* Ownership is not transferred to the caller.
*/
lowest_layer_type& lowest_layer()
{
return next_layer_.lowest_layer();
}
/// Get a reference to the lowest layer.
/**
* This function returns a reference to the lowest layer in a stack of
* stream layers.
*
* @return A reference to the lowest layer in the stack of stream layers.
* Ownership is not transferred to the caller.
*/
const lowest_layer_type& lowest_layer() const
{
return next_layer_.lowest_layer();
}
/// Set the peer verification mode.
/**
* This function may be used to configure the peer verification mode used by
* the stream. The new mode will override the mode inherited from the context.
*
* @param v A bitmask of peer verification modes. See @ref verify_mode for
* available values.
*
* @throws boost::system::system_error Thrown on failure.
*
* @note Calls @c SSL_set_verify.
*/
void set_verify_mode(verify_mode v)
{
boost::system::error_code ec;
set_verify_mode(v, ec);
boost::asio::detail::throw_error(ec, "set_verify_mode");
}
/// Set the peer verification mode.
/**
* This function may be used to configure the peer verification mode used by
* the stream. The new mode will override the mode inherited from the context.
*
* @param v A bitmask of peer verification modes. See @ref verify_mode for
* available values.
*
* @param ec Set to indicate what error occurred, if any.
*
* @note Calls @c SSL_set_verify.
*/
boost::system::error_code set_verify_mode(
verify_mode v, boost::system::error_code& ec)
{
return core_.engine_.set_verify_mode(v, ec);
}
/// Set the callback used to verify peer certificates.
/**
* This function is used to specify a callback function that will be called
* by the implementation when it needs to verify a peer certificate.
*
* @param callback The function object to be used for verifying a certificate.
* The function signature of the handler must be:
* @code bool verify_callback(
* bool preverified, // True if the certificate passed pre-verification.
* verify_context& ctx // The peer certificate and other context.
* ); @endcode
* The return value of the callback is true if the certificate has passed
* verification, false otherwise.
*
* @throws boost::system::system_error Thrown on failure.
*
* @note Calls @c SSL_set_verify.
*/
template <typename VerifyCallback>
void set_verify_callback(VerifyCallback callback)
{
boost::system::error_code ec;
this->set_verify_callback(callback, ec);
boost::asio::detail::throw_error(ec, "set_verify_callback");
}
/// Set the callback used to verify peer certificates.
/**
* This function is used to specify a callback function that will be called
* by the implementation when it needs to verify a peer certificate.
*
* @param callback The function object to be used for verifying a certificate.
* The function signature of the handler must be:
* @code bool verify_callback(
* bool preverified, // True if the certificate passed pre-verification.
* verify_context& ctx // The peer certificate and other context.
* ); @endcode
* The return value of the callback is true if the certificate has passed
* verification, false otherwise.
*
* @param ec Set to indicate what error occurred, if any.
*
* @note Calls @c SSL_set_verify.
*/
template <typename VerifyCallback>
boost::system::error_code set_verify_callback(VerifyCallback callback,
boost::system::error_code& ec)
{
return core_.engine_.set_verify_callback(
new detail::verify_callback<VerifyCallback>(callback), ec);
}
/// Perform SSL handshaking.
/**
* This function is used to perform SSL handshaking on the stream. The
* function call will block until handshaking is complete or an error occurs.
*
* @param type The type of handshaking to be performed, i.e. as a client or as
* a server.
*
* @throws boost::system::system_error Thrown on failure.
*/
void handshake(handshake_type type)
{
boost::system::error_code ec;
handshake(type, ec);
boost::asio::detail::throw_error(ec, "handshake");
}
/// Perform SSL handshaking.
/**
* This function is used to perform SSL handshaking on the stream. The
* function call will block until handshaking is complete or an error occurs.
*
* @param type The type of handshaking to be performed, i.e. as a client or as
* a server.
*
* @param ec Set to indicate what error occurred, if any.
*/
boost::system::error_code handshake(handshake_type type,
boost::system::error_code& ec)
{
detail::io(next_layer_, core_, detail::handshake_op(type), ec);
return ec;
}
/// Start an asynchronous SSL handshake.
/**
* This function is used to asynchronously perform an SSL handshake on the
* stream. This function call always returns immediately.
*
* @param type The type of handshaking to be performed, i.e. as a client or as
* a server.
*
* @param handler The handler to be called when the handshake operation
* completes. Copies will be made of the handler as required. The equivalent
* function signature of the handler must be:
* @code void handler(
* const boost::system::error_code& error // Result of operation.
* ); @endcode
*/
template <typename HandshakeHandler>
void async_handshake(handshake_type type,
BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a HandshakeHandler.
BOOST_ASIO_HANDSHAKE_HANDLER_CHECK(HandshakeHandler, handler) type_check;
detail::async_io(next_layer_, core_, detail::handshake_op(type),
BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler));
}
/// Shut down SSL on the stream.
/**
* This function is used to shut down SSL on the stream. The function call
* will block until SSL has been shut down or an error occurs.
*
* @throws boost::system::system_error Thrown on failure.
*/
void shutdown()
{
boost::system::error_code ec;
shutdown(ec);
boost::asio::detail::throw_error(ec, "shutdown");
}
/// Shut down SSL on the stream.
/**
* This function is used to shut down SSL on the stream. The function call
* will block until SSL has been shut down or an error occurs.
*
* @param ec Set to indicate what error occurred, if any.
*/
boost::system::error_code shutdown(boost::system::error_code& ec)
{
detail::io(next_layer_, core_, detail::shutdown_op(), ec);
return ec;
}
/// Asynchronously shut down SSL on the stream.
/**
* This function is used to asynchronously shut down SSL on the stream. This
* function call always returns immediately.
*
* @param handler The handler to be called when the handshake operation
* completes. Copies will be made of the handler as required. The equivalent
* function signature of the handler must be:
* @code void handler(
* const boost::system::error_code& error // Result of operation.
* ); @endcode
*/
template <typename ShutdownHandler>
void async_shutdown(BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ShutdownHandler.
BOOST_ASIO_SHUTDOWN_HANDLER_CHECK(ShutdownHandler, handler) type_check;
detail::async_io(next_layer_, core_, detail::shutdown_op(),
BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler));
}
/// Write some data to the stream.
/**
* This function is used to write data on the stream. The function call will
* block until one or more bytes of data has been written successfully, or
* until an error occurs.
*
* @param buffers The data to be written.
*
* @returns The number of bytes written.
*
* @throws boost::system::system_error Thrown on failure.
*
* @note The write_some operation may not transmit all of the data to the
* peer. Consider using the @ref write function if you need to ensure that all
* data is written before the blocking operation completes.
*/
template <typename ConstBufferSequence>
std::size_t write_some(const ConstBufferSequence& buffers)
{
boost::system::error_code ec;
std::size_t n = write_some(buffers, ec);
boost::asio::detail::throw_error(ec, "write_some");
return n;
}
/// Write some data to the stream.
/**
* This function is used to write data on the stream. The function call will
* block until one or more bytes of data has been written successfully, or
* until an error occurs.
*
* @param buffers The data to be written to the stream.
*
* @param ec Set to indicate what error occurred, if any.
*
* @returns The number of bytes written. Returns 0 if an error occurred.
*
* @note The write_some operation may not transmit all of the data to the
* peer. Consider using the @ref write function if you need to ensure that all
* data is written before the blocking operation completes.
*/
template <typename ConstBufferSequence>
std::size_t write_some(const ConstBufferSequence& buffers,
boost::system::error_code& ec)
{
return detail::io(next_layer_, core_,
detail::write_op<ConstBufferSequence>(buffers), ec);
}
/// Start an asynchronous write.
/**
* This function is used to asynchronously write one or more bytes of data to
* the stream. The function call always returns immediately.
*
* @param buffers The data to be written to the stream. Although the buffers
* object may be copied as necessary, ownership of the underlying buffers is
* retained by the caller, which must guarantee that they remain valid until
* the handler is called.
*
* @param handler The handler to be called when the write operation completes.
* Copies will be made of the handler as required. The equivalent function
* signature of the handler must be:
* @code void handler(
* const boost::system::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes written.
* ); @endcode
*
* @note The async_write_some operation may not transmit all of the data to
* the peer. Consider using the @ref async_write function if you need to
* ensure that all data is written before the blocking operation completes.
*/
template <typename ConstBufferSequence, typename WriteHandler>
void async_write_some(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::async_io(next_layer_, core_,
detail::write_op<ConstBufferSequence>(buffers),
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
}
/// Read some data from the stream.
/**
* This function is used to read data from the stream. The function call will
* block until one or more bytes of data has been read successfully, or until
* an error occurs.
*
* @param buffers The buffers into which the data will be read.
*
* @returns The number of bytes read.
*
* @throws boost::system::system_error Thrown on failure.
*
* @note The read_some operation may not read all of the requested number of
* bytes. Consider using the @ref read function if you need to ensure that the
* requested amount of data is read before the blocking operation completes.
*/
template <typename MutableBufferSequence>
std::size_t read_some(const MutableBufferSequence& buffers)
{
boost::system::error_code ec;
std::size_t n = read_some(buffers, ec);
boost::asio::detail::throw_error(ec, "read_some");
return n;
}
/// Read some data from the stream.
/**
* This function is used to read data from the stream. The function call will
* block until one or more bytes of data has been read successfully, or until
* an error occurs.
*
* @param buffers The buffers into which the data will be read.
*
* @param ec Set to indicate what error occurred, if any.
*
* @returns The number of bytes read. Returns 0 if an error occurred.
*
* @note The read_some operation may not read all of the requested number of
* bytes. Consider using the @ref read function if you need to ensure that the
* requested amount of data is read before the blocking operation completes.
*/
template <typename MutableBufferSequence>
std::size_t read_some(const MutableBufferSequence& buffers,
boost::system::error_code& ec)
{
return detail::io(next_layer_, core_,
detail::read_op<MutableBufferSequence>(buffers), ec);
}
/// Start an asynchronous read.
/**
* This function is used to asynchronously read one or more bytes of data from
* the stream. The function call always returns immediately.
*
* @param buffers The buffers into which the data will be read. Although the
* buffers object may be copied as necessary, ownership of the underlying
* buffers is retained by the caller, which must guarantee that they remain
* valid until the handler is called.
*
* @param handler The handler to be called when the read operation completes.
* Copies will be made of the handler as required. The equivalent function
* signature of the handler must be:
* @code void handler(
* const boost::system::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes read.
* ); @endcode
*
* @note The async_read_some operation may not read all of the requested
* number of bytes. Consider using the @ref async_read function if you need to
* ensure that the requested amount of data is read before the asynchronous
* operation completes.
*/
template <typename MutableBufferSequence, typename ReadHandler>
void async_read_some(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::async_io(next_layer_, core_,
detail::read_op<MutableBufferSequence>(buffers),
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
}
private:
Stream next_layer_;
detail::stream_core core_;
impl_struct backwards_compatible_impl_;
};
#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_STREAM_HPP

View File

@@ -0,0 +1,61 @@
//
// ssl/stream_base.hpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_STREAM_BASE_HPP
#define BOOST_ASIO_SSL_STREAM_BASE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
/// The stream_base class is used as a base for the boost::asio::ssl::stream
/// class template so that we have a common place to define various enums.
class stream_base
{
public:
/// Different handshake types.
enum handshake_type
{
/// Perform handshaking as a client.
client,
/// Perform handshaking as a server.
server
};
protected:
/// Protected destructor to prevent deletion through this type.
~stream_base()
{
}
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
private:
// Workaround to enable the empty base optimisation with Borland C++.
char dummy_;
#endif
};
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_STREAM_BASE_HPP

View File

@@ -0,0 +1,42 @@
//
// ssl/stream_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_STREAM_SERVICE_HPP
#define BOOST_ASIO_SSL_STREAM_SERVICE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <boost/asio/ssl/old/stream_service.hpp>
#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
using boost::asio::ssl::old::stream_service;
#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_STREAM_SERVICE_HPP

View File

@@ -0,0 +1,75 @@
//
// ssl/verify_context.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_VERIFY_CONTEXT_HPP
#define BOOST_ASIO_SSL_VERIFY_CONTEXT_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
# include <boost/asio/detail/noncopyable.hpp>
# include <boost/asio/ssl/detail/openssl_types.hpp>
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
#if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
/// A simple wrapper around the X509_STORE_CTX type, used during verification of
/// a peer certificate.
/**
* @note The verify_context does not own the underlying X509_STORE_CTX object.
*/
class verify_context
: private noncopyable
{
public:
/// The native handle type of the verification context.
typedef X509_STORE_CTX* native_handle_type;
/// Constructor.
explicit verify_context(native_handle_type handle)
: handle_(handle)
{
}
/// Get the underlying implementation in the native type.
/**
* This function may be used to obtain the underlying implementation of the
* context. This is intended to allow access to context functionality that is
* not otherwise provided.
*/
native_handle_type native_handle()
{
return handle_;
}
private:
// The underlying native implementation.
native_handle_type handle_;
};
#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_VERIFY_CONTEXT_HPP

View File

@@ -0,0 +1,65 @@
//
// ssl/verify_mode.hpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_SSL_VERIFY_MODE_HPP
#define BOOST_ASIO_SSL_VERIFY_MODE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <boost/asio/ssl/detail/openssl_types.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ssl {
/// Bitmask type for peer verification.
/**
* Possible values are:
*
* @li @ref verify_none
* @li @ref verify_peer
* @li @ref verify_fail_if_no_peer_cert
* @li @ref verify_client_once
*/
typedef int verify_mode;
#if defined(GENERATING_DOCUMENTATION)
/// No verification.
const int verify_none = implementation_defined;
/// Verify the peer.
const int verify_peer = implementation_defined;
/// Fail verification if the peer has no certificate. Ignored unless
/// @ref verify_peer is set.
const int verify_fail_if_no_peer_cert = implementation_defined;
/// Do not request client certificate on renegotiation. Ignored unless
/// @ref verify_peer is set.
const int verify_client_once = implementation_defined;
#else
const int verify_none = SSL_VERIFY_NONE;
const int verify_peer = SSL_VERIFY_PEER;
const int verify_fail_if_no_peer_cert = SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
const int verify_client_once = SSL_VERIFY_CLIENT_ONCE;
#endif
} // namespace ssl
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_SSL_VERIFY_MODE_HPP