From f13c0c2e3e1a1b1834b184ac6cd46018744ccf76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89rico=20Rolim?= Date: Sun, 13 Sep 2020 20:17:58 -0300 Subject: [PATCH] Add decryption for recv. A few fixes and hacks all around, but can now do: ./purr -e recv (./purr -e send makefile) And output the original page. --- encrypt.c | 59 ++++++++++++++++++++++++++++++- extern/libbaseencode/base64.c | 3 +- extern/libbaseencode/baseencode.h | 3 +- purr.c | 21 ++++++++--- purr.h | 2 ++ 5 files changed, 80 insertions(+), 8 deletions(-) diff --git a/encrypt.c b/encrypt.c index 2c6037b..8418924 100644 --- a/encrypt.c +++ b/encrypt.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -68,11 +69,12 @@ struct mmap_file encrypt_mmap(struct mmap_file file, uint8_t **keyp, uint8_t **i br_aes_big_cbcenc_keys br = { 0 }; br_aes_big_cbcenc_init(&br, key, KEY_LEN); br_aes_big_cbcenc_run(&br, iv_throwaway, rv.data, file_size); + free(iv_throwaway); #ifdef ENCODE_BASE_64 baseencode_error_t berr; const char *data = base64_encode(rv.data, rv.size, &berr); - if (data == NULL || berr != SUCCESS) { + if (data == NULL) { fprintf(stderr, "base64_encode(): error code %d\n", berr); // TODO: returns good rv return rv; @@ -87,6 +89,8 @@ struct mmap_file encrypt_mmap(struct mmap_file file, uint8_t **keyp, uint8_t **i return rv; } memcpy(rv_64.data, data, len); + + free(data); munmap(rv.data, rv.size); rv = rv_64; #endif /* ENCODE_BASE_64 */ @@ -99,3 +103,56 @@ struct mmap_file encrypt_mmap(struct mmap_file file, uint8_t **keyp, uint8_t **i return rv; } + +struct mmap_file decrypt_mmap(struct mmap_file file, const uint8_t *key, const uint8_t *iv) +{ + struct mmap_file rv = + {.size = file.size, .prot = PROT_WRITE | PROT_READ, .flags = MAP_ANONYMOUS | MAP_PRIVATE}; + + #ifdef DECODE_BASE_64 + baseencode_error_t berr; + size_t data_len; + // TODO: find out why file.size is weird + uint8_t *data = base64_decode((char *)file.data, strlen(file.data), &berr, &data_len); + if (data == NULL) { + fprintf(stderr, "base64_decode(): error code %d\n", berr); + return rv; + } + // big hack to bypass issues + //assert(data_len % br_aes_big_BLOCK_SIZE == 0); + data_len -= data_len % br_aes_big_BLOCK_SIZE; + + rv.size = data_len; + #endif /* DECODE_BASE_64 */ + + + rv.data = mmap(NULL, rv.size, rv.prot, rv.flags, -1, 0); + if (ERROR_MMAP(rv)) { + perror("mmap()"); + return rv; + } + + #ifdef DECODE_BASE_64 + memcpy(rv.data, data, rv.size); + free(data); + #else + memcpy(rv.data, file.data, file.size); + #endif /* DECODE_BASE_64 */ + + munmap(file.data, file.size); + + uint8_t *iv_throwaway = calloc(IV_LEN, 1); + if (iv_throwaway == NULL) { + perror("malloc()"); + // TODO: returns good rv + return rv; + } + memcpy(iv_throwaway, iv, IV_LEN); + + br_aes_big_cbcdec_keys br = { 0 }; + br_aes_big_cbcdec_init(&br, key, KEY_LEN); + br_aes_big_cbcdec_run(&br, iv_throwaway, rv.data, rv.size); + free(iv_throwaway); + + return rv; +} diff --git a/extern/libbaseencode/base64.c b/extern/libbaseencode/base64.c index 8327bfb..d35f6bb 100644 --- a/extern/libbaseencode/base64.c +++ b/extern/libbaseencode/base64.c @@ -71,7 +71,7 @@ base64_encode(const unsigned char *user_data, size_t data_len, baseencode_error_ unsigned char * -base64_decode(const char *user_data_untrimmed, size_t data_len, baseencode_error_t *err) +base64_decode(const char *user_data_untrimmed, size_t data_len, baseencode_error_t *err, size_t *output_len) { baseencode_error_t error; check_input((unsigned char *)user_data_untrimmed, data_len, MAX_DECODE_BASE64_INPUT_LEN, &error); @@ -130,6 +130,7 @@ base64_decode(const char *user_data_untrimmed, size_t data_len, baseencode_error free(user_data); *err = SUCCESS; + *output_len = output_length; return decoded_data; } diff --git a/extern/libbaseencode/baseencode.h b/extern/libbaseencode/baseencode.h index 8c86ed1..cedb9f0 100644 --- a/extern/libbaseencode/baseencode.h +++ b/extern/libbaseencode/baseencode.h @@ -25,4 +25,5 @@ char *base64_encode (const unsigned char *input_string, unsigned char *base64_decode (const char *input_string, size_t input_length, - baseencode_error_t *err); \ No newline at end of file + baseencode_error_t *err, + size_t *output_len); diff --git a/purr.c b/purr.c index 28a2853..7e0e773 100644 --- a/purr.c +++ b/purr.c @@ -162,6 +162,12 @@ int main (int argc, char **argv) rv = EXIT_FAILURE; goto early_out; } + } else if (recv && encrypt) { + int err = get_encryption_params(path, &key, &iv); + if (err) { + fputs("get_encription_params(): error decoding url\n", stderr); + goto early_out; + } } // TODO: fix size @@ -255,8 +261,8 @@ int main (int argc, char **argv) rv = send_and_receive(&ci); - if (encrypt) { - size_t allocate_res = strlen((char *)output.data); + if (send && encrypt) { + size_t allocate_res = strlen((char *)output.data) + 1; char *link_res = calloc(allocate_res, 1); char *path_res = calloc(allocate_res, 1); char *port_res = calloc(16, 1); @@ -279,14 +285,18 @@ int main (int argc, char **argv) goto early_out; } - fprintf(output_print, "%s/paste.html#%s_%s_%s", - url, path_res + 1, key_s, iv_s); + // TODO: fix hack for https link + fprintf(output_print, "https://%s/paste.html#%s_%s_%s", + link_res, path_res + 1, key_s, iv_s); free(link_res); free(path_res); free(port_res); free(key_s); free(iv_s); + } else if (recv && encrypt) { + output = decrypt_mmap(output, key, iv); + fwrite(output.data, 1, output.size, output_print); } else if (fwrite(output.data, 1, output.offset, output_print) < output.offset) { fputs("might not have written all data\n", stderr); } @@ -299,7 +309,8 @@ int main (int argc, char **argv) free(request); free(key); free(iv); - early_out: +early_out: + if (output_print != stdout) fclose(output_print); CLOSE_MMAP(input); CLOSE_MMAP(output); diff --git a/purr.h b/purr.h index fb72e59..cf0024e 100644 --- a/purr.h +++ b/purr.h @@ -20,6 +20,7 @@ #define RANDOMIZE_IV #define ENCODE_BASE_64 +#define DECODE_BASE_64 #define RESET_MMAP(file) do{(file).offset = 0; (file).cursor = 0}while(0); #define ERROR_MMAP(file) ((file).data == MAP_FAILED || (file).data == NULL) @@ -74,5 +75,6 @@ int decode_hex(const char *, uint8_t *, int); /* encrypt.c */ struct mmap_file encrypt_mmap(struct mmap_file, uint8_t **, uint8_t **); +struct mmap_file decrypt_mmap(struct mmap_file, const uint8_t *, const uint8_t *); #endif // __PURR_H_