75
4.3.1 SourceSink BIOs
A BIO that is used for reading is known as a source BIO, and a sink BIO is one that is used for writing. A sourcesink BIO is attached to a concrete inputoutput medium such as a file, a socket,
or memory. Only a single sourcesink BIO may exist in a chain. It is possible to conceive of situations in which it might be useful to have more than one, particularly for writing, but the
sourcesink types of BIOs provided by OpenSSL do not currently allow for more than one sourcesink BIO to exist in a chain.
OpenSSL provides nine sourcesink types of BIOs that can be used with
BIO_new
and
BIO_set
. A function is provided for each that simply returns a
BIO_METHOD
object suitable for passing to
BIO_new
or
BIO_set
. Most of the sourcesink types of BIOs require additional setup work beyond just creating a BIO with the appropriate
BIO_METHOD
. Well cover only the four most commonly used types in any detail here due to space limitations and the huge number of
individual functions that are available to operate on them in various ways.
4.3.1.1 Memory sourcessinks
A memory BIO treats a memory segment the same as a file or socket, and can be created by using
BIO_s_mem
to obtain a
BIO_METHOD
object suitable for use with
BIO_new
and
BIO_set
. As an alternative, the function
BIO_new_mem_buf
can be used to create a read-only memory BIO, which requires a pointer to an existing memory segment for reading as well as the size of the
buffer. If the size of the buffer is specified as -1, the buffer is assumed to be a C-style string, and the size of the buffer is computed to be the length of the string, not including the
NULL
terminating character. When a memory BIO is created using
BIO_new
and
BIO_s_mem
, a new memory segment is created, and resized as necessary. The memory segment is owned by the BIO in this case and is
destroyed when the BIO is destroyed unless
BIO_set_close
prevents it.
BIO_get_mem_data
or
BIO_get_mem_ptr
can be used to obtain a pointer to the memory segment. A memory BIO created with
BIO_new_mem_buf
will never destroy the memory segment attached to the BIO, regardless of whether
BIO_set_close
is used to enable it. Example 4-4
demonstrates how to create a memory BIO.
Example 4-4. Creating a memory BIO
Create a readwrite BIO bio = BIO_newBIO_s_mem;
Create a read-only BIO using an allocated buffer buffer = malloc4096;
bio = BIO_new_mem_bufbuffer, 4096; Create a read-only BIO using a C-style string
bio = BIO_new_mem_bufThis is a read-only buffer., -1; Get a pointer to a memory BIOs memory segment
BIO_get_mem_ptrbio, buffer; Prevent a memory BIO from destroying its memory segment when it is
destroyed BIO_set_closebio, BIO_NOCLOSE;
4.3.1.2 File sourcessinks
76
Two types of file BIOs are available: buffered and unbuffered. A buffered file BIO is a wrapper around the standard C runtime
FILE
object and its related functions. An unbuffered file BIO is a wrapper around a file descriptor and its related functions. With the exception of how the two
different types of file BIOs are created, the interface for using them is essentially the same. A buffered file BIO can be created by using
BIO_s_file
to obtain a
BIO_METHOD
object suitable for use with
BIO_new
and
BIO_set
. Alternatively,
BIO_new_file
can be used the same way as the standard C runtime function,
fopen
, is used, or
BIO_new_fp
can be used to create a BIO around an already existing
FILE
object. Using
BIO_new_fp
, you must specify the
FILE
object to use and a flag indicating whether the
FILE
object should be closed when the BIO is destroyed.
An unbuffered file BIO can be created by using
BIO_s_fd
to obtain a
BIO_METHOD
object suitable for use with
BIO_new
and
BIO_set
. Alternatively,
BIO_new_fd
can be used in the same way that
BIO_new_fp
cis used for buffered BIOs. The difference is that a file descriptor rather than a
FILE
object must be specified. For either a buffered or an unbuffered file BIO created with
BIO_new
or
BIO_set
, additional work must be done to make the BIO usable. Initially, no underlying file object is attached to the
BIO, and any read or write operations performed on the BIO always fail. Unbuffered file types of BIOs require that
BIO_set_fd
be used to attach a file descriptor to the BIO. Buffered file types of BIOs require that
BIO_set_file
be used to attach a
FILE
object to the BIO, or one of
BIO_read_filename
,
BIO_write_filename
,
BIO_append_filename
, or
BIO_rw_filename
be used to create an underlying
FILE
object with the appropriate mode for the BIO.
Example 4-5 shows how to create a file BIO.
Example 4-5. Creating a file BIO
Create a buffered file BIO with an existing FILE object that will be closed when the BIO is destroyed.
file = fopenfilename.ext, r+; bio = BIO_newBIO_s_file;
BIO_set_filebio, file, BIO_CLOSE; Create an unbuffered file BIO with an existing file descriptor
that will not be closed when the BIO is destroyed. fd = openfilename.ext, O_RDWR;
bio = BIO_newBIO_s_fd; BIO_set_fdbio, fd, BIO_NOCLOSE;
Create a buffered file BIO with a new FILE object owned by the BIO bio = BIO_new_filefilename.ext, w;
Create an unbuffered file BIO with an existing file descriptor that will be closed when the BIO is destroyed.
fd = openfilename.ext, O_RDONLY; bio = BIO_new_fdfd, BIO_CLOSE;
4.3.1.3 Socket sourcessinks