diff -rupN '-x*DS*' /home/a2k/tmp/boost_1_52_0_beta1/boost/asio/ssl/context.hpp asio/ssl/context.hpp --- /home/a2k/tmp/boost_1_52_0_beta1/boost/asio/ssl/context.hpp 2012-01-15 15:46:25.000000000 +0200 +++ asio/ssl/context.hpp 2012-10-30 18:04:29.392985357 +0200 @@ -28,6 +28,7 @@ # include # include # include +# include # include #endif // defined(BOOST_ASIO_ENABLE_OLD_SSL) @@ -167,6 +168,15 @@ public: BOOST_ASIO_DECL boost::system::error_code set_verify_mode( verify_mode v, boost::system::error_code& ec); + BOOST_ASIO_DECL void set_psk_identity(const char* psk); + + template + void set_psk_server_callback(PSKCallback callback); + + template + boost::system::error_code set_psk_server_callback(PSKCallback callback, + 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 @@ -494,6 +504,14 @@ public: boost::system::error_code& ec); private: + // Helper function used to set a peer identity and PSK callback. + BOOST_ASIO_DECL boost::system::error_code do_set_psk_server_callback( + detail::psk_callback_base* callback, boost::system::error_code& ec); + + // Callback used when the SSL implementation wants to verify a PSK. + BOOST_ASIO_DECL static unsigned int psk_server_callback_function(SSL *ssl, + const char* identity, unsigned char* psk, unsigned int max_psk_len); + // 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); diff -rupN '-x*DS*' /home/a2k/tmp/boost_1_52_0_beta1/boost/asio/ssl/detail/engine.hpp asio/ssl/detail/engine.hpp --- /home/a2k/tmp/boost_1_52_0_beta1/boost/asio/ssl/detail/engine.hpp 2012-01-15 15:46:25.000000000 +0200 +++ asio/ssl/detail/engine.hpp 2012-10-30 18:04:29.388985026 +0200 @@ -77,6 +77,10 @@ public: BOOST_ASIO_DECL boost::system::error_code set_verify_callback( verify_callback_base* callback, boost::system::error_code& ec); + // Set a peer PSK verification callback + BOOST_ASIO_DECL boost::system::error_code set_psk_server_callback( + psk_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( @@ -116,6 +120,9 @@ private: BOOST_ASIO_DECL static int verify_callback_function( int preverified, X509_STORE_CTX* ctx); + BOOST_ASIO_DECL static unsigned int psk_server_callback_function( + SSL *ssl, const char* identity, unsigned char* psk, unsigned int max_psk_len); + // 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(); diff -rupN '-x*DS*' /home/a2k/tmp/boost_1_52_0_beta1/boost/asio/ssl/detail/impl/engine.ipp asio/ssl/detail/impl/engine.ipp --- /home/a2k/tmp/boost_1_52_0_beta1/boost/asio/ssl/detail/impl/engine.ipp 2012-07-16 09:26:30.000000000 +0300 +++ asio/ssl/detail/impl/engine.ipp 2012-10-30 18:03:44.032985793 +0200 @@ -98,6 +88,20 @@ boost::system::error_code engine::set_ve return ec; } +boost::system::error_code engine::set_psk_server_callback( + psk_callback_base* callback, boost::system::error_code& ec) +{ + if (SSL_get_app_data(ssl_)) + delete static_cast(SSL_get_app_data(ssl_)); + + SSL_set_app_data(ssl_, callback); + + ::SSL_set_psk_server_callback(ssl_, &engine::psk_server_callback_function); + + ec = boost::system::error_code(); + return ec; +} + int engine::verify_callback_function(int preverified, X509_STORE_CTX* ctx) { if (ctx) @@ -119,6 +123,22 @@ int engine::verify_callback_function(int } return 0; +} + +unsigned int engine::psk_server_callback_function(SSL *ssl, + const char* identity, unsigned char* psk, unsigned int max_psk_len) +{ + if (SSL_get_app_data(ssl)) + { + psk_callback_base* callback = + static_cast( + SSL_get_app_data(ssl)); + + psk_context psk_ctx(ssl, identity, psk, max_psk_len); + return callback->call(psk_ctx); + } + + return 0; } engine::want engine::handshake( diff -rupN '-x*DS*' /home/a2k/tmp/boost_1_52_0_beta1/boost/asio/ssl/detail/psk_callback.hpp asio/ssl/detail/psk_callback.hpp --- /home/a2k/tmp/boost_1_52_0_beta1/boost/asio/ssl/detail/psk_callback.hpp 1970-01-01 03:00:00.000000000 +0300 +++ asio/ssl/detail/psk_callback.hpp 2012-10-30 18:18:49.192971249 +0200 @@ -0,0 +1,70 @@ +// +// ssl/detail/psk_callback.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2012 Roman Bovsunovskiy (a2k0001 at gmail 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_PSK_CALLBACK_HPP +#define BOOST_ASIO_SSL_DETAIL_PSK_CALLBACK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#if !defined(BOOST_ASIO_ENABLE_OLD_SSL) +# include +#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL) + +#include + +namespace boost { +namespace asio { +namespace ssl { +namespace detail { + +#if !defined(BOOST_ASIO_ENABLE_OLD_SSL) + +class psk_callback_base +{ +public: + virtual ~psk_callback_base() + { + } + + virtual unsigned int call(psk_context& ctx) = 0; +}; + +template +class psk_callback : public psk_callback_base +{ +public: + explicit psk_callback(PSKCallback callback) + : callback_(callback) + { + } + + virtual unsigned int call(psk_context& ctx) + { + return callback_(ctx); + } + +private: + PSKCallback callback_; +}; + +#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL) + +} // namespace detail +} // namespace ssl +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_SSL_DETAIL_PSK_CALLBACK_HPP diff -rupN '-x*DS*' /home/a2k/tmp/boost_1_52_0_beta1/boost/asio/ssl/impl/context.hpp asio/ssl/impl/context.hpp --- /home/a2k/tmp/boost_1_52_0_beta1/boost/asio/ssl/impl/context.hpp 2012-01-15 15:46:25.000000000 +0200 +++ asio/ssl/impl/context.hpp 2012-10-30 18:04:29.392985357 +0200 @@ -30,6 +30,22 @@ namespace ssl { #if !defined(BOOST_ASIO_ENABLE_OLD_SSL) +template +void context::set_psk_server_callback(PSKCallback callback) +{ + boost::system::error_code ec; + this->set_psk_server_callback(callback, ec); + boost::asio::detail::throw_error(ec, "set_psk_callback"); +} + +template +boost::system::error_code context::set_psk_server_callback(PSKCallback callback, + boost::system::error_code& ec) +{ + return do_set_psk_server_callback( + new detail::psk_callback(callback), ec); +} + template void context::set_verify_callback(VerifyCallback callback) { diff -rupN '-x*DS*' /home/a2k/tmp/boost_1_52_0_beta1/boost/asio/ssl/impl/context.ipp asio/ssl/impl/context.ipp --- /home/a2k/tmp/boost_1_52_0_beta1/boost/asio/ssl/impl/context.ipp 2012-01-15 15:46:25.000000000 +0200 +++ asio/ssl/impl/context.ipp 2012-10-30 18:03:44.036986053 +0200 @@ -475,6 +487,36 @@ int context::verify_callback_function(in return 0; } +BOOST_ASIO_DECL void context::set_psk_identity(const char* identity) +{ + SSL_CTX_use_psk_identity_hint(handle_, identity); +} + +boost::system::error_code context::do_set_psk_server_callback( + detail::psk_callback_base* callback, boost::system::error_code& ec) +{ + SSL_CTX_set_app_data(handle_, callback); + + ::SSL_CTX_set_psk_server_callback(handle_, + &context::psk_server_callback_function); + + ec = boost::system::error_code(); + return ec; +} + +unsigned int context::psk_server_callback_function(SSL *ssl, + const char* identity, unsigned char* psk, unsigned int max_psk_len) +{ + SSL_CTX* handle = ::SSL_get_SSL_CTX(ssl); + + detail::psk_callback_base* callback = + static_cast( + SSL_CTX_get_app_data(handle)); + + psk_context psk_ctx(ssl, identity, psk, max_psk_len); + return callback->call(psk_ctx); +} + boost::system::error_code context::do_set_password_callback( detail::password_callback_base* callback, boost::system::error_code& ec) { diff -rupN '-x*DS*' /home/a2k/tmp/boost_1_52_0_beta1/boost/asio/ssl/psk_context.hpp asio/ssl/psk_context.hpp --- /home/a2k/tmp/boost_1_52_0_beta1/boost/asio/ssl/psk_context.hpp 1970-01-01 03:00:00.000000000 +0300 +++ asio/ssl/psk_context.hpp 2012-10-30 18:18:19.392969787 +0200 @@ -0,0 +1,99 @@ +// +// ssl/psk_context.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2012 Roman Bovsunovskiy (a2k0001 at gmail 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_PSK_CONTEXT_HPP +#define BOOST_ASIO_SSL_PSK_CONTEXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#if !defined(BOOST_ASIO_ENABLE_OLD_SSL) +# include +# include +#endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL) + +#include + +namespace boost { +namespace asio { +namespace ssl { + +#if !defined(BOOST_ASIO_ENABLE_OLD_SSL) + +/** + * @note The psk_context does not own the underlying PSK string. + */ +class psk_context + : private noncopyable +{ +public: + /// The native handle type of the PSK context. + typedef SSL* native_handle_ssl_type; + typedef const char* native_handle_identity_type; + typedef unsigned char* native_handle_psk_type; + typedef unsigned int native_handle_psk_maxlen_type; + + /// Constructor. + explicit psk_context(native_handle_ssl_type ssl_handle, + native_handle_identity_type identity_handle, + native_handle_psk_type psk_handle, + native_handle_psk_maxlen_type psk_maxlen_handle) + : ssl_handle_(ssl_handle_), + identity_handle_(identity_handle), + psk_handle_(psk_handle), + psk_maxlen_handle_(psk_maxlen_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_ssl_type native_ssl_handle() + { + return ssl_handle_; + } + + native_handle_identity_type native_identity_handle() + { + return identity_handle_; + } + + native_handle_psk_type native_psk_handle() + { + return psk_handle_; + } + native_handle_psk_maxlen_type native_psk_maxlen_handle() + { + return psk_maxlen_handle_; + } + +private: + // The underlying native implementation. + native_handle_ssl_type ssl_handle_; + native_handle_identity_type identity_handle_; + native_handle_psk_type psk_handle_; + native_handle_psk_maxlen_type psk_maxlen_handle_; +}; + +#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL) + +} // namespace ssl +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_SSL_PSK_CONTEXT_HPP