title: Correct way to write and read a null-terminated string with an OpenSSL memory BIO
body: <p>If you execute the following example (almost entirely based on the official <a href="https://www.openssl.org/docs/man1.0.2/crypto/BIO_s_mem.html#EXAMPLE" rel="nofollow noreferrer">https://www.openssl.org/docs/man1.0.2/crypto/BIO_s_mem.html#EXAMPLE</a>):</p>
  
  <pre><code>#include &lt;openssl/bio.h&gt;
  #include &lt;openssl/buffer.h&gt;
  
  int main() {
      BIO *mem = BIO_new(BIO_s_mem());
      BIO_puts(mem, "Hello World\n");
  
      BUF_MEM *bptr;
      BIO_get_mem_ptr(mem, &amp;bptr);
      BIO_set_close(mem, BIO_NOCLOSE); /* So BIO_free() leaves BUF_MEM alone */
      BIO_free(mem);
  
      printf("%s", bptr-&gt;data);
  
      BUF_MEM_free(bptr);
      return 0;
  }
  </code></pre>
  
  <p>It just <em>might</em> work as expected depending on the possibility that the uninialised <code>char</code> in the underlying memory buffer after the <code>\n</code> is <code>\000</code> by chance and this can be confirmed with the Valgrind report:</p>
  
  <pre><code>==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)
  </code></pre>
  
  <p>Anyway, I have seen that this happened because the <code>BIO_puts</code> didn't write a null-terminated string into the memory BIO, even when <a href="https://www.openssl.org/docs/man1.0.2/crypto/BIO_puts.html" rel="nofollow noreferrer">https://www.openssl.org/docs/man1.0.2/crypto/BIO_puts.html</a> says:</p>
  
  <blockquote>
    <p>BIO_puts() attempts to write a null terminated string buf to BIO b.</p>
  </blockquote>
  
  <p>So my question is what is the right way to write and read a null-terminated string with an OpenSSL memory BIO.</p>
  
  <p>Additionally, ¿using this API in this way couldn't leak sensitive data?.</p>
  
  <p>Note I'm using OpenSSL <code>1.0.2g</code>.</p>