Enable encrypted pastes properly.

Add base64 encoding per the pattern expected by the web interface.

Fix some pointers and file size things in purr/files.

TODO: files are cut off at random points, despite the efforts to remove
verification of null characters in libbaseencode.
This commit is contained in:
Érico Rolim 2020-09-13 18:05:43 -03:00
parent 1b4c19665c
commit 94f8f4f61d
7 changed files with 81 additions and 45 deletions

View File

@ -26,7 +26,8 @@ struct mmap_file encrypt_mmap(struct mmap_file file, uint8_t **keyp, uint8_t **i
if (blocks * br_aes_big_BLOCK_SIZE < file_size) blocks++;
file_size = blocks * br_aes_big_BLOCK_SIZE;
struct mmap_file rv = {.size = file_size, .prot = PROT_WRITE | PROT_READ, .flags = MAP_ANONYMOUS | MAP_PRIVATE};
struct mmap_file rv =
{.size = file_size, .prot = PROT_WRITE | PROT_READ, .flags = MAP_ANONYMOUS | MAP_PRIVATE};
uint8_t *key = calloc(KEY_LEN, 1);
uint8_t *iv = calloc(IV_LEN, 1);
@ -48,12 +49,11 @@ struct mmap_file encrypt_mmap(struct mmap_file file, uint8_t **keyp, uint8_t **i
fputs("getrandom() error!\n", stderr);
return rv;
}
#endif
#endif /* NO_RANDOMIZE_IV */
rv.data =
mmap(NULL, rv.size, rv.prot, rv.flags, -1, 0);
if (rv.data == MAP_FAILED) {
perror("mmap failure");
rv.data = mmap(NULL, rv.size, rv.prot, rv.flags, -1, 0);
if (ERROR_MMAP(rv)) {
perror("mmap()");
return rv;
}
@ -68,6 +68,28 @@ struct mmap_file encrypt_mmap(struct mmap_file file, uint8_t **keyp, uint8_t **i
br_aes_big_cbcenc_init(&br, key, KEY_LEN);
br_aes_big_cbcenc_run(&br, iv_throwaway, rv.data, file_size);
#ifdef ENCODE_BASE_64
baseencode_error_t berr;
const char *data = base64_encode(rv.data, rv.size, &berr);
if (data == NULL || berr != SUCCESS) {
fprintf(stderr, "base64_encode(): error code %d\n", berr);
// TODO: returns good rv
return rv;
}
size_t len = strlen(data);
struct mmap_file rv_64 =
{.size = len, .prot = PROT_WRITE | PROT_READ, .flags = MAP_ANONYMOUS | MAP_PRIVATE};
rv_64.data = mmap(NULL, rv_64.size, rv_64.prot, rv_64.flags, -1, 0);
if (ERROR_MMAP(rv_64)) {
perror("mmap()");
// TODO: returns good rv
return rv;
}
memcpy(rv_64.data, data, len);
munmap(rv.data, rv.size);
rv = rv_64;
#endif /* ENCODE_BASE_64 */
munmap(file.data, file.size);
// pass pointers to caller

View File

@ -26,17 +26,9 @@ base64_encode(const unsigned char *user_data, size_t data_len, baseencode_error_
}
}
size_t user_data_chars = 0, total_bits = 0;
size_t user_data_chars = data_len;
size_t total_bits = user_data_chars * 8;
int num_of_equals = 0;
for (int i = 0; i < data_len; i++) {
// As it's not known whether data_len is with or without the +1 for the null byte, a manual check is required.
if (user_data[i] != '\0') {
total_bits += 8;
user_data_chars += 1;
} else {
break;
}
}
switch (total_bits % 24) {
case 8:
num_of_equals = 2;

View File

@ -33,18 +33,10 @@ strip_char(char *str, char strip)
static void
check_input(const unsigned char *user_data, size_t data_len, int max_len, baseencode_error_t *err)
{
if (user_data == NULL || (data_len == 0 && user_data[0] != '\0')) {
*err = INVALID_INPUT;
return;
} else if (user_data[0] == '\0') {
*err = EMPTY_STRING;
return;
}
if (data_len > max_len) {
*err = INPUT_TOO_BIG;
return;
}
*err = SUCCESS;
}
}

View File

@ -1,5 +1,5 @@
baseencode.a: base32.o base64.o
$(AR) r $@ $<
$(AR) r $@ $^
clean:
rm -f baseencode.a base32.o base64.o

View File

@ -102,6 +102,7 @@ int write_into_mmap(struct mmap_file *file, const uint8_t *buffer, int n)
}
ssize_t max = file->size - file->offset;
file->cursor = file->data + file->offset;
if (n < max) {
file->offset += n;
} else {
@ -110,7 +111,6 @@ int write_into_mmap(struct mmap_file *file, const uint8_t *buffer, int n)
}
memcpy(file->cursor, buffer, n);
file->cursor = file->data + file->offset;
return n;
}

59
purr.c
View File

@ -153,6 +153,17 @@ int main (int argc, char **argv)
goto early_out;
}
uint8_t *key = NULL;
uint8_t *iv = NULL;
if (send && encrypt) {
// requires error checking
input = encrypt_mmap(input, &key, &iv);
if(ERROR_MMAP(input)) {
rv = EXIT_FAILURE;
goto early_out;
}
}
// TODO: fix size
const int going_to_write = HEADER_MAX_LEN;
char *request = calloc(going_to_write, 1);
@ -226,17 +237,6 @@ int main (int argc, char **argv)
br_ssl_client_reset(&sc, link, 0);
}
uint8_t *key = NULL;
uint8_t *iv = NULL;
if (send && encrypt) {
// requires error checking
input = encrypt_mmap(input, &key, &iv);
if(ERROR_MMAP(input)) {
rv = EXIT_FAILURE;
goto early_out;
}
}
int socket = host_connect(link, port, debug);
// avoid crashing on socket release
signal(SIGPIPE, SIG_IGN);
@ -255,11 +255,40 @@ int main (int argc, char **argv)
rv = send_and_receive(&ci);
if (fwrite(output.data, 1, output.offset, output_print) < output.offset) {
fputs("might not have written all data\n", stderr);
}
if (encrypt) {
print_hex(key, KEY_LEN, true);
size_t allocate_res = strlen((char *)output.data);
char *link_res = calloc(allocate_res, 1);
char *path_res = calloc(allocate_res, 1);
char *port_res = calloc(16, 1);
if (link_res == NULL || path_res == NULL || port_res == NULL) {
perror("allocation failure");
exit(EXIT_FAILURE);
}
clean_up_link((char *)output.data, link_res, path_res, port_res);
// clean up linebreak
char *linebreak = strchr(path_res, '\n');
if(linebreak) {
*linebreak = 0;
}
char *key_s = print_hex(key, KEY_LEN, false);
char *iv_s = print_hex(iv, IV_LEN, false);
if (key_s == NULL || iv_s == NULL) {
perror("malloc()");
goto early_out;
}
fprintf(output_print, "%s/paste.html#%s_%s_%s",
url, path_res + 1, key_s, iv_s);
free(link_res);
free(path_res);
free(port_res);
free(key_s);
free(iv_s);
} else if (fwrite(output.data, 1, output.offset, output_print) < output.offset) {
fputs("might not have written all data\n", stderr);
}
//out:

7
purr.h
View File

@ -19,10 +19,11 @@
#define IV_LEN br_aes_big_BLOCK_SIZE
#define NO_RANDOMIZE_IV
#define ENCODE_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)
#define CLOSE_MMAP(file) do{if(file.data != MAP_FAILED && file.data != NULL) munmap(file.data, file.size);}while(0);
#define RESET_MMAP(file) do{(file).offset = 0; (file).cursor = 0}while(0);
#define ERROR_MMAP(file) ((file).data == MAP_FAILED || (file).data == NULL)
#define CLOSE_MMAP(file) do{if((file).data != MAP_FAILED && (file).data != NULL) munmap((file).data, (file).size);}while(0);
struct connection_information {
br_sslio_context *ioc;