commit 6db4d1cecaadc5336d78381b528d6d40147667ae
parent d10488b4fc62f6e6454edfe884df53035b45d9fa
Author: lash <dev@holbrook.no>
Date: Fri, 3 May 2024 16:57:49 +0100
Rehabilitate key load
Diffstat:
10 files changed, 93 insertions(+), 57 deletions(-)
diff --git a/requirements.txt b/requirements.txt
@@ -4,3 +4,4 @@ faker~=24.0.0
pycryptodome==3.20.0
asn1ate~=0.6
pyasn1~=0.5.0
+pygcrypt~=1.0.1
diff --git a/src/gpg.c b/src/gpg.c
@@ -200,8 +200,10 @@ static char *key_filename(struct gpg_store *gpg, char *path) {
static int key_from_data(gcry_sexp_t *key, const char *indata, size_t indata_len) {
gcry_error_t e;
+ size_t c;
- e = gcry_sexp_new(key, indata, indata_len, 1);
+ c = 0;
+ e = gcry_sexp_sscan(key, &c, indata, indata_len);
if (e != GPG_ERR_NO_ERROR) {
//debug_log(DEBUG_DEBUG, indata);
return ERR_KEYFAIL;
@@ -309,15 +311,15 @@ static int key_create_file(struct gpg_store *gpg, gcry_sexp_t *key, const char *
}
kl = gcry_sexp_sprint(*key, GCRYSEXP_FMT_CANON, NULL, 0);
- m = (size_t)kl;
+ m = (size_t)kl + 1;
p = (char*)v + sizeof(int);
c = 0;
- while (m > 0) {
- kl = gcry_sexp_sprint(*key, GCRYSEXP_FMT_CANON, p, BUFLEN-m);
- m -= (size_t)(kl + 1);
- p += kl;
- c += kl;
- }
+// while (m > 0) {
+// kl = gcry_sexp_sprint(*key, GCRYSEXP_FMT_CANON, p, BUFLEN-m);
+// m -= (size_t)(kl + 1);
+// p += kl;
+// c += kl;
+// }
memcpy(v, &c, sizeof(int));
m = c;
@@ -400,6 +402,7 @@ int gpg_key_create(struct gpg_store *gpg, const char *passphrase) {
return ERR_OK;
}
+/// \todo add key unload to destroy memory
int gpg_key_load(struct gpg_store *gpg, const char *passphrase, enum gpg_find_mode_e mode, const void *criteria) {
int r;
size_t c;
@@ -411,7 +414,7 @@ int gpg_key_load(struct gpg_store *gpg, const char *passphrase, enum gpg_find_mo
strcpy(path, gpg->path);
p = path + strlen(path);
strcpy(p, "kee.key");
- r = key_from_file(gpg->k, path, passphrase);
+ r = key_from_file(&gpg->k, path, passphrase);
if (r) {
return ERR_FAIL;
}
@@ -424,7 +427,7 @@ int gpg_key_load(struct gpg_store *gpg, const char *passphrase, enum gpg_find_mo
if (r) {
return ERR_FAIL;
}
- r = key_from_file(gpg->k, path, passphrase);
+ r = key_from_file(&gpg->k, path, passphrase);
if (r) {
return ERR_FAIL;
}
@@ -433,12 +436,12 @@ int gpg_key_load(struct gpg_store *gpg, const char *passphrase, enum gpg_find_mo
return ERR_FAIL;
}
- p = (char*)gcry_pk_get_keygrip(*gpg->k, (unsigned char*)gpg->fingerprint);
+ p = (char*)gcry_pk_get_keygrip(gpg->k, (unsigned char*)gpg->fingerprint);
if (p == NULL) {
return ERR_KEYFAIL;
}
- r = key_apply_public(gpg, *gpg->k);
+ r = key_apply_public(gpg, gpg->k);
if (r) {
return ERR_FAIL;
}
@@ -505,7 +508,9 @@ int gpg_store_check(struct gpg_store *gpg, const char *passphrase) {
char d[1024];
gcry_sexp_t k;
char *p;
- unsigned char fingerprint[20] = { 0x00 };
+ //unsigned char fingerprint[20] = { 0x00 };
+ unsigned char fingerprint[41] = { 0x00 };
+ //size_t fingerprint_len = 41;
size_t fingerprint_len = 41;
//char passphrase_hash[m_passphrase_digest_len];
char passphrase_hash[gpg->passphrase_digest_len];
@@ -525,39 +530,39 @@ int gpg_store_check(struct gpg_store *gpg, const char *passphrase) {
gpgVersion = v;
sprintf(d, "Using gpg version: %s", gpgVersion);
debug_log(DEBUG_INFO, d);
- //r = key_from_file(&k, p.c_str(), passphrase_hash);
- //r = key_from_file(&k, p, passphrase_hash);
- r = key_from_file(&k, gpg->path, passphrase_hash);
+// r = key_from_file(&k, gpg->path, passphrase_hash);
+ //r = gpg_key_load(gpg, passphrase_hash, KEE_GPG_FIND_MAIN, NULL);
+ r = gpg_key_load(gpg, passphrase_hash, KEE_GPG_FIND_MAIN, NULL);
if (r == ERR_KEYFAIL) {
char pp[2048];
- //sprintf(pp, "could not decrypt key in %s/key.bin", p.c_str());
- sprintf(pp, "could not decrypt key in %s/key.bin", p);
+ sprintf(pp, "could not decrypt key in %s/kee.key", p);
debug_log(DEBUG_INFO, pp);
return 1;
}
if (r != ERR_OK) {
char pp[2048];
- //sprintf(pp, "%s/key.bin", p.c_str());
- sprintf(pp, "%s/key.bin", p);
+ sprintf(pp, "%s/kee.key", p);
r = key_create_file(gpg, &k, passphrase_hash);
if (r != ERR_OK) {
return r;
}
- gcry_pk_get_keygrip(k, fingerprint);
- //bin_to_hex(fingerprint, 20, (unsigned char*)m_fingerprint, &fingerprint_len);
- bin_to_hex(fingerprint, 20, (unsigned char*)gpg->fingerprint, &fingerprint_len);
+ //gcry_pk_get_keygrip(k, fingerprint);
+ gcry_pk_get_keygrip(k, (unsigned char*)gpg->fingerprint);
+ //bin_to_hex(fingerprint, 20, (unsigned char*)gpg->fingerprint, &fingerprint_len);
+ bin_to_hex((unsigned char*)gpg->fingerprint, 20, (unsigned char*)fingerprint, &fingerprint_len);
char ppp[4096];
//sprintf(ppp, "created key %s from %s", m_fingerprint, pp);
- sprintf(ppp, "created key %s from %s", gpg->fingerprint, pp);
+ sprintf(ppp, "created key %s from %s", fingerprint, pp);
debug_log(DEBUG_INFO, ppp);
} else {
- gcry_pk_get_keygrip(k, fingerprint);
- //bin_to_hex(fingerprint, 20, (unsigned char*)m_fingerprint, &fingerprint_len);
- bin_to_hex(fingerprint, 20, (unsigned char*)gpg->fingerprint, &fingerprint_len);
+ //gcry_pk_get_keygrip(k, fingerprint);
+ gcry_pk_get_keygrip(k, (unsigned char*)gpg->fingerprint);
+ //bin_to_hex(fingerprint, 20, (unsigned char*)gpg->fingerprint, &fingerprint_len);
+ bin_to_hex((unsigned char*)gpg->fingerprint, 20, (unsigned char*)fingerprint, &fingerprint_len);
char pp[4096];
//sprintf(pp, "found key %s in %s", (unsigned char*)m_fingerprint, p.c_str());
- sprintf(pp, "found key %s in %s", (unsigned char*)gpg->fingerprint, p);
- debug_log(DEBUG_INFO, pp);
+ sprintf(pp, "found key %s in path: %s", fingerprint, p);
+ //debug_log(DEBUG_INFO, pp);
}
//r = gpg_sign(&o, &k, sign_test);
//return r;
@@ -571,7 +576,6 @@ int gpg_store_sign(struct gpg_store *gpg, char *data, size_t data_len, const cha
int gpg_store_sign_with(struct gpg_store *gpg, char *data, size_t data_len, const char *passphrase, const char *fingerprint) {
int r;
size_t c;
- gcry_sexp_t key;
gcry_sexp_t pnt;
gcry_sexp_t msg;
gcry_sexp_t sig;
@@ -583,7 +587,6 @@ int gpg_store_sign_with(struct gpg_store *gpg, char *data, size_t data_len, cons
return 1;
}
- gpg->k = &key;
if (fingerprint == NULL) {
r = gpg_key_load(gpg, passphrase, KEE_GPG_FIND_MAIN, NULL);
} else {
@@ -599,7 +602,7 @@ int gpg_store_sign_with(struct gpg_store *gpg, char *data, size_t data_len, cons
return 1;
}
- e = gcry_pk_sign(&sig, msg, *gpg->k);
+ e = gcry_pk_sign(&sig, msg, gpg->k);
if (e != GPG_ERR_NO_ERROR) {
return 1;
}
@@ -630,8 +633,7 @@ int gpg_store_sign_with(struct gpg_store *gpg, char *data, size_t data_len, cons
}
memcpy(gpg->last_signature + POINT_LENGTH, p, c);
- gcry_sexp_release(*gpg->k);
- gpg->k = NULL;
+ gcry_sexp_release(gpg->k);
return 0;
}
diff --git a/src/gpg.h b/src/gpg.h
@@ -24,7 +24,7 @@ enum gpg_find_mode_e {
};
struct gpg_store {
- gcry_sexp_t *k;
+ gcry_sexp_t k;
size_t passphrase_digest_len;
char fingerprint[FINGERPRINT_LENGTH];
char public_key[PUBKEY_LENGTH];
diff --git a/src/gtk/kee-entry.c b/src/gtk/kee-entry.c
@@ -110,13 +110,13 @@ static void kee_entry_handle_add(GtkButton *butt, KeeEntry *o) {
buf = gtk_entry_get_buffer(o->form->bob_pubkey);
b = (char*)gtk_entry_buffer_get_text(buf);
c = hex2bin(b, (unsigned char*)o->ledger.pubkey_bob);
-// if (c == 0) {
+ if (c == 0) {
// g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "invalid counterparty public key data");
// return;
// } else if (c != PUBKEY_LENGTH) {
// g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "wrong size for counterparty public key");
// return;
-// }
+ }
o->state |= ENTRYSTATE_LOAD;
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "adding ledger entry");
@@ -128,6 +128,14 @@ static void kee_entry_handle_add(GtkButton *butt, KeeEntry *o) {
return;
}
+ buf = gtk_entry_get_buffer(o->form->passphrase);
+ b = (char*)gtk_entry_buffer_get_text(buf);
+ r = kee_ledger_sign(&o->ledger, o->ledger.last_item, o->gpg, b);
+ if (r) {
+ g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "fail entry sign");
+ return;
+ }
+
r = kee_ledger_serialize_open(&o->ledger, out, &out_len);
if (r) {
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "qr transport renderer failed");
@@ -151,6 +159,7 @@ static void kee_entry_handle_add(GtkButton *butt, KeeEntry *o) {
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "read from qr transport renderer failed");
return;
}
+ /// \todo verify that this frees the buffer
transport_data = g_variant_new_take_string(out);
widget = gtk_widget_get_ancestor(GTK_WIDGET(o), GTK_TYPE_WINDOW);
diff --git a/src/gtk/kee-key.c b/src/gtk/kee-key.c
@@ -4,6 +4,7 @@
#include "kee-key.h"
#include "gpg.h"
#include "err.h"
+#include "hex.h"
typedef struct {
} KeeKeyPrivate;
@@ -39,8 +40,8 @@ static void kee_key_class_init(KeeKeyClass *kls) {
static void kee_key_init(KeeKey *o) {
}
-static void kee_key_finalize(KeeKey *o) {
-}
+//static void kee_key_finalize(KeeKey *o) {
+//}
static void kee_key_handle_unlock_click(GtkWidget *button, KeeKey *o) {
int r;
@@ -87,6 +88,10 @@ KeeKey* kee_key_new(struct gpg_store *gpg) {
}
const char *kee_key_get_fingerprint(KeeKey *o, char *fingerprint) {
- strcpy(fingerprint, o->gpg->fingerprint);
+ size_t fingerprint_len;
+
+ fingerprint_len = 41;
+ bin_to_hex((unsigned char*)o->gpg->fingerprint, 20, (unsigned char*)fingerprint, &fingerprint_len);
+ //strcpy(fingerprint, o->gpg->fingerprint);
return fingerprint;
}
diff --git a/src/ledger.c b/src/ledger.c
@@ -725,17 +725,21 @@ int kee_ledger_item_serialize(struct kee_ledger_item_t *item, char *out, size_t
/// \todo remove external buffer
-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, 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) {
int r;
char *p;
size_t c;
size_t l;
+ char out[1024];
+ size_t out_len;
enum kee_ledger_state_e mode;
- p = out;
- c = *out_len;
- l = *out_len;
- *out_len = 0;
+ out_len = 1024;
+ p = (char*)out;
+ c = out_len;
+ l = out_len;
+ out_len = 0;
mode = KEE_LEDGER_STATE_REQUEST;
if (item->initiator == BOB) {
@@ -753,16 +757,16 @@ int kee_ledger_sign(struct kee_ledger_t *ledger, struct kee_ledger_item_t *item,
c = DIGEST_LENGTH;
p = out + c;
l -= c;
- *out_len += c;
+ out_len += c;
c = l;
r = kee_ledger_item_serialize(item, p, &c, mode);
if (r) {
return ERR_FAIL;
}
- *out_len += c;
+ out_len += c;
- r = gpg_store_sign_with(gpg, out, *out_len, passphrase, gpg->fingerprint);
+ r = gpg_store_sign_with(gpg, (char*)out, out_len, passphrase, gpg->fingerprint);
if (r) {
return ERR_FAIL;
}
diff --git a/src/ledger.h b/src/ledger.h
@@ -61,7 +61,8 @@ 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, 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);
diff --git a/src/settings.c b/src/settings.c
@@ -25,7 +25,7 @@ int settings_new_from_xdg(struct kee_settings *z) {
memset(z, 0, sizeof(struct kee_settings));
- z->key = (unsigned char*)".";
+ z->key = (unsigned char*)"./testdata_crypt";
z->data = malloc(KEE_SETTINGS_CAP);
p = z->data;
diff --git a/src/tests/testutil.c b/src/tests/testutil.c
@@ -35,7 +35,8 @@ int kee_test_sign_request(struct kee_test_t *t) {
size_t c;
c = 1024;
- r = kee_ledger_sign(&t->ledger, t->ledger.last_item, &t->gpg, b, &c, "1234");
+ //r = kee_ledger_sign(&t->ledger, t->ledger.last_item, &t->gpg, b, &c, "1234");
+ r = kee_ledger_sign(&t->ledger, t->ledger.last_item, &t->gpg, "1234");
if (r) {
return 1;
}
@@ -64,7 +65,8 @@ int kee_test_sign_response(struct kee_test_t *t) {
memcpy(t->ledger.last_item->bob_signature, t->ledger.last_item->alice_signature, SIGNATURE_LENGTH);
memset(t->ledger.last_item->alice_signature, 0, SIGNATURE_LENGTH);
- r = kee_ledger_sign(&t->ledger, t->ledger.last_item, &t->gpg, b, &c, "1234");
+ //r = kee_ledger_sign(&t->ledger, t->ledger.last_item, &t->gpg, b, &c, "1234");
+ r = kee_ledger_sign(&t->ledger, t->ledger.last_item, &t->gpg, "1234");
if (r) {
return 1;
}
diff --git a/testdata_asn1.py b/testdata_asn1.py
@@ -19,6 +19,8 @@ from faker.providers import lorem
import varint
from pyasn1.codec.der.encoder import encode as der_encode
from pyasn1.codec.der.decoder import decode as der_decode
+from pygcrypt.gctypes.sexpression import SExpression
+from pygcrypt.gctypes.key import Key as GKey
from testdata_asn1schema import KeeEntryHead
from testdata_asn1schema import KeeEntry
@@ -84,6 +86,7 @@ class LedgerEntryContent(LedgerContent):
pass
+# TODO: do everything with pygcrypt, or calc keygrip with pycryptodome 8|
class LedgerSigner:
def __init__(self, crypto_dir):
@@ -105,9 +108,9 @@ class LedgerSigner:
def __write_key(self, keyname, outdir, pin):
(pk, pubk) = self.keypair[keyname]
wt = io.BytesIO()
- wt.write(b"(8:key-data(10:public-key(3:ecc(5:curve7:Ed25519)(1:q32:")
+ wt.write(b"(8:key-data(10:public-key(3:ecc(5:curve7:Ed25519)(5:flags5:eddsa)(1:q32:")
wt.write(pubk)
- wt.write(b")))(11:private-key(3:ecc(5:curve7:Ed25519)(1:q32:")
+ wt.write(b")))(11:private-key(3:ecc(5:curve7:Ed25519)(5:flags5:eddsa)(1:q32:")
wt.write(pubk)
wt.write(b")(1:d32:")
wt.write(pk)
@@ -118,6 +121,9 @@ class LedgerSigner:
w.write(b)
w.close()
+ sexp = SExpression(b)
+ gk = GKey(sexp)
+
l = len(b)
bl = l.to_bytes(4, byteorder='little')
h = hashlib.new('sha256')
@@ -133,8 +139,12 @@ class LedgerSigner:
w.write(nonce + r)
w.close()
+ # symlink key to keygrip
+ lp = os.path.join(self.crypto_dir, gk.keygrip)
+ os.symlink(fp, lp)
+
wt = io.BytesIO()
- wt.write(b"(8:key-data(10:public-key(3:ecc(5:curve7:Ed25519)(1:q32:")
+ wt.write(b"(8:key-data(10:public-key(3:ecc(5:curve7:Ed25519)(5:flags5:eddsa)(1:q32:")
wt.write(pubk)
wt.write(b"))))")
b = wt.getvalue()
@@ -151,7 +161,6 @@ class LedgerSigner:
pk = Crypto.Util.asn1.DerOctetString().decode(pk_der[1], strict=True).payload
pubk = k.public_key().export_key(format='raw')
-
self.signer[keyname] = eddsa.new(k, 'rfc8032')
self.keypair[keyname] = (pk, pubk)
self.pubkey_rindex[pubk] = keyname
@@ -461,7 +470,10 @@ if __name__ == '__main__':
os.unlink('kee.key')
except FileNotFoundError:
pass
- os.symlink(alice_key, 'kee.key')
+ alice_key_sym = 'kee.key'
+ os.symlink(alice_key, alice_key_sym)
+ alice_key_sym = os.path.join(crypto_dir, alice_key_sym)
+ os.symlink(alice_key, alice_key_sym)
count_ledgers = os.environ.get('COUNT', '1')