在此示例代码中:
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()) 创建内存 bio 时,我可以告诉 OpenSSL 不要使用 BIO_set_close(bio, BIO_NOCLOSE) 释放它的内存缓冲区。我的情况有什么类似的吗?
最佳答案
没有办法阻止 SSL_set_bio
从公共(public) API 中释放当前 BIO。你可以在源代码中看到它只是检查每个 bio 是否不为 null 然后释放它。
主要思想是在你调用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;
}
如果我有合理的理由在生产代码中保留 bio 缓冲区,我会编写自己的 bio 并使用它。它并不像听起来那么难。只需复制 <openssl source>/crypto/bio/bss_mem.c
, 重命名函数和 mem_method
表,然后替换 mem_free()
的行为.然后代替 BIO_s_mem
, 通过 BIO_custom_mem_bio
或者你为你的 bio 命名的访问器函数。
如果我需要它用于调试目的而不是生产代码,我可能只是钻研 ssl_st
的内部结构struct ( SSL *
) 并在调用 SSL_set_bio
之前将所有 bios 设置为 NULL .但我不会在生产代码中这样做,因为 future 的 SSL 版本可能会破坏该代码。
关于c++ - 指示 OpenSSL 在设置新 BIO 时不要释放 BIO 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7554583/