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);