Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package otpclient for openSUSE:Factory 
checked in at 2022-12-30 11:08:53
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/otpclient (Old)
 and      /work/SRC/openSUSE:Factory/.otpclient.new.1563 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "otpclient"

Fri Dec 30 11:08:53 2022 rev:21 rq:1045797 version:3.1.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/otpclient/otpclient.changes      2022-12-20 
20:21:03.782067662 +0100
+++ /work/SRC/openSUSE:Factory/.otpclient.new.1563/otpclient.changes    
2022-12-30 11:09:08.201318769 +0100
@@ -1,0 +2,8 @@
+Fri Dec 30 07:06:40 UTC 2022 - Paolo Stivanin <i...@paolostivanin.com>
+
+- Update to 3.1.1:
+  * Fixed some memory leaks.
+  * Improved error handling.
+  * Use secure functions instead of standard ones .
+
+-------------------------------------------------------------------

Old:
----
  v3.1.0.tar.gz
  v3.1.0.tar.gz.asc

New:
----
  v3.1.1.tar.gz
  v3.1.1.tar.gz.asc

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ otpclient.spec ++++++
--- /var/tmp/diff_new_pack.huiRqu/_old  2022-12-30 11:09:08.609321208 +0100
+++ /var/tmp/diff_new_pack.huiRqu/_new  2022-12-30 11:09:08.613321232 +0100
@@ -18,7 +18,7 @@
 
 %define uclname OTPClient
 Name:           otpclient
-Version:        3.1.0
+Version:        3.1.1
 Release:        0
 Summary:        Simple GTK+ client for managing TOTP and HOTP
 License:        GPL-3.0-or-later


++++++ v3.1.0.tar.gz -> v3.1.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/OTPClient-3.1.0/.github/workflows/codeql-analysis.yml 
new/OTPClient-3.1.1/.github/workflows/codeql-analysis.yml
--- old/OTPClient-3.1.0/.github/workflows/codeql-analysis.yml   2022-12-19 
14:16:00.000000000 +0100
+++ new/OTPClient-3.1.1/.github/workflows/codeql-analysis.yml   2022-12-28 
17:02:45.000000000 +0100
@@ -24,7 +24,7 @@
       uses: actions/checkout@v2
 
     - name: Initialize CodeQL
-      uses: github/codeql-action/init@v1
+      uses: github/codeql-action/init@v2
       with:
         languages: ${{ matrix.language }}
 
@@ -41,4 +41,4 @@
        make
 
     - name: Perform CodeQL Analysis
-      uses: github/codeql-action/analyze@v1
+      uses: github/codeql-action/analyze@v2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/CMakeLists.txt 
new/OTPClient-3.1.1/CMakeLists.txt
--- old/OTPClient-3.1.0/CMakeLists.txt  2022-12-19 14:16:00.000000000 +0100
+++ new/OTPClient-3.1.1/CMakeLists.txt  2022-12-28 17:02:45.000000000 +0100
@@ -1,5 +1,5 @@
 cmake_minimum_required(VERSION 3.10)
-project(OTPClient VERSION "3.1.0" LANGUAGES "C")
+project(OTPClient VERSION "3.1.1" LANGUAGES "C")
 include(GNUInstallDirs)
 
 configure_file("src/common/version.h.in" "version.h")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/README.md 
new/OTPClient-3.1.1/README.md
--- old/OTPClient-3.1.0/README.md       2022-12-19 14:16:00.000000000 +0100
+++ new/OTPClient-3.1.1/README.md       2022-12-28 17:02:45.000000000 +0100
@@ -2,6 +2,10 @@
 <a href="https://circleci.com/gh/paolostivanin/OTPClient";>
   <img alt="CircleCI" 
src="https://circleci.com/gh/paolostivanin/OTPClient.svg?style=svg"/>
 </a>
+<a href="https://scan.coverity.com/projects/paolostivanin-otpclient";>
+  <img alt="Coverity Scan Build Status"
+       src="https://scan.coverity.com/projects/12749/badge.svg"/>
+</a>
 
 Highly secure and easy to use GTK+ software for two-factor authentication that 
supports both Time-based One-time Passwords (TOTP) and HMAC-Based One-Time 
Passwords (HOTP).
 
@@ -42,7 +46,7 @@
   - decrypted file is never saved (and hopefully never swapped) to disk. While 
the app is running, the decrypted content resides in a "secure memory" buffer 
allocated by Gcrypt
 
 ## Testing
-* Before each release, I run PVS Studio in order to catch even more errors 
and/or corner cases
+* Before each release, I run PVS Studio and Coverity in order to catch even 
more bugs.
 * With every commit to master, OTPClient is compiled in CircleCI against 
different distros
 
 ## Protobuf
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/OTPClient-3.1.0/data/com.github.paolostivanin.OTPClient.appdata.xml 
new/OTPClient-3.1.1/data/com.github.paolostivanin.OTPClient.appdata.xml
--- old/OTPClient-3.1.0/data/com.github.paolostivanin.OTPClient.appdata.xml     
2022-12-19 14:16:00.000000000 +0100
+++ new/OTPClient-3.1.1/data/com.github.paolostivanin.OTPClient.appdata.xml     
2022-12-28 17:02:45.000000000 +0100
@@ -83,6 +83,16 @@
   </content_rating>
 
   <releases>
+    <release version="3.1.1" date="2022-12-29">
+      <description>
+        <p>OTPClient 3.1.1 brings lots of small under-the-hood changes:</p>
+        <ul>
+          <li>Fixed some memory leaks</li>
+          <li>Improved error handling</li>
+          <li>Use secure functions instead of standard ones</li>
+        </ul>
+      </description>
+    </release>
     <release version="3.1.0" date="2022-12-19">
       <description>
         <p>OTPClient 3.1.0 the following feature and fixes:</p>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/add-common.c 
new/OTPClient-3.1.1/src/add-common.c
--- old/OTPClient-3.1.0/src/add-common.c        2022-12-19 14:16:00.000000000 
+0100
+++ new/OTPClient-3.1.1/src/add-common.c        2022-12-28 17:02:45.000000000 
+0100
@@ -47,6 +47,7 @@
         if (otp->period < 10 || otp->period > 120) {
             gchar *msg = g_strconcat("[INFO]: invalid period for '", 
otp->account_name, "'. Defaulting back to 30 seconds.", NULL);
             g_printerr ("%s\n", msg);
+            g_free (msg);
             otp->period = 30;
         }
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/add-from-qr.c 
new/OTPClient-3.1.1/src/add-from-qr.c
--- old/OTPClient-3.1.0/src/add-from-qr.c       2022-12-19 14:16:00.000000000 
+0100
+++ new/OTPClient-3.1.1/src/add-from-qr.c       2022-12-28 17:02:45.000000000 
+0100
@@ -1,6 +1,7 @@
 #include <gtk/gtk.h>
 #include <gcrypt.h>
 #include <glib/gstdio.h>
+#include <glib/gi18n.h>
 #include "imports.h"
 #include "qrcode-parser.h"
 #include "message-dialogs.h"
@@ -169,7 +170,9 @@
             gchar *filename = g_build_filename (g_get_tmp_dir (), 
"qrcode_from_cb_uri.png", NULL);
             gdk_pixbuf_save (pbuf, filename, "png", &err, NULL);
             parse_file_and_update_db (filename, app_data, FALSE);
-            g_unlink (filename);
+            if (g_unlink (filename) == -1) {
+                g_printerr ("%s\n", _("Couldn't unlink the temp pixbuf."));
+            }
             g_free (filename);
             g_object_unref (pbuf);
         }
@@ -196,7 +199,9 @@
         } else {
             parse_file_and_update_db (filename, app_data, FALSE);
         }
-        g_unlink (filename);
+        if (g_unlink (filename) == -1) {
+            g_printerr ("%s\n", _("Error while unlinking the temp png."));
+        }
         g_free (filename);
     } else {
         show_message_dialog (app_data->main_window, "Couldn't get QR code 
image from clipboard", GTK_MESSAGE_ERROR);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/app.c 
new/OTPClient-3.1.1/src/app.c
--- old/OTPClient-3.1.0/src/app.c       2022-12-19 14:16:00.000000000 +0100
+++ new/OTPClient-3.1.1/src/app.c       2022-12-28 17:02:45.000000000 +0100
@@ -356,6 +356,7 @@
             return kf;
         }
         g_printerr ("%s\n", err->message);
+        g_clear_error (&err);
     }
     g_free (cfg_file_path);
     g_key_file_free (kf);
@@ -419,6 +420,7 @@
 #endif
         if (!g_key_file_save_to_file (kf, cfg_file_path, &err)) {
             g_printerr ("%s\n", err->message);
+            g_clear_error (&err);
         }
         g_free (cfg_file_path);
         g_key_file_free (kf);
@@ -492,9 +494,9 @@
 #else
         cfg_file_path = g_build_filename (g_get_user_data_dir (), 
"otpclient.cfg", NULL);
 #endif
-        g_key_file_save_to_file (kf, cfg_file_path, &err);
-        if (err != NULL) {
+        if (!g_key_file_save_to_file (kf, cfg_file_path, &err)) {
             g_printerr ("%s\n", err->message);
+            g_clear_error (&err);
         }
         g_free (cfg_file_path);
     }
@@ -568,9 +570,10 @@
         if (!g_key_file_load_from_file (kf, cfg_file_path, G_KEY_FILE_NONE, 
&err)) {
             show_message_dialog (app_data->main_window, err->message, 
GTK_MESSAGE_ERROR);
             g_key_file_free (kf);
+            g_clear_error (&err);
             return NULL;
         }
-        db_path = g_key_file_get_string (kf, "config", "db_path", &err);
+        db_path = g_key_file_get_string (kf, "config", "db_path", NULL);
         if (db_path == NULL) {
             goto new_db;
         }
@@ -601,9 +604,9 @@
     if (res == GTK_RESPONSE_ACCEPT) {
         db_path = gtk_file_chooser_get_filename (chooser);
         g_key_file_set_string (kf, "config", "db_path", db_path);
-        g_key_file_save_to_file (kf, cfg_file_path, &err);
-        if (err != NULL) {
+        if (!g_key_file_save_to_file (kf, cfg_file_path, &err)) {
             g_printerr ("%s\n", err->message);
+            g_clear_error (&err);
         }
     }
 
@@ -764,11 +767,13 @@
     if (g_file_test (cfg_file_path, G_FILE_TEST_EXISTS)) {
         if (!g_key_file_load_from_file (kf, cfg_file_path, G_KEY_FILE_NONE, 
&err)) {
             g_printerr ("%s\n", err->message);
+            g_clear_error (&err);
         } else {
             g_key_file_set_integer (kf, "config", param1_name, param1_value);
             g_key_file_set_integer (kf, "config", param2_name, param2_value);
             if (!g_key_file_save_to_file (kf, cfg_file_path, &err)) {
                 g_printerr ("%s\n", err->message);
+                g_clear_error (&err);
             }
         }
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/change-file-cb.c 
new/OTPClient-3.1.1/src/change-file-cb.c
--- old/OTPClient-3.1.0/src/change-file-cb.c    2022-12-19 14:16:00.000000000 
+0100
+++ new/OTPClient-3.1.1/src/change-file-cb.c    2022-12-28 17:02:45.000000000 
+0100
@@ -1,5 +1,7 @@
 #include <gtk/gtk.h>
+#include <glib/gi18n.h>
 #include "db-misc.h"
+#include "message-dialogs.h"
 
 gboolean
 change_file (AppData *app_data)
@@ -40,7 +42,13 @@
                 cfg_file_path = g_build_filename (g_get_user_data_dir (), 
"otpclient.cfg", NULL);
 #endif
                 g_key_file_set_string (kf, "config", "db_path", db_path);
-                g_key_file_save_to_file (kf, cfg_file_path, NULL);
+                GError *err = NULL;
+                if (!g_key_file_save_to_file (kf, cfg_file_path, &err)) {
+                    gchar *err_msg = g_strconcat (_("Couldn't save the config 
file: "), err->message, NULL);
+                    show_message_dialog (app_data->main_window, err_msg, 
GTK_MESSAGE_ERROR);
+                    g_free (err_msg);
+                    g_clear_error (&err);
+                }
                 g_free (app_data->db_data->db_path);
                 app_data->db_data->db_path = g_strdup (db_path);
                 g_free (db_path);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/change-pwd-cb.c 
new/OTPClient-3.1.1/src/change-pwd-cb.c
--- old/OTPClient-3.1.0/src/change-pwd-cb.c     2022-12-19 14:16:00.000000000 
+0100
+++ new/OTPClient-3.1.1/src/change-pwd-cb.c     2022-12-28 17:02:45.000000000 
+0100
@@ -27,6 +27,7 @@
             GtkApplication *app = gtk_window_get_application 
(GTK_WINDOW(app_data->main_window));
             destroy_cb (app_data->main_window, app_data);
             g_application_quit (G_APPLICATION(app));
+            return;
         }
         show_message_dialog (app_data->main_window, "Password successfully 
changed", GTK_MESSAGE_INFO);
         secret_password_store (OTPCLIENT_SCHEMA, SECRET_COLLECTION_DEFAULT, 
"main_pwd", app_data->db_data->key, NULL, on_password_stored, NULL, "string", 
"main_pwd", NULL);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/cli/main.c 
new/OTPClient-3.1.1/src/cli/main.c
--- old/OTPClient-3.1.0/src/cli/main.c  2022-12-19 14:16:00.000000000 +0100
+++ new/OTPClient-3.1.1/src/cli/main.c  2022-12-28 17:02:45.000000000 +0100
@@ -206,9 +206,10 @@
         if (!g_key_file_load_from_file (kf, cfg_file_path, G_KEY_FILE_NONE, 
&err)) {
             g_printerr ("%s\n", err->message);
             g_key_file_free (kf);
+            g_clear_error (&err);
             return NULL;
         }
-        db_path = g_key_file_get_string (kf, "config", "db_path", &err);
+        db_path = g_key_file_get_string (kf, "config", "db_path", NULL);
         if (db_path == NULL) {
             goto type_db_path;
         }
@@ -226,6 +227,7 @@
     if (fgets (db_path, MAX_ABS_PATH_LEN, stdin) == NULL) {
         g_printerr ("%s\n", _("Couldn't get db path from stdin"));
         g_free (cfg_file_path);
+        g_free (db_path);
         return NULL;
     } else {
         // remove the newline char
@@ -233,6 +235,7 @@
         if (!g_file_test (db_path, G_FILE_TEST_EXISTS)) {
             g_printerr (_("File '%s' does not exist\n"), db_path);
             g_free (cfg_file_path);
+            g_free (db_path);
             return NULL;
         }
     }
@@ -291,6 +294,7 @@
         if (!g_key_file_load_from_file (kf, cfg_file_path, G_KEY_FILE_NONE, 
&err)) {
             g_printerr ("%s\n", err->message);
             g_key_file_free (kf);
+            g_clear_error (&err);
             return FALSE;
         }
         disable_secret_service = g_key_file_get_boolean (kf, "config", 
"disable_secret_service", NULL);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/common/aegis.c 
new/OTPClient-3.1.1/src/common/aegis.c
--- old/OTPClient-3.1.0/src/common/aegis.c      2022-12-19 14:16:00.000000000 
+0100
+++ new/OTPClient-3.1.1/src/common/aegis.c      2022-12-28 17:02:45.000000000 
+0100
@@ -90,12 +90,25 @@
     guchar *key_tag = hexstr_to_bytes (json_string_value (json_object_get (kp, 
"tag")));
     json_t *dbp = json_object_get(json_object_get(json, "header"), "params");
     guchar *keybuf = gcry_malloc (KEY_SIZE);
-    gcry_kdf_derive (password, strlen (password) + 1, GCRY_KDF_SCRYPT, n, 
salt, SALT_SIZE,  p, KEY_SIZE, keybuf);
+    if (gcry_kdf_derive (password, strlen (password) + 1, GCRY_KDF_SCRYPT, n, 
salt, SALT_SIZE,  p, KEY_SIZE, keybuf) != 0) {
+        g_printerr ("Error while deriving the key.\n");
+        g_free (salt);
+        g_free (enc_key);
+        g_free (key_nonce);
+        g_free (key_tag);
+        gcry_free (keybuf);
+        return NULL;
+    }
 
-    gcry_cipher_hd_t hd;
-    gcry_cipher_open (&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, 0);
-    gcry_cipher_setkey (hd, keybuf, gcry_cipher_get_algo_keylen 
(GCRY_CIPHER_AES256));
-    gcry_cipher_setiv (hd, key_nonce, NONCE_SIZE);
+    gcry_cipher_hd_t hd = open_cipher_and_set_data (keybuf, key_nonce, 
NONCE_SIZE);
+    if (hd == NULL) {
+        g_free (salt);
+        g_free (enc_key);
+        g_free (key_nonce);
+        g_free (key_tag);
+        gcry_free (keybuf);
+        return NULL;
+    }
 
     guchar *master_key = gcry_calloc_secure (KEY_SIZE, 1);
     if (gcry_cipher_decrypt (hd, master_key, KEY_SIZE, enc_key, KEY_SIZE) != 
0) {
@@ -104,8 +117,9 @@
         g_free (enc_key);
         g_free (key_nonce);
         g_free (key_tag);
-        gcry_cipher_close (hd);
         gcry_free (master_key);
+        gcry_free (keybuf);
+        gcry_cipher_close (hd);
         return NULL;
     }
     gpg_error_t gpg_err = gcry_cipher_checktag(hd, key_tag, TAG_SIZE);
@@ -115,8 +129,9 @@
         g_free (enc_key);
         g_free (key_nonce);
         g_free (key_tag);
-        gcry_cipher_close (hd);
         gcry_free (master_key);
+        gcry_free (keybuf);
+        gcry_cipher_close (hd);
         return NULL;
     }
 
@@ -124,37 +139,55 @@
     g_free (enc_key);
     g_free (key_nonce);
     g_free (key_tag);
+    gcry_free (keybuf);
     gcry_cipher_close (hd);
 
     guchar *nonce = hexstr_to_bytes (json_string_value (json_object_get (dbp, 
"nonce")));
     guchar *tag = hexstr_to_bytes (json_string_value (json_object_get (dbp, 
"tag")));
-    gcry_cipher_open (&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, 0);
-    gcry_cipher_setkey (hd, master_key, gcry_cipher_get_algo_keylen 
(GCRY_CIPHER_AES256));
-    gcry_cipher_setiv (hd, nonce, 12);
+
+    hd = open_cipher_and_set_data (master_key, nonce, 12);
+    if (hd == NULL) {
+        g_free (tag);
+        g_free (nonce);
+        gcry_free (master_key);
+        return NULL;
+    }
+
     gsize out_len;
-    guchar *b64decoded_db = g_base64_decode (json_string_value 
(json_object_get(json, "db")), &out_len);
+    guchar *b64decoded_db = g_base64_decode_secure (json_string_value 
(json_object_get(json, "db")), &out_len);
     if (out_len > max_file_size) {
         g_set_error (err, file_too_big_gquark (), FILE_TOO_BIG, "File is too 
big");
-        gcry_cipher_close (hd);
+        g_free (tag);
+        g_free (nonce);
         gcry_free (master_key);
+        gcry_free (b64decoded_db);
+        gcry_cipher_close (hd);
         return NULL;
     }
+
     gchar *decrypted_db = gcry_calloc_secure (out_len, 1);
-    gcry_cipher_decrypt (hd, decrypted_db, out_len, b64decoded_db, out_len);
-    gpg_err = gcry_cipher_checktag(hd, tag, TAG_SIZE);
+    gpg_err = gcry_cipher_decrypt (hd, decrypted_db, out_len, b64decoded_db, 
out_len);
+    if (gpg_err) {
+        goto clean_and_exit;
+    }
+    gpg_err = gcry_cipher_checktag (hd, tag, TAG_SIZE);
     if (gpg_err != 0) {
         g_set_error (err, bad_tag_gquark (), BAD_TAG_ERRCODE, "Invalid TAG 
(database). Either the password is wrong or the file is corrupted.");
-        gcry_cipher_close (hd);
+        clean_and_exit:
+        g_free (nonce);
+        g_free (tag);
         gcry_free (master_key);
-        g_free (decrypted_db);
+        gcry_free (decrypted_db);
+        gcry_free (b64decoded_db);
+        gcry_cipher_close (hd);
         return NULL;
     }
 
-    g_free (b64decoded_db);
     g_free (nonce);
     g_free (tag);
     gcry_cipher_close (hd);
     gcry_free (master_key);
+    gcry_free (b64decoded_db);
 
     GSList *otps = parse_json_data (decrypted_db, err);
     gcry_free (decrypted_db);
@@ -173,7 +206,7 @@
     json_object_set (root, "version", json_integer(1));
 
     gcry_cipher_hd_t hd;
-    guchar *derived_master_key, *enc_master_key, *key_nonce, *key_tag, 
*db_nonce, *db_tag, *salt;
+    guchar *derived_master_key = NULL, *enc_master_key = NULL, *key_nonce = 
NULL, *key_tag = NULL, *db_nonce = NULL, *db_tag = NULL, *salt = NULL;
     json_t *aegis_header_obj = json_object ();
     if (password == NULL) {
         json_object_set (aegis_header_obj, "slots", json_null ());
@@ -198,18 +231,32 @@
         gcry_create_nonce (key_nonce, NONCE_SIZE);
 
         derived_master_key = gcry_calloc_secure(KEY_SIZE, 1);
-        gcry_kdf_derive (password, strlen (password) + 1, GCRY_KDF_SCRYPT, 
32768, salt, SALT_SIZE,  1, KEY_SIZE, derived_master_key);
-        gcry_cipher_open (&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, 0);
-        gcry_cipher_setkey (hd, derived_master_key, 
gcry_cipher_get_algo_keylen (GCRY_CIPHER_AES256));
-        gcry_cipher_setiv (hd, key_nonce, NONCE_SIZE);
+        gpg_error_t gpg_err = gcry_kdf_derive (password, strlen (password) + 
1, GCRY_KDF_SCRYPT, 32768, salt, SALT_SIZE,  1, KEY_SIZE, derived_master_key);
+        if (gpg_err) {
+            g_printerr ("Error while deriving the key\n");
+            gcry_free (derived_master_key);
+            return NULL;
+        }
+
+        hd = open_cipher_and_set_data (derived_master_key, key_nonce, 
NONCE_SIZE);
+        if (hd == NULL) {
+            gcry_free (derived_master_key);
+            g_free (key_nonce);
+            g_free (salt);
+            return NULL;
+        }
+
         enc_master_key = gcry_malloc (KEY_SIZE);
         if (gcry_cipher_encrypt (hd, enc_master_key, KEY_SIZE, 
derived_master_key, KEY_SIZE)) {
             g_printerr ("Error while encrypting the master key.\n");
             gcry_free (derived_master_key);
             gcry_free (enc_master_key);
+            g_free (key_nonce);
+            g_free (salt);
             gcry_cipher_close (hd);
             return NULL;
         }
+
         key_tag = g_malloc0 (TAG_SIZE);
         gcry_cipher_gettag (hd, key_tag, TAG_SIZE);
         json_object_set (slot_1, "key", json_string (bytes_to_hexstr 
(enc_master_key, KEY_SIZE)));
@@ -282,9 +329,10 @@
     }
 
     if (password != NULL) {
-        gcry_cipher_open (&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, 0);
-        gcry_cipher_setkey (hd, derived_master_key, 
gcry_cipher_get_algo_keylen (GCRY_CIPHER_AES256));
-        gcry_cipher_setiv (hd, db_nonce, NONCE_SIZE);
+        hd = open_cipher_and_set_data (derived_master_key, db_nonce, 
NONCE_SIZE);
+        if (hd == NULL) {
+            goto clean_and_return;
+        }
         size_t db_size = json_dumpb (aegis_db_obj, NULL, 0, 0);
         guchar *enc_db = g_malloc0 (db_size);
         gchar *dumped_db = g_malloc0 (db_size);
@@ -292,7 +340,9 @@
         if (gcry_cipher_encrypt (hd, enc_db, db_size, dumped_db, db_size)) {
             g_printerr ("Error while encrypting the db.\n");
             g_free (enc_db);
-            gcry_free (dumped_db);
+            g_free (dumped_db);
+            gcry_cipher_close (hd);
+            clean_and_return:
             g_free (key_nonce);
             g_free (key_tag);
             g_free (db_nonce);
@@ -305,7 +355,7 @@
         gcry_cipher_gettag (hd, db_tag, TAG_SIZE);
         json_t *db_params = json_object_get (aegis_header_obj, "params");
         json_object_set (db_params, "tag", json_string (bytes_to_hexstr 
(db_tag, TAG_SIZE)));
-        gcry_free (dumped_db);
+        g_free (dumped_db);
         gchar *b64enc_db = g_base64_encode (enc_db, db_size);
         json_object_set (root, "db", json_string (b64enc_db));
 
@@ -318,6 +368,7 @@
         g_free (salt);
         gcry_free (derived_master_key);
         gcry_free (enc_master_key);
+        gcry_cipher_close (hd);
     }
 
     FILE *fp = fopen (export_path, "w");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/common/andotp.c 
new/OTPClient-3.1.1/src/common/andotp.c
--- old/OTPClient-3.1.0/src/common/andotp.c     2022-12-19 14:16:00.000000000 
+0100
+++ new/OTPClient-3.1.1/src/common/andotp.c     2022-12-28 17:02:45.000000000 
+0100
@@ -3,6 +3,7 @@
 #include <gcrypt.h>
 #include <jansson.h>
 #include <time.h>
+#include <glib/gi18n.h>
 #include "../file-size.h"
 #include "../imports.h"
 #include "../gquarks.h"
@@ -114,8 +115,8 @@
         g_set_error (err, file_too_big_gquark (), FILE_TOO_BIG, "File is too 
big");
         return NULL;
     }
-    guchar *enc_buf = g_malloc0 (enc_buf_size);
 
+    guchar *enc_buf = g_malloc0 (enc_buf_size);
     if (!g_seekable_seek (G_SEEKABLE (in_stream), 4 + ANDOTP_SALT_SIZE + 
ANDOTP_IV_SIZE, G_SEEK_SET, NULL, err)) {
         g_object_unref (in_stream);
         g_object_unref (in_file);
@@ -133,18 +134,28 @@
 
     guchar *derived_key = get_derived_key (password, salt, be_iterations);
 
-    gcry_cipher_hd_t hd;
-    gcry_cipher_open (&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, 
GCRY_CIPHER_SECURE);
-    gcry_cipher_setkey (hd, derived_key, gcry_cipher_get_algo_keylen 
(GCRY_CIPHER_AES256));
-    gcry_cipher_setiv (hd, iv, ANDOTP_IV_SIZE);
+    gcry_cipher_hd_t hd = open_cipher_and_set_data (derived_key, iv, 
ANDOTP_IV_SIZE);
+    if (hd == NULL) {
+        gcry_free (derived_key);
+        g_free (enc_buf);
+        return NULL;
+    }
 
     gchar *decrypted_json = gcry_calloc_secure (enc_buf_size, 1);
-    gcry_cipher_decrypt (hd, decrypted_json, enc_buf_size, enc_buf, 
enc_buf_size);
+    gpg_error_t gpg_err = gcry_cipher_decrypt (hd, decrypted_json, 
enc_buf_size, enc_buf, enc_buf_size);
+    if (gpg_err) {
+        g_free (enc_buf);
+        gcry_free (derived_key);
+        gcry_free (decrypted_json);
+        gcry_cipher_close (hd);
+        return NULL;
+    }
     if (gcry_err_code (gcry_cipher_checktag (hd, tag, ANDOTP_TAG_SIZE)) == 
GPG_ERR_CHECKSUM) {
         g_set_error (err, bad_tag_gquark (), BAD_TAG_ERRCODE, "Either the file 
is corrupted or the password is wrong");
         gcry_cipher_close (hd);
-        gcry_free (derived_key);
         g_free (enc_buf);
+        gcry_free (derived_key);
+        gcry_free (decrypted_json);
         return NULL;
     }
 
@@ -240,14 +251,26 @@
     guchar *salt = g_malloc0 (ANDOTP_SALT_SIZE);
     gcry_create_nonce (salt, ANDOTP_SALT_SIZE);
 
-    gcry_cipher_hd_t hd;
-    gcry_cipher_open (&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, 
GCRY_CIPHER_SECURE);
     guchar *derived_key = get_derived_key (password, salt, le_iterations);
-    gcry_cipher_setkey (hd, derived_key, gcry_cipher_get_algo_keylen 
(GCRY_CIPHER_AES256));
-    gcry_cipher_setiv (hd, iv, ANDOTP_IV_SIZE);
+    gcry_cipher_hd_t hd = open_cipher_and_set_data (derived_key, iv, 
ANDOTP_IV_SIZE);
+    if (hd == NULL) {
+        gcry_free (derived_key);
+        g_free (iv);
+        g_free (salt);
+        return NULL;
+    }
 
     gchar *enc_buf = gcry_calloc_secure (json_data_size, 1);
-    gcry_cipher_encrypt (hd, enc_buf, json_data_size, json_data, 
json_data_size);
+    gpg_error_t gpg_err = gcry_cipher_encrypt (hd, enc_buf, json_data_size, 
json_data, json_data_size);
+    if (gpg_err) {
+        g_printerr ("%s\n", _("Error while encrypting the data."));
+        gcry_free (derived_key);
+        gcry_free (enc_buf);
+        g_free (iv);
+        g_free (salt);
+        gcry_cipher_close (hd);
+        return NULL;
+    }
     guchar tag[ANDOTP_TAG_SIZE];
     gcry_cipher_gettag (hd, tag, ANDOTP_TAG_SIZE);
     gcry_cipher_close (hd);
@@ -257,30 +280,27 @@
     if (err != NULL) {
         goto cleanup_before_exiting;
     }
-    g_output_stream_write (G_OUTPUT_STREAM (out_stream), &be_iterations, 4, 
NULL, &err);
-    if (err != NULL) {
+    if (g_output_stream_write (G_OUTPUT_STREAM (out_stream), &be_iterations, 
4, NULL, &err) == -1) {
         goto cleanup_before_exiting;
     }
-    g_output_stream_write (G_OUTPUT_STREAM (out_stream), salt, 
ANDOTP_SALT_SIZE, NULL, &err);
-    if (err != NULL) {
+    if (g_output_stream_write (G_OUTPUT_STREAM (out_stream), salt, 
ANDOTP_SALT_SIZE, NULL, &err) == -1) {
         goto cleanup_before_exiting;
     }
-    g_output_stream_write (G_OUTPUT_STREAM (out_stream), iv, ANDOTP_IV_SIZE, 
NULL, &err);
-    if (err != NULL) {
+    if (g_output_stream_write (G_OUTPUT_STREAM (out_stream), iv, 
ANDOTP_IV_SIZE, NULL, &err) == -1) {
         goto cleanup_before_exiting;
     }
-    g_output_stream_write (G_OUTPUT_STREAM (out_stream), enc_buf, 
json_data_size, NULL, &err);
-    if (err != NULL) {
+    if (g_output_stream_write (G_OUTPUT_STREAM (out_stream), enc_buf, 
json_data_size, NULL, &err) == -1) {
         goto cleanup_before_exiting;
     }
-    g_output_stream_write (G_OUTPUT_STREAM (out_stream), tag, ANDOTP_TAG_SIZE, 
NULL, &err);
-    if (err != NULL) {
+    if (g_output_stream_write (G_OUTPUT_STREAM (out_stream), tag, 
ANDOTP_TAG_SIZE, NULL, &err) == -1) {
         goto cleanup_before_exiting;
     }
 
     cleanup_before_exiting:
     g_free (iv);
+    g_free (salt);
     gcry_free (json_data);
+    gcry_free (derived_key);
     gcry_free (enc_buf);
     json_array_clear (array);
     g_object_unref (out_stream);
@@ -299,6 +319,7 @@
     guchar *derived_key = gcry_malloc_secure (32);
     if (gcry_kdf_derive (password, (gsize) g_utf8_strlen (password, -1), 
GCRY_KDF_PBKDF2, GCRY_MD_SHA1,
                          salt, ANDOTP_SALT_SIZE, iterations, 32, derived_key) 
!= 0) {
+        gcry_free (derived_key);
         return NULL;
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/common/common.c 
new/OTPClient-3.1.1/src/common/common.c
--- old/OTPClient-3.1.0/src/common/common.c     2022-12-19 14:16:00.000000000 
+0100
+++ new/OTPClient-3.1.1/src/common/common.c     2022-12-28 17:02:45.000000000 
+0100
@@ -2,6 +2,7 @@
 #include <sys/resource.h>
 #include <cotp.h>
 #include <baseencode.h>
+#include <glib/gi18n.h>
 #include "gcrypt.h"
 #include "jansson.h"
 #include "../google-migration.pb-c.h"
@@ -92,7 +93,9 @@
             json_int_t v = json_integer_value (value);
             g_snprintf (tmp_string + strlen (tmp_string), 256, "%ld", (gint64) 
v);
         } else {
-            g_strlcat (tmp_string, json_string_value (value), 256);
+            if (g_strlcat (tmp_string, json_string_value (value), 256) > 256) {
+                g_printerr ("%s\n", _("Truncation occurred."));
+            }
         }
     }
 
@@ -127,9 +130,9 @@
         }
     }
     sec_buf[pos] = '\0';
-    gcry_realloc (sec_buf, g_utf8_strlen(sec_buf, -1) + 1);
+    gchar *secubf_newpos = (gchar *)gcry_realloc (sec_buf, 
g_utf8_strlen(sec_buf, -1) + 1);
 
-    return sec_buf;
+    return secubf_newpos;
 }
 
 
@@ -169,6 +172,139 @@
 }
 
 
+// Backported from Glib 2.68 in order to support Debian "bullseye" and Ubuntu 
20.04
+guint
+g_string_replace_backported (GString     *string,
+                             const gchar *find,
+                             const gchar *replace,
+                             guint        limit)
+{
+    gsize f_len, r_len, pos;
+    gchar *cur, *next;
+    guint n = 0;
+
+    g_return_val_if_fail (string != NULL, 0);
+    g_return_val_if_fail (find != NULL, 0);
+    g_return_val_if_fail (replace != NULL, 0);
+
+    f_len = strlen (find);
+    r_len = strlen (replace);
+    cur = string->str;
+
+    while ((next = strstr (cur, find)) != NULL)
+    {
+        pos = next - string->str;
+        g_string_erase (string, (gssize)pos, (gssize)f_len);
+        g_string_insert (string, (gssize)pos, replace);
+        cur = string->str + pos + r_len;
+        n++;
+        /* Only match the empty string once at any given position, to
+         * avoid infinite loops */
+        if (f_len == 0)
+        {
+            if (cur[0] == '\0')
+                break;
+            else
+                cur++;
+        }
+        if (n == limit)
+            break;
+    }
+
+    return n;
+}
+
+
+// Backported from Glib. The only difference is that it's using gcrypt to 
allocate a secure buffer.
+static int
+unescape_character (const char *scanner)
+{
+    int first_digit;
+    int second_digit;
+
+    first_digit = g_ascii_xdigit_value (*scanner++);
+    if (first_digit < 0)
+        return -1;
+
+    second_digit = g_ascii_xdigit_value (*scanner++);
+    if (second_digit < 0)
+        return -1;
+
+    return (first_digit << 4) | second_digit;
+}
+
+
+// Backported from Glib. The only difference is that it's using gcrypt to 
allocate a secure buffer.
+gchar *
+g_uri_unescape_string_secure (const gchar *escaped_string,
+                              const gchar *illegal_characters)
+{
+    if (escaped_string == NULL)
+        return NULL;
+
+    const gchar *escaped_string_end = escaped_string + strlen (escaped_string);
+
+    gchar *result = gcry_calloc_secure (escaped_string_end - escaped_string + 
1, 1);
+    gchar *out = result;
+
+    const gchar *in;
+    gint character;
+    for (in = escaped_string; in < escaped_string_end; in++) {
+        character = *in;
+
+        if (*in == '%') {
+            in++;
+            if (escaped_string_end - in < 2) {
+                // Invalid escaped char (to short)
+                gcry_free (result);
+                return NULL;
+            }
+
+            character = unescape_character (in);
+
+            // Check for an illegal character. We consider '\0' illegal here.
+            if (character <= 0 ||
+                (illegal_characters != NULL &&
+                 strchr (illegal_characters, (char)character) != NULL)) {
+                gcry_free (result);
+                return NULL;
+            }
+
+            in++; // The other char will be eaten in the loop header
+        }
+        *out++ = (char)character;
+    }
+
+    *out = '\0';
+
+    return result;
+}
+
+
+guchar *
+g_base64_decode_secure (const gchar *text,
+                        gsize       *out_len)
+{
+    guchar *ret;
+    gsize input_length;
+    gint state = 0;
+    guint save = 0;
+
+    g_return_val_if_fail (text != NULL, NULL);
+    g_return_val_if_fail (out_len != NULL, NULL);
+
+    input_length = strlen (text);
+
+    /* We can use a smaller limit here, since we know the saved state is 0,
+       +1 used to avoid calling g_malloc0(0), and hence returning NULL */
+    ret = gcry_calloc_secure ((input_length / 4) * 3 + 1, 1);
+
+    *out_len = g_base64_decode_step (text, input_length, ret, &state, &save);
+
+    return ret;
+}
+
+
 GSList *
 decode_migration_data (const gchar *encoded_uri)
 {
@@ -178,50 +314,58 @@
     }
     encoded_uri_copy += 33;
     gsize out_len;
-    guchar *data = g_base64_decode (g_uri_unescape_string ((encoded_uri_copy), 
NULL), &out_len);
+    gchar *unesc_str = g_uri_unescape_string_secure (encoded_uri_copy, NULL);
+    guchar *data = g_base64_decode_secure (unesc_str, &out_len);
+    gcry_free (unesc_str);
 
     GSList *uris = NULL;
-    gchar *uri = NULL;
+    GString *uri = NULL;
     MigrationPayload *msg = migration_payload__unpack (NULL, out_len, data);
+    gcry_free (data);
     for (gint i = 0; i < msg->n_otp_parameters; i++) {
-        uri = g_strconcat ("otpauth://", NULL);
+        uri = g_string_new ("otpauth://");
         if (msg->otp_parameters[i]->type == 1) {
-            uri = g_strconcat (uri, "hotp/", NULL);
+            g_string_append (uri, "hotp/");
         } else if (msg->otp_parameters[i]->type == 2) {
-            uri = g_strconcat (uri, "totp/", NULL);
+            g_string_append (uri, "totp/");
         } else {
             g_printerr ("OTP type not recognized, skipping %s\n", 
msg->otp_parameters[i]->name);
             goto end;
         }
 
-        uri = g_strconcat (uri, msg->otp_parameters[i]->name, "?", NULL);
+        g_string_append (uri, msg->otp_parameters[i]->name);
+        g_string_append (uri, "?");
 
         if (msg->otp_parameters[i]->algorithm == 1) {
-            uri = g_strconcat (uri, "algorithm=SHA1&", NULL);
+            g_string_append (uri, "algorithm=SHA1&");
         } else if (msg->otp_parameters[i]->algorithm == 2) {
-            uri = g_strconcat (uri, "algorithm=SHA256&", NULL);
+            g_string_append (uri, "algorithm=SHA256&");
         } else if (msg->otp_parameters[i]->algorithm == 3) {
-            uri = g_strconcat (uri, "algorithm=SHA512&", NULL);
+            g_string_append (uri, "algorithm=SHA512&");
         } else {
             g_printerr ("Algorithm type not supported, skipping %s\n", 
msg->otp_parameters[i]->name);
             goto end;
         }
 
         if (msg->otp_parameters[i]->digits == 1) {
-            uri = g_strconcat (uri, "digits=6&", NULL);
+            g_string_append (uri, "digits=6&");
         } else if (msg->otp_parameters[i]->digits == 2) {
-            uri = g_strconcat (uri, "digits=8&", NULL);
+            g_string_append (uri, "digits=8&");
         } else {
             g_printerr ("Algorithm type not supported, skipping %s\n", 
msg->otp_parameters[i]->name);
             goto end;
         }
 
         if (msg->otp_parameters[i]->issuer != NULL) {
-            uri = g_strconcat (uri, "issuer=", msg->otp_parameters[i]->issuer, 
"&", NULL);
+            g_string_append (uri, "issuer=");
+            g_string_append (uri, msg->otp_parameters[i]->issuer);
+            g_string_append (uri, "&");
         }
 
         if (msg->otp_parameters[i]->type == 1) {
-            uri = g_strconcat (uri, "counter=", 
msg->otp_parameters[i]->counter, "&", NULL);
+            g_string_append (uri, "counter=");
+            g_string_append_printf(uri, "%ld", 
msg->otp_parameters[i]->counter);
+            g_string_append (uri, "&");
         }
 
         baseencode_error_t b_err;
@@ -231,56 +375,46 @@
             goto end;
         }
 
-        uri = g_strconcat (uri, "secret=", b32_encoded_secret, NULL);
+        g_string_append (uri, "secret=");
+        g_string_append (uri, b32_encoded_secret);
 
-        uris = g_slist_append (uris, g_strdup (uri));
+        uris = g_slist_append (uris, g_strdup (uri->str));
 
         end:
-        g_free (uri);
+        g_string_free (uri, TRUE);
     }
 
+    migration_payload__free_unpacked (msg, NULL);
+
     return uris;
 }
 
 
-// Backported from Glib 2.68 in order to support Debian "bullseye" and Ubuntu 
20.04
-guint
-g_string_replace_backported (GString     *string,
-                             const gchar *find,
-                             const gchar *replace,
-                             guint        limit)
-{
-    gsize f_len, r_len, pos;
-    gchar *cur, *next;
-    guint n = 0;
-
-    g_return_val_if_fail (string != NULL, 0);
-    g_return_val_if_fail (find != NULL, 0);
-    g_return_val_if_fail (replace != NULL, 0);
+gcry_cipher_hd_t
+open_cipher_and_set_data (guchar *derived_key,
+                          guchar *iv,
+                          gsize   iv_len)
+{
+    gcry_cipher_hd_t hd;
+    gpg_error_t gpg_err = gcry_cipher_open (&hd, GCRY_CIPHER_AES256, 
GCRY_CIPHER_MODE_GCM, GCRY_CIPHER_SECURE);
+    if (gpg_err) {
+        g_printerr ("%s\n", _("Error while opening the cipher handle."));
+        return NULL;
+    }
 
-    f_len = strlen (find);
-    r_len = strlen (replace);
-    cur = string->str;
+    gpg_err = gcry_cipher_setkey (hd, derived_key, gcry_cipher_get_algo_keylen 
(GCRY_CIPHER_AES256));
+    if (gpg_err) {
+        g_printerr ("%s\n", _("Error while setting the cipher key."));
+        gcry_cipher_close (hd);
+        return NULL;
+    }
 
-    while ((next = strstr (cur, find)) != NULL)
-    {
-        pos = next - string->str;
-        g_string_erase (string, pos, f_len);
-        g_string_insert (string, pos, replace);
-        cur = string->str + pos + r_len;
-        n++;
-        /* Only match the empty string once at any given position, to
-         * avoid infinite loops */
-        if (f_len == 0)
-        {
-            if (cur[0] == '\0')
-                break;
-            else
-                cur++;
-        }
-        if (n == limit)
-            break;
+    gpg_err = gcry_cipher_setiv (hd, iv, iv_len);
+    if (gpg_err) {
+        g_printerr ("%s\n", _("Error while setting the cipher iv."));
+        gcry_cipher_close (hd);
+        return NULL;
     }
 
-    return n;
-}
+    return hd;
+}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/common/common.h 
new/OTPClient-3.1.1/src/common/common.h
--- old/OTPClient-3.1.0/src/common/common.h     2022-12-19 14:16:00.000000000 
+0100
+++ new/OTPClient-3.1.1/src/common/common.h     2022-12-28 17:02:45.000000000 
+0100
@@ -2,6 +2,7 @@
 
 #include <glib.h>
 #include <jansson.h>
+#include <gcrypt.h>
 
 G_BEGIN_DECLS
 
@@ -38,4 +39,14 @@
                                              const gchar    *replace,
                                              guint           limit);
 
+gchar      *g_uri_unescape_string_secure    (const gchar    *escaped_string,
+                                             const gchar    
*illegal_characters);
+
+guchar     *g_base64_decode_secure          (const gchar    *text,
+                                             gsize          *out_len);
+
+gcry_cipher_hd_t open_cipher_and_set_data   (guchar         *derived_key,
+                                             guchar         *iv,
+                                             gsize           iv_len);
+
 G_END_DECLS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/common/freeotp.c 
new/OTPClient-3.1.1/src/common/freeotp.c
--- old/OTPClient-3.1.0/src/common/freeotp.c    2022-12-19 14:16:00.000000000 
+0100
+++ new/OTPClient-3.1.1/src/common/freeotp.c    2022-12-28 17:02:45.000000000 
+0100
@@ -11,9 +11,15 @@
                       GError         **err)
 {
     GSList *otps = NULL;
-    gchar *sec_buf = gcry_calloc_secure (get_file_size (path), 1);
+    goffset fs = get_file_size (path);
+    if (fs < 10) {
+        g_printerr ("Couldn't get the file size (file doesn't exit or wrong 
file selected\n");
+        return NULL;
+    }
+    gchar *sec_buf = gcry_calloc_secure (fs, 1);
     if (!g_file_get_contents (path, &sec_buf, NULL, err)) {
         g_printerr("Couldn't read into memory the freeotp txt file\n");
+        gcry_free (sec_buf);
         return NULL;
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/db-actions.c 
new/OTPClient-3.1.1/src/db-actions.c
--- old/OTPClient-3.1.0/src/db-actions.c        2022-12-19 14:16:00.000000000 
+0100
+++ new/OTPClient-3.1.1/src/db-actions.c        2022-12-28 17:02:45.000000000 
+0100
@@ -1,4 +1,5 @@
 #include <gtk/gtk.h>
+#include <glib/gi18n.h>
 #include "data.h"
 #include "message-dialogs.h"
 #include "db-actions.h"
@@ -36,8 +37,6 @@
 void
 update_cfg_file (AppData *app_data)
 {
-    GError *cfg_err = NULL;
-    gchar *msg = NULL;
     GKeyFile *kf = g_key_file_new ();
     gchar *cfg_file_path;
 #ifndef USE_FLATPAK_APP_FOLDER
@@ -45,15 +44,20 @@
 #else
     cfg_file_path = g_build_filename (g_get_user_data_dir (), "otpclient.cfg", 
NULL);
 #endif
-    g_key_file_load_from_file (kf, cfg_file_path, G_KEY_FILE_NONE, NULL);
+    if (!g_key_file_load_from_file (kf, cfg_file_path, G_KEY_FILE_NONE, NULL)) 
{
+        g_printerr ("%s\n", _("Error while loading the config file."));
+    }
     g_key_file_set_string (kf, "config", "db_path", 
app_data->db_data->db_path);
-    g_key_file_save_to_file (kf, cfg_file_path, &cfg_err);
-    if (cfg_err != NULL) {
-        msg = g_strconcat ("Couldn't save the change to the config file: ", 
&cfg_err->message, NULL);
-        show_message_dialog (app_data->main_window, msg, GTK_MESSAGE_ERROR);
-        g_free (msg);
-        g_clear_error (&cfg_err);
+    GError *cfg_err = NULL;
+    if (!g_key_file_save_to_file (kf, cfg_file_path, &cfg_err)) {
+        if (cfg_err != NULL) {
+            gchar *msg = g_strconcat ("Couldn't save the change to the config 
file: ", &cfg_err->message, NULL);
+            show_message_dialog (app_data->main_window, msg, 
GTK_MESSAGE_ERROR);
+            g_free (msg);
+            g_clear_error (&cfg_err);
+        }
     }
+
     g_free (cfg_file_path);
     g_key_file_free (kf);
 }
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/db-misc.c 
new/OTPClient-3.1.1/src/db-misc.c
--- old/OTPClient-3.1.0/src/db-misc.c   2022-12-19 14:16:00.000000000 +0100
+++ new/OTPClient-3.1.1/src/db-misc.c   2022-12-28 17:02:45.000000000 +0100
@@ -2,6 +2,7 @@
 #include <gcrypt.h>
 #include <jansson.h>
 #include <glib/gstdio.h>
+#include <glib/gi18n.h>
 #include "db-misc.h"
 #include "otpclient.h"
 #include "file-size.h"
@@ -166,7 +167,9 @@
         } else {
             g_printerr ("Couldn't update the database (encrypt_db failed)\n");
             if (g_file_test (db_data->db_path, G_FILE_TEST_EXISTS)) {
-                g_unlink (db_data->db_path);
+                if (g_unlink (db_data->db_path) == -1) {
+                    g_printerr ("%s\n", _("Error while unlinking the file."));
+                }
             }
         }
     } else {
@@ -193,7 +196,6 @@
             GError      **err)
 {
     GError *local_err = NULL;
-    gcry_cipher_hd_t hd;
     HeaderData *header_data = g_new0 (HeaderData, 1);
 
     gcry_create_nonce (header_data->iv, IV_SIZE);
@@ -224,35 +226,64 @@
     gsize input_data_len = strlen (in_memory_json) + 1;
     guchar *enc_buffer = g_malloc0 (input_data_len);
 
-    gcry_cipher_open (&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, 0);
-    gcry_cipher_setkey (hd, derived_key, gcry_cipher_get_algo_keylen 
(GCRY_CIPHER_AES256));
-    gcry_cipher_setiv (hd, header_data->iv, IV_SIZE);
-    gcry_cipher_authenticate (hd, header_data, sizeof (HeaderData));
-    gcry_cipher_encrypt (hd, enc_buffer, input_data_len, in_memory_json, 
input_data_len);
+    gcry_cipher_hd_t hd = open_cipher_and_set_data (derived_key, 
header_data->iv, IV_SIZE);
+    if (hd == NULL) {
+        gcry_free (derived_key);
+        g_free (header_data);
+        g_free (enc_buffer);
+        return NULL;
+    }
+
+    gpg_error_t gpg_err = gcry_cipher_authenticate (hd, header_data, sizeof 
(HeaderData));
+    if (gpg_err) {
+        g_printerr ("%s\n", _("Error while processing the authenticated 
data."));
+        gcry_free (derived_key);
+        g_free (header_data);
+        g_free (enc_buffer);
+        gcry_cipher_close (hd);
+        return GENERIC_ERROR;
+    }
+    gpg_err = gcry_cipher_encrypt (hd, enc_buffer, input_data_len, 
in_memory_json, input_data_len);
+    if (gpg_err) {
+        g_printerr ("%s\n", _("Error while encrypting the data."));
+        gcry_free (derived_key);
+        g_free (enc_buffer);
+        g_free (header_data);
+        gcry_cipher_close (hd);
+        return GENERIC_ERROR;
+    }
 
     guchar tag[TAG_SIZE];
-    gcry_cipher_gettag (hd, tag, TAG_SIZE); //append tag to outfile
+    gpg_err = gcry_cipher_gettag (hd, tag, TAG_SIZE); //append tag to outfile
+    if (gpg_err) {
+        g_printerr ("%s\n", _("Error while getting the tag."));
+        gcry_free (derived_key);
+        g_free (enc_buffer);
+        g_free (header_data);
+        gcry_cipher_close (hd);
+        return GENERIC_ERROR;
+    }
 
     if (g_output_stream_write (G_OUTPUT_STREAM(out_stream), enc_buffer, 
input_data_len, NULL, &local_err) == -1) {
         g_set_error (err, generic_error_gquark (), GENERIC_ERRCODE, "Failed 
while writing encrypted buffer to file");
         cleanup (out_file, out_stream, header_data, local_err);
-        gcry_cipher_close (hd);
         g_free (enc_buffer);
         gcry_free (derived_key);
+        gcry_cipher_close (hd);
         return GENERIC_ERROR;
     }
     if (g_output_stream_write (G_OUTPUT_STREAM(out_stream), tag, TAG_SIZE, 
NULL, &local_err) == -1) {
         g_set_error (err, generic_error_gquark (), GENERIC_ERRCODE, "Failed 
while writing tag data to file");
         cleanup (out_file, out_stream, header_data, local_err);
-        gcry_cipher_close (hd);
         g_free (enc_buffer);
         gcry_free (derived_key);
+        gcry_cipher_close (hd);
         return GENERIC_ERROR;
     }
 
-    gcry_cipher_close (hd);
-    gcry_free (derived_key);
     g_free (enc_buffer);
+    gcry_free (derived_key);
+    gcry_cipher_close (hd);
     cleanup (out_file, out_stream, header_data, NULL);
 
     return NULL;
@@ -264,7 +295,6 @@
             const gchar *password)
 {
     GError *err = NULL;
-    gcry_cipher_hd_t hd;
     HeaderData *header_data = g_new0 (HeaderData, 1);
 
     goffset input_file_size = get_file_size (db_path);
@@ -319,19 +349,49 @@
         return (gpointer)derived_key;
     }
 
-    gcry_cipher_open (&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, 0);
-    gcry_cipher_setkey (hd, derived_key, gcry_cipher_get_algo_keylen 
(GCRY_CIPHER_AES256));
-    gcry_cipher_setiv (hd, header_data->iv, IV_SIZE);
-    gcry_cipher_authenticate (hd, header_data, sizeof (HeaderData));
+    gcry_cipher_hd_t hd = open_cipher_and_set_data (derived_key, 
header_data->iv, IV_SIZE);
+    if (hd == NULL) {
+        gcry_free (derived_key);
+        g_free (enc_buf);
+        g_free (header_data);
+        return GENERIC_ERROR;
+    }
+
+    gpg_error_t gpg_err = gcry_cipher_authenticate (hd, header_data, sizeof 
(HeaderData));
+    if (gpg_err) {
+        g_printerr ("%s\n", _("Error while processing the authenticated 
data."));
+        gcry_free (derived_key);
+        g_free (header_data);
+        g_free (enc_buf);
+        gcry_cipher_close (hd);
+        return GENERIC_ERROR;
+    }
 
     gchar *dec_buf = gcry_calloc_secure (enc_buf_size, 1);
-    gcry_cipher_decrypt (hd, dec_buf, enc_buf_size, enc_buf, enc_buf_size);
-    if (gcry_err_code (gcry_cipher_checktag (hd, tag, TAG_SIZE)) == 
GPG_ERR_CHECKSUM) {
+    if (dec_buf == NULL) {
+        g_printerr ("%s\n", _("Error while allocating secure memory."));
+        gcry_free (derived_key);
+        g_free (header_data);
+        g_free (enc_buf);
         gcry_cipher_close (hd);
+        return GENERIC_ERROR;
+    }
+    gpg_err = gcry_cipher_decrypt (hd, dec_buf, enc_buf_size, enc_buf, 
enc_buf_size);
+    if (gpg_err) {
+        g_printerr ("%s\n", _("Error while decrypting the data."));
         gcry_free (derived_key);
+        gcry_free (dec_buf);
         g_free (header_data);
         g_free (enc_buf);
+        gcry_cipher_close (hd);
+        return GENERIC_ERROR;
+    }
+    if (gcry_err_code (gcry_cipher_checktag (hd, tag, TAG_SIZE)) == 
GPG_ERR_CHECKSUM) {
+        gcry_cipher_close (hd);
+        gcry_free (derived_key);
         gcry_free (dec_buf);
+        g_free (header_data);
+        g_free (enc_buf);
         return TAG_MISMATCH;
     }
 
@@ -353,14 +413,14 @@
 
     guchar *derived_key = gcry_malloc_secure (key_len);
     if (derived_key == NULL) {
-        g_printerr ("Couldn't allocate secure memory\n");
+        g_printerr ("%s\n", _("Couldn't allocate the needed secure memory."));
         return SECURE_MEMORY_ALLOC_ERR;
     }
 
     gpg_error_t ret = gcry_kdf_derive (pwd, pwd_len, GCRY_KDF_PBKDF2, 
GCRY_MD_SHA512, header_data->salt, KDF_SALT_SIZE, KDF_ITERATIONS, key_len, 
derived_key);
     if (ret != 0) {
         gcry_free (derived_key);
-        g_printerr ("Error during key derivation\n");
+        g_printerr ("%s\n", _("Error during key derivation."));
         return KEY_DERIV_ERR;
     }
     return derived_key;
@@ -396,7 +456,7 @@
         g_printerr ("Couldn't restore the backup file: %s\n", err->message);
         g_clear_error (&err);
     } else {
-        g_print ("Backup copy successfully restored.\n");
+        g_print ("%s\n", _("Backup copy successfully restored."));
     }
     g_object_unref (src);
     g_object_unref (dst);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/exports.c 
new/OTPClient-3.1.1/src/exports.c
--- old/OTPClient-3.1.0/src/exports.c   2022-12-19 14:16:00.000000000 +0100
+++ new/OTPClient-3.1.1/src/exports.c   2022-12-28 17:02:45.000000000 +0100
@@ -1,5 +1,6 @@
 #include <gtk/gtk.h>
 #include <jansson.h>
+#include <gcrypt.h>
 #include "password-cb.h"
 #include "message-dialogs.h"
 #include "common/exports.h"
@@ -54,6 +55,9 @@
     }
     g_free (ret_msg);
     g_free (exported_file_path);
+    if (encrypted == TRUE) {
+        gcry_free (password);
+    }
 }
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/imports.c 
new/OTPClient-3.1.1/src/imports.c
--- old/OTPClient-3.1.0/src/imports.c   2022-12-19 14:16:00.000000000 +0100
+++ new/OTPClient-3.1.1/src/imports.c   2022-12-28 17:02:45.000000000 +0100
@@ -120,6 +120,12 @@
         }
         show_message_dialog (app_data->main_window, msg, GTK_MESSAGE_ERROR);
         g_free (msg_with_err);
+        if (err != NULL){
+            g_clear_error (&err);
+        }
+        if (pwd != NULL) {
+            gcry_free (pwd);
+        }
         return FALSE;
     }
 
@@ -127,6 +133,9 @@
     if (err_msg != NULL) {
         show_message_dialog (app_data->main_window, err_msg, 
GTK_MESSAGE_ERROR);
         g_free (err_msg);
+        if (pwd != NULL) {
+            gcry_free (pwd);
+        }
         return FALSE;
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/parse-uri.c 
new/OTPClient-3.1.1/src/parse-uri.c
--- old/OTPClient-3.1.0/src/parse-uri.c 2022-12-19 14:16:00.000000000 +0100
+++ new/OTPClient-3.1.1/src/parse-uri.c 2022-12-28 17:02:45.000000000 +0100
@@ -74,7 +74,7 @@
     gchar *escaped_label = g_uri_escape_string (constructed_label, NULL, 
FALSE);
     g_string_append (uri, escaped_label);
     g_string_append (uri, "?secret=");
-    g_string_append (uri,json_string_value (json_object_get (db_obj, 
"secret")));
+    g_string_append (uri, json_string_value (json_object_get (db_obj, 
"secret")));
     if (issuer != NULL && g_ascii_strcasecmp (issuer, "steam") == 0) {
         g_string_append (uri, "&issuer=Steam");
     }
@@ -83,27 +83,32 @@
         g_string_append (uri, json_string_value (json_object_get (db_obj, 
"issuer")));
     }
 
+    gchar *str_to_append = NULL;
     g_string_append (uri, "&digits=");
-    g_string_append (uri,g_strdup_printf ("%lld", json_integer_value ( 
json_object_get (db_obj, "digits"))));
+    str_to_append = g_strdup_printf ("%lld", json_integer_value ( 
json_object_get (db_obj, "digits")));
+    g_string_append (uri,str_to_append);
+    g_free (str_to_append);
     g_string_append (uri, "&algorithm=");
     g_string_append (uri, json_string_value ( json_object_get (db_obj, 
"algo")));
 
     if (g_ascii_strcasecmp (json_string_value (json_object_get (db_obj, 
"type")), "TOTP") == 0) {
         g_string_append (uri, "&period=");
-        g_string_append (uri, g_strdup_printf ("%lld",json_integer_value ( 
json_object_get (db_obj, "period"))));
+        str_to_append = g_strdup_printf ("%lld", json_integer_value ( 
json_object_get (db_obj, "period")));
+        g_string_append (uri, str_to_append);
+        g_free (str_to_append);
     } else {
         g_string_append (uri, "&counter=");
-        g_string_append (uri, g_strdup_printf ("%lld",json_integer_value ( 
json_object_get (db_obj, "counter"))));
+        str_to_append = g_strdup_printf ("%lld", json_integer_value ( 
json_object_get (db_obj, "counter")));
+        g_string_append (uri, str_to_append);
+        g_free (str_to_append);
     }
 
     g_string_append (uri, "\n");
-    gchar *ret_uri = g_strdup (uri->str);
 
     g_free (constructed_label);
     g_free (escaped_label);
-    g_string_free (uri, TRUE);
 
-    return ret_uri;
+    return g_string_free (uri, FALSE);
 }
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/qrcode-parser.c 
new/OTPClient-3.1.1/src/qrcode-parser.c
--- old/OTPClient-3.1.0/src/qrcode-parser.c     2022-12-19 14:16:00.000000000 
+0100
+++ new/OTPClient-3.1.1/src/qrcode-parser.c     2022-12-28 17:02:45.000000000 
+0100
@@ -2,6 +2,7 @@
 #include <zbar.h>
 #include <png.h>
 #include <glib/gstdio.h>
+#include <gcrypt.h>
 #include "common/common.h"
 
 typedef struct image_data_t {
@@ -46,7 +47,9 @@
 
     const zbar_symbol_t *symbol = zbar_image_first_symbol (image);
     for (; symbol; symbol = zbar_symbol_next (symbol)) {
-        *otpauth_uri = secure_strdup (g_uri_unescape_string 
(zbar_symbol_get_data (symbol), NULL));
+        gchar *unesc_str = g_uri_unescape_string_secure (zbar_symbol_get_data 
(symbol), NULL);
+        *otpauth_uri = secure_strdup (unesc_str);
+        gcry_free (unesc_str);
     }
 
     zbar_image_destroy (image);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/settings-cb.c 
new/OTPClient-3.1.1/src/settings-cb.c
--- old/OTPClient-3.1.0/src/settings-cb.c       2022-12-19 14:16:00.000000000 
+0100
+++ new/OTPClient-3.1.1/src/settings-cb.c       2022-12-28 17:02:45.000000000 
+0100
@@ -1,4 +1,5 @@
 #include <gtk/gtk.h>
+#include <glib/gi18n.h>
 #include "otpclient.h"
 #include "message-dialogs.h"
 #include "get-builder.h"
@@ -24,6 +25,7 @@
         g_free (msg);
         g_free (cfg_file_path);
         g_key_file_free (kf);
+        g_clear_error (&err);
         return;
     }
 
@@ -79,7 +81,9 @@
             g_key_file_set_integer (kf, "config", "inactivity_timeout", 
app_data->inactivity_timeout);
             g_key_file_set_boolean (kf, "config", "dark_theme", 
app_data->use_dark_theme);
             g_key_file_set_boolean (kf, "config", "disable_secret_service", 
app_data->disable_secret_service);
-            g_key_file_save_to_file (kf, cfg_file_path, NULL);
+            if (!g_key_file_save_to_file (kf, cfg_file_path, NULL)) {
+                g_printerr ("%s\n", _("Error while saving the config file."));
+            }
             gtk_tree_view_set_search_column 
(GTK_TREE_VIEW(app_data->tree_view), app_data->search_column + 1);
             break;
         case GTK_RESPONSE_CANCEL:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/show-qr-cb.c 
new/OTPClient-3.1.1/src/show-qr-cb.c
--- old/OTPClient-3.1.0/src/show-qr-cb.c        2022-12-19 14:16:00.000000000 
+0100
+++ new/OTPClient-3.1.1/src/show-qr-cb.c        2022-12-28 17:02:45.000000000 
+0100
@@ -2,6 +2,7 @@
 #include <png.h>
 #include <qrencode.h>
 #include <glib/gstdio.h>
+#include <glib/gi18n.h>
 #include "data.h"
 #include "parse-uri.h"
 #include "get-builder.h"
@@ -45,7 +46,9 @@
         gtk_widget_destroy (diag);
         g_object_unref (pbuf);
         g_object_unref (builder);
-        g_unlink (PNG_OUT);
+        if (g_unlink (PNG_OUT) == -1) {
+            g_printerr ("%s\n", _("Couldn't unlink the PNG file."));
+        }
     }
 }
 
@@ -62,40 +65,37 @@
 write_png (const QRcode *qrcode)
 {
     guint realwidth = (qrcode->width + MARGIN * 2) * SIZE;
-    guchar *row = (guchar *)malloc ((size_t)((realwidth + 7) / 8));
+    guchar *row = (guchar *)g_malloc0 ((size_t)((realwidth + 7) / 8));
     if (row == NULL) {
         g_printerr ("Failed to allocate memory.\n");
         return -1;
     }
 
-    FILE *fp = fopen (PNG_OUT, "wb");
-    if (fp == NULL) {
-        g_printerr ("Failed to create file: %s\n", PNG_OUT);
-        perror(NULL);
-        return -1;
-    }
-
     png_structp png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, 
NULL, NULL, NULL);
     if (png_ptr == NULL) {
         g_printerr ("Failed to initialize PNG writer.\n");
+        g_free (row);
         return -1;
     }
 
     png_infop info_ptr = png_create_info_struct (png_ptr);
     if (info_ptr == NULL) {
         g_printerr ("Failed to initialize PNG write.\n");
+        g_free (row);
         return -1;
     }
 
     if (setjmp (png_jmpbuf(png_ptr))) {
         png_destroy_write_struct (&png_ptr, &info_ptr);
         g_printerr ("Failed to write PNG image.\n");
+        g_free (row);
         return -1;
     }
 
-    png_colorp palette = (png_colorp)malloc(sizeof (png_color) * 2);
+    png_colorp palette = (png_colorp)g_malloc0 (sizeof (png_color) * 2);
     if (palette == NULL) {
         g_printerr ("Failed to allocate memory.\n");
+        g_free (row);
         return -1;
     }
 
@@ -114,6 +114,12 @@
     png_set_PLTE(png_ptr, info_ptr, palette, 2);
     png_set_tRNS(png_ptr, info_ptr, alpha_values, 2, NULL);
 
+    FILE *fp = fopen (PNG_OUT, "wb");
+    if (fp == NULL) {
+        g_printerr ("Failed to create file: %s\n", PNG_OUT);
+        g_free (row);
+        return -1;
+    }
     png_init_io (png_ptr, fp);
     png_set_IHDR (png_ptr, info_ptr,
                  (guint)realwidth, (guint)realwidth,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OTPClient-3.1.0/src/webcam-add-cb.c 
new/OTPClient-3.1.1/src/webcam-add-cb.c
--- old/OTPClient-3.1.0/src/webcam-add-cb.c     2022-12-19 14:16:00.000000000 
+0100
+++ new/OTPClient-3.1.1/src/webcam-add-cb.c     2022-12-28 17:02:45.000000000 
+0100
@@ -111,7 +111,9 @@
     ConfigData *cfg_data = (ConfigData *)user_data;
     const zbar_symbol_t *symbol = zbar_image_first_symbol (image);
     for (; symbol; symbol = zbar_symbol_next (symbol)) {
-        cfg_data->otp_uri = secure_strdup (g_uri_unescape_string 
(zbar_symbol_get_data (symbol), NULL));
+        gchar *unesc_str = g_uri_unescape_string_secure (zbar_symbol_get_data 
(symbol), NULL);
+        cfg_data->otp_uri = secure_strdup (unesc_str);
         cfg_data->qrcode_found = TRUE;
+        gcry_free (unesc_str);
     }
 }

Reply via email to