mirror of https://github.com/ericonr/purr-c.git
Add get_encryption_params.
This function is used to split the links to encrypted content into useful parts.
This commit is contained in:
parent
71d813af3e
commit
e20d8ae124
40
formats.c
40
formats.c
|
@ -6,7 +6,7 @@
|
|||
/*
|
||||
* Set print to true to print value, otherwise returns dynamic string with the number
|
||||
*/
|
||||
char *print_hex(uint8_t *buf, int len, bool print)
|
||||
char *print_hex(const uint8_t *buf, int len, bool print)
|
||||
{
|
||||
char *rv = NULL;
|
||||
|
||||
|
@ -36,6 +36,38 @@ char *print_hex(uint8_t *buf, int len, bool print)
|
|||
return rv;
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// buffer to base64
|
||||
// base64 to buffer
|
||||
static bool is_hex_char(char c)
|
||||
{
|
||||
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
|
||||
}
|
||||
|
||||
// from https://lemire.me/blog/2019/04/17/parsing-short-hexadecimal-strings-efficiently/
|
||||
static uint32_t convert_hex_char(uint8_t c) {
|
||||
return (c & 0xF) + 9 * (c >> 6);
|
||||
}
|
||||
|
||||
static uint8_t assemble_u8(const char *cs)
|
||||
{
|
||||
uint8_t rv = 0;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
int index = !i;
|
||||
rv |= convert_hex_char(cs[i]) << (4 * index);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
int decode_hex(const char *s, uint8_t *output, int len)
|
||||
{
|
||||
for (int i = 0; i < len; i++) {
|
||||
int j = i * 2;
|
||||
int k = j + 1;
|
||||
|
||||
if (is_hex_char(s[j]) && is_hex_char(s[k])) {
|
||||
output[i] = assemble_u8(s + j);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
4
purr.h
4
purr.h
|
@ -55,6 +55,7 @@ int socket_write(void *, const uint8_t *, size_t);
|
|||
|
||||
/* urls.c */
|
||||
int clean_up_link(const char *, char *, char *, char *);
|
||||
int get_encryption_params(char *, uint8_t **, uint8_t **);
|
||||
int host_connect(const char *, const char *, bool);
|
||||
|
||||
/* files.c */
|
||||
|
@ -68,7 +69,8 @@ size_t mmap_to_ssl(struct transmission_information);
|
|||
int send_and_receive(struct connection_information *);
|
||||
|
||||
/* formats.c */
|
||||
char *print_hex(uint8_t *, int, bool);
|
||||
char *print_hex(const uint8_t *, int, bool);
|
||||
int decode_hex(const char *, uint8_t *, int);
|
||||
|
||||
/* encrypt.c */
|
||||
struct mmap_file encrypt_mmap(struct mmap_file, uint8_t **, uint8_t **);
|
||||
|
|
31
tests.c
31
tests.c
|
@ -20,6 +20,22 @@ static int compare_strings(const char *expected, const char *result, const char
|
|||
return rv;
|
||||
}
|
||||
|
||||
static int compare_arrays(const uint8_t *expected, const uint8_t *result, size_t len, const char *function)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
printf("%s(): ", function);
|
||||
if (memcmp(expected, result, len)) {
|
||||
rv = 1;
|
||||
puts("failure");
|
||||
printf("expected: %s\ngot: %s\n", print_hex(expected, len, false), print_hex(result, len, false));
|
||||
} else {
|
||||
puts("success");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int rv = 0;
|
||||
|
@ -48,6 +64,21 @@ int main()
|
|||
rv = compare_strings("/", path, "clean_up_link") ? 1 : rv;
|
||||
rv = compare_strings("80", port, "clean_up_link") ? 1 : rv;
|
||||
assert(portn == HTTP_PORT);
|
||||
|
||||
dirty = "https://bsd.ac/paste.html#sieqaqk_73fe_df51";
|
||||
portn = clean_up_link(dirty, clean, path, port);
|
||||
rv = compare_strings("bsd.ac", clean, "clean_up_link") ? 1 : rv;
|
||||
rv = compare_strings("/paste.html#sieqaqk_73fe_df51", path, "clean_up_link") ? 1 : rv;
|
||||
rv = compare_strings("443", port, "clean_up_link") ? 1 : rv;
|
||||
assert(portn == HTTPS_PORT);
|
||||
uint8_t key_exc[KEY_LEN] = {0x73, 0xfe};
|
||||
uint8_t iv_exc[IV_LEN] = {0xdf, 0x51};
|
||||
uint8_t *key, *iv;
|
||||
int err = get_encryption_params(path, &key, &iv);
|
||||
rv = compare_strings("/sieqaqk", path, "get_encryption_params") ? 1 : rv;
|
||||
rv = compare_arrays(key_exc, key, KEY_LEN, "get_encryption_params") ? 1 : rv;
|
||||
rv = compare_arrays(iv_exc, iv, IV_LEN, "get_encryption_params") ? 1 : rv;
|
||||
assert(err == 0);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
|
53
urls.c
53
urls.c
|
@ -1,5 +1,6 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
@ -55,6 +56,58 @@ int clean_up_link(const char *dirty, char *clean, char *path, char *port)
|
|||
return portn;
|
||||
}
|
||||
|
||||
#define MALFORM_ERROR(p) do{if((p) == NULL || (p)[1] == 0) {fputs("get_encryption_params(): malformed URL\n", stderr); return rv;}}while(0);
|
||||
|
||||
int get_encryption_params(char *path, uint8_t **keyp, uint8_t **ivp)
|
||||
{
|
||||
int rv = -1;
|
||||
// parse path in format: "/paste.html#<actual_path>_<key>[_<iv>]"
|
||||
// will update path to point to the proper piece
|
||||
uint8_t *key = calloc(KEY_LEN, 1);
|
||||
uint8_t *iv = calloc(IV_LEN, 1);
|
||||
char *path_temp = calloc(strlen(path), 1);
|
||||
if (key == NULL || iv == NULL || path_temp == NULL) {
|
||||
perror("calloc()");
|
||||
return rv;
|
||||
}
|
||||
*keyp = key;
|
||||
*ivp = iv;
|
||||
|
||||
char *hash = strchr(path, '#');
|
||||
MALFORM_ERROR(hash);
|
||||
char *underscore = strchr(hash + 1, '_');
|
||||
MALFORM_ERROR(underscore);
|
||||
underscore[0] = 0;
|
||||
|
||||
sprintf(path_temp, "/%s", hash + 1);
|
||||
|
||||
char *key_start = underscore + 1;
|
||||
underscore = strchr(key_start, '_');
|
||||
MALFORM_ERROR(underscore);
|
||||
underscore[0] = 0;
|
||||
char *iv_start = underscore + 1;
|
||||
|
||||
size_t key_s_len = strlen(key_start), iv_s_len = strlen(iv_start);
|
||||
// odd number of chars is an error, as well as being too big
|
||||
if (key_s_len & 1 || iv_s_len & 1 || key_s_len / 2 > KEY_LEN || iv_s_len / 2 > IV_LEN) {
|
||||
fputs("get_encryption_params(): malformed KEY and/or IV input\n", stderr);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int err = decode_hex(key_start, key, key_s_len / 2)
|
||||
| decode_hex(iv_start, iv, iv_s_len / 2);
|
||||
if (err) {
|
||||
fputs("get_encryption_params(): malformed KEY and/or IV input\n", stderr);
|
||||
return rv;
|
||||
}
|
||||
|
||||
strcpy(path, path_temp);
|
||||
free(path_temp);
|
||||
|
||||
rv = 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
int host_connect(const char *host, const char *port, bool debug)
|
||||
{
|
||||
struct addrinfo hints = { 0 }, *si = NULL;
|
||||
|
|
Loading…
Reference in New Issue