commit fffae0f311c28b5cf6416b510d68cf0952b3fbf3
parent 8bbcc87ec01112818f325d462c4e3b1bab22a188
Author: lash <dev@holbrook.no>
Date:   Sat, 22 Mar 2025 15:01:20 +0000
WIP add config
Diffstat:
11 files changed, 335 insertions(+), 3 deletions(-)
diff --git a/src/crypto/gcrypt.c b/src/crypto/gcrypt.c
@@ -0,0 +1,122 @@
+#ifdef LQ_GPG
+#define LQ_GPG
+
+#define GPG_MIN_VERSION "1.10.2"
+#define GPG_KEY_TYP 1
+
+#include <gcrypt.h>
+#include <rerr.h>
+
+#include "lq/crypto.h"
+#include "lq/io.h"
+#include "debug.h"
+
+#ifdef RERR
+char *_rerr[7] = {
+	"",
+	"Crypto backend",
+	"Auth fail",
+	"Unlock fail",
+	"Sign reject",
+	"Resource fail",
+	"No key found",
+};
+#endif
+
+const char *gpgVersion = NULL;
+
+struct gpg_store {
+	gcry_sexp_t k;
+	char fingerprint[LQ_FP_LEN];
+	char public_key[LQ_PUBKEY_LEN];
+	char path[LQ_PATH_MAX];
+	char last_signature[LQ_SIG_LEN];
+	char last_data[LQ_DIGEST_LEN];
+};
+
+int lq_crypto_init() {
+#ifdef RERR
+	rerr_register(RERR_PFX_GPG, "crypto", _rerr);
+#endif
+	char *p;
+	size_t c;
+
+	gpg = lq_zero(sizeof(struct gpg_store));
+	if (gpg == NULL) {
+		return ERR_MEM;
+	}
+	gpg->passphrase_digest_len = gcry_md_get_algo_dlen(GCRY_MD_SHA256);
+
+	strcpy(gpg->path, path);
+	c = strlen(gpg->path);
+	p = gpg->path+c;
+	if (*p != '/') {
+		*p = '/';
+		*(p+1) = 0;
+	}
+
+	return ERR_OK;
+}
+
+LQPrivKey* lq_privatekey_new(const char *seed, size_t seed_len, const char *passphrase, size_t passphrase_len) {
+
+}
+
+LQPrivKey* lq_privatekey_load(const char *passphrase, size_t passphrase_len) {
+	LQPrivKey *o;
+
+	o = lq_alloc(sizeof(LQPrivKey));
+	if (o == NULL) {
+		return NULL;
+	}
+	
+	o->key_typ = GPG_KEY_TYP;
+	o->key_state = LQ_KEY_INIT;
+	o->impl = (void*)&gpg;
+	return o;
+}
+
+size_t lq_publickey_bytes(LQPubKey *pubk, char **out) {
+
+}
+
+int lq_privatekey_lock(LQPrivKey *pk, const char *passphrase, size_t passphrase_len) {
+
+}
+
+int lq_privatekey_unlock(LQPrivKey *pk, const char *passphrase, size_t passphrase_len) {
+
+}
+
+LQSig* lq_privatekey_sign(LQPrivKey *pk, const char *msg, size_t msg_len, const char *salt) {
+
+}
+
+LQSig* lq_signature_from_bytes(const char *sig_data, size_t sig_len, LQPubKey *pubkey) {
+
+}
+
+size_t lq_signature_bytes(LQSig *sig, char **out) {
+
+}
+
+void lq_privatekey_free(LQPrivKey *pk) {
+}
+
+void lq_publickey_free(LQPubKey *pubk) {
+
+}
+
+void lq_signature_free(LQSig *sig) {
+
+}
+
+char *lq_publickey_fingerprint(LQPubKey *pubk) {
+
+}
+
+int lq_digest(const char *in, size_t in_len, char *out) {
+
+}
+
+#endif
diff --git a/src/lq/config.c b/src/lq/config.c
@@ -0,0 +1,79 @@
+#include "lq/err.h"
+#include "lq/mem.h"
+#include "lq/config.h"
+
+const int lq_config_core_typs[] = {
+	LQ_TYP_STR,
+};
+
+static struct config_t {
+	void *members;
+	enum  lq_typ_e *typs;
+	size_t last;
+} config;
+
+static int core_apply() {
+	int i;
+	int r;
+
+	for (i = 0; i < LQ_CFG_LAST; i++) {
+		r = lq_config_register(lq_config_core_typs[i]);
+		if (r) {
+			return r;
+		}
+	}
+	return ERR_OK;
+}
+
+int lq_config_init() {
+	config.members = lq_alloc(LQ_CONFIG_MAX * sizeof(void*));
+	if (config.members == NULL) {
+		return ERR_MEM;
+	}
+	config.typs = lq_alloc(LQ_CONFIG_MAX * sizeof(void*));
+	if (config.typs == NULL) {
+		lq_free(config.members);
+		return ERR_MEM;
+	}
+	config.last = 0;
+	return core_apply();
+}
+
+int lq_config_register(enum lq_typ_e typ) {
+	size_t l;
+
+	switch (typ) {
+		case LQ_TYP_VOID:
+			l = sizeof(void*);
+			break;
+		case LQ_TYP_STR:
+			l = sizeof(char*);
+			break;
+		case LQ_TYP_NUM:
+			l = sizeof(long*);
+			break;
+		default:
+			l = 0;
+	}
+
+	if (!l) {
+		return ERR_INIT;
+	}
+	*(config.typs+config.last) = typ;
+	config.last++;
+
+	return ERR_OK;
+}
+
+int lq_config_set(char typ, int k, void *v) {
+	return ERR_OK;
+}
+
+int lq_config_get(int k, void *r) {
+	return ERR_OK;
+}
+
+void lq_config_free() {
+	lq_free(config.typs);
+	lq_free(config.members);
+}
diff --git a/src/lq/config.h b/src/lq/config.h
@@ -0,0 +1,22 @@
+#ifndef LQ_CONFIG_H_
+#define LQ_CONFIG_H_
+
+#ifndef LQ_CONFIG_MAX
+#define LQ_CONFIG_MAX 128
+#endif
+
+#include "lq/mem.h"
+
+enum lq_config_core_e {
+	LQ_CFG_DATA,
+	LQ_CFG_LAST,
+};
+
+
+int lq_config_init();
+int lq_config_register(enum lq_typ_e typ);
+int lq_config_set(char typ, int k, void *v); 
+int lq_config_get(int k, void *r);
+void lq_config_free();
+
+#endif
diff --git a/src/lq/crypto.h b/src/lq/crypto.h
@@ -15,12 +15,39 @@
 #define LQ_PRIVKEY_LEN 32
 #endif
 
+#ifndef LQ_SIGN_LEN
+#define LQ_SIGN_LEN 64
+#endif
+
+#ifndef LQ_FP_LEN
+#define LQ_FP_LEN 20
+#endif
+
 #ifndef LQ_SALT_LEN
 #define LQ_SALT_LEN 32
 #endif
 
+#ifndef LQ_CRYPTO_BUFLEN
+#define LQ_CRYPTO_BUFLEN 524288
+#endif
+
+#define RERR_PFX_CRYPTO 0x100
+/// Crypto backend unavailable
+#define ERR_NOCRYPTO 0x101
+/// Crypto authentication fail
+#define ERR_KEYFAIL 0x102
+/// Fail access to keyfile
+#define ERR_KEYFILE 0x103
+/// Last attempt to unlock key failed
+#define ERR_KEY_UNLOCK 0x104
+/// Usage of key for signature has been rejected (by user)
+#define ERR_KEY_REJECT 0x105
+/// Crypto resource fail
+#define ERR_NOKEY 0x106
+
 enum lq_keystate_e {
-	LQ_KEY_LOCK = 1,
+	LQ_KEY_INIT = 1,
+	LQ_KEY_LOCK = 2,
 };
 
 
@@ -68,6 +95,18 @@ struct lq_signature_t {
 typedef struct lq_signature_t LQSig;
 
 /**
+ * @brief Perform necessary initializations of crypto component.
+ *
+ * @return ERR_OK on success.
+ */
+int lq_crypto_init();
+
+/**
+ * @brief Perform necessary resource release of crypto component.
+ */
+void lq_crypto_free();
+
+/**
  * @brief Create a new private key
  *
  * If passphrase is not null the passphrase will be encrypted using that passphrase by default.
diff --git a/src/lq/err.h b/src/lq/err.h
@@ -8,6 +8,7 @@ enum err_e {
 	ERR_BYTEORDER, ///< Errors related to endianness
 	ERR_OVERFLOW, ///< Not enough space to write
 	ERR_INIT, ///< Failure instantiating object or data
+	ERR_MEM, ///< Failure allocating memory
 	ERR_READ, ///< General data read failure
 	ERR_WRITE, ///< General data write failure
 	ERR_ENCODING, ///< Failure in serialization and data transformation
diff --git a/src/lq/io.h b/src/lq/io.h
@@ -1,6 +1,10 @@
 #ifndef LIBQAEDA_IO_H_
 #define LIBQAEDA_IO_H_
 
+#ifndef LQ_PATH_MAX
+#define LQ_PATH_MAX 1024
+#endif
+
 /**
  * @brief Create temporary directory using template.
  *
diff --git a/src/lq/mem.h b/src/lq/mem.h
@@ -1,8 +1,15 @@
 #ifndef LIBQAEDA_MEM_H_
 #define LIBQAEDA_MEM_H_
 
+enum lq_typ_e {
+	LQ_TYP_VOID,
+	LQ_TYP_NUM,
+	LQ_TYP_STR,
+};
+
 #include <stddef.h>
 
+
 /**
  * @brief Allocate heap memory.
  *
@@ -39,4 +46,14 @@ void* lq_cpy(void *dst, const void *src, size_t len);
  */
 void* lq_set(void *dst, const char b, size_t len);
 
+/**
+ *
+ * @brief Fill memory region zeros.
+ *
+ * @param[out] Destination memory.
+ * @param[in] Number of bytes to write.
+ * @return Pointer to written memory.
+ */
+void* lq_zero(void *dst, size_t len);
+
 #endif // LIBQAEDA_MEM_H_
diff --git a/src/mem/std.c b/src/mem/std.c
@@ -17,3 +17,7 @@ void* lq_cpy(void *dst, const void *src, size_t len) {
 void* lq_set(void *dst, const char b, size_t len) {
 	return memset(dst, (int)b, len);
 }
+
+void* lq_zero(void *dst, const char b, size_t len) {
+	return lq_set(dst, 0, len);
+}
diff --git a/src/test/Makefile b/src/test/Makefile
@@ -2,9 +2,11 @@ OBJS := $(patsubst %.c,%.o,$(wildcard *.c))
 INCLUDES := -I.. -I../aux/include
 CFLAGS += $(INCLUDES) -Wall -g3
 LIBS := ../asn1/defs_asn1_tab.o `pkg-config --libs libtasn1` -L../aux/lib -llash
-LDFLAGS := -lcheck -lsubunit -lm $(LIBS)
+#LDFLAGS := -lcheck -lsubunit -lm $(LIBS)
+LDFLAGS := -lcheck $(LIBS)
 
 all: build
+	CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_config_bin
 	CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_crypto_bin
 	CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_msg_bin
 	CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_cert_bin
@@ -13,6 +15,7 @@ all: build
 test: all
 
 build:
+	$(CC) $(CFLAGS) test_config.c -o test_config_bin ../lq/config.o ../mem/std.o $(LDFLAGS)
 	$(CC) $(CFLAGS) test_crypto.c -o test_crypto_bin ../crypto/dummy.o ../mem/std.o $(LDFLAGS)
 	$(CC) $(CFLAGS) test_msg.c -o test_msg_bin ../crypto/dummy.o ../mem/std.o ../store/dummy.o ../store/file.o ../io/std.o ../lq/msg.o $(LDFLAGS)
 	$(CC) $(CFLAGS) test_cert.c -o test_cert_bin ../crypto/dummy.o ../mem/std.o ../store/dummy.o ../store/file.o ../io/std.o ../lq/msg.o ../lq/cert.o $(LDFLAGS)
diff --git a/src/test/test_config.c b/src/test/test_config.c
@@ -0,0 +1,42 @@
+#include <stdlib.h>
+#include <check.h>
+
+#include "lq/err.h"
+#include "lq/config.h"
+
+
+START_TEST(check_core) {
+	int r;
+
+	r = lq_config_init();
+	ck_assert_int_eq(r, ERR_OK);
+}
+END_TEST
+
+Suite * common_suite(void) {
+	Suite *s;
+	TCase *tc;
+
+	s = suite_create("config");
+	tc = tcase_create("core");
+	tcase_add_test(tc, check_core);
+	suite_add_tcase(s, tc);
+
+	return s;
+}
+
+int main(void) {
+	int n_fail;
+
+	Suite *s;
+	SRunner *sr;
+
+	s = common_suite();	
+	sr = srunner_create(s);
+
+	srunner_run_all(sr, CK_VERBOSE);
+	n_fail = srunner_ntests_failed(sr);
+	srunner_free(sr);
+
+	return (n_fail == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c
@@ -40,7 +40,6 @@ START_TEST(check_digest) {
 END_TEST
 
 START_TEST(check_privatekey) {
-	int r;
 	LQPrivKey *pk;
 
 	pk = lq_privatekey_new(privkeydata, 32, NULL, 0);