diff options
Diffstat (limited to 'boost/asio/ssl')
37 files changed, 1227 insertions, 144 deletions
diff --git a/boost/asio/ssl/basic_context.hpp b/boost/asio/ssl/basic_context.hpp index 1a769426aa..e51d39bc85 100644 --- a/boost/asio/ssl/basic_context.hpp +++ b/boost/asio/ssl/basic_context.hpp @@ -2,7 +2,7 @@ // ssl/basic_context.hpp // ~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) diff --git a/boost/asio/ssl/context.hpp b/boost/asio/ssl/context.hpp index d2eba8e705..e9d4db65d7 100644 --- a/boost/asio/ssl/context.hpp +++ b/boost/asio/ssl/context.hpp @@ -2,7 +2,7 @@ // ssl/context.hpp // ~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) @@ -22,6 +22,7 @@ # include <boost/asio/ssl/context_service.hpp> #else // defined(BOOST_ASIO_ENABLE_OLD_SSL) # include <string> +# include <boost/asio/buffer.hpp> # include <boost/asio/io_service.hpp> # include <boost/asio/ssl/context_base.hpp> # include <boost/asio/ssl/detail/openssl_types.hpp> @@ -109,6 +110,35 @@ public: */ BOOST_ASIO_DECL impl_type impl(); + /// Clear 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 specified options, if currently enabled on the + * context, are cleared. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_clear_options. + */ + BOOST_ASIO_DECL void clear_options(options o); + + /// Clear 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 specified options, if currently enabled on the + * context, are cleared. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_clear_options. + */ + BOOST_ASIO_DECL boost::system::error_code clear_options(options o, + boost::system::error_code& ec); + /// Set options on the context. /** * This function may be used to configure the SSL options used by the context. @@ -167,6 +197,35 @@ public: BOOST_ASIO_DECL boost::system::error_code set_verify_mode( verify_mode v, boost::system::error_code& ec); + /// Set the peer verification depth. + /** + * This function may be used to configure the maximum verification depth + * allowed by the context. + * + * @param depth Maximum depth for the certificate chain verification that + * shall be allowed. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_set_verify_depth. + */ + BOOST_ASIO_DECL void set_verify_depth(int depth); + + /// Set the peer verification depth. + /** + * This function may be used to configure the maximum verification depth + * allowed by the context. + * + * @param depth Maximum depth for the certificate chain verification that + * shall be allowed. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_set_verify_depth. + */ + BOOST_ASIO_DECL boost::system::error_code set_verify_depth( + int depth, 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 @@ -239,6 +298,35 @@ public: BOOST_ASIO_DECL boost::system::error_code load_verify_file( const std::string& filename, boost::system::error_code& ec); + /// Add certification authority for performing verification. + /** + * This function is used to add one trusted certification authority + * from a memory buffer. + * + * @param ca The buffer containing the certification authority certificate. + * The certificate must use the PEM format. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_get_cert_store and @c X509_STORE_add_cert. + */ + BOOST_ASIO_DECL void add_certificate_authority(const const_buffer& ca); + + /// Add certification authority for performing verification. + /** + * This function is used to add one trusted certification authority + * from a memory buffer. + * + * @param ca The buffer containing the certification authority certificate. + * The certificate must use the PEM format. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_get_cert_store and @c X509_STORE_add_cert. + */ + BOOST_ASIO_DECL boost::system::error_code add_certificate_authority( + const const_buffer& ca, boost::system::error_code& ec); + /// Configures the context to use the default directories for finding /// certification authority certificates. /** @@ -299,6 +387,37 @@ public: BOOST_ASIO_DECL boost::system::error_code add_verify_path( const std::string& path, boost::system::error_code& ec); + /// Use a certificate from a memory buffer. + /** + * This function is used to load a certificate into the context from a buffer. + * + * @param certificate The buffer containing the certificate. + * + * @param format The certificate format (ASN.1 or PEM). + * + * @throws boost::system::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_use_certificate or SSL_CTX_use_certificate_ASN1. + */ + BOOST_ASIO_DECL void use_certificate( + const const_buffer& certificate, file_format format); + + /// Use a certificate from a memory buffer. + /** + * This function is used to load a certificate into the context from a buffer. + * + * @param certificate The buffer containing the certificate. + * + * @param format The certificate format (ASN.1 or PEM). + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_use_certificate or SSL_CTX_use_certificate_ASN1. + */ + BOOST_ASIO_DECL boost::system::error_code use_certificate( + const const_buffer& certificate, file_format format, + 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. @@ -330,6 +449,35 @@ public: const std::string& filename, file_format format, boost::system::error_code& ec); + /// Use a certificate chain from a memory buffer. + /** + * This function is used to load a certificate chain into the context from a + * buffer. + * + * @param chain The buffer containing the certificate chain. The certificate + * chain must use the PEM format. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_use_certificate and SSL_CTX_add_extra_chain_cert. + */ + BOOST_ASIO_DECL void use_certificate_chain(const const_buffer& chain); + + /// Use a certificate chain from a memory buffer. + /** + * This function is used to load a certificate chain into the context from a + * buffer. + * + * @param chain The buffer containing the certificate chain. The certificate + * chain must use the PEM format. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_use_certificate and SSL_CTX_add_extra_chain_cert. + */ + BOOST_ASIO_DECL boost::system::error_code use_certificate_chain( + const const_buffer& chain, 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 @@ -359,6 +507,37 @@ public: 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 memory buffer. + /** + * This function is used to load a private key into the context from a buffer. + * + * @param private_key The buffer containing the private key. + * + * @param format The private key format (ASN.1 or PEM). + * + * @throws boost::system::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_use_PrivateKey or SSL_CTX_use_PrivateKey_ASN1. + */ + BOOST_ASIO_DECL void use_private_key( + const const_buffer& private_key, file_format format); + + /// Use a private key from a memory buffer. + /** + * This function is used to load a private key into the context from a buffer. + * + * @param private_key The buffer containing the private key. + * + * @param format The private key format (ASN.1 or PEM). + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_use_PrivateKey or SSL_CTX_use_PrivateKey_ASN1. + */ + BOOST_ASIO_DECL boost::system::error_code use_private_key( + const const_buffer& private_key, file_format format, + 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. @@ -390,6 +569,39 @@ public: const std::string& filename, file_format format, boost::system::error_code& ec); + /// Use an RSA private key from a memory buffer. + /** + * This function is used to load an RSA private key into the context from a + * buffer. + * + * @param private_key The buffer containing the RSA private key. + * + * @param format The private key format (ASN.1 or PEM). + * + * @throws boost::system::system_error Thrown on failure. + * + * @note Calls @c SSL_CTX_use_RSAPrivateKey or SSL_CTX_use_RSAPrivateKey_ASN1. + */ + BOOST_ASIO_DECL void use_rsa_private_key( + const const_buffer& private_key, file_format format); + + /// Use an RSA private key from a memory buffer. + /** + * This function is used to load an RSA private key into the context from a + * buffer. + * + * @param private_key The buffer containing the RSA private key. + * + * @param format The private key format (ASN.1 or PEM). + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_CTX_use_RSAPrivateKey or SSL_CTX_use_RSAPrivateKey_ASN1. + */ + BOOST_ASIO_DECL boost::system::error_code use_rsa_private_key( + const const_buffer& private_key, 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 @@ -423,6 +635,37 @@ public: const std::string& filename, file_format format, boost::system::error_code& ec); + /// Use the specified memory buffer to obtain the temporary Diffie-Hellman + /// parameters. + /** + * This function is used to load Diffie-Hellman parameters into the context + * from a buffer. + * + * @param dh The memory buffer containing the Diffie-Hellman parameters. The + * buffer 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(const const_buffer& dh); + + /// Use the specified memory buffer to obtain the temporary Diffie-Hellman + /// parameters. + /** + * This function is used to load Diffie-Hellman parameters into the context + * from a buffer. + * + * @param dh The memory buffer containing the Diffie-Hellman parameters. The + * buffer 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( + const const_buffer& dh, 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 @@ -494,6 +737,12 @@ public: boost::system::error_code& ec); private: + struct bio_cleanup; + struct x509_cleanup; + struct evp_pkey_cleanup; + struct rsa_cleanup; + struct dh_cleanup; + // 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); @@ -510,6 +759,13 @@ private: BOOST_ASIO_DECL static int password_callback_function( char* buf, int size, int purpose, void* data); + // Helper function to set the temporary Diffie-Hellman parameters from a BIO. + BOOST_ASIO_DECL boost::system::error_code do_use_tmp_dh( + BIO* bio, boost::system::error_code& ec); + + // Helper function to make a BIO from a memory buffer. + BOOST_ASIO_DECL BIO* make_buffer_bio(const const_buffer& b); + // The underlying native implementation. native_handle_type handle_; diff --git a/boost/asio/ssl/context_base.hpp b/boost/asio/ssl/context_base.hpp index 3c0b59d65f..692372d4ba 100644 --- a/boost/asio/ssl/context_base.hpp +++ b/boost/asio/ssl/context_base.hpp @@ -2,7 +2,7 @@ // ssl/context_base.hpp // ~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) @@ -16,7 +16,6 @@ #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> @@ -67,33 +66,59 @@ public: sslv23_client, /// SSL/TLS server. - sslv23_server + sslv23_server, + + /// Generic TLS version 1.1. + tlsv11, + + /// TLS version 1.1 client. + tlsv11_client, + + /// TLS version 1.1 server. + tlsv11_server, + + /// Generic TLS version 1.2. + tlsv12, + + /// TLS version 1.2 client. + tlsv12_client, + + /// TLS version 1.2 server. + tlsv12_server }; /// Bitmask type for SSL options. - typedef int options; + typedef long options; #if defined(GENERATING_DOCUMENTATION) /// Implement various bug workarounds. - static const int default_workarounds = implementation_defined; + static const long default_workarounds = implementation_defined; /// Always create a new key when using tmp_dh parameters. - static const int single_dh_use = implementation_defined; + static const long single_dh_use = implementation_defined; /// Disable SSL v2. - static const int no_sslv2 = implementation_defined; + static const long no_sslv2 = implementation_defined; /// Disable SSL v3. - static const int no_sslv3 = implementation_defined; + static const long no_sslv3 = implementation_defined; /// Disable TLS v1. - static const int no_tlsv1 = implementation_defined; + static const long no_tlsv1 = implementation_defined; + + /// Disable compression. Compression is disabled by default. + static const long no_compression = 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); + BOOST_ASIO_STATIC_CONSTANT(long, default_workarounds = SSL_OP_ALL); + BOOST_ASIO_STATIC_CONSTANT(long, single_dh_use = SSL_OP_SINGLE_DH_USE); + BOOST_ASIO_STATIC_CONSTANT(long, no_sslv2 = SSL_OP_NO_SSLv2); + BOOST_ASIO_STATIC_CONSTANT(long, no_sslv3 = SSL_OP_NO_SSLv3); + BOOST_ASIO_STATIC_CONSTANT(long, no_tlsv1 = SSL_OP_NO_TLSv1); +# if defined(SSL_OP_NO_COMPRESSION) + BOOST_ASIO_STATIC_CONSTANT(long, no_compression = SSL_OP_NO_COMPRESSION); +# else // defined(SSL_OP_NO_COMPRESSION) + BOOST_ASIO_STATIC_CONSTANT(long, no_compression = 0x20000L); +# endif // defined(SSL_OP_NO_COMPRESSION) #endif /// File format types. @@ -111,11 +136,11 @@ public: // 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, + BOOST_ASIO_STATIC_CONSTANT(int, verify_none = SSL_VERIFY_NONE); + BOOST_ASIO_STATIC_CONSTANT(int, verify_peer = SSL_VERIFY_PEER); + BOOST_ASIO_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); + BOOST_ASIO_STATIC_CONSTANT(int, verify_client_once = SSL_VERIFY_CLIENT_ONCE); #endif /// Purpose of PEM password. @@ -133,12 +158,6 @@ protected: ~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 diff --git a/boost/asio/ssl/context_service.hpp b/boost/asio/ssl/context_service.hpp index e998d42341..3222dc52c7 100644 --- a/boost/asio/ssl/context_service.hpp +++ b/boost/asio/ssl/context_service.hpp @@ -2,7 +2,7 @@ // ssl/context_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) diff --git a/boost/asio/ssl/detail/buffered_handshake_op.hpp b/boost/asio/ssl/detail/buffered_handshake_op.hpp new file mode 100644 index 0000000000..10608b0eb9 --- /dev/null +++ b/boost/asio/ssl/detail/buffered_handshake_op.hpp @@ -0,0 +1,112 @@ +// +// ssl/detail/buffered_handshake_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2014 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_BUFFERED_HANDSHAKE_OP_HPP +#define BOOST_ASIO_SSL_DETAIL_BUFFERED_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) + +template <typename ConstBufferSequence> +class buffered_handshake_op +{ +public: + buffered_handshake_op(stream_base::handshake_type type, + const ConstBufferSequence& buffers) + : type_(type), + buffers_(buffers), + total_buffer_size_(boost::asio::buffer_size(buffers_)) + { + } + + engine::want operator()(engine& eng, + boost::system::error_code& ec, + std::size_t& bytes_transferred) const + { + typename ConstBufferSequence::const_iterator iter = buffers_.begin(); + typename ConstBufferSequence::const_iterator end = buffers_.end(); + std::size_t accumulated_size = 0; + + for (;;) + { + engine::want want = eng.handshake(type_, ec); + if (want != engine::want_input_and_retry + || bytes_transferred == total_buffer_size_) + return want; + + // Find the next buffer piece to be fed to the engine. + while (iter != end) + { + const_buffer buffer(*iter); + + // Skip over any buffers which have already been consumed by the engine. + if (bytes_transferred >= accumulated_size + buffer_size(buffer)) + { + accumulated_size += buffer_size(buffer); + ++iter; + continue; + } + + // The current buffer may have been partially consumed by the engine on + // a previous iteration. If so, adjust the buffer to point to the + // unused portion. + if (bytes_transferred > accumulated_size) + buffer = buffer + (bytes_transferred - accumulated_size); + + // Pass the buffer to the engine, and update the bytes transferred to + // reflect the total number of bytes consumed so far. + bytes_transferred += buffer_size(buffer); + buffer = eng.put_input(buffer); + bytes_transferred -= buffer_size(buffer); + break; + } + } + } + + 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: + stream_base::handshake_type type_; + ConstBufferSequence buffers_; + std::size_t total_buffer_size_; +}; + +#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_BUFFERED_HANDSHAKE_OP_HPP diff --git a/boost/asio/ssl/detail/engine.hpp b/boost/asio/ssl/detail/engine.hpp index 41c4ee7426..8b24a96f01 100644 --- a/boost/asio/ssl/detail/engine.hpp +++ b/boost/asio/ssl/detail/engine.hpp @@ -2,7 +2,7 @@ // ssl/detail/engine.hpp // ~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) @@ -73,6 +73,10 @@ public: BOOST_ASIO_DECL boost::system::error_code set_verify_mode( verify_mode v, boost::system::error_code& ec); + // Set the peer verification depth. + BOOST_ASIO_DECL boost::system::error_code set_verify_depth( + int depth, 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); diff --git a/boost/asio/ssl/detail/handshake_op.hpp b/boost/asio/ssl/detail/handshake_op.hpp index 3c57a4de96..b886bb52f6 100644 --- a/boost/asio/ssl/detail/handshake_op.hpp +++ b/boost/asio/ssl/detail/handshake_op.hpp @@ -2,7 +2,7 @@ // ssl/detail/handshake_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) diff --git a/boost/asio/ssl/detail/impl/engine.ipp b/boost/asio/ssl/detail/impl/engine.ipp index a7da0c1967..5aa9b5a68a 100644 --- a/boost/asio/ssl/detail/impl/engine.ipp +++ b/boost/asio/ssl/detail/impl/engine.ipp @@ -2,7 +2,7 @@ // ssl/detail/impl/engine.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) @@ -39,7 +39,8 @@ engine::engine(SSL_CTX* context) { if (!ssl_) { - boost::system::error_code ec(::ERR_get_error(), + boost::system::error_code ec( + static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category()); boost::asio::detail::throw_error(ec, "engine"); } @@ -83,6 +84,15 @@ boost::system::error_code engine::set_verify_mode( return ec; } +boost::system::error_code engine::set_verify_depth( + int depth, boost::system::error_code& ec) +{ + ::SSL_set_verify_depth(ssl_, depth); + + ec = boost::system::error_code(); + return ec; +} + boost::system::error_code engine::set_verify_callback( verify_callback_base* callback, boost::system::error_code& ec) { @@ -166,7 +176,7 @@ boost::asio::mutable_buffers_1 engine::get_output( { int length = ::BIO_read(ext_bio_, boost::asio::buffer_cast<void*>(data), - boost::asio::buffer_size(data)); + static_cast<int>(boost::asio::buffer_size(data))); return boost::asio::buffer(data, length > 0 ? static_cast<std::size_t>(length) : 0); @@ -177,7 +187,7 @@ boost::asio::const_buffer engine::put_input( { int length = ::BIO_write(ext_bio_, boost::asio::buffer_cast<const void*>(data), - boost::asio::buffer_size(data)); + static_cast<int>(boost::asio::buffer_size(data))); return boost::asio::buffer(data + (length > 0 ? static_cast<std::size_t>(length) : 0)); @@ -228,7 +238,7 @@ engine::want engine::perform(int (engine::* op)(void*, std::size_t), 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(); + int sys_error = static_cast<int>(::ERR_get_error()); std::size_t pending_output_after = ::BIO_ctrl_pending(ext_bio_); if (ssl_error == SSL_ERROR_SSL) @@ -296,12 +306,14 @@ int engine::do_shutdown(void*, std::size_t) int engine::do_read(void* data, std::size_t length) { - return ::SSL_read(ssl_, data, length < INT_MAX ? length : INT_MAX); + return ::SSL_read(ssl_, data, + length < INT_MAX ? static_cast<int>(length) : INT_MAX); } int engine::do_write(void* data, std::size_t length) { - return ::SSL_write(ssl_, data, length < INT_MAX ? length : INT_MAX); + return ::SSL_write(ssl_, data, + length < INT_MAX ? static_cast<int>(length) : INT_MAX); } #endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL) diff --git a/boost/asio/ssl/detail/impl/openssl_init.ipp b/boost/asio/ssl/detail/impl/openssl_init.ipp index fe62e6eabc..d732fef309 100644 --- a/boost/asio/ssl/detail/impl/openssl_init.ipp +++ b/boost/asio/ssl/detail/impl/openssl_init.ipp @@ -3,7 +3,7 @@ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com -// Copyright (c) 2005-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2005-2014 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) @@ -18,7 +18,7 @@ #include <boost/asio/detail/config.hpp> #include <vector> -#include <boost/assert.hpp> +#include <boost/asio/detail/assert.hpp> #include <boost/asio/detail/mutex.hpp> #include <boost/asio/detail/tss_ptr.hpp> #include <boost/asio/ssl/detail/openssl_init.hpp> @@ -45,10 +45,22 @@ public: 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); + +#if !defined(SSL_OP_NO_COMPRESSION) \ + && (OPENSSL_VERSION_NUMBER >= 0x00908000L) + null_compression_methods_ = sk_SSL_COMP_new_null(); +#endif // !defined(SSL_OP_NO_COMPRESSION) + // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) } ~do_init() { +#if !defined(SSL_OP_NO_COMPRESSION) \ + && (OPENSSL_VERSION_NUMBER >= 0x00908000L) + sk_SSL_COMP_free(null_compression_methods_); +#endif // !defined(SSL_OP_NO_COMPRESSION) + // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) + ::CRYPTO_set_id_callback(0); ::CRYPTO_set_locking_callback(0); ::ERR_free_strings(); @@ -61,18 +73,27 @@ public: #endif // !defined(OPENSSL_NO_ENGINE) } +#if !defined(SSL_OP_NO_COMPRESSION) \ + && (OPENSSL_VERSION_NUMBER >= 0x00908000L) + STACK_OF(SSL_COMP)* get_null_compression_methods() const + { + return null_compression_methods_; + } +#endif // !defined(SSL_OP_NO_COMPRESSION) + // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) + private: static unsigned long openssl_id_func() { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) return ::GetCurrentThreadId(); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) void* id = instance()->thread_id_; if (id == 0) instance()->thread_id_ = id = &id; // Ugh. - BOOST_ASSERT(sizeof(unsigned long) >= sizeof(void*)); + BOOST_ASIO_ASSERT(sizeof(unsigned long) >= sizeof(void*)); return reinterpret_cast<unsigned long>(id); -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } static void openssl_locking_func(int mode, int n, @@ -88,10 +109,16 @@ private: std::vector<boost::asio::detail::shared_ptr< boost::asio::detail::mutex> > mutexes_; -#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#if !defined(BOOST_ASIO_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__) +#endif // !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__) + +#if !defined(SSL_OP_NO_COMPRESSION) \ + && (OPENSSL_VERSION_NUMBER >= 0x00908000L) + STACK_OF(SSL_COMP)* null_compression_methods_; +#endif // !defined(SSL_OP_NO_COMPRESSION) + // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) }; boost::asio::detail::shared_ptr<openssl_init_base::do_init> @@ -101,6 +128,15 @@ openssl_init_base::instance() return init; } +#if !defined(SSL_OP_NO_COMPRESSION) \ + && (OPENSSL_VERSION_NUMBER >= 0x00908000L) +STACK_OF(SSL_COMP)* openssl_init_base::get_null_compression_methods() +{ + return instance()->get_null_compression_methods(); +} +#endif // !defined(SSL_OP_NO_COMPRESSION) + // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) + } // namespace detail } // namespace ssl } // namespace asio diff --git a/boost/asio/ssl/detail/io.hpp b/boost/asio/ssl/detail/io.hpp index e83934e313..ef821000ba 100644 --- a/boost/asio/ssl/detail/io.hpp +++ b/boost/asio/ssl/detail/io.hpp @@ -2,7 +2,7 @@ // ssl/detail/io.hpp // ~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) @@ -96,6 +96,8 @@ public: : next_layer_(next_layer), core_(core), op_(op), + start_(0), + want_(engine::want_nothing), bytes_transferred_(0), handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) { @@ -106,6 +108,7 @@ public: : next_layer_(other.next_layer_), core_(other.core_), op_(other.op_), + start_(other.start_), want_(other.want_), ec_(other.ec_), bytes_transferred_(other.bytes_transferred_), @@ -117,6 +120,7 @@ public: : next_layer_(other.next_layer_), core_(other.core_), op_(other.op_), + start_(other.start_), want_(other.want_), ec_(other.ec_), bytes_transferred_(other.bytes_transferred_), @@ -128,7 +132,7 @@ public: void operator()(boost::system::error_code ec, std::size_t bytes_transferred = ~std::size_t(0), int start = 0) { - switch (start) + switch (start_ = start) { case 1: // Called after at least one async operation. do @@ -149,10 +153,10 @@ public: // 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) + if (core_.pending_read_.expires_at() == core_.neg_infin()) { // Prevent other read operations from being started. - core_.pending_read_.expires_at(boost::posix_time::pos_infin); + core_.pending_read_.expires_at(core_.pos_infin()); // Start reading some data from the underlying transport. next_layer_.async_read_some( @@ -176,10 +180,10 @@ public: // 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) + if (core_.pending_write_.expires_at() == core_.neg_infin()) { // Prevent other write operations from being started. - core_.pending_write_.expires_at(boost::posix_time::pos_infin); + core_.pending_write_.expires_at(core_.pos_infin()); // Start writing all the data to the underlying transport. boost::asio::async_write(next_layer_, @@ -234,7 +238,7 @@ public: core_.input_ = core_.engine_.put_input(core_.input_); // Release any waiting read operations. - core_.pending_read_.expires_at(boost::posix_time::neg_infin); + core_.pending_read_.expires_at(core_.neg_infin()); // Try the operation again. continue; @@ -242,7 +246,7 @@ public: case engine::want_output_and_retry: // Release any waiting write operations. - core_.pending_write_.expires_at(boost::posix_time::neg_infin); + core_.pending_write_.expires_at(core_.neg_infin()); // Try the operation again. continue; @@ -250,7 +254,7 @@ public: case engine::want_output: // Release any waiting write operations. - core_.pending_write_.expires_at(boost::posix_time::neg_infin); + core_.pending_write_.expires_at(core_.neg_infin()); // Fall through to call handler. @@ -275,6 +279,7 @@ public: Stream& next_layer_; stream_core& core_; Operation op_; + int start_; engine::want want_; boost::system::error_code ec_; std::size_t bytes_transferred_; @@ -297,6 +302,14 @@ inline void asio_handler_deallocate(void* pointer, std::size_t size, pointer, size, this_handler->handler_); } +template <typename Stream, typename Operation, typename Handler> +inline bool asio_handler_is_continuation( + io_op<Stream, Operation, Handler>* this_handler) +{ + return this_handler->start_ == 0 ? true + : boost_asio_handler_cont_helpers::is_continuation(this_handler->handler_); +} + template <typename Function, typename Stream, typename Operation, typename Handler> inline void asio_handler_invoke(Function& function, @@ -317,7 +330,7 @@ inline void asio_handler_invoke(const Function& function, template <typename Stream, typename Operation, typename Handler> inline void async_io(Stream& next_layer, stream_core& core, - const Operation& op, Handler handler) + const Operation& op, Handler& handler) { io_op<Stream, Operation, Handler>( next_layer, core, op, handler)( diff --git a/boost/asio/ssl/detail/openssl_init.hpp b/boost/asio/ssl/detail/openssl_init.hpp index c68909d16b..985c14d9c5 100644 --- a/boost/asio/ssl/detail/openssl_init.hpp +++ b/boost/asio/ssl/detail/openssl_init.hpp @@ -2,7 +2,7 @@ // ssl/detail/openssl_init.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) @@ -19,6 +19,7 @@ #include <cstring> #include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/detail/shared_ptr.hpp> +#include <boost/asio/ssl/detail/openssl_types.hpp> #include <boost/asio/detail/push_options.hpp> @@ -40,6 +41,14 @@ protected: // 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(); + +#if !defined(SSL_OP_NO_COMPRESSION) \ + && (OPENSSL_VERSION_NUMBER >= 0x00908000L) + // Get an empty stack of compression methods, to be used when disabling + // compression. + BOOST_ASIO_DECL static STACK_OF(SSL_COMP)* get_null_compression_methods(); +#endif // !defined(SSL_OP_NO_COMPRESSION) + // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) }; template <bool Do_Init = true> @@ -62,6 +71,12 @@ public: { } +#if !defined(SSL_OP_NO_COMPRESSION) \ + && (OPENSSL_VERSION_NUMBER >= 0x00908000L) + using openssl_init_base::get_null_compression_methods; +#endif // !defined(SSL_OP_NO_COMPRESSION) + // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) + private: // Instance to force initialisation of openssl at global scope. static openssl_init instance_; diff --git a/boost/asio/ssl/detail/openssl_types.hpp b/boost/asio/ssl/detail/openssl_types.hpp index a3c3729332..58b4733db6 100644 --- a/boost/asio/ssl/detail/openssl_types.hpp +++ b/boost/asio/ssl/detail/openssl_types.hpp @@ -2,7 +2,7 @@ // ssl/detail/openssl_types.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) diff --git a/boost/asio/ssl/detail/password_callback.hpp b/boost/asio/ssl/detail/password_callback.hpp index 438320a00b..d64bf3a5be 100644 --- a/boost/asio/ssl/detail/password_callback.hpp +++ b/boost/asio/ssl/detail/password_callback.hpp @@ -2,7 +2,7 @@ // ssl/detail/password_callback.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) diff --git a/boost/asio/ssl/detail/read_op.hpp b/boost/asio/ssl/detail/read_op.hpp index abf329c7b7..e0a0ad0ee8 100644 --- a/boost/asio/ssl/detail/read_op.hpp +++ b/boost/asio/ssl/detail/read_op.hpp @@ -2,7 +2,7 @@ // ssl/detail/read_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) diff --git a/boost/asio/ssl/detail/shutdown_op.hpp b/boost/asio/ssl/detail/shutdown_op.hpp index cfeb8e572e..6a716f7090 100644 --- a/boost/asio/ssl/detail/shutdown_op.hpp +++ b/boost/asio/ssl/detail/shutdown_op.hpp @@ -2,7 +2,7 @@ // ssl/detail/shutdown_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) diff --git a/boost/asio/ssl/detail/stream_core.hpp b/boost/asio/ssl/detail/stream_core.hpp index b8f0afa4a1..663e258c03 100644 --- a/boost/asio/ssl/detail/stream_core.hpp +++ b/boost/asio/ssl/detail/stream_core.hpp @@ -2,7 +2,7 @@ // ssl/detail/stream_core.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) @@ -18,7 +18,11 @@ #include <boost/asio/detail/config.hpp> #if !defined(BOOST_ASIO_ENABLE_OLD_SSL) -# include <boost/asio/deadline_timer.hpp> +# if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) +# include <boost/asio/deadline_timer.hpp> +# else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) +# include <boost/asio/steady_timer.hpp> +# endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) # include <boost/asio/ssl/detail/engine.hpp> # include <boost/asio/buffer.hpp> #endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL) @@ -34,7 +38,7 @@ namespace detail { struct stream_core { - // According to the OpenSSL documentation, this is the buffer size that is is + // According to the OpenSSL documentation, this is the buffer size that is // sufficient to hold the largest possible TLS record. enum { max_tls_record_size = 17 * 1024 }; @@ -47,8 +51,8 @@ struct stream_core 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); + pending_read_.expires_at(neg_infin()); + pending_write_.expires_at(neg_infin()); } ~stream_core() @@ -58,20 +62,52 @@ struct stream_core // The SSL engine. engine engine_; +#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) // 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_; + // Helper function for obtaining a time value that always fires. + static boost::asio::deadline_timer::time_type neg_infin() + { + return boost::posix_time::neg_infin; + } + + // Helper function for obtaining a time value that never fires. + static boost::asio::deadline_timer::time_type pos_infin() + { + return boost::posix_time::pos_infin; + } +#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) + // Timer used for storing queued read operations. + boost::asio::steady_timer pending_read_; + + // Timer used for storing queued write operations. + boost::asio::steady_timer pending_write_; + + // Helper function for obtaining a time value that always fires. + static boost::asio::steady_timer::time_point neg_infin() + { + return (boost::asio::steady_timer::time_point::min)(); + } + + // Helper function for obtaining a time value that never fires. + static boost::asio::steady_timer::time_point pos_infin() + { + return (boost::asio::steady_timer::time_point::max)(); + } +#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) + // Buffer space used to prepare output intended for the transport. - std::vector<unsigned char> output_buffer_space_; + 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_; + 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_; + 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_; diff --git a/boost/asio/ssl/detail/verify_callback.hpp b/boost/asio/ssl/detail/verify_callback.hpp index 2d497d1ce1..eb40f488f4 100644 --- a/boost/asio/ssl/detail/verify_callback.hpp +++ b/boost/asio/ssl/detail/verify_callback.hpp @@ -2,7 +2,7 @@ // ssl/detail/verify_callback.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) diff --git a/boost/asio/ssl/detail/write_op.hpp b/boost/asio/ssl/detail/write_op.hpp index 82ecbb9212..24020983df 100644 --- a/boost/asio/ssl/detail/write_op.hpp +++ b/boost/asio/ssl/detail/write_op.hpp @@ -2,7 +2,7 @@ // ssl/detail/write_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) diff --git a/boost/asio/ssl/error.hpp b/boost/asio/ssl/error.hpp index c1001104ac..a308fd2626 100644 --- a/boost/asio/ssl/error.hpp +++ b/boost/asio/ssl/error.hpp @@ -2,7 +2,7 @@ // ssl/error.hpp // ~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) diff --git a/boost/asio/ssl/impl/context.hpp b/boost/asio/ssl/impl/context.hpp index 1ab03b91cf..345bc5b2ca 100644 --- a/boost/asio/ssl/impl/context.hpp +++ b/boost/asio/ssl/impl/context.hpp @@ -3,7 +3,7 @@ // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com -// Copyright (c) 2005-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2005-2014 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) diff --git a/boost/asio/ssl/impl/context.ipp b/boost/asio/ssl/impl/context.ipp index 54f4fd15d1..06c2743fdb 100644 --- a/boost/asio/ssl/impl/context.ipp +++ b/boost/asio/ssl/impl/context.ipp @@ -3,7 +3,7 @@ // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com -// Copyright (c) 2005-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2005-2014 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) @@ -34,6 +34,36 @@ namespace ssl { #if !defined(BOOST_ASIO_ENABLE_OLD_SSL) +struct context::bio_cleanup +{ + BIO* p; + ~bio_cleanup() { if (p) ::BIO_free(p); } +}; + +struct context::x509_cleanup +{ + X509* p; + ~x509_cleanup() { if (p) ::X509_free(p); } +}; + +struct context::evp_pkey_cleanup +{ + EVP_PKEY* p; + ~evp_pkey_cleanup() { if (p) ::EVP_PKEY_free(p); } +}; + +struct context::rsa_cleanup +{ + RSA* p; + ~rsa_cleanup() { if (p) ::RSA_free(p); } +}; + +struct context::dh_cleanup +{ + DH* p; + ~dh_cleanup() { if (p) ::DH_free(p); } +}; + context::context(context::method m) : handle_(0) { @@ -84,6 +114,42 @@ context::context(context::method m) case context::sslv23_server: handle_ = ::SSL_CTX_new(::SSLv23_server_method()); break; +#if defined(SSL_TXT_TLSV1_1) + case context::tlsv11: + handle_ = ::SSL_CTX_new(::TLSv1_1_method()); + break; + case context::tlsv11_client: + handle_ = ::SSL_CTX_new(::TLSv1_1_client_method()); + break; + case context::tlsv11_server: + handle_ = ::SSL_CTX_new(::TLSv1_1_server_method()); + break; +#else // defined(SSL_TXT_TLSV1_1) + case context::tlsv11: + case context::tlsv11_client: + case context::tlsv11_server: + boost::asio::detail::throw_error( + boost::asio::error::invalid_argument, "context"); + break; +#endif // defined(SSL_TXT_TLSV1_1) +#if defined(SSL_TXT_TLSV1_2) + case context::tlsv12: + handle_ = ::SSL_CTX_new(::TLSv1_2_method()); + break; + case context::tlsv12_client: + handle_ = ::SSL_CTX_new(::TLSv1_2_client_method()); + break; + case context::tlsv12_server: + handle_ = ::SSL_CTX_new(::TLSv1_2_server_method()); + break; +#else // defined(SSL_TXT_TLSV1_2) + case context::tlsv12: + case context::tlsv12_client: + case context::tlsv12_server: + boost::asio::detail::throw_error( + boost::asio::error::invalid_argument, "context"); + break; +#endif // defined(SSL_TXT_TLSV1_2) default: handle_ = ::SSL_CTX_new(0); break; @@ -91,10 +157,13 @@ context::context(context::method m) if (handle_ == 0) { - boost::system::error_code ec(::ERR_get_error(), + boost::system::error_code ec( + static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category()); boost::asio::detail::throw_error(ec, "context"); } + + set_options(no_compression); } context::context(boost::asio::io_service&, context::method m) @@ -157,6 +226,40 @@ context::impl_type context::impl() return handle_; } +void context::clear_options(context::options o) +{ + boost::system::error_code ec; + clear_options(o, ec); + boost::asio::detail::throw_error(ec, "clear_options"); +} + +boost::system::error_code context::clear_options( + context::options o, boost::system::error_code& ec) +{ +#if (OPENSSL_VERSION_NUMBER >= 0x009080DFL) \ + && (OPENSSL_VERSION_NUMBER != 0x00909000L) +# if !defined(SSL_OP_NO_COMPRESSION) + if ((o & context::no_compression) != 0) + { +# if (OPENSSL_VERSION_NUMBER >= 0x00908000L) + handle_->comp_methods = SSL_COMP_get_compression_methods(); +# endif // (OPENSSL_VERSION_NUMBER >= 0x00908000L) + o ^= context::no_compression; + } +# endif // !defined(SSL_OP_NO_COMPRESSION) + + ::SSL_CTX_clear_options(handle_, o); + + ec = boost::system::error_code(); +#else // (OPENSSL_VERSION_NUMBER >= 0x009080DFL) + // && (OPENSSL_VERSION_NUMBER != 0x00909000L) + (void)o; + ec = boost::asio::error::operation_not_supported; +#endif // (OPENSSL_VERSION_NUMBER >= 0x009080DFL) + // && (OPENSSL_VERSION_NUMBER != 0x00909000L) + return ec; +} + void context::set_options(context::options o) { boost::system::error_code ec; @@ -167,6 +270,17 @@ void context::set_options(context::options o) boost::system::error_code context::set_options( context::options o, boost::system::error_code& ec) { +#if !defined(SSL_OP_NO_COMPRESSION) + if ((o & context::no_compression) != 0) + { +#if (OPENSSL_VERSION_NUMBER >= 0x00908000L) + handle_->comp_methods = + boost::asio::ssl::detail::openssl_init<>::get_null_compression_methods(); +#endif // (OPENSSL_VERSION_NUMBER >= 0x00908000L) + o ^= context::no_compression; + } +#endif // !defined(SSL_OP_NO_COMPRESSION) + ::SSL_CTX_set_options(handle_, o); ec = boost::system::error_code(); @@ -189,6 +303,22 @@ boost::system::error_code context::set_verify_mode( return ec; } +void context::set_verify_depth(int depth) +{ + boost::system::error_code ec; + set_verify_depth(depth, ec); + boost::asio::detail::throw_error(ec, "set_verify_depth"); +} + +boost::system::error_code context::set_verify_depth( + int depth, boost::system::error_code& ec) +{ + ::SSL_CTX_set_verify_depth(handle_, depth); + + ec = boost::system::error_code(); + return ec; +} + void context::load_verify_file(const std::string& filename) { boost::system::error_code ec; @@ -201,7 +331,8 @@ boost::system::error_code context::load_verify_file( { if (::SSL_CTX_load_verify_locations(handle_, filename.c_str(), 0) != 1) { - ec = boost::system::error_code(::ERR_get_error(), + ec = boost::system::error_code( + static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category()); return ec; } @@ -210,6 +341,41 @@ boost::system::error_code context::load_verify_file( return ec; } +void context::add_certificate_authority(const const_buffer& ca) +{ + boost::system::error_code ec; + add_certificate_authority(ca, ec); + boost::asio::detail::throw_error(ec, "add_certificate_authority"); +} + +boost::system::error_code context::add_certificate_authority( + const const_buffer& ca, boost::system::error_code& ec) +{ + ::ERR_clear_error(); + + bio_cleanup bio = { make_buffer_bio(ca) }; + if (bio.p) + { + x509_cleanup cert = { ::PEM_read_bio_X509(bio.p, 0, 0, 0) }; + if (cert.p) + { + if (X509_STORE* store = ::SSL_CTX_get_cert_store(handle_)) + { + if (::X509_STORE_add_cert(store, cert.p) == 1) + { + ec = boost::system::error_code(); + return ec; + } + } + } + } + + ec = boost::system::error_code( + static_cast<int>(::ERR_get_error()), + boost::asio::error::get_ssl_category()); + return ec; +} + void context::set_default_verify_paths() { boost::system::error_code ec; @@ -222,7 +388,8 @@ boost::system::error_code context::set_default_verify_paths( { if (::SSL_CTX_set_default_verify_paths(handle_) != 1) { - ec = boost::system::error_code(::ERR_get_error(), + ec = boost::system::error_code( + static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category()); return ec; } @@ -243,7 +410,8 @@ boost::system::error_code context::add_verify_path( { if (::SSL_CTX_load_verify_locations(handle_, 0, path.c_str()) != 1) { - ec = boost::system::error_code(::ERR_get_error(), + ec = boost::system::error_code( + static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category()); return ec; } @@ -252,6 +420,58 @@ boost::system::error_code context::add_verify_path( return ec; } +void context::use_certificate( + const const_buffer& certificate, file_format format) +{ + boost::system::error_code ec; + use_certificate(certificate, format, ec); + boost::asio::detail::throw_error(ec, "use_certificate"); +} + +boost::system::error_code context::use_certificate( + const const_buffer& certificate, file_format format, + boost::system::error_code& ec) +{ + ::ERR_clear_error(); + + if (format == context_base::asn1) + { + if (::SSL_CTX_use_certificate_ASN1(handle_, + static_cast<int>(buffer_size(certificate)), + buffer_cast<const unsigned char*>(certificate)) == 1) + { + ec = boost::system::error_code(); + return ec; + } + } + else if (format == context_base::pem) + { + bio_cleanup bio = { make_buffer_bio(certificate) }; + if (bio.p) + { + x509_cleanup cert = { ::PEM_read_bio_X509(bio.p, 0, 0, 0) }; + if (cert.p) + { + if (::SSL_CTX_use_certificate(handle_, cert.p) == 1) + { + ec = boost::system::error_code(); + return ec; + } + } + } + } + else + { + ec = boost::asio::error::invalid_argument; + return ec; + } + + ec = boost::system::error_code( + static_cast<int>(::ERR_get_error()), + boost::asio::error::get_ssl_category()); + return ec; +} + void context::use_certificate_file( const std::string& filename, file_format format) { @@ -282,7 +502,8 @@ boost::system::error_code context::use_certificate_file( if (::SSL_CTX_use_certificate_file(handle_, filename.c_str(), file_type) != 1) { - ec = boost::system::error_code(::ERR_get_error(), + ec = boost::system::error_code( + static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category()); return ec; } @@ -291,6 +512,76 @@ boost::system::error_code context::use_certificate_file( return ec; } +void context::use_certificate_chain(const const_buffer& chain) +{ + boost::system::error_code ec; + use_certificate_chain(chain, ec); + boost::asio::detail::throw_error(ec, "use_certificate_chain"); +} + +boost::system::error_code context::use_certificate_chain( + const const_buffer& chain, boost::system::error_code& ec) +{ + ::ERR_clear_error(); + + bio_cleanup bio = { make_buffer_bio(chain) }; + if (bio.p) + { + x509_cleanup cert = { + ::PEM_read_bio_X509_AUX(bio.p, 0, + handle_->default_passwd_callback, + handle_->default_passwd_callback_userdata) }; + if (!cert.p) + { + ec = boost::system::error_code(ERR_R_PEM_LIB, + boost::asio::error::get_ssl_category()); + return ec; + } + + int result = ::SSL_CTX_use_certificate(handle_, cert.p); + if (result == 0 || ::ERR_peek_error() != 0) + { + ec = boost::system::error_code( + static_cast<int>(::ERR_get_error()), + boost::asio::error::get_ssl_category()); + return ec; + } + + if (handle_->extra_certs) + { + ::sk_X509_pop_free(handle_->extra_certs, X509_free); + handle_->extra_certs = 0; + } + + while (X509* cacert = ::PEM_read_bio_X509(bio.p, 0, + handle_->default_passwd_callback, + handle_->default_passwd_callback_userdata)) + { + if (!::SSL_CTX_add_extra_chain_cert(handle_, cacert)) + { + ec = boost::system::error_code( + static_cast<int>(::ERR_get_error()), + boost::asio::error::get_ssl_category()); + return ec; + } + } + + result = ::ERR_peek_last_error(); + if ((ERR_GET_LIB(result) == ERR_LIB_PEM) + && (ERR_GET_REASON(result) == PEM_R_NO_START_LINE)) + { + ::ERR_clear_error(); + ec = boost::system::error_code(); + return ec; + } + } + + ec = boost::system::error_code( + static_cast<int>(::ERR_get_error()), + boost::asio::error::get_ssl_category()); + return ec; +} + void context::use_certificate_chain_file(const std::string& filename) { boost::system::error_code ec; @@ -303,7 +594,8 @@ boost::system::error_code context::use_certificate_chain_file( { if (::SSL_CTX_use_certificate_chain_file(handle_, filename.c_str()) != 1) { - ec = boost::system::error_code(::ERR_get_error(), + ec = boost::system::error_code( + static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category()); return ec; } @@ -312,6 +604,55 @@ boost::system::error_code context::use_certificate_chain_file( return ec; } +void context::use_private_key( + const const_buffer& private_key, context::file_format format) +{ + boost::system::error_code ec; + use_private_key(private_key, format, ec); + boost::asio::detail::throw_error(ec, "use_private_key"); +} + +boost::system::error_code context::use_private_key( + const const_buffer& private_key, context::file_format format, + boost::system::error_code& ec) +{ + ::ERR_clear_error(); + + bio_cleanup bio = { make_buffer_bio(private_key) }; + if (bio.p) + { + evp_pkey_cleanup evp_private_key = { 0 }; + switch (format) + { + case context_base::asn1: + evp_private_key.p = ::d2i_PrivateKey_bio(bio.p, 0); + break; + case context_base::pem: + evp_private_key.p = ::PEM_read_bio_PrivateKey(bio.p, 0, 0, 0); + break; + default: + { + ec = boost::asio::error::invalid_argument; + return ec; + } + } + + if (evp_private_key.p) + { + if (::SSL_CTX_use_PrivateKey(handle_, evp_private_key.p) == 1) + { + ec = boost::system::error_code(); + return ec; + } + } + } + + ec = boost::system::error_code( + static_cast<int>(::ERR_get_error()), + boost::asio::error::get_ssl_category()); + return ec; +} + void context::use_private_key_file( const std::string& filename, context::file_format format) { @@ -320,6 +661,55 @@ void context::use_private_key_file( boost::asio::detail::throw_error(ec, "use_private_key_file"); } +void context::use_rsa_private_key( + const const_buffer& private_key, context::file_format format) +{ + boost::system::error_code ec; + use_rsa_private_key(private_key, format, ec); + boost::asio::detail::throw_error(ec, "use_rsa_private_key"); +} + +boost::system::error_code context::use_rsa_private_key( + const const_buffer& private_key, context::file_format format, + boost::system::error_code& ec) +{ + ::ERR_clear_error(); + + bio_cleanup bio = { make_buffer_bio(private_key) }; + if (bio.p) + { + rsa_cleanup rsa_private_key = { 0 }; + switch (format) + { + case context_base::asn1: + rsa_private_key.p = ::d2i_RSAPrivateKey_bio(bio.p, 0); + break; + case context_base::pem: + rsa_private_key.p = ::PEM_read_bio_RSAPrivateKey(bio.p, 0, 0, 0); + break; + default: + { + ec = boost::asio::error::invalid_argument; + return ec; + } + } + + if (rsa_private_key.p) + { + if (::SSL_CTX_use_RSAPrivateKey(handle_, rsa_private_key.p) == 1) + { + ec = boost::system::error_code(); + return ec; + } + } + } + + ec = boost::system::error_code( + static_cast<int>(::ERR_get_error()), + boost::asio::error::get_ssl_category()); + return ec; +} + boost::system::error_code context::use_private_key_file( const std::string& filename, context::file_format format, boost::system::error_code& ec) @@ -342,7 +732,8 @@ boost::system::error_code context::use_private_key_file( if (::SSL_CTX_use_PrivateKey_file(handle_, filename.c_str(), file_type) != 1) { - ec = boost::system::error_code(::ERR_get_error(), + ec = boost::system::error_code( + static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category()); return ec; } @@ -382,7 +773,8 @@ boost::system::error_code context::use_rsa_private_key_file( if (::SSL_CTX_use_RSAPrivateKey_file( handle_, filename.c_str(), file_type) != 1) { - ec = boost::system::error_code(::ERR_get_error(), + ec = boost::system::error_code( + static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category()); return ec; } @@ -391,6 +783,28 @@ boost::system::error_code context::use_rsa_private_key_file( return ec; } +void context::use_tmp_dh(const const_buffer& dh) +{ + boost::system::error_code ec; + use_tmp_dh(dh, ec); + boost::asio::detail::throw_error(ec, "use_tmp_dh"); +} + +boost::system::error_code context::use_tmp_dh( + const const_buffer& dh, boost::system::error_code& ec) +{ + bio_cleanup bio = { make_buffer_bio(dh) }; + if (bio.p) + { + return do_use_tmp_dh(bio.p, ec); + } + + ec = boost::system::error_code( + static_cast<int>(::ERR_get_error()), + boost::asio::error::get_ssl_category()); + return ec; +} + void context::use_tmp_dh_file(const std::string& filename) { boost::system::error_code ec; @@ -401,32 +815,36 @@ void context::use_tmp_dh_file(const std::string& filename) 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) + bio_cleanup bio = { ::BIO_new_file(filename.c_str(), "r") }; + if (bio.p) { - ec = boost::asio::error::invalid_argument; - return ec; + return do_use_tmp_dh(bio.p, ec); } - ::DH* dh = ::PEM_read_bio_DHparams(bio, 0, 0, 0); - if (!dh) - { - ::BIO_free(bio); - ec = boost::asio::error::invalid_argument; - return ec; - } + ec = boost::system::error_code( + static_cast<int>(::ERR_get_error()), + boost::asio::error::get_ssl_category()); + return ec; +} + +boost::system::error_code context::do_use_tmp_dh( + BIO* bio, boost::system::error_code& ec) +{ + ::ERR_clear_error(); - ::BIO_free(bio); - int result = ::SSL_CTX_set_tmp_dh(handle_, dh); - ::DH_free(dh); - if (result != 1) + dh_cleanup dh = { ::PEM_read_bio_DHparams(bio, 0, 0, 0) }; + if (dh.p) { - ec = boost::system::error_code(::ERR_get_error(), - boost::asio::error::get_ssl_category()); - return ec; + if (::SSL_CTX_set_tmp_dh(handle_, dh.p) == 1) + { + ec = boost::system::error_code(); + return ec; + } } - ec = boost::system::error_code(); + ec = boost::system::error_code( + static_cast<int>(::ERR_get_error()), + boost::asio::error::get_ssl_category()); return ec; } @@ -503,19 +921,26 @@ int context::password_callback_function( 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) +#if defined(BOOST_ASIO_HAS_SECURE_RTL) strcpy_s(buf, size, passwd.c_str()); -#else +#else // defined(BOOST_ASIO_HAS_SECURE_RTL) *buf = '\0'; strncat(buf, passwd.c_str(), size); -#endif +#endif // defined(BOOST_ASIO_HAS_SECURE_RTL) - return strlen(buf); + return static_cast<int>(strlen(buf)); } return 0; } +BIO* context::make_buffer_bio(const const_buffer& b) +{ + return ::BIO_new_mem_buf( + const_cast<void*>(buffer_cast<const void*>(b)), + static_cast<int>(buffer_size(b))); +} + #endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL) } // namespace ssl diff --git a/boost/asio/ssl/impl/error.ipp b/boost/asio/ssl/impl/error.ipp index 6d462352a2..bacfc7bbf1 100644 --- a/boost/asio/ssl/impl/error.ipp +++ b/boost/asio/ssl/impl/error.ipp @@ -2,7 +2,7 @@ // ssl/impl/error.ipp // ~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) @@ -30,7 +30,7 @@ namespace detail { class ssl_category : public boost::system::error_category { public: - const char* name() const + const char* name() const BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT { return "asio.ssl"; } diff --git a/boost/asio/ssl/impl/rfc2818_verification.ipp b/boost/asio/ssl/impl/rfc2818_verification.ipp index 8d577b83aa..e4f28ef946 100644 --- a/boost/asio/ssl/impl/rfc2818_verification.ipp +++ b/boost/asio/ssl/impl/rfc2818_verification.ipp @@ -2,7 +2,7 @@ // ssl/impl/rfc2818_verification.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) @@ -70,7 +70,10 @@ bool rfc2818_verification::operator()( 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())) + { + GENERAL_NAMES_free(gens); return true; + } } } else if (gen->type == GEN_IPADD && is_address) @@ -82,17 +85,24 @@ bool rfc2818_verification::operator()( { ip::address_v4::bytes_type bytes = address.to_v4().to_bytes(); if (memcmp(bytes.data(), ip_address->data, 4) == 0) + { + GENERAL_NAMES_free(gens); 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) + { + GENERAL_NAMES_free(gens); return true; + } } } } } + GENERAL_NAMES_free(gens); // 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. diff --git a/boost/asio/ssl/impl/src.hpp b/boost/asio/ssl/impl/src.hpp index 285bae4b1b..bc15b4e238 100644 --- a/boost/asio/ssl/impl/src.hpp +++ b/boost/asio/ssl/impl/src.hpp @@ -2,7 +2,7 @@ // impl/ssl/src.hpp // ~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) diff --git a/boost/asio/ssl/old/basic_context.hpp b/boost/asio/ssl/old/basic_context.hpp index 2ee0a23a57..b0b4b135d9 100644 --- a/boost/asio/ssl/old/basic_context.hpp +++ b/boost/asio/ssl/old/basic_context.hpp @@ -3,7 +3,7 @@ // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com -// Copyright (c) 2005-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2005-2014 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) diff --git a/boost/asio/ssl/old/context_service.hpp b/boost/asio/ssl/old/context_service.hpp index fc09102901..0912b55f2e 100644 --- a/boost/asio/ssl/old/context_service.hpp +++ b/boost/asio/ssl/old/context_service.hpp @@ -3,7 +3,7 @@ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com -// Copyright (c) 2005-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2005-2014 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) diff --git a/boost/asio/ssl/old/detail/openssl_context_service.hpp b/boost/asio/ssl/old/detail/openssl_context_service.hpp index 260a05c66f..a6e25c9d96 100644 --- a/boost/asio/ssl/old/detail/openssl_context_service.hpp +++ b/boost/asio/ssl/old/detail/openssl_context_service.hpp @@ -3,7 +3,7 @@ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com -// Copyright (c) 2005-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2005-2014 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) diff --git a/boost/asio/ssl/old/detail/openssl_operation.hpp b/boost/asio/ssl/old/detail/openssl_operation.hpp index c4a8feea61..6835f5ff6a 100644 --- a/boost/asio/ssl/old/detail/openssl_operation.hpp +++ b/boost/asio/ssl/old/detail/openssl_operation.hpp @@ -17,9 +17,9 @@ #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/assert.hpp> #include <boost/asio/detail/socket_ops.hpp> #include <boost/asio/placeholders.hpp> #include <boost/asio/ssl/detail/openssl_types.hpp> @@ -154,7 +154,7 @@ public: // 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 + // for read, it is done when retcode > 0 int error_code = !is_operation_done ? ::SSL_get_error( session_, rc ) : @@ -314,7 +314,7 @@ private: unsigned char *data_start = send_buf_.get_unused_start(); send_buf_.data_added(len); - BOOST_ASSERT(strand_); + BOOST_ASIO_ASSERT(strand_); boost::asio::async_write ( socket_, @@ -379,7 +379,7 @@ private: int do_async_read() { // Wait for new data - BOOST_ASSERT(strand_); + BOOST_ASIO_ASSERT(strand_); socket_.async_read_some ( boost::asio::buffer(recv_buf_.get_unused_start(), diff --git a/boost/asio/ssl/old/detail/openssl_stream_service.hpp b/boost/asio/ssl/old/detail/openssl_stream_service.hpp index 0efed751bb..ab8f8cf439 100644 --- a/boost/asio/ssl/old/detail/openssl_stream_service.hpp +++ b/boost/asio/ssl/old/detail/openssl_stream_service.hpp @@ -3,7 +3,7 @@ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com -// Copyright (c) 2005-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2005-2014 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) diff --git a/boost/asio/ssl/old/stream.hpp b/boost/asio/ssl/old/stream.hpp index 133a29d066..3bfe56df4a 100644 --- a/boost/asio/ssl/old/stream.hpp +++ b/boost/asio/ssl/old/stream.hpp @@ -3,7 +3,7 @@ // ~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com -// Copyright (c) 2005-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2005-2014 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) @@ -19,8 +19,8 @@ #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/detail/type_traits.hpp> #include <boost/asio/error.hpp> #include <boost/asio/ssl/basic_context.hpp> #include <boost/asio/ssl/stream_base.hpp> @@ -60,7 +60,7 @@ class stream { public: /// The type of the next layer. - typedef typename boost::remove_reference<Stream>::type next_layer_type; + typedef typename remove_reference<Stream>::type next_layer_type; /// The type of the lowest layer. typedef typename next_layer_type::lowest_layer_type lowest_layer_type; diff --git a/boost/asio/ssl/old/stream_service.hpp b/boost/asio/ssl/old/stream_service.hpp index c8b7a47490..3acecc5d5a 100644 --- a/boost/asio/ssl/old/stream_service.hpp +++ b/boost/asio/ssl/old/stream_service.hpp @@ -3,7 +3,7 @@ // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com -// Copyright (c) 2005-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2005-2014 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) diff --git a/boost/asio/ssl/rfc2818_verification.hpp b/boost/asio/ssl/rfc2818_verification.hpp index 63ba948d6c..f2687b9461 100644 --- a/boost/asio/ssl/rfc2818_verification.hpp +++ b/boost/asio/ssl/rfc2818_verification.hpp @@ -2,7 +2,7 @@ // ssl/rfc2818_verification.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) diff --git a/boost/asio/ssl/stream.hpp b/boost/asio/ssl/stream.hpp index 20b4e3b3cd..3eafd16e9c 100644 --- a/boost/asio/ssl/stream.hpp +++ b/boost/asio/ssl/stream.hpp @@ -2,7 +2,7 @@ // ssl/stream.hpp // ~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) @@ -20,10 +20,13 @@ #if defined(BOOST_ASIO_ENABLE_OLD_SSL) # include <boost/asio/ssl/old/stream.hpp> #else // defined(BOOST_ASIO_ENABLE_OLD_SSL) +# include <boost/asio/async_result.hpp> # 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/detail/type_traits.hpp> # include <boost/asio/ssl/context.hpp> +# include <boost/asio/ssl/detail/buffered_handshake_op.hpp> # include <boost/asio/ssl/detail/handshake_op.hpp> # include <boost/asio/ssl/detail/io.hpp> # include <boost/asio/ssl/detail/read_op.hpp> @@ -31,7 +34,6 @@ # 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> @@ -87,7 +89,7 @@ public: typedef impl_struct* impl_type; /// The type of the next layer. - typedef typename boost::remove_reference<Stream>::type next_layer_type; + typedef typename remove_reference<Stream>::type next_layer_type; /// The type of the lowest layer. typedef typename next_layer_type::lowest_layer_type lowest_layer_type; @@ -257,6 +259,43 @@ public: return core_.engine_.set_verify_mode(v, ec); } + /// Set the peer verification depth. + /** + * This function may be used to configure the maximum verification depth + * allowed by the stream. + * + * @param depth Maximum depth for the certificate chain verification that + * shall be allowed. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note Calls @c SSL_set_verify_depth. + */ + void set_verify_depth(int depth) + { + boost::system::error_code ec; + set_verify_depth(depth, ec); + boost::asio::detail::throw_error(ec, "set_verify_depth"); + } + + /// Set the peer verification depth. + /** + * This function may be used to configure the maximum verification depth + * allowed by the stream. + * + * @param depth Maximum depth for the certificate chain verification that + * shall be allowed. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls @c SSL_set_verify_depth. + */ + boost::system::error_code set_verify_depth( + int depth, boost::system::error_code& ec) + { + return core_.engine_.set_verify_depth(depth, ec); + } + /// Set the callback used to verify peer certificates. /** * This function is used to specify a callback function that will be called @@ -343,6 +382,47 @@ public: return 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 buffers The buffered data to be reused for the handshake. + * + * @throws boost::system::system_error Thrown on failure. + */ + template <typename ConstBufferSequence> + void handshake(handshake_type type, const ConstBufferSequence& buffers) + { + boost::system::error_code ec; + handshake(type, buffers, 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 buffers The buffered data to be reused for the handshake. + * + * @param ec Set to indicate what error occurred, if any. + */ + template <typename ConstBufferSequence> + boost::system::error_code handshake(handshake_type type, + const ConstBufferSequence& buffers, boost::system::error_code& ec) + { + detail::io(next_layer_, core_, + detail::buffered_handshake_op<ConstBufferSequence>(type, buffers), ec); + return ec; + } + /// Start an asynchronous SSL handshake. /** * This function is used to asynchronously perform an SSL handshake on the @@ -359,15 +439,66 @@ public: * ); @endcode */ template <typename HandshakeHandler> - void async_handshake(handshake_type type, + BOOST_ASIO_INITFN_RESULT_TYPE(HandshakeHandler, + void (boost::system::error_code)) + 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::detail::async_result_init< + HandshakeHandler, void (boost::system::error_code)> init( BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler)); + + detail::async_io(next_layer_, core_, + detail::handshake_op(type), init.handler); + + return init.result.get(); + } + + /// 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 buffers The buffered data to be reused for the handshake. 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 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. + * std::size_t bytes_transferred // Amount of buffers used in handshake. + * ); @endcode + */ + template <typename ConstBufferSequence, typename BufferedHandshakeHandler> + BOOST_ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler, + void (boost::system::error_code, std::size_t)) + async_handshake(handshake_type type, const ConstBufferSequence& buffers, + BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a BufferedHandshakeHandler. + BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( + BufferedHandshakeHandler, handler) type_check; + + boost::asio::detail::async_result_init<BufferedHandshakeHandler, + void (boost::system::error_code, std::size_t)> init( + BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler)); + + detail::async_io(next_layer_, core_, + detail::buffered_handshake_op<ConstBufferSequence>(type, buffers), + init.handler); + + return init.result.get(); } /// Shut down SSL on the stream. @@ -410,14 +541,21 @@ public: * ); @endcode */ template <typename ShutdownHandler> - void async_shutdown(BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler) + BOOST_ASIO_INITFN_RESULT_TYPE(ShutdownHandler, + void (boost::system::error_code)) + 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::detail::async_result_init< + ShutdownHandler, void (boost::system::error_code)> init( BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler)); + + detail::async_io(next_layer_, core_, detail::shutdown_op(), init.handler); + + return init.result.get(); } /// Write some data to the stream. @@ -492,16 +630,23 @@ public: * 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_INITFN_RESULT_TYPE(WriteHandler, + void (boost::system::error_code, std::size_t)) + 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::detail::async_result_init< + WriteHandler, void (boost::system::error_code, std::size_t)> init( BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + + detail::async_io(next_layer_, core_, + detail::write_op<ConstBufferSequence>(buffers), init.handler); + + return init.result.get(); } /// Read some data from the stream. @@ -577,16 +722,23 @@ public: * operation completes. */ template <typename MutableBufferSequence, typename ReadHandler> - void async_read_some(const MutableBufferSequence& buffers, + BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (boost::system::error_code, std::size_t)) + 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::detail::async_result_init< + ReadHandler, void (boost::system::error_code, std::size_t)> init( BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + + detail::async_io(next_layer_, core_, + detail::read_op<MutableBufferSequence>(buffers), init.handler); + + return init.result.get(); } private: diff --git a/boost/asio/ssl/stream_base.hpp b/boost/asio/ssl/stream_base.hpp index 712c1bda17..06d7849530 100644 --- a/boost/asio/ssl/stream_base.hpp +++ b/boost/asio/ssl/stream_base.hpp @@ -2,7 +2,7 @@ // ssl/stream_base.hpp // ~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) @@ -16,7 +16,6 @@ #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> @@ -44,12 +43,6 @@ protected: ~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 diff --git a/boost/asio/ssl/stream_service.hpp b/boost/asio/ssl/stream_service.hpp index 628972ee76..9fcb48e82c 100644 --- a/boost/asio/ssl/stream_service.hpp +++ b/boost/asio/ssl/stream_service.hpp @@ -2,7 +2,7 @@ // ssl/stream_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) diff --git a/boost/asio/ssl/verify_context.hpp b/boost/asio/ssl/verify_context.hpp index 6b5013cb24..ddd3fec5da 100644 --- a/boost/asio/ssl/verify_context.hpp +++ b/boost/asio/ssl/verify_context.hpp @@ -2,7 +2,7 @@ // ssl/verify_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) diff --git a/boost/asio/ssl/verify_mode.hpp b/boost/asio/ssl/verify_mode.hpp index ec772389e0..4d4a1ed9bf 100644 --- a/boost/asio/ssl/verify_mode.hpp +++ b/boost/asio/ssl/verify_mode.hpp @@ -2,7 +2,7 @@ // ssl/verify_mode.hpp // ~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 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) |