strange i think it has something to do with me using "rb" and "wb" instead of "r" and "w"...
On Fri, Aug 16, 2013 at 2:14 AM, Ztatik Light <ztatik.li...@gmail.com>wrote: > 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 + 4 )]; >> >> 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??? >