使用OpenSSL内存BIO写入和读取以空值终止的字符串的正确方法 [英] Correct way to write and read a null-terminated string with an OpenSSL memory BIO
问题描述
If you execute the following example (almost entirely based on the official 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\n");
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;
}
它可能可能按预期工作,具体取决于\n
之后基础存储缓冲区中未初始化的char
偶然是\000
的可能性,这可以通过Valgrind进行确认.报告:
It just might work as expected depending on the possibility that the uninialised char
in the underlying memory buffer after the \n
is \000
by chance and this can be confirmed with the Valgrind report:
==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中写入以null终止的字符串,即使
Anyway, I have seen that this happened because the BIO_puts
didn't write a null-terminated string into the memory BIO, even when https://www.openssl.org/docs/man1.0.2/crypto/BIO_puts.html says:
BIO_puts()尝试将以null终止的字符串buf写入BIO b.
BIO_puts() attempts to write a null terminated string buf to BIO b.
所以我的问题是使用OpenSSL内存BIO写入和读取以空值结尾的字符串的正确方法是什么.
So my question is what is the right way to write and read a null-terminated string with an OpenSSL memory BIO.
此外,以这种方式使用此API不会泄漏敏感数据吗?".
Additionally, ¿using this API in this way couldn't leak sensitive data?.
请注意,我正在使用OpenSSL 1.0.2g
.
Note I'm using OpenSSL 1.0.2g
.
推荐答案
BIO_puts将所有数据写成字符串,直到NUL终止符为止-但它不包括NUL终止符本身.而是使用BIO_write():
BIO_puts writes all the data in a string up until the NUL terminator - but it does not include the NUL terminator itself. Instead use BIO_write():
const char *mystr = "Hello World\n";
BIO_write(mem, mystr, strlen(mystr) + 1);
或者:
BIO_puts(mem, "Hello World\n");
BIO_write(mem, "", 1);
这篇关于使用OpenSSL内存BIO写入和读取以空值终止的字符串的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!