about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorWilliam Wennerström <william@wstrm.dev>2020-06-28 12:17:21 +0200
committerWilliam Wennerström <william@wstrm.dev>2020-11-16 21:58:08 +0100
commitd5b1dc0eb6ee9c4caee6c73b9cf26133c875a1c8 (patch)
tree928dee2c32592dcff47ddd96f8320c4e09ffbd4d /src
parente9d58757825e542fe4ec15ce350c0df4192ec29d (diff)
downloadprofani-tty-d5b1dc0eb6ee9c4caee6c73b9cf26133c875a1c8.tar.gz
Move setup for AESGCM to omemo/crypto
Diffstat (limited to 'src')
-rw-r--r--src/command/cmd_funcs.c71
-rw-r--r--src/omemo/crypto.c50
-rw-r--r--src/omemo/crypto.h9
-rw-r--r--src/tools/http_upload.c2
4 files changed, 68 insertions, 64 deletions
diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c
index d16cd938..74a21a09 100644
--- a/src/command/cmd_funcs.c
+++ b/src/command/cmd_funcs.c
@@ -4812,27 +4812,13 @@ cmd_disco(ProfWin* window, const char* const command, gchar** args)
     return TRUE;
 }
 
-char *create_aesgcm_fragment(unsigned char *key, int key_size,
-                             unsigned char *nonce, int nonce_size) {
-    char fragment[(nonce_size+key_size)*2+1];
-
-    for (int i = 0; i < nonce_size; i++) {
-        sprintf(&(fragment[i*2]), "%02x", nonce[i]);
-    }
-
-    for (int i = 0; i < key_size; i++) {
-        sprintf(&(fragment[(i+nonce_size)*2]), "%02x", key[i]);
-    }
-
-    return strdup(fragment);
-}
-
 gboolean
 cmd_sendfile(ProfWin* window, const char* const command, gchar** args)
 {
     jabber_conn_status_t conn_status = connection_get_status();
     char *filename = args[0];
-    unsigned char *key = NULL;
+    char *alt_scheme = NULL;
+    char *alt_fragment = NULL;
 
     // expand ~ to $HOME
     if (filename[0] == '~' && filename[1] == '/') {
@@ -4870,8 +4856,6 @@ cmd_sendfile(ProfWin* window, const char* const command, gchar** args)
     }
 
     FILE *fh = fdopen(fd, "rb");
-    char *alt_scheme = NULL;
-    char *alt_fragment = NULL;
 
     switch (window->type) {
         case WIN_MUC:
@@ -4881,37 +4865,25 @@ cmd_sendfile(ProfWin* window, const char* const command, gchar** args)
             assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK);
 
             if (chatwin->is_omemo && !prefs_get_boolean(PREF_OMEMO_SENDFILE)) {
+
+                // Create temporary file for writing ciphertext.
                 int tmpfd;
                 if ((tmpfd = g_file_open_tmp("profanity.XXXXXX", NULL, NULL)) == -1) {
-                    cons_show_error("Unable to create temporary file for encrypted transfer.");
-                    win_println(window, THEME_ERROR, "-", "Unable to create temporary file for encrypted transfer.");
+                    char *msg = "Unable to create temporary file for encrypted transfer.";
+                    cons_show_error(msg);
+                    win_println(window, THEME_ERROR, "-", msg);
                     fclose(fh);
                     goto out;
                 }
-
                 FILE *tmpfh = fdopen(tmpfd, "wb");
 
                 int crypt_res = GPG_ERR_NO_ERROR;
-
-                // TODO(wstrm): Move these to omemo/crypto.c
-                unsigned char nonce[AES256_GCM_NONCE_LENGTH];
-                key = gcry_malloc_secure(AES256_GCM_KEY_LENGTH);
-                if (key == NULL) {
-                    cons_show_error("Cannot allocate secure memory for encryption.");
-                    win_println(window, THEME_ERROR, "-", "Cannot allocate secure memory for encryption.");
-                    fclose(fh);
-                    fclose(tmpfh);
-                    goto out;
-                }
-
-                key = gcry_random_bytes_secure(AES256_GCM_KEY_LENGTH, GCRY_VERY_STRONG_RANDOM);
-                gcry_create_nonce(nonce, AES256_GCM_NONCE_LENGTH);
-
-                crypt_res = aes256gcm_encrypt_file(fh, tmpfh, file_size(fd), key, nonce);
-
+                alt_scheme = AESGCM_URL_SCHEME;
+                alt_fragment = aes256gcm_encrypt_file(fh, tmpfh, file_size(fd), &crypt_res);
                 if (crypt_res != 0) {
-                    cons_show_error("Failed to encrypt file.");
-                    win_println(window, THEME_ERROR, "-", "Failed to encrypt file.");
+                    char *msg = "Failed to encrypt file.";
+                    cons_show_error(msg);
+                    win_println(window, THEME_ERROR, "-", msg);
                     fclose(fh);
                     fclose(tmpfh);
                     goto out;
@@ -4927,11 +4899,6 @@ cmd_sendfile(ProfWin* window, const char* const command, gchar** args)
                 fd = tmpfd;
                 fh = tmpfh;
 
-                alt_scheme = AESGCM_URL_SCHEME;
-                alt_fragment = create_aesgcm_fragment(
-                        key, AES256_GCM_KEY_LENGTH,
-                        nonce, AES256_GCM_NONCE_LENGTH);
-
                 break;
             }
 
@@ -4943,11 +4910,7 @@ cmd_sendfile(ProfWin* window, const char* const command, gchar** args)
             }
             break;
         }
-        case WIN_PRIVATE:
-        {
-            // We don't support encryption in private MUC windows.
-            break;
-        }
+        case WIN_PRIVATE: // We don't support encryption in private MUC windows.
         default:
 			cons_show_error("Unsupported window for file transmission.");
             goto out;
@@ -4972,14 +4935,14 @@ cmd_sendfile(ProfWin* window, const char* const command, gchar** args)
     upload->filehandle = fh;
     upload->filesize = file_size(fd);
     upload->mime_type = file_mime_type(filename);
-    upload->alt_scheme = alt_scheme;
-    upload->alt_fragment = alt_fragment;
+    upload->alt_scheme = strdup(alt_scheme);
+    upload->alt_fragment = strdup(alt_fragment);
 
     iq_http_upload_request(upload);
 
 out:
-    if (key != NULL)
-        gcry_free(key);
+    if (alt_fragment != NULL)
+        aes256gcm_fragment_free(alt_fragment);
     if (filename != NULL)
         free(filename);
 
diff --git a/src/omemo/crypto.c b/src/omemo/crypto.c
index 6d6ba519..7dd3be10 100644
--- a/src/omemo/crypto.c
+++ b/src/omemo/crypto.c
@@ -463,12 +463,50 @@ out:
     return res;
 }
 
-int aes256gcm_encrypt_file(FILE *in, FILE *out, off_t file_size,
-    unsigned char key[], unsigned char nonce[]) {
-    return aes256gcm_crypt_file(in, out, file_size, key, nonce, true);
+char *aes256gcm_create_secure_fragment(unsigned char *key, unsigned char *nonce) {
+    int key_size = AES256_GCM_KEY_LENGTH;
+    int nonce_size = AES256_GCM_NONCE_LENGTH;
+
+    char *fragment = gcry_malloc_secure((nonce_size+key_size)*2+1);
+
+    for (int i = 0; i < nonce_size; i++) {
+        sprintf(&(fragment[i*2]), "%02x", nonce[i]);
+    }
+
+    for (int i = 0; i < key_size; i++) {
+        sprintf(&(fragment[(i+nonce_size)*2]), "%02x", key[i]);
+    }
+
+    return fragment;
 }
 
-int aes256gcm_decrypt_file(FILE *in, FILE *out, off_t file_size,
-    unsigned char key[], unsigned char nonce[]) {
-    return aes256gcm_crypt_file(in, out, file_size, key, nonce, false);
+void aes256gcm_fragment_free(char *fragment) {
+    gcry_free(fragment);
 }
+
+char *aes256gcm_encrypt_file(FILE *in, FILE *out, off_t file_size, int *gcry_res) {
+    unsigned char *key = gcry_random_bytes_secure(
+        AES256_GCM_KEY_LENGTH,
+        GCRY_VERY_STRONG_RANDOM);
+
+    // Create nonce/IV with random bytes.
+    unsigned char nonce[AES256_GCM_NONCE_LENGTH];
+    gcry_create_nonce(nonce, AES256_GCM_NONCE_LENGTH);
+
+    char *fragment = aes256gcm_create_secure_fragment(key, nonce);
+    *gcry_res = aes256gcm_crypt_file(in, out, file_size, key, nonce, true);
+
+    if (*gcry_res != GPG_ERR_NO_ERROR) {
+        gcry_free(fragment);
+        fragment = NULL;
+    }
+
+    gcry_free(key);
+
+    return fragment;
+}
+
+//int aes256gcm_decrypt_file(FILE *in, FILE *out, off_t file_size,
+//    unsigned char key[], unsigned char nonce[]) {
+//    return aes256gcm_crypt_file(in, out, file_size, key, nonce, false);
+//}
diff --git a/src/omemo/crypto.h b/src/omemo/crypto.h
index 916486b7..34cbb82c 100644
--- a/src/omemo/crypto.h
+++ b/src/omemo/crypto.h
@@ -185,8 +185,9 @@ int aes128gcm_decrypt(unsigned char *plaintext,
     size_t ciphertext_len, const unsigned char *const iv, size_t iv_len,
     const unsigned char *const key, const unsigned char *const tag);
 
-int aes256gcm_encrypt_file(FILE *in, FILE *out, off_t file_size,
-    unsigned char key[], unsigned char nonce[]);
+char *aes256gcm_encrypt_file(FILE *in, FILE *out, off_t file_size, int *gcry_res);
 
-int aes256gcm_decrypt_file(FILE *in, FILE *out, off_t file_size,
-    unsigned char key[], unsigned char nonce[]);
+//int aes256gcm_decrypt_file(FILE *in, FILE *out, off_t file_size,
+//    unsigned char key[], unsigned char nonce[]);
+
+void aes256gcm_fragment_free(char *fragment);
diff --git a/src/tools/http_upload.c b/src/tools/http_upload.c
index 69587c08..d9742e30 100644
--- a/src/tools/http_upload.c
+++ b/src/tools/http_upload.c
@@ -328,6 +328,8 @@ http_file_put(void *userdata)
     free(upload->mime_type);
     free(upload->get_url);
     free(upload->put_url);
+    free(upload->alt_scheme);
+    free(upload->alt_fragment);
     free(upload);
 
     return NULL;