6MarViN
6MarViN

Reputation: 111

Excessive message size with boost asio and SSL

I am currently working on a server that uses SSL to secure the transmissions. After accepting a conenction, the server makes the hadshake and if it succeeds, it sends a packet to the client.

My code is working perfectly fine on Windows, but when I run it on Debian 7, I get an "Excessive message size" error when I try to write that packet.

I'm pretty sure it does not come from my certificates, since I tried running the boost asio SSL example with the same certificates and it works perfectly fine.

Here is the code:

Initialization of the server:

Server::Server(configuration::Configuration const & conf, utils::Logger & log): _cmds(conf, log), _conf(conf), _logger(log), _ctx(boost::asio::ssl::context::sslv23)
{
tcp::endpoint endpoint(tcp::v4(), conf.getPort());
configuration::SSL_conf ssl = conf.getSLLInfos();

try
{
    this->_ctx.set_options(boost::asio::ssl::context::default_workarounds
    | boost::asio::ssl::context::no_sslv2
    | boost::asio::ssl::context::single_dh_use);
    this->_ctx.set_password_callback(boost::bind(&Server::_getPass, this, _1, _2));
    this->_ctx.use_certificate_file(ssl.certificate.string(), boost::asio::ssl::context_base::pem);
    this->_ctx.use_private_key_file(ssl.key.string(), boost::asio::ssl::context_base::pem);
    this->_ctx.use_tmp_dh_file(ssl.certificate.string());
    this->_acceptor.reset(new tcp::acceptor(this->_service, endpoint));
    this->_logger.logMsg(3, "Starting listen on port " + std::to_string(endpoint.port()));
    for (int i = 0; i < 256; ++i)
        this->_c.push_back(std::shared_ptr<Client>(new Client(this->_service, this->_cmds, conf, log, i, this->_ctx)));
    this->_acceptor->async_accept(this->_c.front()->getSocket(),
        boost::bind(&Server::_handleAccept, this,
        this->_c.front(),
        boost::asio::placeholders::error));
}
catch (boost::system::system_error & err)
{
    this->_logger.logErr(err.what());
}
}

The initialization of the session:

void                    Client::init()
{
this->_logger.logMsg(3, "Client [" + std::to_string(this->_id) + "] initialized");
this->_isAlive = true;
this->_socket.async_handshake(boost::asio::ssl::stream_base::server,
    boost::bind(&Client::handleHandshake, this,
      boost::asio::placeholders::error));
}

The handhsake callback:

void                    Client::handleHandshake(boost::system::error_code const & err)
{
if (!err)
{
    memset(&this->_header, 0, sizeof(protocol::header));
    this->_keepAlive = this->_conf.getKeepAlive();
    this->_header.keepAlive = 1;
    this->_logger.logStruct<protocol::header>("Client [" + std::to_string(this->_id) + "] Sending handhsake: ", this->_header);
    boost::asio::async_write(this->_socket, boost::asio::buffer(&this->_header, sizeof(protocol::header)),
        boost::bind(&Client::handleWrite, this,
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred));
}
else
    this->kill();
}

And finally, the write callback where I receive the error:

void                    Client::handleWrite(boost::system::error_code const & err, std::size_t)
{
if (!err && this->_keepAlive)
{
    clearBuff(this->_outBuff);
    boost::asio::async_read(this->_socket, boost::asio::buffer(&this->_header, sizeof(protocol::header)),
        boost::bind(&Client::handleHeaderRead, this,
        boost::asio::placeholders::error,
        boost::asio::placeholders::bytes_transferred));
}
else
{
    this->_logger.logErr("Client [" + std::to_string(this->_id) + "] write failed : " + err.message());
    this->kill();
}
}

As I said the handleWrite callback receives an error with the value "Excessive message size". I really don't understand why since my use of boost asio is pretty standard and my certificates, that are self signed work with other applications.

Thank you for helping.

Upvotes: 1

Views: 2310

Answers (3)

sehe
sehe

Reputation: 393134

Try to configure a specific SSL protocol version (e.g. only SSLv3). This reduces the list of items to be sent.

Also, consider sending a minimized certificate bundle (in the certificate file on the server) because the client won't be interested in most root certificates in the chain, unless it already knows them anyways

Upvotes: 1

6MarViN
6MarViN

Reputation: 111

Alright, so as said in a comment, the problem was that for some reason, letting the client and server decide which version to choose from seemed to screw things up. By forcing the use of SSLV3, it solve it. Thank you all for your help though.

Upvotes: 1

kenba
kenba

Reputation: 4549

From your description, the problem is not with the SSL handshake itself, but with the buffer in the call to async_write in Client::handleHandshake.

I'd recommend logging both sizeof(_header) and sizeof(protocol::header) and comparing them in both implementations.

BTW where do you allocate the memory for _header? Is it done in the Constructor? Because it's not done in Client::init()

Upvotes: 1

Related Questions