December 02, 2017

How to Base64 decode using BIO

Base64 decode with BIO function

This code was excerpted from wargame write-up(Link)


<Code Synopsis>
1. fmemopen() : Open the entered value(a1) with read permission.
2. BIO_new(BIO_f_base64()) : Create a Base64 BIO struct.
3. BIO_new_fp() : Create a BIO struct with an opened file pointer(stream).
4. BIO_push() : Create BIO chain(base64-stream).
5. BIO_set_flags() : Set BIO_FLAGS_BASE64_NO_NL(=256) flag to make result in one line. It ignores new line characters.
6. BIO_read() : sAll data in stream is loaded, decoded in Base64, and stored in buffer(a2)(base64←stream). Stores 0 (= NULL) at the end of the stored value.
7. BIO_free_all() : frees all BIOs in the BIO chain.


<Function description>
❑ fmemopen() : This opens a file with the permission of "opentype" as much as "size" in "buf". It returns the opened file pointer.
* FILE * fmemopen(void *buf, size_t size, const char *opentype)

❑ BIO : BIO is an I/O abstraction for system input/output and It is struct. socket, There is a source/sink BIO that handles the file and a filter BIO that processes the data(Base64, MD5 etc.).
* #include <openssl/bio.h>

❑ bio_f_base64() : This returns the base64 BIO method(BIO_METHOD *). The method can Base64 incode/decode.

❑ BIO_new() : This create new BIO struct with a "type".
*  BIO * BIO_new(BIO_METHOD *type);
❑ BIO_new_fp() : This create new BIO struct with FILE pointer.

❑ BIO_flush() : This is used for data encode end signal.

❑ BIO_push() : This appends "a" to "b" to create a BIO chain for encode/decode. It returns b.
* BIO * BIO_push(BIO *b, BIO *a);
e.g.
BIO_push(b, a);
BIO_push(c, b);
  → A BIO chain is created in order "c-b-a" and "c" is returned.

❑ BIO_pop() : This removes "b" from a BIO chain. It returns the next BIO struct of the chain.
*  BIO * BIO_pop(BIO *b);
e.g.
BIO_pop(b)
  → "b" is removed from the "c-b-a" chain, then now it becomes "c-a" and "a" is returned("a" is next of "b").

❑ BIO_read() : This reads "len" bytes from "b" and stores the data in "buf". it returns amount of the data read.
* int BIO_read(BIO *b, void *buf, int len);
❍ When there is a BIO chain in order of "MD5-Base64-file", when reading BIO MD5, the data of "file" is decoded to "Base64", is digested to "MD5", and then the result is stored in the "buf"(MD5←Base64←file).

❑ BIO_write() : This reads "len" bytes from "buf" and writes the data in "b". it returns amount of the data written.
* int BIO_write(BIO *b, const void *buf, int len);
❍ When there is a BIO chain in order of "MD5-Base64-file", when writing to BIO MD5, the data of the "buf" is digested to "MD5", is encoded to "Base64", and then the result is stored in "file"(MD5→Base64→file).

❑ BIO_free_all() : frees up a BIO chain.


※ BIO function reference(Link)