使用OpenSSL内存BIO以正确的方式写入和读取以null结尾的字符串

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用OpenSSL内存BIO以正确的方式写入和读取以null结尾的字符串相关的知识,希望对你有一定的参考价值。

如果您执行以下示例(几乎完全基于官方https://www.openssl.org/docs/man1.0.2/crypto/BIO_s_mem.html#EXAMPLE):

#include <openssl/bio.h>
#include <openssl/buffer.h>

int main() {
    BIO *mem = BIO_new(BIO_s_mem());
    BIO_puts(mem, "Hello World
");

    BUF_MEM *bptr;
    BIO_get_mem_ptr(mem, &bptr);
    BIO_set_close(mem, BIO_NOCLOSE); /* So BIO_free() leaves BUF_MEM alone */
    BIO_free(mem);

    printf("%s", bptr->data);

    BUF_MEM_free(bptr);
    return 0;
}

它可能会按预期工作,这取决于char之后的基础记忆缓冲区中未经初始化的 偶然是00的可能性,这可以通过Valgrind报告确认:

==17122== Conditional jump or move depends on uninitialised value(s)
==17122==    at 0x52CCCC0: vfprintf (vfprintf.c:1632)
==17122==    by 0x52D3898: printf (printf.c:33)
==17122==    by 0x4008CC: main (test1.c:13)
==17122==  Uninitialised value was created by a heap allocation
==17122==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17122==    by 0x4E9CE77: CRYPTO_malloc (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==17122==    by 0x4F4A4B3: BUF_MEM_grow_clean (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==17122==    by 0x4F4BBDD: mem_write (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==17122==    by 0x4F4AC8E: BIO_puts (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==17122==    by 0x40086E: main (test1.c:6)

无论如何,我已经看到这发生了,因为BIO_puts没有在内存BIO中写入以空字符结尾的字符串,即使https://www.openssl.org/docs/man1.0.2/crypto/BIO_puts.html说:

BIO_puts()尝试将空终止的字符串buf写入BIO b。

所以我的问题是用OpenSSL内存BIO编写和读取以null结尾的字符串的正确方法是什么。

此外,以这种方式使用此API无法泄露敏感数据?

注意我正在使用OpenSSL 1.0.2g

答案

BIO_puts将所有数据写入字符串直到NUL终止符 - 但它不包括NUL终结符本身。而是使用BIO_write():

const char *mystr = "Hello World
";

BIO_write(mem, mystr, strlen(mystr) + 1);

或者:

BIO_puts(mem, "Hello World
");
BIO_write(mem, "", 1);

以上是关于使用OpenSSL内存BIO以正确的方式写入和读取以null结尾的字符串的主要内容,如果未能解决你的问题,请参考以下文章

OpenSSL 内存 BIO 和部分密码块

openssl RSA 内存读取密钥

OpenSSL等待读取数据可用

BIO,NIO,AIO

BIO,NIO,AIO

OpenSSL:促使不安全的BIO保护它