指示OpenSSL在设置新BIO时不释放BIO对象

directing OpenSSL not to free a BIO object upon setting a new BIO

本文关键字:BIO 释放 对象 OpenSSL 设置 指示      更新时间:2023-10-16

示例代码:

BIO *bio1 = BIO_new(BIO_s_mem());
BIO *bio2 = BIO_new(BIO_s_mem());
SSL_set_bio(ssl, bio1, bio1);
SSL_set_bio(ssl, bio2, bio2);

最后一次调用SSL_set_bio会自动调用BIO_free(bio1)。是否有办法告诉OpenSSL不要这样做?

我知道在用BIO_new(BIO_s_mem())创建内存生物时,我可以告诉OpenSSL不要用BIO_set_close(bio, BIO_NOCLOSE)释放它的内存缓冲区。我的案子也有类似的情况吗?

没有办法阻止SSL_set_bio在公共API中释放当前BIO。你可以在源代码中看到,它只是检查每个生物是否不为空,然后释放它。

主要思想是在调用SSL_set_bio之后,OpenSSL拥有BIO并对其负责。

void SSL_set_bio(SSL *s,BIO *rbio,BIO *wbio)
        {
        /* If the output buffering BIO is still in place, remove it
         */
        if (s->bbio != NULL)
                {
                if (s->wbio == s->bbio)
                        {
                        s->wbio=s->wbio->next_bio;
                        s->bbio->next_bio=NULL;
                        }
                }
        if ((s->rbio != NULL) && (s->rbio != rbio))
                BIO_free_all(s->rbio);
        if ((s->wbio != NULL) && (s->wbio != wbio) && (s->rbio != s->wbio))
                BIO_free_all(s->wbio);
        s->rbio=rbio;
        s->wbio=wbio;
        }

如果我有正当的理由在生产代码中保留生物缓冲区,我会编写自己的生物并使用它。其实没听起来那么难。只需复制<openssl source>/crypto/bio/bss_mem.c,重新命名函数和mem_method表,然后替换mem_free()的行为。然后传递BIO_custom_mem_bio或任何您为您的生物命名的访问器函数而不是BIO_s_mem

如果我需要它用于调试目的而不是生产代码,我可能只需要深入ssl_st结构体(SSL *)的内部并在调用SSL_set_bio之前将所有bios设置为NULL。但我不会在产品代码中这样做,因为未来的SSL版本可能会破坏这些代码。

您可以使用BIO_up_ref()来增加引用计数。BIO_free()将减少计数,但不会释放它。