From 3fb51823009484f3afff784882b5df64e2b1c1cc Mon Sep 17 00:00:00 2001 From: Hannes Rantzsch Date: Mon, 3 Jun 2019 16:17:50 +0200 Subject: Use TLS::Context::verifyCallback as tls_verify_cert_chain callback StreamCore uses the user-provided verify callback as a tls_verify_cert_chain if any is provided to the Context. Stream allows configuring the context as well using Stream::set_verify_callback. Stream now keeps a reference to the Context, rather than copying it. This allows users to configure the Context after constructing the Stream, but requires them to manage its lifetime. --- src/lib/tls/asio/asio_stream.h | 84 +++++++++++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 22 deletions(-) (limited to 'src/lib') diff --git a/src/lib/tls/asio/asio_stream.h b/src/lib/tls/asio/asio_stream.h index 7cdd8d3dd..59776d1bd 100644 --- a/src/lib/tls/asio/asio_stream.h +++ b/src/lib/tls/asio/asio_stream.h @@ -52,21 +52,38 @@ class Stream //! \name construction //! @{ + /** + * @brief Construct a new Stream + * + * @param context The context parameter is be used to set up the underlying native handle. Using code is + * responsible for lifetime management of the context and must ensure that is is available for the + * lifetime of the stream. + * @param args Arguments to be forwarded to the construction of the next layer. + */ template explicit Stream(Context& context, Args&& ... args) : m_context(context) , m_nextLayer(std::forward(args)...) - , m_core(m_receive_buffer, m_send_buffer) + , m_core(m_receive_buffer, m_send_buffer, m_context) , m_input_buffer_space(MAX_CIPHERTEXT_SIZE, '\0') , m_input_buffer(m_input_buffer_space.data(), m_input_buffer_space.size()) {} - // overload for boost::asio::ssl::stream compatibility + /** + * @brief Construct a new Stream + * + * Convenience overload for boost::asio::ssl::stream compatibility. + * + * @param arg This argument is forwarded to the construction of the next layer. + * @param context The context parameter is be used to set up the underlying native handle. Using code is + * responsible for lifetime management of the context and must ensure that is is available for the + * lifetime of the stream. + */ template explicit Stream(Arg&& arg, Context& context) : m_context(context) , m_nextLayer(std::forward(arg)) - , m_core(m_receive_buffer, m_send_buffer) + , m_core(m_receive_buffer, m_send_buffer, m_context) , m_input_buffer_space(MAX_CIPHERTEXT_SIZE, '\0') , m_input_buffer(m_input_buffer_space.data(), m_input_buffer_space.size()) {} @@ -102,24 +119,30 @@ class Stream //! \name configuration and callback setters //! @{ - //! @throws Not_Implemented - template - void set_verify_callback(VerifyCallback callback) + /** + * @brief Override the tls_verify_cert_chain callback + * + * This changes the verify_callback in the stream's TLS::Context, and hence the tls_verify_cert_chain callback + * used in the handshake. + * Using this function is equivalent to setting the callback via @see Botan::TLS::Context::set_verify_callback + */ + void set_verify_callback(Context::Verify_Callback callback) { - BOTAN_UNUSED(callback); - throw Not_Implemented("set_verify_callback is not implemented"); + m_context.set_verify_callback(std::move(callback)); } /** - * Not Implemented. - * @param ec Will be set to `Botan::ErrorType::NotImplemented` + * @brief Override the tls_verify_cert_chain callback + * + * This changes the verify_callback in the stream's TLS::Context, and hence the tls_verify_cert_chain callback + * used in the handshake. + * + * @param ec This parameter is unused. */ - template - void set_verify_callback(VerifyCallback callback, - boost::system::error_code& ec) + void set_verify_callback(Context::Verify_Callback callback, boost::system::error_code& ec) { - BOTAN_UNUSED(callback); - ec = Botan::ErrorType::NotImplemented; + BOTAN_UNUSED(ec); + m_context.set_verify_callback(std::move(callback)); } //! @throws Not_Implemented @@ -133,8 +156,7 @@ class Stream * Not Implemented. * @param ec Will be set to `Botan::ErrorType::NotImplemented` */ - void set_verify_depth(int depth, - boost::system::error_code& ec) + void set_verify_depth(int depth, boost::system::error_code& ec) { BOTAN_UNUSED(depth); ec = Botan::ErrorType::NotImplemented; @@ -153,8 +175,7 @@ class Stream * @param ec Will be set to `Botan::ErrorType::NotImplemented` */ template - void set_verify_mode(verify_mode v, - boost::system::error_code& ec) + void set_verify_mode(verify_mode v, boost::system::error_code& ec) { BOTAN_UNUSED(v); ec = Botan::ErrorType::NotImplemented; @@ -511,8 +532,8 @@ class Stream class StreamCore : public Botan::TLS::Callbacks { public: - StreamCore(boost::beast::flat_buffer& receive_buffer, boost::beast::flat_buffer& send_buffer) - : m_receive_buffer(receive_buffer), m_send_buffer(send_buffer) {} + StreamCore(boost::beast::flat_buffer& receive_buffer, boost::beast::flat_buffer& send_buffer, Context& context) + : m_receive_buffer(receive_buffer), m_send_buffer(send_buffer), m_tls_context(context) {} virtual ~StreamCore() = default; @@ -546,8 +567,27 @@ class Stream return true; } + void tls_verify_cert_chain( + const std::vector& cert_chain, + const std::vector>& ocsp_responses, + const std::vector& trusted_roots, + Usage_Type usage, + const std::string& hostname, + const TLS::Policy& policy) override + { + if(m_tls_context.has_verify_callback()) + { + m_tls_context.verifyCallback(cert_chain, ocsp_responses, trusted_roots, usage, hostname, policy); + } + else + { + Callbacks::tls_verify_cert_chain(cert_chain, ocsp_responses, trusted_roots, usage, hostname, policy); + } + } + boost::beast::flat_buffer& m_receive_buffer; boost::beast::flat_buffer& m_send_buffer; + Context& m_tls_context; }; const boost::asio::mutable_buffer& input_buffer() { return m_input_buffer; } @@ -653,7 +693,7 @@ class Stream } } - Context m_context; + Context& m_context; StreamLayer m_nextLayer; boost::beast::flat_buffer m_receive_buffer; -- cgit v1.2.3