Openssl BIO API, file saving and reading examples

By | June 16, 2022

The acronym BIO stands for Basic Input/Output. It is multipurpose API for various types of input and output operations, including file, memory buffer, networking. The main header file for BIO methods is bio.h, binary linking references are presented in libcrypto.so library. Below presented 3 examples of BIO API file usage which create and read 3 type of files: plain text, base64 encoded and encrypted. To build all these application use the following command:
g++ -o <output_executable> <source_file>.cpp -lssl -lcrypto

Example of plain text file creation:


#include <openssl/bio.h>
#include <string.h>
int main(int n, char ** s)
{
   char strbio[] = "BIO – Basic Input Output";
   char filename[] = "biotext.txt";
   BIO * out = BIO_new_file(filename, "w");
   if(!out)
      printf("Cannot create file – %s\n", filename);
   else {
      BIO_write(out, strbio, strlen(strbio));
      BIO_free(out);
   }
   return 0;
}

Example of plain text file reading:


#include <openssl/bio.h>
#include <string.h>
int main(int n, char ** s)
{
   char strbio[256];
   char filename[] = "biotext.txt";
   memset(strbio, 0, 256);
   BIO * in = BIO_new_file(filename, "r");
   if(!in)
      printf("Cannot open file – %s\n", filename);
   else {
      BIO_read(in, strbio, sizeof(strbio));
      BIO_free(in);
      printf("%s\n", strbio);
   }
   return 0;
}

Execution:


# ./biowrite
# cat biotext.txt
BIO – Basic Input Output
# ./bioread
BIO – Basic Input Output

Example of base64 file creation:


#include <openssl/bio.h>
#include <openssl/evp.h>
#include <string.h>
int main(int n, char ** s)
{
   char strbio[] = "BIO – Basic Input Output, base64";
   char filename[] = "biotext64.txt";
   BIO * out = BIO_new_file(filename, "w");
   BIO * base64 = BIO_new(BIO_f_base64());
   BIO_push(base64, out);
   if(!out)
      printf("Cannot create file – %s\n", filename);
   else {
      BIO_write(base64, strbio, strlen(strbio));
      BIO_flush(base64);
      BIO_free_all(base64);
   }
   return 0;
}

Example of base64 file reading with decoding


#include <openssl/bio.h>
#include <openssl/evp.h>
#include <string.h>
int main(int n, char ** s)
{
   char strbio[256];
   char filename[] = "biotext64.txt";
   memset(strbio, 0, 256);
   BIO * in = BIO_new_file(filename, "r");
   const BIO_METHOD* bm = BIO_f_base64();
   BIO * base64 = BIO_new(bm);
   BIO_push(base64, in);
   if(!in)
      printf("Cannot open file – %s\n", filename);
   else {
      BIO_read(base64, strbio, sizeof(strbio));
      BIO_free_all(base64);
      printf("%s\n", strbio);
   }
   return 0;
}

Execution:


# ./biowrite64
# cat biotext64.txt
QklPIC0gQmFzaWMgSW5wdXQgT3V0cHV0LCBiYXNlNjQ=
# ./bioread64
BIO – Basic Input Output, base64

Example of encrypted file creation:


#include <openssl/bio.h>
#include <openssl/evp.h>
#include <string.h>
int main(int n, char ** s)
{
   // size of key and iv must be 256 bit for aes256
   unsigned char key[32];
   unsigned char iv[32];
   memset(key, 'k', 32);
   memset(iv, 'i', 32);
   char strbio[] = "BIO – Basic Input Output, crypto";
   char filename[] = "biotextcrypt.txt";
   BIO * out = BIO_new_file(filename, "w");
   BIO * cipher = BIO_new(BIO_f_cipher());
   BIO_set_cipher(cipher, EVP_aes_256_cbc(), key, iv, 1);
   BIO_push(cipher, out);
   if(!out)
      printf("Cannot create file – %s\n", filename);
   else {
      BIO_write(cipher, strbio, strlen(strbio));
      BIO_flush(cipher);
      BIO_free_all(cipher);
   }
   return 0;
}

Example of encrypted file reading with decryption


#include <openssl/bio.h>
#include <openssl/evp.h>
#include <string.h>
int main(int n, char ** s)
{
   // size of key and iv must be 256 bit for aes256
   unsigned char key[32];
   unsigned char iv[32];
   memset(key, 'k', 32);
   memset(iv, 'i', 32);
   char strbio[256];
   memset(strbio, 0, 256);
   char filename[] = "biotextcrypt.txt";
   BIO * in = BIO_new_file(filename, "r");
   BIO * cipher = BIO_new(BIO_f_cipher());
   BIO_set_cipher(cipher, EVP_aes_256_cbc(), key, iv, 0);
   BIO_push(cipher, in);
   if(!in)
      printf("Open file – %s\n", filename);
   else {
      BIO_read(cipher, strbio, sizeof(strbio));
      BIO_free_all(cipher);
      printf("%s\n", strbio);
   }
   return 0;
}

Execution:


# ./biowritecrypt
# xxd biotextcrypt.txt
00000000: 67da 0b17 fc9c d0ab 7501 8929 4f67 a31f g…….u..)Og..
00000010: 15cd 4fa9 acc4 15b2 050f 9998 46ba e21e ..O………F…
00000020: 0625 c309 6e9c a877 d059 5392 38e0 17f8 .%..n..w.YS.8…
# ./bioreadcrypt
BIO – Basic Input Output, crypto

Leave a Reply

Your email address will not be published. Required fields are marked *