kee

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

commit a134f5e1671129af6bc1295f9e25b40c798bee0b
parent 4c1d61c490a1c90eb577da135f5f22a6dec2fa58
Author: lash <dev@holbrook.no>
Date:   Sun, 28 Apr 2024 14:25:38 +0100

Implement multi element transport with asn1 serialization

Diffstat:
Msrc/asn1/schema_entry.txt | 2++
Msrc/gtk/kee-entry.c | 14+++++++++++---
Msrc/gtk/tests/Makefile | 4++--
Msrc/ledger.c | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/ledger.h | 1+
Msrc/tests/ledger.c | 25++++++++++++++++++++++++-
Msrc/tests/transport.c | 108++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/transport.c | 114++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/transport.h | 4++--
Mtestdata_asn1.py | 5++++-
10 files changed, 250 insertions(+), 121 deletions(-)

diff --git a/src/asn1/schema_entry.txt b/src/asn1/schema_entry.txt @@ -24,4 +24,6 @@ Kee DEFINITIONS EXPLICIT TAGS ::= BEGIN response BOOLEAN, signatureResponse OCTET STRING } + + KeeTransport ::= SEQUENCE OF ANY END diff --git a/src/gtk/kee-entry.c b/src/gtk/kee-entry.c @@ -120,19 +120,27 @@ static void kee_entry_handle_add(GtkButton *butt, KeeEntry *o) { o->state |= ENTRYSTATE_LOAD; g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "adding ledger entry"); + // serialize ledger + + // serialize item out_len = 1024; out = malloc(out_len); if (out == NULL) { g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "memory for item serialization buffer for qr transport fail"); return; } - r = kee_ledger_item_serialize(item, out, &out_len, KEE_LEDGER_ITEM_SERIALIZE_REQUEST); +// r = kee_ledger_item_serialize(item, out, &out_len, KEE_LEDGER_ITEM_SERIALIZE_REQUEST); +// if (r) { +// g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "item serialization failed"); +// return; +// } + r = kee_ledger_serialize_open(&o->ledger, out, &out_len); if (r) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "item serialization failed"); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "qr transport renderer failed"); return; } - r = kee_transport_single(&trans, KEE_TRANSPORT_BASE64, KEE_CMD_LEDGER, c); + r = kee_transport_single(&trans, KEE_TRANSPORT_BASE64, KEE_CMD_LEDGER, out_len); if (r) { g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "qr transport renderer failed"); return; diff --git a/src/gtk/tests/Makefile b/src/gtk/tests/Makefile @@ -3,9 +3,9 @@ OBJS := $(patsubst %.c,%.o,$(wildcard *.c)) LINKOBJS := $(wildcard ../../*.o) $(wildcard ../*.o) INCLUDES := -I../.. -I.. -CFLAGS += `pkg-config --cflags gtk4 gstreamer-1.0` $(INCLUDES) -Wall +CFLAGS += `pkg-config --cflags gtk4 gstreamer-1.0 libqrencode` $(INCLUDES) -Wall #LIBS := `pkg-config --libs gtk4 zlib lmdb libgcrypt libxdg-basedir gstreamer-1.0` -lb64 -lvarint -lcmime -llash -LIBS := `pkg-config --libs gtk4 zlib lmdb libgcrypt libxdg-basedir gstreamer-1.0` -lb64 -lcmime -llash -ltasn1 -lldap +LIBS := `pkg-config --libs gtk4 zlib lmdb libgcrypt libxdg-basedir gstreamer-1.0 libqrencode` -lb64 -lcmime -llash -ltasn1 -lldap LDFLAGS += $(LIBS) all: $(OBJS) diff --git a/src/ledger.c b/src/ledger.c @@ -12,10 +12,9 @@ #include "content.h" #include "endian.h" #include "gpg.h" +#include "wire.h" -extern const asn1_static_node schema_entry_asn1_tab[]; - char zero_content[64]; static char *get_message(struct kee_ledger_t *ledger, asn1_node item, char *out_digest, char *out_data, size_t *out_len) { @@ -686,3 +685,94 @@ int kee_ledger_sign(struct kee_ledger_t *ledger, struct kee_ledger_item_t *item, return ERR_OK; } + +//int kee_ledger_serialize_pair() { +// int r; +// asn1_node root; +// asn1_node item; +// asn1_node entry; +// asn1_node pair; +// char err[1024]; +// +// memset(&root, 0, sizeof(root)); +// r = asn1_array2tree(schema_entry_asn1_tab, &root, err); +// if (r != ASN1_SUCCESS) { +// debug_log(DEBUG_ERROR, err); +// return ERR_FAIL; +// } +// +// r = asn1_create_element(root, "Kee.KeeEntryInit.KeeEntryHead", &entry); +// if (r != ASN1_SUCCESS) { +// return ERR_FAIL; +// } +// +// r = asn1_create_element(root, "Kee.KeeEntryInit.KeeEntryHead", &entry); +// if (r != ASN1_SUCCESS) { +// return ERR_FAIL; +// } +// +// r = asn1_create_element(root, "Kee.KeeEntryInit.KeeEntry", &item); +// if (r != ASN1_SUCCESS) { +// return ERR_FAIL; +// } +// +// c = strlen(ledger->uoa); +// r = asn1_write_value(node, "Kee.KeeEntryHead.uoa", ledger->uoa, c); +// if (r != ASN1_SUCCESS) { +// return ERR_FAIL; +// } +// +// return ERR_OK; +//} + +int kee_ledger_serialize_open(struct kee_ledger_t *ledger, char *out, size_t *out_len) { + int r; + char err[1024]; + char b[1024]; + size_t c; + asn1_node root; + + memset(&root, 0, sizeof(root)); + r = asn1_array2tree(schema_entry_asn1_tab, &root, err); + if (r != ASN1_SUCCESS) { + debug_log(DEBUG_ERROR, err); + return ERR_FAIL; + } + + c = 1024; + r = kee_ledger_serialize(ledger, b, &c); + if (r) { + return ERR_FAIL; + } + r = asn1_write_value(root, "Kee.KeeTransport", "NEW", 1); + if (r) { + return ERR_FAIL; + } + r = asn1_write_value(root, "Kee.KeeTransport.?1", b, c); + if (r) { + return ERR_FAIL; + } + + c = 1024; + r = kee_ledger_item_serialize(ledger->last_item, b, &c, KEE_LEDGER_ITEM_SERIALIZE_RESPONSE); + if (r) { + return ERR_FAIL; + } + + r = asn1_write_value(root, "Kee.KeeTransport", "NEW", 1); + if (r) { + return ERR_FAIL; + } + r = asn1_write_value(root, "Kee.KeeTransport.?2", b, c); + if (r) { + return ERR_FAIL; + } + + r = asn1_der_coding(root, "Kee.KeeTransport", out, (int*)out_len, err); + if (r) { + debug_log(DEBUG_ERROR, err); + return ERR_FAIL; + } + + return ERR_OK; +} diff --git a/src/ledger.h b/src/ledger.h @@ -64,5 +64,6 @@ int kee_ledger_sign(struct kee_ledger_t *ledger, struct kee_ledger_item_t *item, void kee_ledger_item_init(struct kee_ledger_item_t *item); int kee_ledger_item_serialize(struct kee_ledger_item_t *item, char *out, size_t *out_len, enum kee_item_serialize_mode_e mode); +int kee_ledger_serialize_open(struct kee_ledger_t *ledger, char *out, size_t *out_len); #endif diff --git a/src/tests/ledger.c b/src/tests/ledger.c @@ -368,6 +368,26 @@ int test_parse() { return 0; } +int test_pair() { + int r; + struct kee_test_t t; + char out[1024]; + size_t out_len; + + r = kee_test_generate(&t); + if (r) { + return 1; + } + + out_len = 1024; + r = kee_ledger_serialize_open(&t.ledger, out, &out_len); + if (r) { + return 1; + } + + return 0; +} + int main() { int r; @@ -387,7 +407,10 @@ int main() { if (r) { return 1; } - + r = test_pair(); + if (r) { + return 1; + } return 0; } diff --git a/src/tests/transport.c b/src/tests/transport.c @@ -71,60 +71,60 @@ int test_pack() { } int test_msg() { - int r; - char *p; - size_t c; - struct kee_test_t t; - struct kee_transport_t ledger_transport; - struct kee_transport_t item_transport; - struct kee_transport_t merged_transport; - char out[1024]; - size_t out_len; - - r = kee_test_generate(&t); - if (r) { - return 1; - } - - c = kee_test_get_ledger_data(&t, &p); - if (c == 0) { - return 1; - } - r = kee_transport_single(&ledger_transport, KEE_TRANSPORT_RAW, KEE_CMD_LEDGER, t.ledger_bytes_len); - if (r) { - return 1; - } - r = kee_transport_write(&ledger_transport, t.ledger_bytes, t.ledger_bytes_len); - if (r) { - return 1; - } - - c = kee_test_get_ledger_item_data(&t, 0, &p); - if (c == 0) { - return 1; - } - r = kee_transport_single(&item_transport, KEE_TRANSPORT_RAW, KEE_CMD_DELTA, t.ledger_item_bytes_len); - if (r) { - return 1; - } - r = kee_transport_write(&item_transport, t.ledger_item_bytes, t.ledger_item_bytes_len); - if (r) { - return 1; - } - - out_len = 1024; - r = kee_transport_encode_ledger(&ledger_transport, &item_transport, &merged_transport, KEE_TRANSPORT_RAW); - if (r) { - return 1; - } - - r = kee_transport_validate(&merged_transport); - if (r) { - return 1; - } - - kee_test_free(&t); - +// int r; +// char *p; +// size_t c; +// struct kee_test_t t; +// struct kee_transport_t ledger_transport; +// struct kee_transport_t item_transport; +// struct kee_transport_t merged_transport; +// char out[1024]; +// size_t out_len; +// +// r = kee_test_generate(&t); +// if (r) { +// return 1; +// } +// +// c = kee_test_get_ledger_data(&t, &p); +// if (c == 0) { +// return 1; +// } +// r = kee_transport_single(&ledger_transport, KEE_TRANSPORT_RAW, KEE_CMD_LEDGER, t.ledger_bytes_len); +// if (r) { +// return 1; +// } +// r = kee_transport_write(&ledger_transport, t.ledger_bytes, t.ledger_bytes_len); +// if (r) { +// return 1; +// } +// +// c = kee_test_get_ledger_item_data(&t, 0, &p); +// if (c == 0) { +// return 1; +// } +// r = kee_transport_single(&item_transport, KEE_TRANSPORT_RAW, KEE_CMD_DELTA, t.ledger_item_bytes_len); +// if (r) { +// return 1; +// } +// r = kee_transport_write(&item_transport, t.ledger_item_bytes, t.ledger_item_bytes_len); +// if (r) { +// return 1; +// } +// +// out_len = 1024; +// r = kee_transport_encode_ledger(&ledger_transport, &item_transport, &merged_transport, KEE_TRANSPORT_RAW); +// if (r) { +// return 1; +// } +// +// r = kee_transport_validate(&merged_transport); +// if (r) { +// return 1; +// } +// +// kee_test_free(&t); +// return 0; } diff --git a/src/transport.c b/src/transport.c @@ -6,6 +6,7 @@ #include <zlib.h> #include "transport.h" #include "err.h" +#include "ledger.h" static int pack_compress(char *in, size_t in_len, char *out, size_t *out_len) { @@ -252,6 +253,7 @@ int kee_transport_read(struct kee_transport_t *trans, char *out, size_t *out_len return ERR_OK; } +// make sure reported sizes add up to data boundary static int validate_multi(char *data, size_t data_len) { char *p; size_t c; @@ -293,59 +295,59 @@ int kee_transport_validate(struct kee_transport_t *trans) { } -int kee_transport_encode_ledger(struct kee_transport_t *trans_ledger, struct kee_transport_t *trans_item, struct kee_transport_t *trans_out, enum kee_transport_mode_e mode) { - int r; - char *p; - unsigned short part_length; - size_t l; - size_t c; - char *out; - - l = sizeof(unsigned short); - out = malloc(trans_ledger->chunker.data_len + trans_item->chunker.data_len + (l * 2) + 1); - // only use raw mode for this, since we are joining data - if (trans_ledger->mode != KEE_TRANSPORT_RAW) { - return ERR_FAIL; - } - if (trans_item->mode != KEE_TRANSPORT_RAW) { - return ERR_FAIL; - } - c = 0; - p = out; - 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, l); - p += sizeof(unsigned short); - c += l; - memcpy(p, trans_ledger->chunker.data, trans_ledger->chunker.data_len); - p += trans_ledger->chunker.data_len; - c += 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, l); - p += l; - c += l; - memcpy(p, trans_item->chunker.data, trans_item->chunker.data_len); - p += trans_item->chunker.data_len; - c += trans_item->chunker.data_len; - - r = kee_transport_single(trans_out, mode, KEE_CMD_PACKED, c); - if (r) { - return ERR_FAIL; - } - r = kee_transport_write(trans_out, out, c); - if (r) { - return ERR_FAIL; - } - - free(out); - - return ERR_OK; -} +//int kee_transport_encode_ledger(struct kee_transport_t *trans_ledger, struct kee_transport_t *trans_item, struct kee_transport_t *trans_out, enum kee_transport_mode_e mode) { +// int r; +// char *p; +// unsigned short part_length; +// size_t l; +// size_t c; +// char *out; +// +// l = sizeof(unsigned short); +// out = malloc(trans_ledger->chunker.data_len + trans_item->chunker.data_len + (l * 2) + 1); +// // only use raw mode for this, since we are joining data +// if (trans_ledger->mode != KEE_TRANSPORT_RAW) { +// return ERR_FAIL; +// } +// if (trans_item->mode != KEE_TRANSPORT_RAW) { +// return ERR_FAIL; +// } +// c = 0; +// p = out; +// 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, l); +// p += sizeof(unsigned short); +// c += l; +// memcpy(p, trans_ledger->chunker.data, trans_ledger->chunker.data_len); +// p += trans_ledger->chunker.data_len; +// c += 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, l); +// p += l; +// c += l; +// memcpy(p, trans_item->chunker.data, trans_item->chunker.data_len); +// p += trans_item->chunker.data_len; +// c += trans_item->chunker.data_len; +// +// r = kee_transport_single(trans_out, mode, KEE_CMD_PACKED, c); +// if (r) { +// return ERR_FAIL; +// } +// r = kee_transport_write(trans_out, out, c); +// if (r) { +// return ERR_FAIL; +// } +// +// free(out); +// +// return ERR_OK; +//} diff --git a/src/transport.h b/src/transport.h @@ -64,6 +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, struct kee_transport_t *trans_out, enum kee_transport_mode_e mode); -int kee_transport_validate(struct kee_transport_t *trans); +//int kee_transport_encode_ledger(struct kee_transport_t *trans_ledger, struct kee_transport_t *trans_item, struct kee_transport_t *trans_out, enum kee_transport_mode_e mode); +//int kee_transport_validate(struct kee_transport_t *trans); #endif // _KEE_TRANSPORT_H diff --git a/testdata_asn1.py b/testdata_asn1.py @@ -457,7 +457,10 @@ if __name__ == '__main__': keys = ['alice'] alice_key = os.path.join(crypto_dir, 'alice.key.bin') - os.unlink('kee.key') + try: + os.unlink('kee.key') + except FileNotFoundError: + pass os.symlink(alice_key, 'kee.key') count_ledgers = os.environ.get('COUNT', '1')