aboutsummaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
authorHannes Rantzsch <[email protected]>2019-05-23 16:21:49 +0200
committerHannes Rantzsch <[email protected]>2019-05-23 16:21:49 +0200
commitc43ef790e50a96bc3209fc8f39cd4fd1e6c65371 (patch)
treef525d0578e6da47bc117c2990d9cae73a32fff33 /doc
parent3e05398ab52313b111a9fd36723569edd9be1b74 (diff)
Add TLS::Stream code example
Diffstat (limited to 'doc')
-rw-r--r--doc/manual/tls.rst133
1 files changed, 133 insertions, 0 deletions
diff --git a/doc/manual/tls.rst b/doc/manual/tls.rst
index 199e03763..164b6b8d6 100644
--- a/doc/manual/tls.rst
+++ b/doc/manual/tls.rst
@@ -1709,3 +1709,136 @@ It offers the following interface:
Policy* policy;
Server_Information serverInfo;
};
+
+
+Stream Code Example
+^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: cpp
+
+ #include <iostream>
+
+ #include <botan/asio_stream.h>
+ #include <botan/auto_rng.h>
+ #include <botan/certstor_system.h>
+
+ #include <boost/asio.hpp>
+ #include <boost/beast.hpp>
+ #include <boost/bind.hpp>
+
+ namespace http = boost::beast::http;
+ namespace _ = boost::asio::placeholders;
+
+ // very basic credentials manager
+ class Credentials_Manager : public Botan::Credentials_Manager
+ {
+ public:
+ Credentials_Manager() {}
+
+ std::vector<Botan::Certificate_Store*>
+ trusted_certificate_authorities(const std::string&, const std::string&) override
+ {
+ return {&cert_store_};
+ }
+
+ private:
+ Botan::System_Certificate_Store cert_store_;
+ };
+
+ // a simple https client based on TLS::Stream
+ class client
+ {
+ public:
+ client(boost::asio::io_context& io_context,
+ boost::asio::ip::tcp::resolver::iterator endpoint_iterator,
+ http::request<http::string_body> req)
+ : request_(req)
+ , ctx_{&credentials_mgr_,
+ &rng_,
+ &session_mgr_,
+ &policy_,
+ Botan::TLS::Server_Information()}
+ , stream_(io_context, ctx_)
+ {
+ boost::asio::async_connect(stream_.lowest_layer(), endpoint_iterator,
+ boost::bind(&client::handle_connect, this, _::error));
+ }
+
+ void handle_connect(const boost::system::error_code& error)
+ {
+ if(error)
+ {
+ std::cout << "Connect failed: " << error.message() << "\n";
+ return;
+ }
+ stream_.async_handshake(Botan::TLS::Connection_Side::CLIENT,
+ boost::bind(&client::handle_handshake, this, _::error));
+ }
+
+ void handle_handshake(const boost::system::error_code& error)
+ {
+ if(error)
+ {
+ std::cout << "Handshake failed: " << error.message() << "\n";
+ return;
+ }
+ http::async_write(stream_, request_,
+ boost::bind(&client::handle_write, this, _::error, _::bytes_transferred));
+ }
+
+ void handle_write(const boost::system::error_code& error, size_t)
+ {
+ if(error)
+ {
+ std::cout << "Write failed: " << error.message() << "\n";
+ return;
+ }
+ http::async_read(stream_, reply_, response_,
+ boost::bind(&client::handle_read, this, _::error, _::bytes_transferred));
+ }
+
+ void handle_read(const boost::system::error_code& error, size_t)
+ {
+ if(!error)
+ {
+ std::cout << "Reply: ";
+ std::cout << response_.body() << "\n";
+ }
+ else
+ {
+ std::cout << "Read failed: " << error.message() << "\n";
+ }
+ }
+
+ private:
+ http::request<http::dynamic_body> request_;
+ http::response<http::string_body> response_;
+ boost::beast::flat_buffer reply_;
+
+ Botan::TLS::Session_Manager_Noop session_mgr_;
+ Botan::AutoSeeded_RNG rng_;
+ Credentials_Manager credentials_mgr_;
+ Botan::TLS::Policy policy_;
+
+ Botan::TLS::Context ctx_;
+ Botan::TLS::Stream<boost::asio::ip::tcp::socket> stream_;
+ };
+
+ int main()
+ {
+ boost::asio::io_context io_context;
+
+ boost::asio::ip::tcp::resolver resolver(io_context);
+ boost::asio::ip::tcp::resolver::query query("botan.randombit.net", "443");
+ boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
+
+ http::request<http::string_body> req;
+ req.version(11);
+ req.method(http::verb::get);
+ req.target("/news.html");
+ req.set(http::field::host, "botan.randombit.net");
+
+ client c(io_context, iterator, req);
+
+ io_context.run();
+ }