commit 3b310df2078f8d6c5a1297908a1f24853fa70c12
parent 4c941396f33c8178398480e39f13ffaf5f544384
Author: lash <dev@holbrook.no>
Date: Sun, 21 Apr 2024 09:21:45 +0100
Add DN to pubkey, ldap dn parse on kee entry
Diffstat:
11 files changed, 217 insertions(+), 21 deletions(-)
diff --git a/README.md b/README.md
@@ -19,6 +19,7 @@ Below are the library versions of the [archlinux](https://archlinux.org/) compon
| libgcrypt | 1.10.3 |
| libxdg-basedir | 1.2.3 |
| lmdb | 0.9.32 |
+| openldap | 2.6.7 |
| rustup | 1.26.0 |
| zbar | 0.23.90 |
| zlib | 1.3.1 |
diff --git a/src/db.h b/src/db.h
@@ -29,6 +29,8 @@ enum DbKey {
DbKeyLedgerHead = 0x01,
/// A credit item record
DbKeyLedgerEntry = 0x02,
+ /// A DN record
+ DbKeyDN = 0x03,
/// A reverse lookup record; resolves the content hash to the content entry in the database.
DbKeyReverse = 0xff,
};
diff --git a/src/dn.c b/src/dn.c
@@ -0,0 +1,70 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include <ldap.h>
+
+#include "err.h"
+#include "dn.h"
+
+struct kee_dn_t* kee_dn_init(struct kee_dn_t *dn, size_t cap) {
+ if (cap == 0) {
+ cap = KEE_DN_DEFAULT_CAP;
+ }
+ dn->mem = malloc(cap);
+ dn->p = (char*)dn->mem;
+ dn->cn = NULL;
+ return dn;
+}
+
+int kee_dn_from_str(struct kee_dn_t *dn, const char *s, size_t l) {
+ int r;
+ int i;
+ LDAPDN ldn;
+ LDAPRDN lrdn;
+ LDAPAVA *ldnav;
+ char tmp[1024];
+ char *dst;
+
+ memcpy(tmp, s, l);
+ *(tmp+l) = 0;
+ r = ldap_str2dn(tmp, &ldn, LDAP_DN_FORMAT_LDAPV3);
+ if (r) {
+ return ERR_FAIL;
+ }
+
+ i = 0;
+ while(1) {
+ lrdn = *(ldn+i);
+ if (lrdn == NULL) {
+ break;
+ }
+ ldnav = *lrdn;
+
+ memcpy(tmp, ldnav->la_attr.bv_val, ldnav->la_attr.bv_len);
+ tmp[ldnav->la_attr.bv_len] = 0;
+ if (!strcmp(tmp, "CN")) {
+ dn->cn = dn->p;
+ dst = dn->cn;
+ } else if (!strcmp(tmp, "O")) {
+ dn->o = dn->p;
+ dst = dn->o;
+ } else {
+ return 1;
+ }
+ memcpy(dst, ldnav->la_value.bv_val, ldnav->la_value.bv_len);
+ *(dst+ldnav->la_value.bv_len) = 0;
+ dn->p += ldnav->la_value.bv_len + 1;
+ i++;
+ }
+ if (dn->cn == NULL) {
+ return 1;
+ }
+
+ ldap_dnfree(ldn);
+
+ return 0;
+}
+
+void kee_dn_free(struct kee_dn_t *dn) {
+ free(dn->mem);
+}
diff --git a/src/dn.h b/src/dn.h
@@ -0,0 +1,23 @@
+#ifndef KEE_DN_H_
+#define KEE_DN_H_
+
+#ifndef KEE_DN_DEFAULT_CAP
+#define KEE_DN_DEFAULT_CAP 1024
+#endif
+
+struct kee_dn_t {
+ char *mem;
+ char *p;
+ char *cn;
+ char *c;
+ char *o;
+ char *uid;
+ char *dc;
+};
+
+struct kee_dn_t* kee_dn_init(struct kee_dn_t *dn, size_t cap);
+int kee_dn_from_str(struct kee_dn_t *dn, const char *s, size_t l);
+void kee_dn_free(struct kee_dn_t *dn);
+
+#endif
+
diff --git a/src/gtk/Makefile b/src/gtk/Makefile
@@ -5,7 +5,7 @@ INCLUDES := -I.. -I../aux/include
CFLAGS += `pkg-config --cflags gtk4 gstreamer-1.0 libtasn1` $(INCLUDES) -g3 -Wall
#LIBS := `pkg-config --libs gtk4 zlib lmdb libgcrypt libxdg-basedir gstreamer-1.0 libcmime` -lb64
#LIBS := `pkg-config --libs gtk4 zlib lmdb libgcrypt libxdg-basedir gstreamer-1.0 libtasn1` -lb64 -lcmime -lvarint -llash
-LIBS := `pkg-config --libs gtk4 zlib lmdb libgcrypt libxdg-basedir gstreamer-1.0 libtasn1` -lb64 -lcmime -llash
+LIBS := `pkg-config --libs gtk4 zlib lmdb libgcrypt libxdg-basedir gstreamer-1.0 libtasn1` -lb64 -lcmime -llash -lldap
LDFLAGS += $(LIBS)
all: resource $(OBJS)
diff --git a/src/gtk/kee-entry-store.c b/src/gtk/kee-entry-store.c
@@ -62,6 +62,7 @@ static guint kee_entry_store_get_n_items(GListModel *list) {
static gpointer kee_entry_store_get_item(GListModel *list, guint index) {
+ int r;
KeeEntry *o;
KeeEntryStore *store;
@@ -71,7 +72,10 @@ static gpointer kee_entry_store_get_item(GListModel *list, guint index) {
kee_entry_set_resolver(o, &store->resolver);
kee_entry_store_seek(store, index);
//kee_entry_deserialize(o, store->last_key, 9, store->last_value, store->last_value_length);
- kee_entry_deserialize(o, store->last_value, store->last_value_length);
+ r = kee_entry_deserialize(o, store->last_value, store->last_value_length);
+ if (r) {
+ return NULL;
+ }
//return o;
kee_entry_apply_list_item_widget(o);
diff --git a/src/gtk/kee-entry.c b/src/gtk/kee-entry.c
@@ -19,6 +19,7 @@
#include "endian.h"
#include "strip.h"
#include "ledger.h"
+#include "dn.h"
typedef struct {
@@ -35,7 +36,8 @@ struct _KeeEntry {
GtkWidget parent;
int state;
char header[1024];
- char *current_id[128];
+ struct kee_dn_t bob_dn;
+ char current_id[128];
struct kee_ledger_t ledger;
struct Cadiz *resolver;
struct db_ctx *db;
@@ -68,6 +70,9 @@ static void kee_entry_finalize(GObject *o) {
KeeEntry *entry = KEE_ENTRY(o);
kee_ledger_free(&entry->ledger);
+
+ kee_dn_free(&entry->bob_dn);
+
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "tearing down entry");
//G_OBJECT_CLASS(kee_entry_parent_class)->finalize(o);
}
@@ -87,6 +92,7 @@ KeeEntry* kee_entry_new(struct db_ctx *db) {
KeeEntry *o;
o = KEE_ENTRY(g_object_new(KEE_TYPE_ENTRY, "orientation", GTK_ORIENTATION_VERTICAL, NULL));
o->db = db;
+ kee_dn_init(&o->bob_dn, 0);
return o;
}
@@ -96,6 +102,15 @@ void kee_entry_set_resolver(KeeEntry *o, struct Cadiz *resolver) {
int kee_entry_deserialize(KeeEntry *o, const char *data, size_t data_len) {
int r;
+ size_t key_len;
+ size_t last_value_length;
+ char mem[33 + 1024];
+ char *last_key;
+ char *last_value = mem + 33;
+
+ last_key = mem;
+ key_len = 33;
+ last_value_length = 1024;
r = kee_ledger_parse(&o->ledger, data, data_len);
if (r) {
@@ -103,6 +118,20 @@ int kee_entry_deserialize(KeeEntry *o, const char *data, size_t data_len) {
}
kee_content_resolve(&o->ledger.content, o->resolver);
+ last_value_length = 2048;
+ *last_key = DbKeyDN;
+ memcpy(last_key+1, o->ledger.pubkey_bob, 32);
+ key_len = 33;
+ r = db_next(o->db, DbKeyDN, &last_key, &key_len, &last_value, &last_value_length);
+ if (r) {
+ return ERR_FAIL;
+ }
+ db_rewind(o->db);
+ r = kee_dn_from_str(&o->bob_dn, last_value, last_value_length);
+ if (r) {
+ return ERR_FAIL;
+ }
+
r = calculate_digest_algo(data, data_len, o->current_id, GCRY_MD_SHA512);
if (r) {
return ERR_DIGESTFAIL;
@@ -132,16 +161,24 @@ static int kee_entry_deserialize_item(KeeEntry *o, const char *data, size_t data
}
void kee_entry_apply_list_item_widget(KeeEntry *o) {
+ int r;
GtkWidget *widget;
size_t l;
unsigned char alice_hex[129];
unsigned char bob_hex[129];
+ char *bob;
if (o->state) {
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "entry must be loaded first");
return;
}
+// bob = NULL;
+// r = ldap_rdn2str(*o->bob_dn, &bob, LDAP_DN_FORMAT_LDAPV3);
+// if (r) {
+// return;
+// }
+
l = 129;
bin_to_hex((unsigned char*)o->ledger.pubkey_alice, 64, alice_hex, &l);
l = 129;
@@ -149,7 +186,7 @@ void kee_entry_apply_list_item_widget(KeeEntry *o) {
sprintf(o->header, "[%s] %s -> %s", o->ledger.uoa, alice_hex, bob_hex);
widget = gtk_label_new(o->header);
gtk_box_append(GTK_BOX(o), widget);
- widget = gtk_label_new(o->ledger.content.subject);
+ widget = gtk_label_new(o->bob_dn.cn);
gtk_box_append(GTK_BOX(o), widget);
return;
}
@@ -226,6 +263,8 @@ void kee_entry_apply_entry(KeeEntry *target, KeeEntry *orig) {
memcpy(target->current_id, orig->current_id, 128);
target->resolver = orig->resolver;
target->ledger = orig->ledger;
+ target->state = orig->state;
+ target->bob_dn = orig->bob_dn;
return;
}
diff --git a/src/ledger.c b/src/ledger.c
@@ -299,6 +299,9 @@ struct kee_ledger_item_t *kee_ledger_parse_item(struct kee_ledger_t *ledger, con
}
void kee_ledger_item_free(struct kee_ledger_item_t *item) {
+ if (item == NULL) {
+ return;
+ }
if (item->prev_item != NULL) {
kee_ledger_item_free(item->prev_item);
}
diff --git a/src/tests/Makefile b/src/tests/Makefile
@@ -5,7 +5,7 @@ LINKOBJS := $(wildcard ../*.o)
INCLUDES := -I..
CFLAGS += `pkg-config --cflags gtk4 gstreamer-1.0` $(INCLUDES) -Wall
#LIBS := `pkg-config --libs gtk4 zlib lmdb libgcrypt libxdg-basedir gstreamer-1.0` -lb64 -lvarint -llash
-LIBS := `pkg-config --libs gtk4 zlib lmdb libgcrypt libxdg-basedir gstreamer-1.0` -lb64 -llash -ltasn1 -lcmime
+LIBS := `pkg-config --libs gtk4 zlib lmdb libgcrypt libxdg-basedir gstreamer-1.0` -lb64 -llash -ltasn1 -lcmime -lldap
LDFLAGS += $(LIBS)
all: obj_debug $(OBJS)
@@ -22,6 +22,7 @@ test_run:
./test_cadir
./test_content
./test_ledger
+ ./test_dn
test: all test_run
diff --git a/src/tests/dn.c b/src/tests/dn.c
@@ -0,0 +1,28 @@
+#include <string.h>
+#include <stddef.h>
+
+#include "dn.h"
+
+int main() {
+ int r;
+ struct kee_dn_t dn;
+
+ kee_dn_init(&dn, 0);
+
+ r = kee_dn_from_str(&dn, "CN=Foo Bar,O=Baz", 16);
+ if (r) {
+ return 1;
+ }
+
+ if (strcmp(dn.cn, "Foo Bar")) {
+ return 1;
+ }
+
+ if (strcmp(dn.o, "Baz")) {
+ return 1;
+ }
+
+ kee_dn_free(&dn);
+
+ return 0;
+}
diff --git a/testdata_asn1.py b/testdata_asn1.py
@@ -35,7 +35,7 @@ NOBODY = b'\x00' * 64
NOSIG = b''
PFX_LEDGER_HEAD = b'\x01'
PFX_LEDGER_ENTRY = b'\x02'
-PFX_LEDGER_COUNTERKEY = b'\x03'
+PFX_LEDGER_PUBKEY = b'\x03'
random.seed(int(time.time_ns()))
@@ -89,9 +89,18 @@ class LedgerSigner:
self.signer = {}
self.keypair = {}
self.pubkey_rindex = {}
+ self.names = {}
self.crypto_dir = crypto_dir
+ def get_pubkey(self, k):
+ return self.keypair[k][1]
+
+
+ def get_name(self, k):
+ return self.names[k]
+
+
def __write_key(self, keyname, outdir, pin):
(pk, pubk) = self.keypair[keyname]
wt = io.BytesIO()
@@ -132,7 +141,7 @@ class LedgerSigner:
w = open(fp, "wb")
w.write(b)
w.close()
-
+
def create_key(self, keyname, outdir=None, pin='1234'):
k = ECC.generate(curve='Ed25519')
@@ -141,6 +150,7 @@ 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
@@ -150,6 +160,8 @@ class LedgerSigner:
self.__write_key(keyname, outdir, pin)
+ self.names[keyname] = fake.name()
+
return pubk
@@ -303,7 +315,7 @@ class LedgerEntry(Ledger):
collateral_bob = 0
ms = 0
- def __init__(self, head, signer, generator, parent=None, body=NOBODY):
+ def __init__(self, head, signer, generator, parent=None, body=NOBODY, bob_name='bob'):
self.head = head
self.parent = parent
if self.parent == None:
@@ -315,9 +327,9 @@ class LedgerEntry(Ledger):
delta = generator.delta()
self.signer_sequence = []
if delta[2]:
- self.signer_sequence = ['bob', 'alice']
+ self.signer_sequence = [bob_name, 'alice']
else:
- self.signer_sequence = ['alice', 'bob']
+ self.signer_sequence = ['alice', bob_name]
self.credit_delta = delta[0]
self.collateral_delta = delta[1]
@@ -378,8 +390,8 @@ class LedgerEntry(Ledger):
return r
-def generate_entry(data_dir, signer, generator, head, parent):
- o = LedgerEntry(head, signer, generator, parent=parent)
+def generate_entry(data_dir, signer, generator, head, bob_name, parent):
+ o = LedgerEntry(head, signer, generator, parent=parent, bob_name=bob_name)
w = io.BytesIO()
r = o.serialize(data_dir, w=w)
h = hashlib.new('sha512')
@@ -389,7 +401,7 @@ def generate_entry(data_dir, signer, generator, head, parent):
return (z, b,)
-def generate_ledger(data_dir, signer, entry_count=3, alice=None, bob=None):
+def generate_ledger(dbi, data_dir, signer, bob_name, entry_count=3, alice=None, bob=None):
r = []
o = LedgerHead(alice_key=alice, bob_key=bob)
w = io.BytesIO()
@@ -408,7 +420,7 @@ def generate_ledger(data_dir, signer, entry_count=3, alice=None, bob=None):
generator = LedgerGenerator()
for i in range(entry_count):
try:
- v = generate_entry(data_dir, signer, generator, k, parent=parent)
+ v = generate_entry(data_dir, signer, generator, k, bob_name, parent)
except OverflowError:
break
# \todo generate key value already here
@@ -437,22 +449,29 @@ if __name__ == '__main__':
d = db_init(d)
- f = open('key.bin', 'wb')
+ env = lmdb.open(d)
+ dbi = env.open_db()
+
signer = LedgerSigner(crypto_dir)
- alice = signer.create_key('alice', data_dir)
- f.close()
+ alice = signer.create_key('alice', outdir=data_dir)
#bob = bob(d)
- bob = signer.create_key('bob', data_dir)
- env = lmdb.open(d)
- dbi = env.open_db()
+ keys = ['alice']
+
+ alice_key = os.path.join(crypto_dir, 'alice.key.bin')
+ os.unlink('key.bin')
+ os.symlink(alice_key, 'key.bin')
count_ledgers = os.environ.get('COUNT', '1')
with env.begin(write=True) as tx:
for i in range(int(count_ledgers)):
+ bob_name = 'Bob ' + fake.last_name()
+ keys.append(bob_name)
+ bob = signer.create_key(bob_name, outdir=data_dir)
+
c = random.randint(2, 20)
- r = generate_ledger(data_dir, signer, entry_count=c, alice=alice, bob=bob)
+ r = generate_ledger(dbi, data_dir, signer, bob_name, entry_count=c, alice=alice, bob=bob)
v = r.pop(0)
@@ -463,3 +482,9 @@ if __name__ == '__main__':
for v in r:
k = LedgerEntry.to_key(v[1], z)
tx.put(k, v[1])
+
+ for k in keys:
+ pubk = signer.get_pubkey(k)
+ name = signer.get_name(k).encode('utf-8')
+ tx.put(PFX_LEDGER_PUBKEY + pubk, b'CN=' + name)
+