LCOV - code coverage report
Current view: top level - asio/sockets - ssl_socket.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 4 4
Test Date: 2026-11-10 10:38:07 Functions: 100.0 % 3 3

            Line data    Source code
       1              : #ifndef THINGER_ASIO_SSL_SOCKET_HPP
       2              : #define THINGER_ASIO_SSL_SOCKET_HPP
       3              : 
       4              : #include "tcp_socket.hpp"
       5              : #include "../ssl/certificate_manager.hpp"
       6              : #include "../ssl/client_verify.hpp"
       7              : #include <boost/asio.hpp>
       8              : #include <boost/asio/ssl.hpp>
       9              : 
      10              : namespace thinger::asio {
      11              : 
      12              : class ssl_socket : public tcp_socket {
      13              : public:
      14              :     // constructors and destructors
      15              :     ssl_socket(const std::string& context, boost::asio::io_context& io_context,
      16              :                const std::shared_ptr<boost::asio::ssl::context>& ssl_context);
      17              :     ssl_socket(const std::string& context, const std::shared_ptr<tcp_socket>& socket,
      18              :                const std::shared_ptr<boost::asio::ssl::context>& ssl_context);
      19              :     ~ssl_socket() override;
      20              : 
      21              :     // socket control
      22              :     void close() override;
      23              :     bool requires_handshake() const override;
      24              :     // Without a host, the server handshake: it fails if an earlier session is resumed
      25              :     // without a client certificate where the host name requires one (see
      26              :     // certificate_manager::set_client_verify()), as no certificate is asked for then
      27              :     awaitable<boost::system::error_code> handshake(const std::string& host = "") override;
      28              : 
      29              :     // read operations
      30              :     awaitable<io_result> read_some(uint8_t buffer[], size_t max_size) override;
      31              :     awaitable<io_result> read_some_cancellable(uint8_t buffer[], size_t max_size,
      32              :                                                boost::asio::cancellation_slot slot) override;
      33              :     awaitable<io_result> read(uint8_t buffer[], size_t size) override;
      34              :     awaitable<io_result> read(boost::asio::streambuf& buffer, size_t size) override;
      35              :     awaitable<io_result> read_until(boost::asio::streambuf& buffer, std::string_view delim) override;
      36              : 
      37              :     // wait
      38              :     awaitable<boost::system::error_code> wait(boost::asio::socket_base::wait_type type) override;
      39              :     awaitable<boost::system::error_code> peer_closed() override;
      40              : 
      41              :     // write operations
      42              :     awaitable<io_result> write(const uint8_t buffer[], size_t size) override;
      43              :     awaitable<io_result> write(std::string_view str) override;
      44              :     awaitable<io_result> write(const std::vector<boost::asio::const_buffer>& buffers) override;
      45              :     // Writes go through the TLS stream: never written without waiting
      46         6623 :     size_t write_now(const std::vector<boost::asio::const_buffer>& buffers, boost::system::error_code& ec) override {
      47         6623 :         return socket::write_now(buffers, ec);
      48              :     }
      49              : 
      50              :     // some getters to check the state
      51              :     bool is_secure() const override;
      52              :     // Decrypted data waiting to be read counts too
      53              :     bool readable_now() const override;
      54              :     // Once the handshake is done (none before, or once closed)
      55              :     std::optional<tls_session> tls() const override;
      56              :     // Checked against the record of the server handshake (none on the client side)
      57         3845 :     bool misdirected(std::string_view host) const override { return handshake_.misdirected(host); }
      58              : 
      59              :     // The certificate of the peer (its leaf), without copying it: null if it sent none (or
      60              :     // before the handshake). Owned by the connection: not to be used once the socket is closed
      61              :     // or destroyed (X509_up_ref() it to keep it)
      62              :     X509* peer_certificate() const;
      63              :     // The certificates the peer sent, without copying them, as OpenSSL keeps them: on the
      64              :     // server side without the leaf (see peer_certificate()), on the client side with it first.
      65              :     // Null if none; owned by the connection, as peer_certificate()
      66              :     STACK_OF(X509)* peer_chain() const;
      67              : 
      68              :     // OpenSSL handle of the TLS stream, e.g. to set the name a client verifies in the
      69              :     // certificate of the server before the handshake
      70          261 :     SSL* native_handle() { return ssl_stream_.native_handle(); }
      71              : 
      72              :     // Internal: only listener calls it, until tls_socket (0.10); applications set
      73              :     // listener_options::client_verify. Ask the client for its certificate with `policy` (see
      74              :     // client_verify_policy), kept as long as the socket; before the server handshake
      75              :     void set_client_verify(std::shared_ptr<const client_verify_policy> policy);
      76              : 
      77              : private:
      78              :     // Move up to `size` bytes of read_ahead_ to `buffer`; how many were moved
      79              :     size_t take_read_ahead(uint8_t buffer[], size_t size);
      80              :     // Move read_ahead_ to `buffer`
      81              :     void take_read_ahead(boost::asio::streambuf& buffer, size_t max_size);
      82              : 
      83              :     boost::asio::ssl::stream<boost::asio::ip::tcp::socket&> ssl_stream_;
      84              :     // Data already decrypted by peer_closed(), served before reading from the stream
      85              :     std::string read_ahead_;
      86              :     std::shared_ptr<boost::asio::ssl::context> ssl_context_;
      87              :     // Client certificates asked for (server side), referred to by the SSL
      88              :     std::shared_ptr<const client_verify_policy> client_verify_;
      89              :     // What the server handshake chose by the host name of its client, kept once it completes
      90              :     tls_handshake_record handshake_;
      91              : };
      92              : 
      93              : }
      94              : 
      95              : #endif
        

Generated by: LCOV version 2.0-1