kee

Offline IOU signer with QR as transport
git clone https://holbrook.no/src/kee
Info | Log | Files | Refs | README | LICENSE

commit 84d47cf9ac064d8271b98afdb313550052869c66
parent 09ca913e0591522a128c1fff200046f7da9587be
Author: lash <dev@holbrook.no>
Date:   Sat, 27 Apr 2024 20:54:25 +0100

Add c test data helper utilities

Diffstat:
Msrc/gtk/kee-entry-item.c | 5+++++
Msrc/gtk/ui.c | 21++++++++++++++++++++-
Msrc/ledger.c | 3++-
Msrc/tests/Makefile | 10+++++++---
Msrc/tests/ledger.c | 22+++++++++++++++++++---
Asrc/tests/testutil.c | 162+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/tests/testutil.h | 34++++++++++++++++++++++++++++++++++
Msrc/tests/transport.c | 32+++++++++++++++++++++++++++++++-
Msrc/transport.c | 32++++++++++++++++++++++++++++++++
Msrc/transport.h | 6+++++-
10 files changed, 317 insertions(+), 10 deletions(-)

diff --git a/src/gtk/kee-entry-item.c b/src/gtk/kee-entry-item.c @@ -128,3 +128,8 @@ void kee_entry_item_apply_edit_widget(GtkBox *box, struct kee_entry_item_form_t } +KeeEntryItem* kee_entry_item_import(const char *data, size_t data_len) { + KeeEntryItem *item; + + item = g_object_new(KEE_TYPE_ENTRY_ITEM, "orientation", GTK_ORIENTATION_VERTICAL, NULL); +} diff --git a/src/gtk/ui.c b/src/gtk/ui.c @@ -31,6 +31,22 @@ static void ui_handle_unlock(KeeKey *o, KeeMenu *menu) { kee_menu_prev(menu); } +static void ui_handle_import(KeeImport *import, GString *v, KeeMenu *menu) { + GtkWidget *widget; + kee_transport_t trans; + char *s; + + s = (char*)v.str; + kee_transport_import(&trans, KEE_TRANSPORT_BASE64, s, strlen(s) + 1); + kee_transport_read(&trans); + + switch(kee_transport_cmd(&trans)) { + case KEE_CMD_DELTA: + widget = kee_menu_next("item"); + } + +} + //static GtkWidget* ui_build_view(KeeMenu *menu) { // GtkListItemFactory *factory; // GtkSelectionModel *sel; @@ -70,11 +86,14 @@ void ui_build(GtkApplication *gapp, struct kee_context *ctx) { import = kee_import_new(win); kee_menu_add(win, "import", GTK_WIDGET(import)); - g_signal_connect(import, "data_available", G_CALLBACK(kee_transport_handle_read)); + g_signal_connect(import, "data_available", G_CALLBACK(ui_handle_import), win); widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); kee_menu_add(win, "entry", widget); + //widget = g_object(GTK_ORIENTATION_VERTICAL, 0); + //kee_menu_add(win, "item", widget); + trans = g_object_new(KEE_TYPE_TRANSPORT, "orientation", GTK_ORIENTATION_VERTICAL, NULL); kee_menu_add(win, "transport", GTK_WIDGET(trans)); diff --git a/src/ledger.c b/src/ledger.c @@ -218,7 +218,8 @@ struct kee_ledger_item_t *kee_ledger_add_item(struct kee_ledger_t *ledger) { struct kee_ledger_item_t *prev; prev = ledger->last_item; - ledger->last_item = calloc(sizeof(struct kee_ledger_item_t), 1); + ledger->last_item = malloc(sizeof(struct kee_ledger_item_t)); + kee_ledger_item_init(ledger->last_item); ledger->last_item->prev_item = prev; return ledger->last_item; diff --git a/src/tests/Makefile b/src/tests/Makefile @@ -1,6 +1,6 @@ # TODO: test files are only generated on second run # -OBJS := $(patsubst %.c,%.o,$(wildcard *.c)) +OBJS := $(patsubst %.c,%.o,$(filter-out util.c,$(wildcard *.c))) LINKOBJS := $(wildcard ../*.o) INCLUDES := -I.. CFLAGS += `pkg-config --cflags gtk4 gstreamer-1.0 zbar` $(INCLUDES) -Wall @@ -9,11 +9,14 @@ LDFLAGS += $(LIBS) all: obj_debug $(OBJS) -obj_debug: +util: + $(CC) $(CFLAGS) -c testutil.c -o testutil.o + +obj_debug: util $(CC) $(CFLAGS) -c debug.c -o debug.o %.o: %.c - $(CC) $(CFLAGS) $< -o test_$* debug.o $(LINKOBJS) $(LDFLAGS) + $(CC) $(CFLAGS) $< -o test_$* debug.o testutil.o $(LINKOBJS) $(LDFLAGS) #test_run: $(wildcard test_*) # ./$< @@ -29,3 +32,4 @@ test: all test_run clean: rm -vf test_* + rm -vf *.o diff --git a/src/tests/ledger.c b/src/tests/ledger.c @@ -3,6 +3,8 @@ #include "ledger.h" #include "hex.h" #include "digest.h" +#include "testutil.h" + const char *test_ledger_data = "30818e0c035553440201020420c67ee54f93d63d00f4b8c9a7e1c11b39657b55c525704bb32e15ec85bc140d140420adcaf6474132ac36e97d3dbee693d3b186cd8399d402dc505073069c46b5bd780440878102c19c032fd0d06f6b054a01e969b823ccfe7d5ba37a37beef3e64feb5f9b38e1a0f7413b781a4626b884f89bb3052f662692c53578453dc7c7d911d8609"; @@ -10,10 +12,20 @@ const char *test_item_data_a = "3082011d0440000000000000000000000000000000000000 const char *test_item_data_b = "3082011d0440c2b795d9d3183bcc9d6ae1ae2960c302d7364a04996013dd9f31be628c46d2ee87b0cba51db67cd851a64dba04cc3e191dd48e7d7f3e063b0c850fd7b9b82218020817c94f8dec3e67aa02020ce20202049504401f78629f3015afa72f443005fc6711f7a7e2e20072eac86c98874c1dbe42095de3408d5711fb8fca56428461139992e8ff0452dc2092d2ba6ddb9658607f90ac0440d5d6cd6d905d0eb104ff3ab825cfc1be27f69a5377a3c84c33b3c5a0e6902e2af74d9024db58e1b90375be316e687a928edb881f8b6b3795682c20e533f9ed040101ff04409e8ffbbd5684b75aed7bf42a044914ea5813b1fccd9645462664317fa92dd9766c9ede39ea381e9648ef88bad220d0808660be63c94bf9954cf00daddad1150e01"; -const char *content_test = "Subject: foo\n\nsome content\n"; -const char *content_test_item = "Subject: bar\n\nsome other content\n"; -/// \todo split up function +int test_util() { + int r; + struct kee_test_t t; + + r = kee_test_generate(&t); + if (r) { + return r; + } + kee_test_free(&t); + return 0; +} + +/// \todo split up function (use util.c) int test_sign() { int r; gcry_sexp_t alice; @@ -363,6 +375,10 @@ int main() { if (r) { return 1; } + r = test_util(); + if (r) { + return 1; + } r = test_sign(); if (r) { return 1; diff --git a/src/tests/testutil.c b/src/tests/testutil.c @@ -0,0 +1,162 @@ +#include <string.h> +#include <stdlib.h> +#include <fcntl.h> +#include <gcrypt.h> + +#include "testutil.h" +#include "ledger.h" +#include "err.h" +#include "content.h" +#include "digest.h" + + +int kee_test_generate(struct kee_test_t *t) { + int r; + char *p; + char path[64]; + const char *version; + char out[1024]; + size_t out_len; + struct kee_ledger_item_t *item; + struct kee_content_t *content_item; + + memset(t, 0, sizeof(struct kee_test_t)); + t->content_item = malloc(sizeof(struct kee_content_t*) * 2); + *t->content_item = malloc(sizeof(struct kee_content_t)); + *(t->content_item+1) = NULL; + + version = gcry_check_version(NULL); + if (version == 0x0) { + return 1; + } + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + + strcpy(path, "/tmp/keetest_key_XXXXXX"); + p = mkdtemp(path); + if (p == NULL) { + return 1; + } + + kee_ledger_init(&t->ledger); + + gpg_store_init(&t->gpg, p); + t->gpg.k = &t->alice; + r = gpg_key_create(&t->gpg, "1234"); // alice + if (r) { + return 1; + } + memcpy(t->ledger.pubkey_alice, t->gpg.public_key, PUBKEY_LENGTH); + memcpy(t->alice_fingerprint, t->gpg.fingerprint, FINGERPRINT_LENGTH); + + gpg_store_init(&t->gpg, p); + t->gpg.k = &t->bob; + r = gpg_key_create(&t->gpg, "1234"); // bob + if (r) { + return 1; + } + memcpy(t->ledger.pubkey_bob, t->gpg.public_key, PUBKEY_LENGTH); + memcpy(t->alice_fingerprint, t->gpg.fingerprint, FINGERPRINT_LENGTH); + + strcpy(t->ledger.uoa, "USD"); + t->ledger.uoa_decimals = 2; + + r = calculate_digest_algo(content_test, strlen(content_test), t->content_ledger.key, GCRY_MD_SHA512); + if (r) { + return 1; + } + r = kee_content_init(&t->content_ledger, t->content_ledger.key, 0); + if (r) { + return 1; + } + r = calculate_digest_algo(content_test, strlen(content_test), t->content_ledger.key, GCRY_MD_SHA512); + if (r) { + return 1; + } + + out_len = 1024; + r = kee_ledger_serialize(&t->ledger, out, &out_len); + if (r) { + return 1; + } + + r = calculate_digest_algo(out, out_len, t->ledger.digest, GCRY_MD_SHA512); + if (r) { + return 1; + } + + item = kee_ledger_add_item(&t->ledger); + item->alice_credit_delta = 666; + item->bob_credit_delta = -42; + item->alice_collateral_delta = 1024; + item->bob_collateral_delta = 2048; + r = clock_gettime(CLOCK_REALTIME, &item->time); + if (r) { + return 1; + } + item->initiator = ALICE; + item->response = 1; + + content_item = *t->content_item; + r = calculate_digest_algo(content_test_item, strlen(content_test_item), content_item->key, GCRY_MD_SHA512); + if (r) { + return 1; + } + r = kee_content_init(content_item, content_item->key, 0); + if (r) { + return 1; + } + r = calculate_digest_algo(content_test_item, strlen(content_test_item), content_item->key, GCRY_MD_SHA512); + if (r) { + return 1; + } + + return ERR_OK; +} + +void kee_test_free(struct kee_test_t *t) { + struct kee_content_t **p; + + p = t->content_item; + if (p == NULL) { + return; + } + while (*p != NULL) { + free(*p); + p++; + } +} + +size_t kee_test_get_ledger_data(struct kee_test_t *t, char **out) { + int r; + + t->ledger_bytes_len = 1024; + r = kee_ledger_serialize(&t->ledger, t->ledger_bytes, &t->ledger_bytes_len); + if (r) { + return 0; + } + return (size_t)t->ledger_bytes_len; +} + +size_t kee_test_get_ledger_item_data(struct kee_test_t *t, int idx, char **out) { + int r; + int i; + struct kee_ledger_item_t *item; + + item = t->ledger.last_item; + i = 0; + while (i < idx) { + if (item->prev_item == NULL) { + return ERR_FAIL; + } + item = item->prev_item; + i++; + } + + t->ledger_item_bytes_len = 1024; + r = kee_ledger_item_serialize(item, t->ledger_item_bytes, &t->ledger_item_bytes_len, KEE_LEDGER_ITEM_SERIALIZE_REQUEST); + if (r) { + return 0; + } + return (size_t)t->ledger_item_bytes_len; +} diff --git a/src/tests/testutil.h b/src/tests/testutil.h @@ -0,0 +1,34 @@ +#ifndef KEE_TEST_H_ +#define KEE_TEST_H_ + +#include <gcrypt.h> + +#include "ledger.h" + +static const char *content_test = "Subject: foo\n\nsome content\n"; +static const char *content_test_item = "Subject: bar\n\nsome other content\n"; + + +struct kee_test_t { + struct kee_ledger_t ledger; + struct gpg_store gpg; + gcry_sexp_t alice; + gcry_sexp_t bob; + char alice_fingerprint[20]; + char bob_fingerprint[20]; + struct kee_content_t content_ledger; + struct kee_content_t **content_item; //last first + char ledger_bytes[1024]; + size_t ledger_bytes_len; + char ledger_item_bytes[1024]; + size_t ledger_item_bytes_len; + size_t item_count; +}; + +int kee_test_generate(struct kee_test_t *t); +int kee_test_ledger_data(struct kee_test_t *t); +void kee_test_free(struct kee_test_t *t); +size_t kee_test_get_ledger_data(struct kee_test_t *t, char **out); +size_t kee_test_get_ledger_item_data(struct kee_test_t *t, int idx, char **out); + +#endif diff --git a/src/tests/transport.c b/src/tests/transport.c @@ -1,6 +1,7 @@ #include <string.h> #include "transport.h" +#include "testutil.h" int test_raw() { @@ -69,6 +70,31 @@ int test_pack() { return 0; } +int test_msg() { + int r; + char *p; + size_t c; + struct kee_test_t t; + + r = kee_test_generate(&t); + if (r) { + return 1; + } + + c = kee_test_get_ledger_data(&t, &p); + if (c == 0) { + return 1; + } + + c = kee_test_get_ledger_item_data(&t, 0, &p); + if (c == 0) { + return 1; + } + + kee_test_free(&t); + + return 0; +} int main() { int r; @@ -81,5 +107,9 @@ int main() { if (r) { return 1; } - + r = test_msg(); + if (r) { + return 1; + } + return 0; } diff --git a/src/transport.c b/src/transport.c @@ -251,3 +251,35 @@ int kee_transport_read(struct kee_transport_t *trans, char *out, size_t *out_len return ERR_OK; } + +enum kee_cmd_e kee_transport_cmd(struct kee_transport_t *trans) { + return *trans->cmd & 0x1f; +} + +int kee_transport_encode_ledger(struct kee_transport_t *trans_ledger, struct kee_transport_t *trans_item, char *out, size_t out_len) { + int r; + char *p; + unsigned short part_length; + + *out = 0; + p = out + 1; + part_length = (unsigned short)trans_ledger->chunker.data_len; + r = to_endian(TO_ENDIAN_BIG, 2, &part_length); + if (r) { + return ERR_FAIL; + } + memcpy(p, &part_length, sizeof(unsigned short)); + p += sizeof(unsigned short); + memcpy(p, trans_ledger->chunker.data, trans_ledger->chunker.data_len); + + part_length = (unsigned short)trans_item->chunker.data_len; + r = to_endian(TO_ENDIAN_BIG, 2, &part_length); + if (r) { + return ERR_FAIL; + } + memcpy(p, &part_length, sizeof(unsigned short)); + p += sizeof(unsigned short); + memcpy(p, trans_item->chunker.data, trans_item->chunker.data_len); + + return ERR_OK; +} diff --git a/src/transport.h b/src/transport.h @@ -11,11 +11,13 @@ enum kee_transport_mode_e { }; enum kee_cmd_e { // max number 31 - KEE_CMD_ID = 0, + KEE_CMD_PACKED = 0, + KEE_CMD_ID, KEE_CMD_LEDGER, KEE_CMD_DELTA, KEE_CMD_CLEAR, KEE_N_CMD, + KEE_INVALID_CMD, }; #define KEE_CMD_SIGN_RESPONSE 64 @@ -62,4 +64,6 @@ void kee_transport_set_response(struct kee_transport_t *trans); int kee_transport_import(struct kee_transport_t *trans, enum kee_transport_mode_e mode, const char *data, size_t data_len); int kee_transport_read(struct kee_transport_t *trans, char *out, size_t *out_len); +int kee_transport_encode_ledger(struct kee_transport_t *trans_ledger, struct kee_transport_t *trans_item, char *out, size_t out_len); + #endif // _KEE_TRANSPORT_H