Search code examples
c++sslproxyboost-asioboost-beast

SSL tunnel with Boost::Beast


I want to connect to a proxy server that only allows HTTP connections, to speak with the target server by HTTPS.

The proxy server documentation states that the only way to do that is by means of the HTTP Connect verb (they are planning to add direct HTTPS connections to the proxy server itself, but for the moment only HTTP connections are allowed).

In my C++ program, I successfully connected and worked with the target server using ssl_stream's during a couple of months, using boost::asio without boost::beast, but I want now to use a proxy using boost::beast to make things easier; so, I now how to work with boost::asio but I'm a boost::beast newbie (and I don't fully understand how SSL works either).

The think is that, in my understanding, when you use a ssl_stream, you encript the whole communication, however, what I need now is to insert the encrypted message within the CONNECT HTTP body, and I don't know how to do that.

I've readed that this has something to do with the lowest_layer/next_layer thing but I'm not sure.

Could anybody provide an example of a full read/write connection with a proxy-server? or at least further clarifications?


Solution

    1. Declare a variable for the connection (ioc is the io_context)

      boost::asio::ssl::stream<boost::asio::ip::tcp::socket> stream{ioc};

    2. Build a CONNECT HTTP request message (req) using Beast

    3. Send the request to the proxy in plain-text (note next_layer())

      boost::beast::http::write(stream.next_layer(), req);

    4. Read the HTTP response from the proxy

    5. If the response has OK status, the tunnel is established
    6. Now perform the SSL handshake:

      stream.handshake(boost::asio::ssl::stream_base::client);

    At this point you can write HTTP requests to stream and read HTTP responses from stream using Beast as normal (do not use next_layer() again).