summary refs log tree commit diff stats
path: root/plugins/fishlim/keystore.c
diff options
context:
space:
mode:
authorBakasura <bakasura@protonmail.ch>2020-07-13 18:27:27 -0500
committerGitHub <noreply@github.com>2020-07-13 16:27:27 -0700
commitc5a798beec0f24f6828cd3c43bbefd1e18a9d33a (patch)
tree3d79de60cbcaf71562bf93c8b59db926eb020671 /plugins/fishlim/keystore.c
parent2f376953f3fd7d358aa25bf29c01d70a57d40e0c (diff)
FiSHLiM: Support for CBC mode + more commands (#2347)
Diffstat (limited to 'plugins/fishlim/keystore.c')
-rw-r--r--plugins/fishlim/keystore.c61
1 files changed, 46 insertions, 15 deletions
diff --git a/plugins/fishlim/keystore.c b/plugins/fishlim/keystore.c
index 061faa03..adefc700 100644
--- a/plugins/fishlim/keystore.c
+++ b/plugins/fishlim/keystore.c
@@ -103,27 +103,55 @@ static gchar *get_nick_value(GKeyFile *keyfile, const char *nick, const char *it
 /**
  * Extracts a key from the key store file.
  */
-char *keystore_get_key(const char *nick) {
+char *keystore_get_key(const char *nick, enum fish_mode *mode) {
+    GKeyFile *keyfile;
+    char *escaped_nick;
+    gchar *value, *key_mode;
+    int encrypted_mode;
+    char *password;
+    char *encrypted;
+    char *decrypted;
+
     /* Get the key */
-    GKeyFile *keyfile = getConfigFile();
-    char *escaped_nick = escape_nickname(nick);
-    gchar *value = get_nick_value(keyfile, escaped_nick, "key");
+    keyfile = getConfigFile();
+    escaped_nick = escape_nickname(nick);
+    value = get_nick_value(keyfile, escaped_nick, "key");
+    key_mode = get_nick_value(keyfile, escaped_nick, "mode");
     g_key_file_free(keyfile);
     g_free(escaped_nick);
 
+    /* Determine cipher mode */
+    *mode = FISH_ECB_MODE;
+    if (key_mode) {
+        if (*key_mode == '1')
+            *mode = FISH_ECB_MODE;
+        else if (*key_mode == '2')
+            *mode = FISH_CBC_MODE;
+        g_free(key_mode);
+    }
+
     if (!value)
         return NULL;
-    
-    if (strncmp(value, "+OK ", 4) != 0) {
-        /* Key is stored in plaintext */
-        return value;
-    } else {
+
+    if (strncmp(value, "+OK ", 4) == 0) {
         /* Key is encrypted */
-        const char *encrypted = value+4;
-        const char *password = get_keystore_password();
-        char *decrypted = fish_decrypt(password, strlen(password), encrypted);
+        encrypted = (char *) value;
+        encrypted += 4;
+
+        encrypted_mode = FISH_ECB_MODE;
+
+        if (*encrypted == '*') {
+            ++encrypted;
+            encrypted_mode = FISH_CBC_MODE;
+        }
+
+        password = (char *) get_keystore_password();
+        decrypted = fish_decrypt_str((const char *) password, strlen(password), (const char *) encrypted, encrypted_mode);
         g_free(value);
         return decrypted;
+    } else {
+        /* Key is stored in plaintext */
+        return value;
     }
 }
 
@@ -189,7 +217,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
 /**
  * Sets a key in the key store file.
  */
-gboolean keystore_store_key(const char *nick, const char *key) {
+gboolean keystore_store_key(const char *nick, const char *key, enum fish_mode mode) {
     const char *password;
     char *encrypted;
     char *wrapped;
@@ -204,11 +232,11 @@ gboolean keystore_store_key(const char *nick, const char *key) {
     password = get_keystore_password();
     if (password) {
         /* Encrypt the password */
-        encrypted = fish_encrypt(password, strlen(password), key);
+        encrypted = fish_encrypt(password, strlen(password), key, strlen(key), FISH_CBC_MODE);
         if (!encrypted) goto end;
         
         /* Prepend "+OK " */
-        wrapped = g_strconcat("+OK ", encrypted, NULL);
+        wrapped = g_strconcat("+OK *", encrypted, NULL);
         g_free(encrypted);
         
         /* Store encrypted in file */
@@ -218,6 +246,9 @@ gboolean keystore_store_key(const char *nick, const char *key) {
         /* Store unencrypted in file */
         g_key_file_set_string(keyfile, escaped_nick, "key", key);
     }
+
+    /* Store cipher mode */
+    g_key_file_set_integer(keyfile, escaped_nick, "mode", mode);
     
     /* Save key store file */
     ok = save_keystore(keyfile);