commit a329ade72aff32f4af6595eb1f9fbe55ed4524c8
parent 1385f473d54dbf7a28aaaf111f1f4096d93107ed
Author: lash <dev@holbrook.no>
Date: Sat, 4 May 2024 09:55:04 +0100
Add initiator detection to use for ledger import
Diffstat:
6 files changed, 170 insertions(+), 65 deletions(-)
diff --git a/src/gpg.c b/src/gpg.c
@@ -284,8 +284,6 @@ static int key_create(struct gpg_store *gpg, gcry_sexp_t *key) {
/**
* \todo consistent endianness for key length in persistent storage (fwrite)
- et* \todo implement MAC
- * \todo test new data length location (part of ciphertext)
* \todo doc must have enough in path for path + fingerprint hex
*
*/
@@ -325,14 +323,6 @@ static int key_create_file(struct gpg_store *gpg, gcry_sexp_t *key, const char *
m = c;
c = get_padsize(m, ENCRYPT_BLOCKSIZE);
- /// \todo malloc
-//
-// l = c;
-// c = fwrite(&kl, sizeof(int), 1, f);
-// if (c != 1) {
-// fclose(f);
-// return ERR_KEYFAIL;
-// }
gcry_create_nonce(nonce, CHACHA20_NONCE_LENGTH_BYTES);
r = encryptb(ciphertext, c, v, m+sizeof(int), passphrase, nonce);
if (r) {
@@ -349,11 +339,7 @@ static int key_create_file(struct gpg_store *gpg, gcry_sexp_t *key, const char *
return ERR_KEYFAIL;
}
l = c;
-// c = fwrite(&kl, sizeof(int), 1, f);
-// if (c != 1) {
-// fclose(f);
-// return ERR_KEYFAIL;
-// }
+
c = fwrite(nonce, CHACHA20_NONCE_LENGTH_BYTES, 1, f);
if (c != 1) {
fclose(f);
diff --git a/src/ledger.c b/src/ledger.c
@@ -70,13 +70,6 @@ static char *get_message_asn(struct kee_ledger_t *ledger, asn1_node item, char *
return NULL;
}
-// c = 64;
-// r = asn1_read_value(item, "signatureResponse", sig, (int*)&c);
-// if (r != ASN1_SUCCESS) {
-// printf("%d (%s) %s\n", r, err, asn1_strerror(r));
-// return NULL;
-// }
-
if (mode == KEE_LEDGER_STATE_FINAL) {
r = asn1_copy_node(root, "Kee.KeeEntry.signatureResponse", item, "signatureResponse");
if (r != ASN1_SUCCESS) {
@@ -693,7 +686,7 @@ int kee_ledger_item_serialize(struct kee_ledger_item_t *item, char *out, size_t
}
c = 5;
- if (item->response) {
+ if (item->response && mode > KEE_LEDGER_STATE_REQUEST) {
response_s = "TRUE";
} else {
response_s = "FALSE";
@@ -1022,7 +1015,13 @@ static struct kee_ledger_item_t* get_item_by_idx(struct kee_ledger_t *ledger, in
return item;
}
-static void get_authentication_params(struct kee_ledger_t *ledger, struct kee_ledger_item_t *item, char **pubkey_request, char **sig_request, char **pubkey_response, char **sig_response) {
+static int get_authentication_params(struct kee_ledger_t *ledger, struct kee_ledger_item_t *item, char **pubkey_request, char **sig_request, char **pubkey_response, char **sig_response, enum kee_initiator_e initiator) {
+ if (item->initiator == NOONE) {
+ item->initiator = initiator;
+ }
+ if (item->initiator == NOONE) {
+ return ERR_FAIL;
+ }
if (item->initiator == BOB) {
*pubkey_request = ledger->pubkey_bob;
*pubkey_response = ledger->pubkey_alice;
@@ -1040,13 +1039,33 @@ static void get_authentication_params(struct kee_ledger_t *ledger, struct kee_le
if (!memcmp(*sig_response, zero_content, SIGNATURE_LENGTH)) {
*sig_response = NULL;
}
+ return ERR_OK;
}
-// idx shows which item in ledger execution terminated
-int kee_ledger_verify(struct kee_ledger_t *ledger, int *idx) {
+static int verify_item(struct kee_ledger_t *ledger, struct kee_ledger_item_t *item, enum kee_ledger_state_e mode, const char *sig, const char *pubkey) {
int r;
char b[1024];
size_t c;
+
+ c = 960;
+ r = kee_ledger_item_serialize(item, ((char*)b)+DIGEST_LENGTH, &c, mode);
+ if (r) {
+ return ERR_FAIL;
+ }
+ r = kee_ledger_digest(ledger, b);
+ if (r) {
+ return ERR_FAIL;
+ }
+ r = verify_item_data(ledger, b, c + DIGEST_LENGTH, sig, pubkey);
+ if (r) {
+ return ERR_FAIL;
+ }
+ return ERR_OK;
+}
+
+// idx shows which item in ledger execution terminated
+int kee_ledger_verify(struct kee_ledger_t *ledger, int *idx) {
+ int r;
struct kee_ledger_item_t *item;
char *pubkey_request;
char *pubkey_response;
@@ -1059,41 +1078,38 @@ int kee_ledger_verify(struct kee_ledger_t *ledger, int *idx) {
return ERR_FAIL;
}
+ r = 0;
while (1) {
- get_authentication_params(ledger, item, &pubkey_request, &sig_request, &pubkey_response, &sig_response);
+ r = get_authentication_params(ledger, item, &pubkey_request, &sig_request, &pubkey_response, &sig_response, NOONE);
+ if (r) {
+ return ERR_FAIL;
+ }
if (sig_response == NULL) {
if (*idx > 0) {
return ERR_FAIL;
}
} else {
- c = 960;
- r = kee_ledger_item_serialize(item, ((char*)b)+DIGEST_LENGTH, &c, KEE_LEDGER_STATE_RESPONSE);
- if (r) {
- return ERR_FAIL;
- }
- r = kee_ledger_digest(ledger, b);
- if (r) {
- return ERR_FAIL;
- }
- r = verify_item_data(ledger, b, c + DIGEST_LENGTH, sig_response, pubkey_response);
- if (r) {
- return ERR_FAIL;
- }
+ r = verify_item(ledger, item, KEE_LEDGER_STATE_RESPONSE, sig_response, pubkey_response);
}
+
if (sig_request != NULL) {
- c = 960;
- r = kee_ledger_item_serialize(item, ((char*)b)+DIGEST_LENGTH, &c, KEE_LEDGER_STATE_REQUEST);
- if (r) {
- return ERR_FAIL;
- }
- r = kee_ledger_digest(ledger, b);
- if (r) {
- return ERR_FAIL;
- }
- r = verify_item_data(ledger, b, c + DIGEST_LENGTH, sig_request, pubkey_request);
- if (r) {
- return ERR_FAIL;
- }
+ r = verify_item(ledger, item, KEE_LEDGER_STATE_REQUEST, sig_request, pubkey_request);
+// c = 960;
+// r = kee_ledger_item_serialize(item, ((char*)b)+DIGEST_LENGTH, &c, KEE_LEDGER_STATE_REQUEST);
+// if (r) {
+// return ERR_FAIL;
+// }
+// r = kee_ledger_digest(ledger, b);
+// if (r) {
+// return ERR_FAIL;
+// }
+// r = verify_item_data(ledger, b, c + DIGEST_LENGTH, sig_request, pubkey_request);
+// if (r) {
+// return ERR_FAIL;
+// }
+ }
+ if (r) {
+ return ERR_FAIL;
}
item = item->prev_item;
if (item == NULL) {
@@ -1174,3 +1190,15 @@ enum kee_ledger_state_e kee_ledger_item_state(struct kee_ledger_item_t *item) {
return state;
}
+
+/// \todo consider optional verify with item signature
+/// \todo don't get confused; ledger alice is ALWAYS the requester, but when SIGNING alice is always the current keystore private key holder - consider renaming the latter to carol/dave...
+enum kee_initiator_e kee_ledger_item_initiator(struct kee_ledger_t *ledger, struct kee_ledger_item_t *item, struct gpg_store *gpg) {
+ item->initiator = NOONE;
+ if (!memcmp(ledger->pubkey_alice, gpg->public_key, PUBKEY_LENGTH)) {
+ item->initiator = ALICE;
+ } else if (memcmp(ledger->pubkey_bob, zero_content, PUBKEY_LENGTH)) {
+ item->initiator = BOB;
+ }
+ return item->initiator;
+}
diff --git a/src/ledger.h b/src/ledger.h
@@ -10,7 +10,7 @@
#include "digest.h"
enum kee_initiator_e {
- UNKNOWN,
+ NOONE,
ALICE,
BOB,
};
@@ -54,26 +54,25 @@ struct kee_ledger_t {
struct kee_ledger_cache_t *cache;
};
-struct kee_ledger_item_t *kee_ledger_parse_item(struct kee_ledger_t *ledger, const char *data, size_t data_len);
-struct kee_ledger_item_t *kee_ledger_add_item(struct kee_ledger_t *ledger);
int kee_ledger_parse(struct kee_ledger_t *ledger, const char *data, size_t data_len);
int kee_ledger_serialize(struct kee_ledger_t *ledger, char *out, size_t *out_len);
void kee_ledger_init(struct kee_ledger_t *ledger);
void kee_ledger_free(struct kee_ledger_t *ledger);
-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);
int kee_ledger_sign(struct kee_ledger_t *ledger, struct kee_ledger_item_t *item, struct gpg_store *gpg, 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_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);
int kee_ledger_item_put(struct kee_ledger_t *ledger, struct db_ctx *db, int idx);
int kee_ledger_verify(struct kee_ledger_t *ledger, int *err_idx);
+struct kee_ledger_item_t *kee_ledger_parse_item(struct kee_ledger_t *ledger, const char *data, size_t data_len);
+struct kee_ledger_item_t *kee_ledger_add_item(struct kee_ledger_t *ledger);
+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_ledger_state_e mode);
+void kee_ledger_item_free(struct kee_ledger_item_t *item);
+enum kee_ledger_state_e kee_ledger_item_state(struct kee_ledger_item_t *item);
+enum kee_initiator_e kee_ledger_item_initiator(struct kee_ledger_t *ledger, struct kee_ledger_item_t *item, struct gpg_store *gpg);
#endif
diff --git a/src/tests/ledger.c b/src/tests/ledger.c
@@ -188,6 +188,60 @@ int test_verify() {
return 0;
}
+int test_initiator() {
+ int r;
+ struct kee_test_t t;
+ struct kee_ledger_item_t *item;
+ enum kee_initiator_e initiator;
+
+ r = kee_test_generate(&t);
+ if (r) {
+ return 1;
+ }
+
+ item = t.ledger.last_item;
+
+ r = kee_test_sign_request(&t);
+ if (r) {
+ return 1;
+ }
+ r = kee_test_sign_response(&t);
+ if (r) {
+ return 1;
+ }
+
+ item->initiator = NOONE;
+ initiator = kee_ledger_item_initiator(&t.ledger, item, &t.gpg);
+ if (initiator != ALICE) {
+ return 1;
+ }
+
+ kee_test_free(&t);
+ r = kee_test_generate(&t);
+ if (r) {
+ return 1;
+ }
+
+ kee_test_swap_identities(&t);
+ r = kee_test_sign_request(&t);
+ if (r) {
+ return 1;
+ }
+ r = kee_test_sign_response(&t);
+ if (r) {
+ return 1;
+ }
+
+ item = t.ledger.last_item;
+ item->initiator = NOONE;
+ initiator = kee_ledger_item_initiator(&t.ledger, item, &t.gpg);
+ if (initiator != BOB) {
+ return 1;
+ }
+
+ return 0;
+}
+
int main() {
int i;
int r;
@@ -213,6 +267,11 @@ int main() {
return i;
}
i++;
+ r = test_initiator();
+ if (r) {
+ return i;
+ }
+ i++;
r = test_pair();
if (r) {
return i;
diff --git a/src/tests/testutil.c b/src/tests/testutil.c
@@ -33,6 +33,7 @@ int kee_test_db(struct kee_test_t *t) {
int kee_test_sign_request(struct kee_test_t *t) {
int r;
+ t->ledger.last_item->initiator = ALICE;
r = kee_ledger_sign(&t->ledger, t->ledger.last_item, &t->gpg, "1234");
if (r) {
return 1;
@@ -41,10 +42,19 @@ int kee_test_sign_request(struct kee_test_t *t) {
return 0;
}
+//int kee_test_swap_keys(struct kee_test_t *t) {
+// if (t->gpg.k == t->alice) {
+// t->gpg.k = t->bob;
+// } else {
+// t->gpg.k = t->alice;
+// }
+//}
+//
int kee_test_sign_response(struct kee_test_t *t) {
int r;
struct kee_ledger_item_t item_swap;
+ t->ledger.last_item->response = 1;
t->gpg.k = t->bob;
r = gpg_key_load(&t->gpg, "1234", KEE_GPG_FIND_FINGERPRINT, t->bob_fingerprint);
if (r) {
@@ -75,6 +85,29 @@ int kee_test_sign_response(struct kee_test_t *t) {
return 0;
}
+void kee_test_swap_identities(struct kee_test_t *t) {
+ char swap[128];
+ struct kee_ledger_t *ledger;
+ struct kee_ledger_item_t *item;
+
+ ledger = &t->ledger;
+ item = ledger->last_item;
+
+ memcpy(swap, ledger->pubkey_alice, PUBKEY_LENGTH);
+ memcpy(ledger->pubkey_alice, ledger->pubkey_bob, PUBKEY_LENGTH);
+ memcpy(ledger->pubkey_bob, swap, PUBKEY_LENGTH);
+
+// memcpy(swap, item->alice_signature, SIGNATURE_LENGTH);
+// memcpy(item->alice_signature, item->bob_signature, SIGNATURE_LENGTH);
+// memcpy(item->bob_signature, swap, SIGNATURE_LENGTH);
+
+ if (item->initiator == ALICE) {
+ item->initiator = BOB;
+ } else if (item->initiator == BOB) {
+ item->initiator = ALICE;
+ }
+
+}
int kee_test_generate(struct kee_test_t *t) {
int r;
@@ -158,9 +191,7 @@ int kee_test_generate(struct kee_test_t *t) {
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) {
@@ -196,6 +227,7 @@ void kee_test_free(struct kee_test_t *t) {
free(*p);
p++;
}
+ kee_ledger_free(&t->ledger);
}
size_t kee_test_get_ledger_data(struct kee_test_t *t, char **out) {
diff --git a/src/tests/testutil.h b/src/tests/testutil.h
@@ -35,5 +35,6 @@ size_t kee_test_get_ledger_item_data(struct kee_test_t *t, int idx, char **out);
int kee_test_db(struct kee_test_t *t);
int kee_test_sign_request(struct kee_test_t *t);
int kee_test_sign_response(struct kee_test_t *t);
+//void kee_test_swap_identities(struct kee_test_t *t);
#endif