// // Copyright (c) 2021 Kasper Laudrup (laudrup at stacktrace dot dk) // // 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_WINTLS_DETAIL_ENCRYPT_BUFFERS_HPP #define BOOST_WINTLS_DETAIL_ENCRYPT_BUFFERS_HPP #include #include #include namespace boost { namespace wintls { namespace detail { class encrypt_buffers : public sspi_buffer_sequence<4> { public: encrypt_buffers(ctxt_handle& ctxt_handle) : sspi_buffer_sequence(std::array { SECBUFFER_STREAM_HEADER, SECBUFFER_DATA, SECBUFFER_STREAM_TRAILER, SECBUFFER_EMPTY }) , ctxt_handle_(ctxt_handle) { } template std::size_t operator()(const ConstBufferSequence& buffers, SECURITY_STATUS& sc) { if (data_.empty()) { sc = sspi_functions::QueryContextAttributes(ctxt_handle_.get(), SECPKG_ATTR_STREAM_SIZES, &stream_sizes_); if (sc != SEC_E_OK) { return 0; } data_.resize(stream_sizes_.cbHeader + stream_sizes_.cbMaximumMessage + stream_sizes_.cbTrailer); } const auto size_consumed = std::min(net::buffer_size(buffers), static_cast(stream_sizes_.cbMaximumMessage)); buffers_[0].pvBuffer = data_.data(); buffers_[0].cbBuffer = stream_sizes_.cbHeader; net::buffer_copy(net::buffer(data_.data() + stream_sizes_.cbHeader, size_consumed), buffers); buffers_[1].pvBuffer = data_.data() + stream_sizes_.cbHeader; buffers_[1].cbBuffer = static_cast(size_consumed); buffers_[2].pvBuffer = data_.data() + stream_sizes_.cbHeader + size_consumed; buffers_[2].cbBuffer = stream_sizes_.cbTrailer; return size_consumed; } private: ctxt_handle& ctxt_handle_; std::vector data_; SecPkgContext_StreamSizes stream_sizes_{0, 0, 0, 0, 0}; }; } // namespace detail } // namespace wintls } // namespace boost #endif // BOOST_WINTLS_DETAIL_ENCRYPT_BUFFERS_HPP