2 years ago
#61007
Fabio
Is it possible to use an asio ssl stream class to alternate between encrypted and clear traffic?
I am writing a client server application using the standalone version of asio
.
I would like to use the same tcp socket for ssl and non ssl traffic.
Say I have a variable m_socket
of type asio::ssl::stream<tcp::socket>
, where I have already successfully completed the handshake. I want to use it to send/receive messages in clear, e.g.
// send in clear
asio::async_write(m_socket.next_layer(), buffer, handler);
or encrypted, e.g.
// send encrypted
asio::async_write(m_socket, buffer, handler);
To test if it is even possible to use the raw socket embedded in an ssl stream to send and receive traffic in clear, I wrote the following mini client-server programs. It works correctly when I use the ssl stream in read/write operations. If instead I replace socket
with socket.next_layer()
(i.e. if I change the #if 1
to #if 0
in both programs) then the text received by the client is garbled.
//////////////////
// CLIENT
//
#include <cstdlib>
#include <iostream>
#include <asio.hpp>
#include <asio/ssl.hpp>
#if 1 // change this to zero to send/recv in clear
#define SOCKET socket
#else
#define SOCKET socket.next_layer()
#endif
using asio::ip::tcp;
int main(int argc, char* argv[])
{
char message[4] = {};
try
{
asio::io_context io_context;
asio::ssl::context sslctx(asio::ssl::context::sslv23);
sslctx.use_certificate_chain_file("certificate.pem");
sslctx.use_private_key_file("key.pem", asio::ssl::context::pem);
sslctx.use_tmp_dh_file("dh2048.pem");
sslctx.set_options(
asio::ssl::context::default_workarounds
| asio::ssl::context::no_sslv2
| asio::ssl::context::single_dh_use);
asio::ssl::stream<tcp::socket> socket(io_context, sslctx);
tcp::acceptor(io_context, tcp::endpoint(tcp::v4(), 15000)).accept(socket.next_layer());
socket.handshake(asio::ssl::stream_base::server);
for (int i = 0; i < 10; ++i) {
asio::read(SOCKET, asio::buffer(message, 3));
std::cout << "read: " << message << "\n";
snprintf(message, sizeof(message), "%03d", 1 + atoi(message));
asio::write(SOCKET, asio::buffer(message, 3));
std::cout << "sent: " << message << "\n";
}
}
catch (std::exception& e) {
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
and
//////////////////
// SERVER
//
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <asio.hpp>
#include <asio/ssl.hpp>
#if 1 // change this to 0 to send/receive in clear
#define SOCKET socket
#else
#define SOCKET socket.next_layer()
#endif
using asio::ip::tcp;
int main(int argc, char* argv[])
{
char message[4] = {};
try
{
asio::io_context io_context;
asio::ssl::context sslctx(asio::ssl::context::sslv23);
sslctx.load_verify_file("certificate.pem");
asio::ssl::stream<tcp::socket> socket(io_context, sslctx);
socket.set_verify_mode(asio::ssl::verify_peer);
auto endpoints = tcp::resolver(io_context).resolve(tcp::v4(), "localhost", "15000");
asio::connect(socket.lowest_layer(), endpoints);
socket.handshake(asio::ssl::stream_base::client);
for (int i = 0; i < 10; ++i) {
snprintf(message, sizeof(message), "%03d", 2*i);
asio::write(SOCKET, asio::buffer(message, 3));
std::cout << "sent: " << message << "\n";
asio::read(SOCKET, asio::buffer(message, 3));
std::cout << "read: " << message << "\n";
}
}
catch (std::exception& e) {
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
Does somebody know if what I am trying to do is even possible using an asio ssl stream?
c++
sockets
boost-asio
asio
tls1.3
0 Answers
Your Answer