Jump to content
  • Advertisement
Sign in to follow this  
3TATUK2

OpenSSL BIO_* Bug?

This topic is 1826 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So, I'm having a really weird issue... i'm trying simple file encryption/decryption with BIO_*, but if the encrypted file is in a subdirectory.. i get garbage data,

 
I'll post the code i'm using, with a brief elaboration on how i'm using it and what behaviour i'm getting:
 
/*
  Example of ssl read and write to a file

  gcc ssl_write_read.c -lssl
  ./a.out


*/



#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/ssl.h>
#include <openssl/x509v3.h>

int read_whole_file( char* filename, char** data ){
	FILE* file = fopen( filename, "rb" );
	fseek( file, 0, SEEK_END );
	long fileSize = ftell( file );
	rewind( file );
	*data = malloc( fileSize );
	fread( *data, fileSize, 1, file );
	fclose( file );
	return fileSize;
}
void encrypt_file( char* filename ){
	char new_filename[strlen( filename ) + 5];
	strcpy( new_filename, filename );
	strcat( new_filename, ".enc" );
	char* data;
	int fileSize = read_whole_file( filename, &data );
	write_data( new_filename, data, fileSize, (unsigned char*)"mykey" );
	free( data );
}

int write_data(const char *filename, char *out, int len, unsigned char *key)
{
  int total, written;
  BIO *cipher, *buffer, *file;
 
  /* Create a buffered file BIO for writing */
  file = BIO_new_file(filename, "wb");
  if (!file)
    return 0;
 
  /* Create a buffering filter BIO to buffer writes to the file */
  buffer = BIO_new(BIO_f_buffer(  ));
 
  /* Create a base64 encoding filter BIO */
//  b64 = BIO_new(BIO_f_base64(  ));
 
  /* Create the cipher filter BIO and set the key.  The last parameter of
     BIO_set_cipher is 1 for encryption and 0 for decryption */
  cipher = BIO_new(BIO_f_cipher(  ));
  BIO_set_cipher(cipher, EVP_des_ede3_cbc(  ), key, NULL, 1);
 
  /* Assemble the BIO chain to be in the order cipher-b64-buffer-file */
//  BIO_push(cipher, b64);
//  BIO_push(b64, buffer);
BIO_push(cipher,buffer);
  BIO_push(buffer, file);

  /* This loop writes the data to the file.  It checks for errors as if the
     underlying file were non-blocking */
  for (total = 0;  total < len;  total += written)
    {
      if ((written = BIO_write(cipher, out + total, len - total)) <= 0)
        {
	  if (BIO_should_retry(cipher))
            {
	      written = 0;
	      continue;
            }
	  break;
        }
    }
 
  /* Ensure all of our data is pushed all the way to the file */
  BIO_flush(cipher);
 
  BIO_free_all(cipher);
}

BIO* decrypt_open( const char *filename, unsigned char *key ){
  int total, written;
  BIO *cipher, *buffer, *file;
  //char *b = malloc(len);
 
  /* Create a buffered file BIO for reading */
  file = BIO_new_file(filename, "rb");
  if (!file)
    return 0;
 
  /* Create a buffering filter BIO to buffer writes to the file */
  buffer = BIO_new(BIO_f_buffer(  ));
 
  /* Create a base64 encoding filter BIO */
//  b64 = BIO_new(BIO_f_base64(  ));
 
  /* Create the cipher filter BIO and set the key.  The last parameter of
     BIO_set_cipher is 1 for encryption and 0 for decryption */
  cipher = BIO_new(BIO_f_cipher(  ));
  BIO_set_cipher(cipher, EVP_des_ede3_cbc(  ), key, NULL, 0);
 
  /* Assemble the BIO chain to be in the order cipher-b64-buffer-file */
//  BIO_push(cipher, b64);
//  BIO_push(b64, buffer);
BIO_push(cipher,buffer);
  BIO_push(buffer, file);
  return cipher;
}
char* decrypt_read( BIO* cipher, int len, char* b ){
  int total, written;

//	char b[len + 1];
  for (total = 0;  total < len;  total += written)
    {
      if ((written = BIO_read(cipher, b, len - total)) <= 0)
        {
	  if (BIO_should_retry(cipher))
            {
	      written = 0;
	      continue;
            }
	  break;
        }
    }
 
  b[total] = '\0';
  
  return b;
}

int main(void)
{
//chdir("subdirectory");
	char *file_="test.txt";
	char* data = "howdy\n";
	write_data( file_, data, strlen(data), "mykey");

	BIO* cipher = decrypt_open( file_, (unsigned char*)"mykey" );
	char b[999999];
	decrypt_read( cipher, 999999, b );
		BIO_flush( cipher );
	BIO_free_all( cipher );
	printf(">%s\n",b);

//char* test="plain.txt";
//encrypt_file(test);

}
 
1. So, first run creates and writes encrypted file "test.txt" and then decrypts and prints out the contents, "howdy",
 
2. Now, comment out line 141 // write_data( ... re-run to verify "howdy", works fine
 
3. make directory "temp", move "test.txt" into "temp" and change line 139 to reflect that: char *file_="temp/test.txt";.. re-run - I get no results ??
 
4. Even more weird: change line 139 back to just "test.txt", and replace file_ on line 143 with "temp/test.txt" ... so it reads: BIO* cipher = decrypt_open( "temp/test.txt", (unsigned char*)"mykey" ); // re-run... now it works again all of a sudden. BUT - if you comment out line 139 // char *file_="test.txt";.... then it doesn't work again? Even though *file_ isn't being used??? 

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!