代码之家  ›  专栏  ›  技术社区  ›  Iceman

如何重用OpenSSL上下文以避免BIO和自身的重新分配?

  •  0
  • Iceman  · 技术社区  · 4 年前

    我想为新连接的客户端重置并使用之前断开连接的客户端的SSL上下文,并避免重新分配。

    OpenSSL在项目中仅用于加密和TLS协议支持,网络是手动控制的。客户端类有一个指向加密后端的指针,如下所示:

    class Security
    {
        SSL* ctx;
        BIO* R;
        BIO* W;
    
        int status(int n) const;
    
    public:
        Security();
        ~Security();
        bool init(SSL_CTX* config);
        // other stuff...
    };
    

    这个 init 方法在客户端每次连接时都被调用,这里我想重置上下文而不重新分配:

    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;
    }
    

    SSL_CTX在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);
    

    这样,只有第一个连接是好的。在它关闭后,下一个将尝试重用此安全上下文。由于协议错误,它将被删除,因为上一个会话中仍有一些配置。 所以 SSL_clear 没有像我预期的那样工作,而且 SSL_free / SSL_new 这不仅会导致SSL上下文的重新分配,还会导致BIOs的重新分配。当服务器在高负载下工作时,这些重新配置是非常不需要的。 如何执行SSL上下文的完全重置?

    0 回复  |  直到 4 年前
        1
  •  1
  •   user14820413 user14820413    3 年前

    您可能找不到该问题的答案,因为即使是手册也无法推荐重新分配的替代方案。相反,您可能需要考虑使用一个用于分配的池内存,尽管这是一个独立的问题和答案。以下是手册页面中的相关警告:

    SSL_clear()重置SSL对象以允许另一个连接。然而,重置操作保留了上一次会话的几个设置(其中一些设置是在最后一次握手时自动进行的)。它只适用于与共享这些设置的对等方完全相同的新连接,如果该对等方在连接之间更改其设置,则可能会失败。使用序列SSL_get_session(3);SSL_new(3);SSL_设置_会话(3);而不是SSL_-free(3),以避免此类故障(或简单地说是SSL_-free(3);SSL_新增(3)如果不需要会话重用)。

    OpenSSL manpage online