Iceman
Iceman

Reputation: 397

How to reuse OpenSSL context to avoid reallocations of BIO and itself?

I would like to reset and use the SSL context of the previous disconnected client for the newly connected client and avoid reallocations.

OpenSSL is used in project just for cryptography and TLS protocol support, the networking is controlled manually. The client class has a pointer to crypto-backend, which looks like this:

class Security
{
    SSL* ctx;
    BIO* R;
    BIO* W;

    int status(int n) const;

public:
    Security();
    ~Security();
    bool init(SSL_CTX* config);
    // other stuff...
};

The init method is called each time the client connects, and here I want to reset the context without reallocating:

bool Security::init(SSL_CTX* config)
{
    if (!R)
    {
        R = BIO_new(BIO_s_mem());
        if (!R)
            return false;
    }
    else BIO_reset(R);

    if (!W)
    {
        W = BIO_new(BIO_s_mem());
        if (!W)
            return false;
    }
    else BIO_reset(W);
    
    if (!ctx)
    {
        ctx = SSL_new(config);
        if (!ctx)
            return false;
    }
    else SSL_clear(ctx);

    SSL_set_bio(ctx, R, W);
    SSL_set_accept_state(ctx);

    return true;
}

The SSL_CTX receives next options on init:

// Force to use TLS 1.3 only
SSL_CTX_set_options(config,
            | SSL_OP_ALL
            | SSL_OP_NO_SSLv2
            | SSL_OP_NO_SSLv3
            | SSL_OP_NO_TLSv1
            | SSL_OP_NO_TLSv1_1
            | SSL_OP_NO_TLSv1_2
            | SSL_OP_NO_TICKET
            | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);

In this way only the first connection wokrs good. After it closes and the next one will try to reuse this security context — it will be dropped due to protocol error, because there are still some configs from previous session left. So SSL_clear did not work as I expected, and the SSL_free/SSL_new will lead to reallocations not only for SSL context, but also both BIOs. These realocations are very unwanted when the server works at high load. How to perform a complete reset of SSL context?

Upvotes: 1

Views: 1303

Answers (1)

user14820413
user14820413

Reputation:

You may not find an answer to that question, as even the manual cannot recommend an alternative to reallocating. You may instead need to consider a using pooled memory for allocations, though that is a separate question and answer. What follows is the relevant warning from the manual page:

SSL_clear() resets the SSL object to allow for another connection. The reset operation however keeps several settings of the last sessions (some of these settings were made automatically during the last handshake). It only makes sense for a new connection with the exact same peer that shares these settings, and may fail if that peer changes its settings between connections. Use the sequence SSL_get_session(3); SSL_new(3); SSL_set_session(3); SSL_free(3) instead to avoid such failures (or simply SSL_free(3); SSL_new(3) if session reuse is not desired).

OpenSSL manpage online

Upvotes: 1

Related Questions