summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/pychrysalide/core/Makefile.am3
-rw-r--r--plugins/pychrysalide/core/module.c2
-rw-r--r--plugins/pychrysalide/glibext/Makefile.am1
-rw-r--r--plugins/pychrysalide/glibext/module.c2
-rw-r--r--plugins/pychrysalide/glibext/secstorage.c (renamed from plugins/pychrysalide/core/secstorage.c)483
-rw-r--r--plugins/pychrysalide/glibext/secstorage.h (renamed from plugins/pychrysalide/core/secstorage.h)18
-rw-r--r--plugins/pychrysalide/helpers.h2
-rw-r--r--src/core/Makefile.am3
-rw-r--r--src/core/core.c5
-rw-r--r--src/core/global.c46
-rw-r--r--src/core/global.h7
-rw-r--r--src/glibext/Makefile.am2
-rw-r--r--src/glibext/secstorage-int.h56
-rw-r--r--src/glibext/secstorage.c (renamed from src/core/secstorage.c)263
-rw-r--r--src/glibext/secstorage.h (renamed from src/core/secstorage.h)31
-rw-r--r--tests/glibext/re.chrysalide.tests.secstorage.gschema.xml (renamed from tests/core/re.chrysalide.tests.secstorage.gschema.xml)0
-rw-r--r--tests/glibext/secstorage.py (renamed from tests/core/secstorage.py)59
17 files changed, 647 insertions, 336 deletions
diff --git a/plugins/pychrysalide/core/Makefile.am b/plugins/pychrysalide/core/Makefile.am
index 6ba9fc8..5588c9f 100644
--- a/plugins/pychrysalide/core/Makefile.am
+++ b/plugins/pychrysalide/core/Makefile.am
@@ -15,8 +15,7 @@ libpychrysacore_la_SOURCES = \
constants.h constants.c \
logs.h logs.c \
module.h module.c \
- nox.h nox.c \
- secstorage.h secstorage.c
+ nox.h nox.c
libpychrysacore_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
-I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
diff --git a/plugins/pychrysalide/core/module.c b/plugins/pychrysalide/core/module.c
index 7eceddd..4af0403 100644
--- a/plugins/pychrysalide/core/module.c
+++ b/plugins/pychrysalide/core/module.c
@@ -35,7 +35,6 @@
//#include "params.h"
//#include "processors.h"
//#include "queue.h"
-#include "secstorage.h"
#include "../helpers.h"
@@ -111,7 +110,6 @@ bool populate_core_module(void)
//if (result) result = populate_core_module_with_params();
//if (result) result = populate_core_module_with_processors();
//if (result) result = populate_core_module_with_queue();
- if (result) result = populate_core_module_with_secstorage();
assert(result);
diff --git a/plugins/pychrysalide/glibext/Makefile.am b/plugins/pychrysalide/glibext/Makefile.am
index 2d45244..af1d9f2 100644
--- a/plugins/pychrysalide/glibext/Makefile.am
+++ b/plugins/pychrysalide/glibext/Makefile.am
@@ -26,6 +26,7 @@ libpychrysaglibext_la_SOURCES = \
module.h module.c \
objhole.h objhole.c \
portion.h portion.c \
+ secstorage.h secstorage.c \
singleton.h singleton.c \
strbuilder.h strbuilder.c \
work.h work.c \
diff --git a/plugins/pychrysalide/glibext/module.c b/plugins/pychrysalide/glibext/module.c
index 8adae07..6ce0709 100644
--- a/plugins/pychrysalide/glibext/module.c
+++ b/plugins/pychrysalide/glibext/module.c
@@ -43,6 +43,7 @@
#include "hashable.h"
#include "objhole.h"
#include "portion.h"
+#include "secstorage.h"
#include "singleton.h"
#include "strbuilder.h"
#include "work.h"
@@ -121,6 +122,7 @@ bool populate_glibext_module(void)
if (result) result = ensure_python_thick_object_is_registered();
if (result) result = ensure_python_binary_portion_is_registered();
if (result) result = ensure_python_generic_work_is_registered();
+ if (result) result = ensure_python_secret_storage_is_registered();
if (result) result = ensure_python_singleton_factory_is_registered();
if (result) result = ensure_python_work_queue_is_registered();
diff --git a/plugins/pychrysalide/core/secstorage.c b/plugins/pychrysalide/glibext/secstorage.c
index 67779af..b5adb7c 100644
--- a/plugins/pychrysalide/core/secstorage.c
+++ b/plugins/pychrysalide/glibext/secstorage.c
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * secstorage.c - équivalent Python du fichier "core/secstorage.c"
+ * secstorage.c - équivalent Python du fichier "glibext/secstorage.c"
*
* Copyright (C) 2025 Cyrille Bagard
*
@@ -25,7 +25,11 @@
#include "secstorage.h"
-#include <core/secstorage.h>
+#include <assert.h>
+#include <pygobject.h>
+
+
+#include <glibext/secstorage-int.h>
#include "../access.h"
@@ -34,76 +38,107 @@
-/* Détermine si une clef de chiffrement protégée est en place. */
-static PyObject *py_secstorage_has_secret_storage_key(PyObject *, PyObject *);
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+CREATE_DYN_CONSTRUCTOR(secret_storage, G_TYPE_SECRET_STORAGE);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_secret_storage_init(PyObject *, PyObject *, PyObject *);
-/* Définit un mot de passe pour protéger une clef maître. */
-static PyObject *py_secstorage_set_secret_storage_password(PyObject *, PyObject *);
-/* Détermine si la clef de chiffrement maître est vérouillée. */
-static PyObject *py_secstorage_is_secret_storage_locked(PyObject *, PyObject *);
+
+/* ------------------------- CONNEXION AVEC L'API DE PYTHON ------------------------- */
+
+
+/* Définit un mot de passe pour protéger une clef maître. */
+static PyObject *py_secret_storage_set_password(PyObject *, PyObject *);
/* Déverrouille la clef de chiffrement maître. */
-static PyObject *py_secstorage_unlock_secret_storage(PyObject *, PyObject *);
+static PyObject *py_secret_storage_unlock(PyObject *, PyObject *);
/* Verrouille la clef de chiffrement maître. */
-static PyObject *py_secstorage_lock_secret_storage(PyObject *, PyObject *);
+static PyObject *py_secret_storage_lock(PyObject *, PyObject *);
/* Chiffre des données avec la clef de chiffrement maître. */
-static PyObject *py_secstorage_encrypt_secret_storage_data(PyObject *, PyObject *);
+static PyObject *py_secret_storage_encrypt_data(PyObject *, PyObject *);
/* Déchiffre des données avec la clef de chiffrement maître. */
-static PyObject *py_secstorage_decrypt_secret_storage_data(PyObject *, PyObject *);
+static PyObject *py_secret_storage_decrypt_data(PyObject *, PyObject *);
+/* Détermine si une clef de chiffrement protégée est en place. */
+static PyObject *py_secret_storage_has_key(PyObject *, void *);
+
+/* Détermine si la clef de chiffrement maître est vérouillée. */
+static PyObject *py_secret_storage_is_locked(PyObject *, void *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : self = objet Python concerné par l'appel. *
+* Paramètres : self = objet à initialiser (théoriquement). *
* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
* *
-* Description : Détermine si un mot de passe est actuellement en place. *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
* *
-* Retour : Bilan de l'analyse. *
+* Retour : 0. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_secstorage_has_secret_storage_key(PyObject *self, PyObject *args)
+static int py_secret_storage_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- PyObject *result; /* Conversion à retourner */
GSettings *settings; /* Configuration à considérer */
int ret; /* Bilan de lecture des args. */
- bool status; /* Bilan de situation */
+ GSecretStorage *storage; /* Stockage natif à manipuler */
+
+#define SECRET_STORAGE_DOC \
+ "SecretStorage acts as guardian for secrets using ecryption," \
+ " mainly for sensitive information stored as configuration" \
+ " parameters.\n" \
+ "\n" \
+ "Instances can be created using the following constructor:\n" \
+ "\n" \
+ " SecretStorage(settings)" \
+ "\n" \
+ "The *settings* arguement must point to a GSettings intance;" \
+ " the main configuration settings are used by default." \
-#define SECSTORAGE_HAS_SECRET_STORAGE_KEY_METHOD PYTHON_METHOD_DEF \
-( \
- has_secret_storage_key, "/, settings=None", \
- METH_VARARGS, py_secstorage, \
- "Indicate if a master key used for protecting secrets seems to have"\
- " been defined.\n" \
- "\n" \
- "The *settings* arguement must point to a GSettings intance; the" \
- " main configuration settings are used by default.\n" \
- "\n" \
- "The result is a boolean status: *True* if the master key seems" \
- " to exist, *False* otherwise." \
-)
+ settings = NULL;
- ret = PyArg_ParseTuple(args, "O&", convert_to_gsettings, &settings);
- if (!ret) return NULL;
+ ret = PyArg_ParseTuple(args, "|O&", convert_to_gsettings, &settings);
+ if (!ret) return -1;
- status = has_secret_storage_key(settings);
+ /* Initialisation d'un objet GLib */
- result = status ? Py_True : Py_False;
- Py_INCREF(result);
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
- return result;
+ /* Eléments de base */
+
+ storage = G_SECRET_STORAGE(pygobject_get(self));
+
+ if (!g_secret_storage_create(storage, settings))
+ return -1;
+
+ return 0;
}
+
+/* ---------------------------------------------------------------------------------- */
+/* CONNEXION AVEC L'API DE PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
* Paramètres : self = objet Python concerné par l'appel. *
@@ -117,85 +152,35 @@ static PyObject *py_secstorage_has_secret_storage_key(PyObject *self, PyObject *
* *
******************************************************************************/
-static PyObject *py_secstorage_set_secret_storage_password(PyObject *self, PyObject *args)
+static PyObject *py_secret_storage_set_password(PyObject *self, PyObject *args)
{
PyObject *result; /* Conversion à retourner */
- GSettings *settings; /* Configuration à considérer */
const char *passwd; /* Mot de passe associé */
int ret; /* Bilan de lecture des args. */
+ GSecretStorage *storage; /* Stockage sécurisé visé */
bool status; /* Bilan de situation */
-#define SECSTORAGE_SET_SECRET_STORAGE_PASSWORD_METHOD PYTHON_METHOD_DEF \
+#define SECRET_STORAGE_SET_PASSWORD_METHOD PYTHON_METHOD_DEF \
( \
- set_secret_storage_password, "/, settings=None, password=''", \
- METH_VARARGS, py_secstorage, \
+ set_password, "/, password=''", \
+ METH_VARARGS, py_secret_storage, \
"Create a master key used for protecting secrets. This key is" \
" itself protected by the provided password.\n" \
"\n" \
- "The *settings* arguement must point to a GSettings intance; the" \
- " main configuration settings are used by default. The supplied" \
- " *password* has to be a string.\n" \
+ "The supplied *password* has to be a string.\n" \
"\n" \
"The result is a boolean status: *True* if the operation successed,"\
" *False* otherwise." \
)
- settings = NULL;
passwd = "";
- ret = PyArg_ParseTuple(args, "|O&s", convert_to_gsettings, &settings, &passwd);
+ ret = PyArg_ParseTuple(args, "|s", &passwd);
if (!ret) return NULL;
- status = set_secret_storage_password(settings, passwd);
-
- result = status ? Py_True : Py_False;
- Py_INCREF(result);
-
- return result;
-
-}
+ storage = G_SECRET_STORAGE(pygobject_get(self));
-
-/******************************************************************************
-* *
-* Paramètres : self = objet Python concerné par l'appel. *
-* args = arguments fournis à l'appel. *
-* *
-* Description : Détermine si la clef de chiffrement maître est vérouillée. *
-* *
-* Retour : Bilan de la détermination. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_secstorage_is_secret_storage_locked(PyObject *self, PyObject *args)
-{
- PyObject *result; /* Conversion à retourner */
- GSettings *settings; /* Configuration à considérer */
- int ret; /* Bilan de lecture des args. */
- bool status; /* Bilan de situation */
-
-#define SECSTORAGE_IS_SECRET_STORAGE_LOCKED_METHOD PYTHON_METHOD_DEF \
-( \
- is_secret_storage_locked, "/, settings=None", \
- METH_VARARGS, py_secstorage, \
- "Indicate if the master key used for protecting secrets is" \
- " currently decrypted in memory.\n" \
- "\n" \
- "The *settings* arguement must point to a GSettings intance; the" \
- " main configuration settings are used by default.\n" \
- "\n" \
- "The result is a boolean status: *True* if the master key is" \
- " unlocked and ready for use, *False* otherwise." \
-)
-
- settings = NULL;
-
- ret = PyArg_ParseTuple(args, "|O&", convert_to_gsettings, &settings);
- if (!ret) return NULL;
-
- status = is_secret_storage_locked(settings);
+ status = g_secret_storage_set_password(storage, passwd);
result = status ? Py_True : Py_False;
Py_INCREF(result);
@@ -218,35 +203,35 @@ static PyObject *py_secstorage_is_secret_storage_locked(PyObject *self, PyObject
* *
******************************************************************************/
-static PyObject *py_secstorage_unlock_secret_storage(PyObject *self, PyObject *args)
+static PyObject *py_secret_storage_unlock(PyObject *self, PyObject *args)
{
PyObject *result; /* Conversion à retourner */
- GSettings *settings; /* Configuration à considérer */
const char *passwd; /* Mot de passe associé */
int ret; /* Bilan de lecture des args. */
+ GSecretStorage *storage; /* Stockage sécurisé visé */
bool status; /* Bilan de situation */
-#define SECSTORAGE_UNLOCK_SECRET_STORAGE_METHOD PYTHON_METHOD_DEF \
+#define SECRET_STORAGE_UNLOCK_METHOD PYTHON_METHOD_DEF \
( \
- unlock_secret_storage, "/, settings=None, password=''", \
- METH_VARARGS, py_secstorage, \
+ unlock, "/, password=''", \
+ METH_VARARGS, py_secret_storage, \
"Decrypt in memory the master key used for protecting secrets.\n" \
"\n" \
- "The *settings* arguement must point to a GSettings intance; the" \
- " main configuration settings are used by default. The supplied" \
- " *password* is the primary password used to protect this key.\n" \
+ "The supplied *password* is the primary password used to protect" \
+ " this key.\n" \
"\n" \
"The result is a boolean status: *True* if the operation successed" \
" or if the master key is already unlocked, *False* otherwise." \
)
- settings = NULL;
passwd = "";
- ret = PyArg_ParseTuple(args, "|O&s", convert_to_gsettings, &settings, &passwd);
+ ret = PyArg_ParseTuple(args, "|s", &passwd);
if (!ret) return NULL;
- status = unlock_secret_storage(settings, passwd);
+ storage = G_SECRET_STORAGE(pygobject_get(self));
+
+ status = g_secret_storage_unlock(storage, passwd);
result = status ? Py_True : Py_False;
Py_INCREF(result);
@@ -269,28 +254,21 @@ static PyObject *py_secstorage_unlock_secret_storage(PyObject *self, PyObject *a
* *
******************************************************************************/
-static PyObject *py_secstorage_lock_secret_storage(PyObject *self, PyObject *args)
+static PyObject *py_secret_storage_lock(PyObject *self, PyObject *args)
{
PyObject *result; /* Conversion à retourner */
- GSettings *settings; /* Configuration à considérer */
- int ret; /* Bilan de lecture des args. */
+ GSecretStorage *storage; /* Stockage sécurisé visé */
-#define SECSTORAGE_LOCK_SECRET_STORAGE_METHOD PYTHON_METHOD_DEF \
-( \
- lock_secret_storage, "/, settings=None", \
- METH_VARARGS, py_secstorage, \
- "Clear from memory the master key used for protecting secrets.\n" \
- "\n" \
- "The *settings* arguement must point to a GSettings intance; the" \
- " main configuration settings are used by default." \
+#define SECRET_STORAGE_LOCK_METHOD PYTHON_METHOD_DEF \
+( \
+ lock, "", \
+ METH_NOARGS, py_secret_storage, \
+ "Clear from memory the master key used for protecting secrets." \
)
- settings = NULL;
+ storage = G_SECRET_STORAGE(pygobject_get(self));
- ret = PyArg_ParseTuple(args, "|O&", convert_to_gsettings, &settings);
- if (!ret) return NULL;
-
- lock_secret_storage(settings);
+ g_secret_storage_lock(storage);
result = Py_None;
Py_INCREF(result);
@@ -313,39 +291,38 @@ static PyObject *py_secstorage_lock_secret_storage(PyObject *self, PyObject *arg
* *
******************************************************************************/
-static PyObject *py_secstorage_encrypt_secret_storage_data(PyObject *self, PyObject *args)
+static PyObject *py_secret_storage_encrypt_data(PyObject *self, PyObject *args)
{
PyObject *result; /* Conversion à retourner */
const char *data_in; /* Données d'entrée à chiffrer */
Py_ssize_t size_in; /* Quantité de ces données */
- GSettings *settings; /* Configuration à considérer */
int ret; /* Bilan de lecture des args. */
sized_binary_t in; /* Données à chiffer */
+ GSecretStorage *storage; /* Stockage sécurisé visé */
bool status; /* Bilan de situation */
sized_binary_t out; /* Données chiffrées */
-#define SECSTORAGE_ENCRYPT_SECRET_STORAGE_DATA_METHOD PYTHON_METHOD_DEF \
+#define SECRET_STORAGE_ENCRYPT_DATA_METHOD PYTHON_METHOD_DEF \
( \
- encrypt_secret_storage_data, "data, /, settings=None", \
- METH_VARARGS, py_secstorage, \
+ encrypt_data, "data", \
+ METH_VARARGS, py_secret_storage, \
"Encrypt data using an unlocked the master key.\n" \
"\n" \
- "The *settings* arguement must point to a GSettings intance; the" \
- " main configuration settings are used by default." \
+ "The *data* arguement points to bytes to process." \
"\n" \
- "The result is either encrypted data as bytes in case of success," \
+ "The result is either encrypted *data* as bytes in case of success,"\
" or *None* in case of failure." \
)
- settings = NULL;
-
- ret = PyArg_ParseTuple(args, "s#|O&", &data_in, &size_in, convert_to_gsettings, &settings);
+ ret = PyArg_ParseTuple(args, "s#", &data_in, &size_in);
if (!ret) return NULL;
in.static_data = data_in;
in.size = size_in;
- status = encrypt_secret_storage_data(settings, &in, &out);
+ storage = G_SECRET_STORAGE(pygobject_get(self));
+
+ status = g_secret_storage_encrypt_data(storage, &in, &out);
if (status)
{
@@ -377,39 +354,38 @@ static PyObject *py_secstorage_encrypt_secret_storage_data(PyObject *self, PyObj
* *
******************************************************************************/
-static PyObject *py_secstorage_decrypt_secret_storage_data(PyObject *self, PyObject *args)
+static PyObject *py_secret_storage_decrypt_data(PyObject *self, PyObject *args)
{
PyObject *result; /* Conversion à retourner */
const char *data_in; /* Données d'entrée à chiffrer */
Py_ssize_t size_in; /* Quantité de ces données */
- GSettings *settings; /* Configuration à considérer */
int ret; /* Bilan de lecture des args. */
sized_binary_t in; /* Données à chiffer */
+ GSecretStorage *storage; /* Stockage sécurisé visé */
bool status; /* Bilan de situation */
sized_binary_t out; /* Données chiffrées */
-#define SECSTORAGE_DECRYPT_SECRET_STORAGE_DATA_METHOD PYTHON_METHOD_DEF \
+#define SECRET_STORAGE_DECRYPT_DATA_METHOD PYTHON_METHOD_DEF \
( \
- decrypt_secret_storage_data, "data, /, settings=None", \
- METH_VARARGS, py_secstorage, \
+ decrypt_data, "data", \
+ METH_VARARGS, py_secret_storage, \
"Decrypt data using an unlocked the master key.\n" \
"\n" \
- "The *settings* arguement must point to a GSettings intance; the" \
- " main configuration settings are used by default." \
+ "The *data* arguement points to bytes to process." \
"\n" \
- "The result is either decrypted data as bytes in case of success," \
+ "The result is either decrypted *data* as bytes in case of success,"\
" or *None* in case of failure." \
)
- settings = NULL;
-
- ret = PyArg_ParseTuple(args, "s#|O&", &data_in, &size_in, convert_to_gsettings, &settings);
+ ret = PyArg_ParseTuple(args, "s#", &data_in, &size_in);
if (!ret) return NULL;
in.static_data = data_in;
in.size = size_in;
- status = decrypt_secret_storage_data(settings, &in, &out);
+ storage = G_SECRET_STORAGE(pygobject_get(self));
+
+ status = g_secret_storage_decrypt_data(storage, &in, &out);
if (status)
{
@@ -430,35 +406,218 @@ static PyObject *py_secstorage_decrypt_secret_storage_data(PyObject *self, PyObj
/******************************************************************************
* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Détermine si une clef de chiffrement protégée est en place. *
+* *
+* Retour : Bilan de l'analyse. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_secret_storage_has_key(PyObject *self, void *closure)
+{
+ PyObject *result; /* Instance Python à retourner */
+ GSecretStorage *storage; /* Stockage sécurisé visé */
+ bool status; /* Bilan de consultation */
+
+#define PY_SECRET_STORAGE_HAS_KEY_ATTRIB PYTHON_HAS_DEF_FULL \
+( \
+ key, py_secret_storage, \
+ "Indicate if a master key used for protecting secrets seems to have"\
+ " been defined. Without any unlocking attempt, the test only relies"\
+ " on the length of saved master data.\n" \
+ "\n" \
+ "The returned status is a boolean status: *True* if the master key" \
+ " seems to exist, *False* otherwise." \
+)
+
+ storage = G_SECRET_STORAGE(pygobject_get(self));
+
+ status = g_secret_storage_has_key(storage);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Détermine si la clef de chiffrement maître est vérouillée. *
+* *
+* Retour : Bilan de la détermination. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_secret_storage_is_locked(PyObject *self, void *closure)
+{
+ PyObject *result; /* Instance Python à retourner */
+ GSecretStorage *storage; /* Stockage sécurisé visé */
+ bool status; /* Bilan de consultation */
+
+#define SECRET_STORAGE_IS_LOCKED_ATTRIB PYTHON_IS_DEF_FULL \
+( \
+ locked, py_secret_storage, \
+ "Indicate if the master key used for protecting secrets is" \
+ " currently decrypted in memory.\n" \
+ "\n" \
+ "The *settings* arguement must point to a GSettings intance; the" \
+ " main configuration settings are used by default.\n" \
+ "\n" \
+ "The returned status is a boolean status: *True* if the master key" \
+ " is unlocked and ready for use, *False* otherwise." \
+)
+
+ storage = G_SECRET_STORAGE(pygobject_get(self));
+
+ status = g_secret_storage_is_locked(storage);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : - *
* *
-* Description : Définit une extension du module 'core' à compléter. *
+* Description : Fournit un accès à une définition de type à diffuser. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : Définition d'objet pour Python. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool populate_core_module_with_secstorage(void)
+PyTypeObject *get_python_secret_storage_type(void)
{
- bool result; /* Bilan à retourner */
- PyObject *module; /* Module à recompléter */
+ static PyMethodDef py_secret_storage_methods[] = {
+ SECRET_STORAGE_SET_PASSWORD_METHOD,
+ SECRET_STORAGE_UNLOCK_METHOD,
+ SECRET_STORAGE_LOCK_METHOD,
+ SECRET_STORAGE_ENCRYPT_DATA_METHOD,
+ SECRET_STORAGE_DECRYPT_DATA_METHOD,
+ { NULL }
+ };
- static PyMethodDef py_secstorage_methods[] = {
- SECSTORAGE_HAS_SECRET_STORAGE_KEY_METHOD,
- SECSTORAGE_SET_SECRET_STORAGE_PASSWORD_METHOD,
- SECSTORAGE_IS_SECRET_STORAGE_LOCKED_METHOD,
- SECSTORAGE_UNLOCK_SECRET_STORAGE_METHOD,
- SECSTORAGE_LOCK_SECRET_STORAGE_METHOD,
- SECSTORAGE_ENCRYPT_SECRET_STORAGE_DATA_METHOD,
- SECSTORAGE_DECRYPT_SECRET_STORAGE_DATA_METHOD,
+ static PyGetSetDef py_secret_storage_getseters[] = {
+ PY_SECRET_STORAGE_HAS_KEY_ATTRIB,
+ SECRET_STORAGE_IS_LOCKED_ATTRIB,
{ NULL }
};
- module = get_access_to_python_module("pychrysalide.core");
+ static PyTypeObject py_secret_storage_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.glibext.SecretStorage",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = SECRET_STORAGE_DOC,
+
+ .tp_methods = py_secret_storage_methods,
+ .tp_getset = py_secret_storage_getseters,
+
+ .tp_init = py_secret_storage_init,
+ .tp_new = py_secret_storage_new,
+
+ };
+
+ return &py_secret_storage_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.glibext.SecretStorage'.*
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool ensure_python_secret_storage_is_registered(void)
+{
+ PyTypeObject *type; /* Type Python 'SecretStorage' */
+ PyObject *module; /* Module à recompléter */
+ PyObject *dict; /* Dictionnaire du module */
+
+ type = get_python_secret_storage_type();
- result = register_python_module_methods(module, py_secstorage_methods);
+ if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+ {
+ module = get_access_to_python_module("pychrysalide.glibext");
+
+ dict = PyModule_GetDict(module);
+
+ if (!register_class_for_pygobject(dict, G_TYPE_SECRET_STORAGE, type))
+ return false;
+
+ }
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : arg = argument quelconque à tenter de convertir. *
+* dst = destination des valeurs récupérées en cas de succès. *
+* *
+* Description : Tente de convertir en gardien des secrets avec stockage. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_secret_storage(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_secret_storage_type());
+
+ switch (result)
+ {
+ case -1:
+ /* L'exception est déjà fixée par Python */
+ result = 0;
+ break;
+
+ case 0:
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to secret storage");
+ break;
+
+ case 1:
+ *((GSecretStorage **)dst) = G_SECRET_STORAGE(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
return result;
diff --git a/plugins/pychrysalide/core/secstorage.h b/plugins/pychrysalide/glibext/secstorage.h
index d05d052..68726c3 100644
--- a/plugins/pychrysalide/core/secstorage.h
+++ b/plugins/pychrysalide/glibext/secstorage.h
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * secstorage.h - prototypes pour l'équivalent Python du fichier "core/secstorage.h"
+ * secstorage.h - prototypes pour l'équivalent Python du fichier "glibext/secstorage.h"
*
* Copyright (C) 2025 Cyrille Bagard
*
@@ -22,8 +22,8 @@
*/
-#ifndef _PLUGINS_PYCHRYSALIDE_CORE_SECSTORAGE_H
-#define _PLUGINS_PYCHRYSALIDE_CORE_SECSTORAGE_H
+#ifndef _PLUGINS_PYCHRYSALIDE_GLIBEXT_SECSTORAGE_H
+#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_SECSTORAGE_H
#include <Python.h>
@@ -31,9 +31,15 @@
-/* Définit une extension du module 'core' à compléter. */
-bool populate_core_module_with_secstorage(void);
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_secret_storage_type(void);
+/* Prend en charge l'objet 'pychrysalide.glibext.SecretStorage'. */
+bool ensure_python_secret_storage_is_registered(void);
+/* Tente de convertir en gardien des secrets avec stockage. */
+int convert_to_secret_storage(PyObject *, void *);
-#endif /* _PLUGINS_PYCHRYSALIDE_CORE_SECSTORAGE_H */
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_GLIBEXT_SECSTORAGE_H */
diff --git a/plugins/pychrysalide/helpers.h b/plugins/pychrysalide/helpers.h
index 0aaf976..745d013 100644
--- a/plugins/pychrysalide/helpers.h
+++ b/plugins/pychrysalide/helpers.h
@@ -132,7 +132,7 @@ bool register_python_module_object(PyObject *, PyTypeObject *);
PYTHON_GETSET_DEF("is_" #name, base ## _is_ ## name, NULL, ATTRIB_RO doc, NULL)
#define PYTHON_HAS_DEF_FULL(name, base, doc) \
- PYTHON_GETSET_DEF(#name, base ## _has_ ## name, NULL, ATTRIB_RO doc, NULL)
+ PYTHON_GETSET_DEF("has_" #name, base ## _has_ ## name, NULL, ATTRIB_RO doc, NULL)
#define PYTHON_RAWGET_DEF_FULL(name, base, doc) \
PYTHON_GETSET_DEF(#name, base ## _ ## name, NULL, ATTRIB_RO doc, NULL)
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index 906c383..17fd2bf 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -20,8 +20,7 @@ libcore4_la_SOURCES = \
logs.h logs.c \
nox.h nox.c \
nproc.h nproc.c \
- paths.h paths.c \
- secstorage.h secstorage.c
+ paths.h paths.c
libcore4_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBSSL_CFLAGS)
diff --git a/src/core/core.c b/src/core/core.c
index eaf7763..8fe12f5 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -25,7 +25,6 @@
#include "global.h"
-#include "secstorage.h"
@@ -54,7 +53,7 @@ bool load_core_components(AvailableCoreComponent flags)
if ((flags & ACC_GLOBAL_VARS) != 0 && (__loaded & ACC_GLOBAL_VARS) == 0)
{
- init_secret_storage();
+ set_secret_storage(g_secret_storage_new(NULL));
set_work_queue(g_work_queue_new());
@@ -85,7 +84,7 @@ void unload_core_components(AvailableCoreComponent flags)
{
set_work_queue(NULL);
- exit_secret_storage();
+ set_secret_storage(NULL);
__loaded &= ~ACC_GLOBAL_VARS;
diff --git a/src/core/global.c b/src/core/global.c
index d38656b..0275e09 100644
--- a/src/core/global.c
+++ b/src/core/global.c
@@ -36,6 +36,9 @@ static size_t _bytes_sent = 0;
/* Gestionnaire de tâches parallèles */
static GWorkQueue *_queue = NULL;
+/* Gardien des secrets avec support des stockages */
+static GSecretStorage *_storage = NULL;
+
/******************************************************************************
@@ -131,6 +134,49 @@ GWorkQueue *get_work_queue(void)
}
+/******************************************************************************
+* *
+* Paramètres : queue = nouveau stockage sécurisé à mémoriser ou NULL. *
+* *
+* Description : Définit le stockage sécurisé principal. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void set_secret_storage(/* __steal */GSecretStorage *storage)
+{
+ if (_storage != NULL)
+ unref_object(_storage);
+
+ _storage = storage;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit le stockage sécurisé principal. *
+* *
+* Retour : Gestionnaire de traitements parallèles courant. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GSecretStorage *get_secret_storage(void)
+{
+ ref_object(_storage);
+
+ return _storage;
+
+}
+
+
diff --git a/src/core/global.h b/src/core/global.h
index b861ad8..f5d8a62 100644
--- a/src/core/global.h
+++ b/src/core/global.h
@@ -25,6 +25,7 @@
#define _CORE_GLOBAL_H
+#include "../glibext/secstorage.h"
#include "../glibext/workqueue.h"
@@ -41,6 +42,12 @@ void set_work_queue(/* __steal */GWorkQueue *);
/* Fournit le gestionnaire de traitements parallèles courant. */
GWorkQueue *get_work_queue(void);
+/* Définit le stockage sécurisé principal. */
+void set_secret_storage(/* __steal */GSecretStorage *);
+
+/* Fournit le stockage sécurisé principal. */
+GSecretStorage *get_secret_storage(void);
+
diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am
index 2e9e86d..81d13d2 100644
--- a/src/glibext/Makefile.am
+++ b/src/glibext/Makefile.am
@@ -47,6 +47,8 @@ libglibext_la_SOURCES = \
objhole.h objhole.c \
portion-int.h \
portion.h portion.c \
+ secstorage-int.h \
+ secstorage.h secstorage.c \
singleton-int.h \
singleton.h singleton.c \
strbuilder-int.h \
diff --git a/src/glibext/secstorage-int.h b/src/glibext/secstorage-int.h
new file mode 100644
index 0000000..310fbbc
--- /dev/null
+++ b/src/glibext/secstorage-int.h
@@ -0,0 +1,56 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * secstorage-int.h - définitions internes pour la conservation sécurisée d'éléments de configuration
+ *
+ * Copyright (C) 2025 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GLIBEXT_SECSTORAGE_INT_H
+#define _GLIBEXT_SECSTORAGE_INT_H
+
+
+#include "secstorage.h"
+
+
+
+/* Gardien des secrets avec support des stockages (instance) */
+struct _GSecretStorage
+{
+ GObject parent; /* A laisser en premier */
+
+ GSettings *settings; /* Configuration sollicitée */
+
+ void *master_key; /* Clef déverrouillée */
+
+};
+
+/* Gardien des secrets avec support des stockages (classe) */
+struct _GSecretStorageClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+};
+
+
+/* Met en place un gardien des secrets avec support de stockage. */
+bool g_secret_storage_create(GSecretStorage *, GSettings *);
+
+
+
+#endif /* _GLIBEXT_SECSTORAGE_INT_H */
diff --git a/src/core/secstorage.c b/src/glibext/secstorage.c
index 7f57b1c..84fc10c 100644
--- a/src/core/secstorage.c
+++ b/src/glibext/secstorage.c
@@ -30,8 +30,8 @@
#include <openssl/rand.h>
+#include "secstorage-int.h"
#include "../core/logs.h"
-#include "../glibext/helpers.h"
@@ -71,20 +71,54 @@
#define SECRET_STORAGE_IV_SIZE SECRET_STORAGE_BLOCK_SIZE
-/* Conservation des clefs de déchiffrement maîtres par configuration. */
-static GHashTable *__unlocked_keys = NULL;
+/* Initialise la classe des stockages de secrets. */
+static void g_secret_storage_class_init(GSecretStorageClass *);
-/* Fournit l'espace de configuration réel à manipuler. */
-static GSettings *get_secret_storage_settings(GSettings *);
+/* Initialise une instance de stockage de secrets. */
+static void g_secret_storage_init(GSecretStorage *);
+/* Supprime toutes les références externes. */
+static void g_secret_storage_dispose(GObject *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_secret_storage_finalize(GObject *);
+
+
+
+/* Indique le type défini pour un gardien des secrets avec support des stockages. */
+G_DEFINE_TYPE(GSecretStorage, g_secret_storage, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des stockages de secrets. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_secret_storage_class_init(GSecretStorageClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = g_secret_storage_dispose;
+ object->finalize = g_secret_storage_finalize;
+
+}
/******************************************************************************
* *
-* Paramètres : - *
+* Paramètres : storage = instance à initialiser. *
* *
-* Description : Initialise le stockage des clefs de déchiffrement en place. *
+* Description : Initialise une instance de stockage de secrets. *
* *
* Retour : - *
* *
@@ -92,18 +126,20 @@ static GSettings *get_secret_storage_settings(GSettings *);
* *
******************************************************************************/
-void init_secret_storage(void)
+static void g_secret_storage_init(GSecretStorage *storage)
{
- __unlocked_keys = g_hash_table_new_full(g_direct_hash, g_direct_equal, g_object_unref, free);
+ storage->settings = NULL;
+
+ storage->master_key = NULL;
}
/******************************************************************************
* *
-* Paramètres : - *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
-* Description : Supprime le stockage des clefs de déchiffrement en place. *
+* Description : Supprime toutes les références externes. *
* *
* Retour : - *
* *
@@ -111,42 +147,97 @@ void init_secret_storage(void)
* *
******************************************************************************/
-void exit_secret_storage(void)
+static void g_secret_storage_dispose(GObject *object)
{
- assert(__unlocked_keys != NULL);
+ GSecretStorage *storage; /* Gestion de stockage sécurisé*/
+
+ storage = G_SECRET_STORAGE(object);
- g_hash_table_remove_all(__unlocked_keys);
- g_hash_table_unref(__unlocked_keys);
+ g_clear_object(&storage->settings);
- __unlocked_keys = NULL;
+ G_OBJECT_CLASS(g_secret_storage_parent_class)->dispose(object);
}
/******************************************************************************
* *
-* Paramètres : settings = éventuel espace de configuration à manipuler. *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
-* Description : Fournit l'espace de configuration réel à manipuler. *
+* Description : Procède à la libération totale de la mémoire. *
* *
-* Retour : Instance de travail à employer avant libération. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static GSettings *get_secret_storage_settings(GSettings *settings)
+static void g_secret_storage_finalize(GObject *object)
{
- GSettings *result; /* Instance à retourner */
+ GSecretStorage *storage; /* Gestion de stockage sécurisé*/
+
+ storage = G_SECRET_STORAGE(object);
+
+ if (storage->master_key != NULL)
+ free(storage->master_key);
+
+ G_OBJECT_CLASS(g_secret_storage_parent_class)->finalize(object);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : settings = éventuel espace de configuration à utiliser. *
+* *
+* Description : Créé un nouveau gardien des secrets avec support de stockage.*
+* *
+* Retour : Gestionnaire de stockage sécurisé mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GSecretStorage *g_secret_storage_new(GSettings *settings)
+{
+ GSecretStorage *result; /* Instance à retourner */
+
+ result = g_object_new(G_TYPE_SECRET_STORAGE, NULL);
+ if (!g_secret_storage_create(result, settings))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : storage = stockage sécurisé à initialiser. *
+* settings = éventuel espace de configuration à utiliser. *
+* *
+* Description : Met en place un gardien des secrets avec support de stockage.*
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_secret_storage_create(GSecretStorage *storage, GSettings *settings)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
if (settings != NULL)
{
ref_object(settings);
- result = settings;
+ storage->settings = settings;
}
else
- result = NULL; // TODO
+ result = false; // TODO
return result;
@@ -155,7 +246,7 @@ static GSettings *get_secret_storage_settings(GSettings *settings)
/******************************************************************************
* *
-* Paramètres : settings = éventuel espace de configuration à manipuler. *
+* Paramètres : storage = espace de stockage sécurisé à consulter. *
* *
* Description : Détermine si une clef de chiffrement protégée est en place. *
* *
@@ -165,7 +256,7 @@ static GSettings *get_secret_storage_settings(GSettings *settings)
* *
******************************************************************************/
-bool has_secret_storage_key(GSettings *settings)
+bool g_secret_storage_has_key(const GSecretStorage *storage)
{
bool result; /* Bilan à retourner */
GVariant *value; /* Valeur de configuration */
@@ -173,10 +264,7 @@ bool has_secret_storage_key(GSettings *settings)
result = false;
- settings = get_secret_storage_settings(settings);
- assert(settings != NULL);
-
- value = g_settings_get_value(settings, "master");
+ value = g_settings_get_value(storage->settings, "master");
g_variant_get_fixed_array(value, &length, 1);
@@ -184,8 +272,6 @@ bool has_secret_storage_key(GSettings *settings)
g_variant_unref(value);
- unref_object(settings);
-
return result;;
}
@@ -193,7 +279,7 @@ bool has_secret_storage_key(GSettings *settings)
/******************************************************************************
* *
-* Paramètres : settings = éventuel espace de configuration à manipuler. *
+* Paramètres : storage = espace de stockage sécurisé à consulter. *
* password = mot de passe principal à appliquer. *
* *
* Description : Définit un mot de passe pour protéger une clef maître. *
@@ -204,7 +290,7 @@ bool has_secret_storage_key(GSettings *settings)
* *
******************************************************************************/
-bool set_secret_storage_password(GSettings *settings, const char *passwd)
+bool g_secret_storage_set_password(const GSecretStorage *storage, const char *passwd)
{
bool result; /* Bilan à retourner */
unsigned char salt[SECRET_STORAGE_SALT_SIZE]; /* Sel pour la dérivation*/
@@ -220,10 +306,7 @@ bool set_secret_storage_password(GSettings *settings, const char *passwd)
result = false;
- settings = get_secret_storage_settings(settings);
- assert(settings != NULL);
-
- if (has_secret_storage_key(settings))
+ if (g_secret_storage_has_key(storage))
goto exit;
/* Création d'un sel pour la dérivation du mot de passe */
@@ -250,7 +333,7 @@ bool set_secret_storage_password(GSettings *settings, const char *passwd)
* Il n'y a donc pas lieu d'appeler g_variant_unref().
*/
- g_settings_set_value(settings, "salt", value);
+ g_settings_set_value(storage->settings, "salt", value);
/* Dérivation du mot de passe */
@@ -329,7 +412,7 @@ bool set_secret_storage_password(GSettings *settings, const char *passwd)
value = g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE,
encrypted, iter - encrypted, sizeof(unsigned char));
- g_settings_set_value(settings, "master", value);
+ g_settings_set_value(storage->settings, "master", value);
result = true;
@@ -339,8 +422,6 @@ bool set_secret_storage_password(GSettings *settings, const char *passwd)
exit:
- unref_object(settings);
-
return result;
}
@@ -348,7 +429,7 @@ bool set_secret_storage_password(GSettings *settings, const char *passwd)
/******************************************************************************
* *
-* Paramètres : settings = éventuel espace de configuration à manipuler. *
+* Paramètres : storage = espace de stockage sécurisé à consulter. *
* *
* Description : Détermine si la clef de chiffrement maître est vérouillée. *
* *
@@ -358,16 +439,11 @@ bool set_secret_storage_password(GSettings *settings, const char *passwd)
* *
******************************************************************************/
-bool is_secret_storage_locked(GSettings *settings)
+bool g_secret_storage_is_locked(const GSecretStorage *storage)
{
bool result; /* Bilan à retourner */
- settings = get_secret_storage_settings(settings);
- assert(settings != NULL);
-
- result = (g_hash_table_lookup(__unlocked_keys, settings) == NULL);
-
- unref_object(settings);
+ result = (storage->master_key == NULL);
return result;
@@ -376,7 +452,7 @@ bool is_secret_storage_locked(GSettings *settings)
/******************************************************************************
* *
-* Paramètres : settings = éventuel espace de configuration à manipuler. *
+* Paramètres : storage = espace de stockage sécurisé à manipuler. *
* password = mot de passe principal à utiliser. *
* *
* Description : Déverrouille la clef de chiffrement maître. *
@@ -387,7 +463,7 @@ bool is_secret_storage_locked(GSettings *settings)
* *
******************************************************************************/
-bool unlock_secret_storage(GSettings *settings, const char *passwd)
+bool g_secret_storage_unlock(GSecretStorage *storage, const char *passwd)
{
bool result; /* Bilan à retourner */
GVariant *salt_value; /* Valeur du sel configuré */
@@ -403,17 +479,10 @@ bool unlock_secret_storage(GSettings *settings, const char *passwd)
unsigned char key[SECRET_STORAGE_KEY_SIZE]; /* Clef maître */
unsigned char *iter; /* Tête d'écriture */
int outlen; /* Taille des données utiles */
- void *unlocked; /* Zone de conservation */
-#ifndef NDEBUG
- gboolean new; /* Validation de la création */
-#endif
result = false;
- settings = get_secret_storage_settings(settings);
- assert(settings != NULL);
-
- if (!is_secret_storage_locked(settings))
+ if (!g_secret_storage_is_locked(storage))
{
result = true;
goto quick_exit;
@@ -421,7 +490,7 @@ bool unlock_secret_storage(GSettings *settings, const char *passwd)
/* Récupération du sel mis en place */
- salt_value = g_settings_get_value(settings, "salt");
+ salt_value = g_settings_get_value(storage->settings, "salt");
salt = g_variant_get_fixed_array(salt_value, &salt_length, sizeof(bin_t));
@@ -443,7 +512,7 @@ bool unlock_secret_storage(GSettings *settings, const char *passwd)
/* Récupération des paramètres chiffrés */
- enc_value = g_settings_get_value(settings, "master");
+ enc_value = g_settings_get_value(storage->settings, "master");
encrypted = g_variant_get_fixed_array(enc_value, &enc_length, sizeof(bin_t));
@@ -495,17 +564,8 @@ bool unlock_secret_storage(GSettings *settings, const char *passwd)
/* Stockage de la clef maître en mémoire */
- ref_object(settings);
-
- unlocked = malloc(SECRET_STORAGE_KEY_SIZE);
- memcpy(unlocked, key, SECRET_STORAGE_KEY_SIZE);
-
-#ifndef NDEBUG
- new = g_hash_table_replace(__unlocked_keys, settings, unlocked);
- assert(new);
-#else
- g_hash_table_replace(__unlocked_keys, settings, unlocked);
-#endif
+ storage->master_key = malloc(SECRET_STORAGE_KEY_SIZE);
+ memcpy(storage->master_key, key, SECRET_STORAGE_KEY_SIZE);
result = true;
@@ -525,8 +585,6 @@ bool unlock_secret_storage(GSettings *settings, const char *passwd)
quick_exit:
- unref_object(settings);
-
return result;
}
@@ -534,7 +592,7 @@ bool unlock_secret_storage(GSettings *settings, const char *passwd)
/******************************************************************************
* *
-* Paramètres : settings = éventuel espace de configuration à manipuler. *
+* Paramètres : storage = espace de stockage sécurisé à manipuler. *
* *
* Description : Verrouille la clef de chiffrement maître. *
* *
@@ -544,23 +602,22 @@ bool unlock_secret_storage(GSettings *settings, const char *passwd)
* *
******************************************************************************/
-void lock_secret_storage(GSettings *settings)
+void g_secret_storage_lock(GSecretStorage *storage)
{
- settings = get_secret_storage_settings(settings);
- assert(settings != NULL);
-
- g_hash_table_remove(__unlocked_keys, settings);
-
- unref_object(settings);
+ if (storage->master_key != NULL)
+ {
+ free(storage->master_key);
+ storage->master_key = NULL;
+ }
}
/******************************************************************************
* *
-* Paramètres : settings = éventuel espace de configuration à manipuler. *
-* in = séquence d'octets à traiter. *
-* out = séquence d'octets résultantes. [OUT] *
+* Paramètres : storage = espace de stockage sécurisé à consulter. *
+* in = séquence d'octets à traiter. *
+* out = séquence d'octets résultantes. [OUT] *
* *
* Description : Chiffre des données avec la clef de chiffrement maître. *
* *
@@ -570,10 +627,9 @@ void lock_secret_storage(GSettings *settings)
* *
******************************************************************************/
-bool encrypt_secret_storage_data(GSettings *settings, const sized_binary_t *in, sized_binary_t *out)
+bool g_secret_storage_encrypt_data(const GSecretStorage *storage, const sized_binary_t *in, sized_binary_t *out)
{
bool result; /* Bilan à retourner */
- gpointer key; /* Clef de chiffrement */
unsigned char iv[SECRET_STORAGE_IV_SIZE]; /* IV associé */
int ret; /* Bilan à d'un appel */
EVP_CIPHER_CTX *ctx; /* Contexte pour le chiffrement*/
@@ -583,16 +639,11 @@ bool encrypt_secret_storage_data(GSettings *settings, const sized_binary_t *in,
result = false;
- settings = get_secret_storage_settings(settings);
- assert(settings != NULL);
-
- if (is_secret_storage_locked(settings))
+ if (g_secret_storage_is_locked(storage))
goto quick_exit;
/* Récupération de la clef maître et d'un IV de chiffrement */
- key = g_hash_table_lookup(__unlocked_keys, settings);
-
ret = RAND_bytes(iv, sizeof(iv));
if (ret != 1)
{
@@ -616,7 +667,7 @@ bool encrypt_secret_storage_data(GSettings *settings, const sized_binary_t *in,
goto exit;
}
- ret = EVP_EncryptInit_ex2(ctx, EVP_aes_256_cbc(), key, iv, NULL);
+ ret = EVP_EncryptInit_ex2(ctx, EVP_aes_256_cbc(), storage->master_key, iv, NULL);
if (ret != 1)
{
LOG_ERROR_OPENSSL;
@@ -661,8 +712,6 @@ bool encrypt_secret_storage_data(GSettings *settings, const sized_binary_t *in,
exit:
quick_exit:
- unref_object(settings);
-
return result;
}
@@ -670,9 +719,9 @@ bool encrypt_secret_storage_data(GSettings *settings, const sized_binary_t *in,
/******************************************************************************
* *
-* Paramètres : settings = éventuel espace de configuration à manipuler. *
-* in = séquence d'octets à traiter. *
-* out = séquence d'octets résultantes. [OUT] *
+* Paramètres : storage = espace de stockage sécurisé à consulter. *
+* in = séquence d'octets à traiter. *
+* out = séquence d'octets résultantes. [OUT] *
* *
* Description : Déchiffre des données avec la clef de chiffrement maître. *
* *
@@ -682,10 +731,9 @@ bool encrypt_secret_storage_data(GSettings *settings, const sized_binary_t *in,
* *
******************************************************************************/
-bool decrypt_secret_storage_data(GSettings *settings, const sized_binary_t *in, sized_binary_t *out)
+bool g_secret_storage_decrypt_data(const GSecretStorage *storage, const sized_binary_t *in, sized_binary_t *out)
{
bool result; /* Bilan à retourner */
- gpointer key; /* Clef de chiffrement */
unsigned char iv[SECRET_STORAGE_IV_SIZE]; /* IV associé */
int ret; /* Bilan à d'un appel */
EVP_CIPHER_CTX *ctx; /* Contexte pour le chiffrement*/
@@ -695,15 +743,10 @@ bool decrypt_secret_storage_data(GSettings *settings, const sized_binary_t *in,
result = false;
- settings = get_secret_storage_settings(settings);
- assert(settings != NULL);
-
- if (is_secret_storage_locked(settings))
+ if (g_secret_storage_is_locked(storage))
goto quick_exit;
- /* Récupération de la clef maître et d'un IV de chiffrement */
-
- key = g_hash_table_lookup(__unlocked_keys, settings);
+ /* Récupération d'un IV de déchiffrement */
if (in->size < SECRET_STORAGE_IV_SIZE)
goto exit;
@@ -726,7 +769,7 @@ bool decrypt_secret_storage_data(GSettings *settings, const sized_binary_t *in,
goto exit;
}
- ret = EVP_DecryptInit_ex2(ctx, EVP_aes_256_cbc(), key, iv, NULL);
+ ret = EVP_DecryptInit_ex2(ctx, EVP_aes_256_cbc(), storage->master_key, iv, NULL);
if (ret != 1)
{
LOG_ERROR_OPENSSL;
@@ -772,8 +815,6 @@ bool decrypt_secret_storage_data(GSettings *settings, const sized_binary_t *in,
exit:
quick_exit:
- unref_object(settings);
-
return result;
}
diff --git a/src/core/secstorage.h b/src/glibext/secstorage.h
index 7c27e07..a75b1a3 100644
--- a/src/core/secstorage.h
+++ b/src/glibext/secstorage.h
@@ -21,45 +21,48 @@
*/
-#ifndef _CORE_SECSTORAGE_H
-#define _CORE_SECSTORAGE_H
+#ifndef _GLIBEXT_SECSTORAGE_H
+#define _GLIBEXT_SECSTORAGE_H
#include <stdbool.h>
#include <gio/gio.h>
+#include "helpers.h"
#include "../common/szbin.h"
-/* Initialise le stockage des clefs de déchiffrement en place. */
-void init_secret_storage(void);
+#define G_TYPE_SECRET_STORAGE (g_secret_storage_get_type())
-/* Supprime le stockage des clefs de déchiffrement en place. */
-void exit_secret_storage(void);
+DECLARE_GTYPE(GSecretStorage, g_secret_storage, G, SECRET_STORAGE);
+
+
+/* Créé un nouveau gardien des secrets avec support de stockage. */
+GSecretStorage *g_secret_storage_new(GSettings *);
/* Détermine si une clef de chiffrement protégée est en place. */
-bool has_secret_storage_key(GSettings *);
+bool g_secret_storage_has_key(const GSecretStorage *);
/* Définit un mot de passe pour protéger une clef maître. */
-bool set_secret_storage_password(GSettings *, const char *);
+bool g_secret_storage_set_password(const GSecretStorage *, const char *);
/* Détermine si la clef de chiffrement maître est vérouillée. */
-bool is_secret_storage_locked(GSettings *);
+bool g_secret_storage_is_locked(const GSecretStorage *);
/* Déverrouille la clef de chiffrement maître. */
-bool unlock_secret_storage(GSettings *, const char *);
+bool g_secret_storage_unlock(GSecretStorage *, const char *);
/* Verrouille la clef de chiffrement maître. */
-void lock_secret_storage(GSettings *);
+void g_secret_storage_lock(GSecretStorage *);
/* Chiffre des données avec la clef de chiffrement maître. */
-bool encrypt_secret_storage_data(GSettings *, const sized_binary_t *, sized_binary_t *);
+bool g_secret_storage_encrypt_data(const GSecretStorage *, const sized_binary_t *, sized_binary_t *);
/* Déchiffre des données avec la clef de chiffrement maître. */
-bool decrypt_secret_storage_data(GSettings *, const sized_binary_t *, sized_binary_t *);
+bool g_secret_storage_decrypt_data(const GSecretStorage *, const sized_binary_t *, sized_binary_t *);
-#endif /* _CORE_SECSTORAGE_H */
+#endif /* _GLIBEXT_SECSTORAGE_H */
diff --git a/tests/core/re.chrysalide.tests.secstorage.gschema.xml b/tests/glibext/re.chrysalide.tests.secstorage.gschema.xml
index 6afa96b..6afa96b 100644
--- a/tests/core/re.chrysalide.tests.secstorage.gschema.xml
+++ b/tests/glibext/re.chrysalide.tests.secstorage.gschema.xml
diff --git a/tests/core/secstorage.py b/tests/glibext/secstorage.py
index 1f82388..248b3e3 100644
--- a/tests/core/secstorage.py
+++ b/tests/glibext/secstorage.py
@@ -4,8 +4,8 @@ import os
import subprocess
from chrysacase import ChrysalideTestCase
-from pychrysalide import core
from gi.repository import Gio, GLib
+from pychrysalide.glibext import SecretStorage
class TestSecretStorage(ChrysalideTestCase):
@@ -47,19 +47,21 @@ class TestSecretStorage(ChrysalideTestCase):
settings = Gio.Settings.new('re.chrysalide.tests.secstorage')
+ storage = SecretStorage(settings)
+
settings.reset('master')
self.assertEqual(len(settings.get_value('master').unpack()), 0)
- self.assertFalse(core.has_secret_storage_key(settings))
+ self.assertFalse(storage.has_key)
settings.set_value('master', GLib.Variant('ay', b'ABC'))
- self.assertFalse(core.has_secret_storage_key(settings))
+ self.assertFalse(storage.has_key)
settings.set_value('master', GLib.Variant('ay', b'A' * 23))
- self.assertTrue(core.has_secret_storage_key(settings))
+ self.assertTrue(storage.has_key)
def testMasterKeyCreation(self):
@@ -67,46 +69,35 @@ class TestSecretStorage(ChrysalideTestCase):
settings = Gio.Settings.new('re.chrysalide.tests.secstorage')
+ storage = SecretStorage(settings)
+
settings.reset('salt')
settings.reset('master')
- status = core.has_secret_storage_key(settings)
+ self.assertFalse(storage.has_key)
- self.assertFalse(status);
-
- status = core.set_secret_storage_password(settings, '')
+ status = storage.set_password('')
self.assertTrue(status);
- status = core.has_secret_storage_key(settings)
-
- self.assertTrue(status);
+ self.assertTrue(storage.has_key)
+ self.assertTrue(storage.is_locked)
- status = core.is_secret_storage_locked(settings)
+ status = storage.unlock('')
self.assertTrue(status)
- status = core.unlock_secret_storage(settings, '')
-
- self.assertTrue(status)
+ self.assertFalse(storage.is_locked)
- status = core.is_secret_storage_locked(settings)
+ storage.lock()
- self.assertFalse(status)
+ self.assertTrue(storage.is_locked)
- core.lock_secret_storage(settings)
-
- status = core.is_secret_storage_locked(settings)
-
- self.assertTrue(status)
-
- status = core.unlock_secret_storage(settings, 'XXX')
+ status = storage.unlock('XXX')
self.assertFalse(status)
- status = core.is_secret_storage_locked(settings)
-
- self.assertTrue(status)
+ self.assertTrue(storage.is_locked)
def testDataEncryption(self):
@@ -114,25 +105,27 @@ class TestSecretStorage(ChrysalideTestCase):
settings = Gio.Settings.new('re.chrysalide.tests.secstorage')
+ storage = SecretStorage(settings)
+
settings.reset('salt')
settings.reset('master')
- status = core.set_secret_storage_password(settings, '<s3cUre>')
+ status = storage.set_password('<s3cUre>')
self.assertTrue(status);
- status = core.unlock_secret_storage(settings, '<s3cUre>')
+ status = storage.unlock('<s3cUre>')
self.assertTrue(status)
original = b'ABC'
- encrypted = core.encrypt_secret_storage_data(original, settings)
+ encrypted = storage.encrypt_data(original)
self.assertIsNotNone(encrypted)
- plain = core.decrypt_secret_storage_data(encrypted, settings)
+ plain = storage.decrypt_data(encrypted)
self.assertIsNotNone(plain)
self.assertEqual(original, plain)
@@ -140,11 +133,11 @@ class TestSecretStorage(ChrysalideTestCase):
original = b'A' * 136
- encrypted = core.encrypt_secret_storage_data(original, settings)
+ encrypted = storage.encrypt_data(original)
self.assertIsNotNone(encrypted)
- plain = core.decrypt_secret_storage_data(encrypted, settings)
+ plain = storage.decrypt_data(encrypted)
self.assertIsNotNone(plain)
self.assertEqual(original, plain)