kee

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

commit ca8ee87db35ce01f48d7f2d5b6edef090222de22
parent 30e79688141ecfb749a735365dfe8d5f0fee0da2
Author: lash <dev@holbrook.no>
Date:   Thu,  2 May 2024 16:30:03 +0100

Add state check for ledger before add

Diffstat:
Msrc/gtk/kee-entry-store.c | 24+++++++++++++++++++++---
Msrc/ledger.c | 109+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Msrc/ledger.h | 11++++++-----
Msrc/tests/testutil.c | 2+-
4 files changed, 96 insertions(+), 50 deletions(-)

diff --git a/src/gtk/kee-entry-store.c b/src/gtk/kee-entry-store.c @@ -144,7 +144,9 @@ void kee_entry_store_finalize(GObject *go) { int kee_entry_store_add(KeeEntryStore *o, GVariant *v) { int r; struct kee_ledger_t ledger; + struct kee_ledger_item_t *item; const char *b; + enum kee_ledger_state_e item_state; size_t c; c = (size_t)g_variant_n_children(v); @@ -154,9 +156,25 @@ int kee_entry_store_add(KeeEntryStore *o, GVariant *v) { return r; } - r = kee_ledger_put(&ledger, o->db); - if (r) { - return ERR_FAIL; + item = ledger.last_item; + item_state = kee_ledger_item_state(item); + + switch (item_state) { + case KEE_LEDGER_STATE_FINAL: + r = kee_ledger_put(&ledger, o->db); + if (r) { + return ERR_FAIL; + } + break; + case KEE_LEDGER_STATE_RESPONSE: + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "detected response state"); + break; + case KEE_LEDGER_STATE_REQUEST: + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "detected request state, ignoring"); + break; + default: + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "invalid item state after parse"); + return ERR_FAIL; } return ERR_OK; diff --git a/src/ledger.c b/src/ledger.c @@ -18,7 +18,7 @@ char zero_content[64]; /// \todo consolidate with get_message_data -static char *get_message_asn(struct kee_ledger_t *ledger, asn1_node item, char *out_digest, char *out_data, size_t *out_len, enum kee_item_serialize_mode_e mode) { +static char *get_message_asn(struct kee_ledger_t *ledger, asn1_node item, char *out_digest, char *out_data, size_t *out_len, enum kee_ledger_state_e mode) { int r; size_t c; asn1_node root; @@ -77,7 +77,7 @@ static char *get_message_asn(struct kee_ledger_t *ledger, asn1_node item, char * // return NULL; // } - if (mode == KEE_LEDGER_ITEM_SERIALIZE_FINAL) { + if (mode == KEE_LEDGER_STATE_FINAL) { r = asn1_copy_node(root, "Kee.KeeEntry.signatureResponse", item, "signatureResponse"); if (r != ASN1_SUCCESS) { printf("%d (%s) %s\n", r, err, asn1_strerror(r)); @@ -92,7 +92,7 @@ static char *get_message_asn(struct kee_ledger_t *ledger, asn1_node item, char * } } - if (mode > KEE_LEDGER_ITEM_SERIALIZE_REQUEST) { + if (mode > KEE_LEDGER_STATE_REQUEST) { r = asn1_copy_node(root, "Kee.KeeEntry.signatureRequest", item, "signatureRequest"); if (r != ASN1_SUCCESS) { printf("%d (%s) %s\n", r, err, asn1_strerror(r)); @@ -153,7 +153,7 @@ static int verify_item_data(struct kee_ledger_t *ledger, const char* item_data, if (item_data_len) { r = calculate_digest_algo(item_data, item_data_len, b, GCRY_MD_SHA512); if (r) { - return NULL; + return 1; } r = gpg_store_verify(sig_data, b, pubkey_data); @@ -237,7 +237,7 @@ static int verify_item_asn(struct kee_ledger_t *ledger, asn1_node item, const ch if (c) { c = 1024; - p = get_message_asn(ledger, item, p, p+64, &c, KEE_LEDGER_ITEM_SERIALIZE_RESPONSE); + p = get_message_asn(ledger, item, p, p+64, &c, KEE_LEDGER_STATE_RESPONSE); if (p == NULL) { return 1; } @@ -248,7 +248,7 @@ static int verify_item_asn(struct kee_ledger_t *ledger, asn1_node item, const ch } } - return; + return 0; } static int kee_ledger_digest(struct kee_ledger_t *ledger, char *out) { @@ -270,34 +270,34 @@ static int kee_ledger_digest(struct kee_ledger_t *ledger, char *out) { return ERR_OK; } -static int kee_ledger_item_digest(struct kee_ledger_t *ledger, struct kee_ledger_item_t *item, enum kee_item_serialize_mode_e mode, char *out) { - char *p; - int r; - char b[1024]; - size_t c; - - p = (char*)b; -// r = kee_ledger_digest(ledger, p); +//static int kee_ledger_item_digest(struct kee_ledger_t *ledger, struct kee_ledger_item_t *item, enum kee_ledger_state_e mode, char *out) { +// char *p; +// int r; +// char b[1024]; +// size_t c; +// +// p = (char*)b; +//// r = kee_ledger_digest(ledger, p); +//// if (r) { +//// return ERR_FAIL; +//// } +// memcpy(p, ledger->digest, DIGEST_LENGTH); +// p += DIGEST_LENGTH; +// +// c = 1024; +// r = kee_ledger_item_serialize(item, p, &c, mode); // if (r) { // return ERR_FAIL; // } - memcpy(p, ledger->digest, DIGEST_LENGTH); - p += DIGEST_LENGTH; - - c = 1024; - r = kee_ledger_item_serialize(item, p, &c, mode); - if (r) { - return ERR_FAIL; - } - - r = calculate_digest_algo(b, c + DIGEST_LENGTH, out, GCRY_MD_SHA512); - if (r) { - return ERR_FAIL; - } - - return ERR_OK; -} - +// +// r = calculate_digest_algo(b, c + DIGEST_LENGTH, out, GCRY_MD_SHA512); +// if (r) { +// return ERR_FAIL; +// } +// +// return ERR_OK; +//} +// void kee_ledger_item_apply_cache(struct kee_ledger_t *ledger, struct kee_ledger_item_t *item) { @@ -595,7 +595,7 @@ int kee_ledger_serialize(struct kee_ledger_t *ledger, char *out, size_t *out_len return 0; } -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_item_serialize(struct kee_ledger_item_t *item, char *out, size_t *out_len, enum kee_ledger_state_e mode) { int r; char err[1024]; asn1_node node; @@ -681,7 +681,7 @@ int kee_ledger_item_serialize(struct kee_ledger_item_t *item, char *out, size_t return r; } - if (mode == KEE_LEDGER_ITEM_SERIALIZE_REQUEST) { + if (mode == KEE_LEDGER_STATE_REQUEST) { signature_request = zero_content; c = 0; } else { @@ -704,7 +704,7 @@ int kee_ledger_item_serialize(struct kee_ledger_item_t *item, char *out, size_t return r; } - if (mode < KEE_LEDGER_ITEM_SERIALIZE_FINAL) { + if (mode < KEE_LEDGER_STATE_FINAL) { signature_response = zero_content; c = 0; } else { @@ -730,16 +730,16 @@ int kee_ledger_sign(struct kee_ledger_t *ledger, struct kee_ledger_item_t *item, char *p; size_t c; size_t l; - enum kee_item_serialize_mode_e mode; + enum kee_ledger_state_e mode; p = out; c = *out_len; l = *out_len; *out_len = 0; - mode = KEE_LEDGER_ITEM_SERIALIZE_REQUEST; + mode = KEE_LEDGER_STATE_REQUEST; if (item->initiator == BOB) { - mode = KEE_LEDGER_ITEM_SERIALIZE_RESPONSE; + mode = KEE_LEDGER_STATE_RESPONSE; } if (memcmp(item->alice_signature, zero_content, SIGNATURE_LENGTH)) { @@ -800,7 +800,7 @@ int kee_ledger_serialize_open(struct kee_ledger_t *ledger, char *out, size_t *ou } c = 1024; - r = kee_ledger_item_serialize(ledger->last_item, b, &c, KEE_LEDGER_ITEM_SERIALIZE_RESPONSE); + r = kee_ledger_item_serialize(ledger->last_item, b, &c, KEE_LEDGER_STATE_RESPONSE); if (r) { return ERR_FAIL; } @@ -1063,7 +1063,7 @@ int kee_ledger_verify(struct kee_ledger_t *ledger, int *idx) { } } else { c = 960; - r = kee_ledger_item_serialize(item, ((char*)b)+DIGEST_LENGTH, &c, KEE_LEDGER_ITEM_SERIALIZE_RESPONSE); + r = kee_ledger_item_serialize(item, ((char*)b)+DIGEST_LENGTH, &c, KEE_LEDGER_STATE_RESPONSE); if (r) { return ERR_FAIL; } @@ -1078,7 +1078,7 @@ int kee_ledger_verify(struct kee_ledger_t *ledger, int *idx) { } if (sig_request != NULL) { c = 960; - r = kee_ledger_item_serialize(item, ((char*)b)+DIGEST_LENGTH, &c, KEE_LEDGER_ITEM_SERIALIZE_REQUEST); + r = kee_ledger_item_serialize(item, ((char*)b)+DIGEST_LENGTH, &c, KEE_LEDGER_STATE_REQUEST); if (r) { return ERR_FAIL; } @@ -1131,7 +1131,7 @@ int kee_ledger_item_put(struct kee_ledger_t *ledger, struct db_ctx *db, int idx) } c = 928; - r = kee_ledger_item_serialize(item, v, &c, KEE_LEDGER_ITEM_SERIALIZE_FINAL); + r = kee_ledger_item_serialize(item, v, &c, KEE_LEDGER_STATE_FINAL); if (r) { return ERR_FAIL; } @@ -1142,3 +1142,30 @@ int kee_ledger_item_put(struct kee_ledger_t *ledger, struct db_ctx *db, int idx) return ERR_OK; } + + +enum kee_ledger_state_e kee_ledger_item_state(struct kee_ledger_item_t *item) { + char *sig_request; + char *sig_response; + + enum kee_ledger_state_e state; + + if (item->initiator == BOB) { + sig_request = item->bob_signature; + sig_response = item->alice_signature; + } else { + sig_request = item->bob_signature; + sig_response = item->alice_signature; + } + + state = KEE_LEDGER_STATE_REQUEST; + if (memcmp(sig_request, zero_content, SIGNATURE_LENGTH)) { + if (memcmp(sig_response, zero_content, SIGNATURE_LENGTH)) { + state = KEE_LEDGER_STATE_FINAL; + } else { + state = KEE_LEDGER_STATE_RESPONSE; + } + } + + return state; +} diff --git a/src/ledger.h b/src/ledger.h @@ -13,10 +13,10 @@ enum kee_initiator_e { BOB, }; -enum kee_item_serialize_mode_e { - KEE_LEDGER_ITEM_SERIALIZE_REQUEST, - KEE_LEDGER_ITEM_SERIALIZE_RESPONSE, - KEE_LEDGER_ITEM_SERIALIZE_FINAL, +enum kee_ledger_state_e { + KEE_LEDGER_STATE_REQUEST, + KEE_LEDGER_STATE_RESPONSE, + KEE_LEDGER_STATE_FINAL, }; struct kee_ledger_item_t { @@ -62,9 +62,10 @@ void kee_ledger_item_free(struct kee_ledger_item_t *item); void kee_ledger_resolve(struct kee_ledger_t *ledger, Cadiz *cadiz); void kee_ledger_reset_cache(struct kee_ledger_t *ledger); int kee_ledger_sign(struct kee_ledger_t *ledger, struct kee_ledger_item_t *item, struct gpg_store *gpg, char *out, size_t *out_len, const char *passphrase); +enum kee_ledger_state_e kee_ledger_item_state(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_item_serialize(struct kee_ledger_item_t *item, char *out, size_t *out_len, enum kee_ledger_state_e mode); int kee_ledger_serialize_open(struct kee_ledger_t *ledger, char *out, size_t *out_len); int kee_ledger_parse_open(struct kee_ledger_t *ledger, const char *in, size_t in_len); int kee_ledger_put(struct kee_ledger_t *ledger, struct db_ctx *db); diff --git a/src/tests/testutil.c b/src/tests/testutil.c @@ -226,7 +226,7 @@ size_t kee_test_get_ledger_item_data(struct kee_test_t *t, int idx, char **out) } 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); + r = kee_ledger_item_serialize(item, t->ledger_item_bytes, &t->ledger_item_bytes_len, KEE_LEDGER_STATE_REQUEST); if (r) { return 0; }