From: Jonathan McDowell <noodles@earth.li>
Date: Fri, 11 Jun 2004 18:18:22 +0000 (+0000)
Subject: Inital subkey searching support for db3 backend.
X-Git-Url: https://git.sommitrealweird.co.uk/onak.git/commitdiff_plain/010b333715b8385c78c4bacaf9031e9faed42cfd?ds=inline;hp=e0e1556867850c43983674881ca00436ceec13a8

Inital subkey searching support for db3 backend.
Adds support for searching on keys via a subkey. Only supported by the db3
backend so far.
---

diff --git a/decodekey.c b/decodekey.c
index 8fca176..5818488 100644
--- a/decodekey.c
+++ b/decodekey.c
@@ -249,3 +249,30 @@ char **keyuids(struct openpgp_publickey *key, char **primary)
 
 	return uids;
 }
+
+/**
+ *	keysubkeys - Takes a key and returns an array of its subkey keyids.
+ *	@key: The key to get the subkeys of.
+ *
+ *	keysubkeys takes a public key structure and returns an array of the
+ *	subkey keyids for that key.
+ */
+uint64_t *keysubkeys(struct openpgp_publickey *key)
+{
+	struct openpgp_signedpacket_list *cursubkey = NULL;
+	uint64_t                         *subkeys = NULL;
+	int                               count = 0;
+        
+	if (key != NULL && key->subkeys != NULL) {
+		subkeys = malloc((spsize(key->subkeys) + 1) *
+				sizeof (uint64_t));
+		cursubkey = key->subkeys;
+		while (cursubkey != NULL) {
+			subkeys[count++] = get_packetid(cursubkey->packet);
+			cursubkey = cursubkey -> next;
+		}
+		subkeys[count] = NULL;
+	}
+
+	return subkeys;
+}
diff --git a/decodekey.h b/decodekey.h
index 91929d3..ba3027b 100644
--- a/decodekey.h
+++ b/decodekey.h
@@ -44,4 +44,13 @@ uint64_t sig_keyid(struct openpgp_packet *packet);
  */
 char **keyuids(struct openpgp_publickey *key, char **primary);
 
+/**
+ *	keysubkeys - Takes a key and returns an array of its subkey keyids.
+ *	@key: The key to get the subkeys of.
+ *
+ *	keysubkeys takes a public key structure and returns an array of the
+ *	subkey keyids for that key.
+ */
+uint64_t *keysubkeys(struct openpgp_publickey *key);
+
 #endif
diff --git a/keydb_db3.c b/keydb_db3.c
index 27b090e..191ebc6 100644
--- a/keydb_db3.c
+++ b/keydb_db3.c
@@ -490,6 +490,7 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update)
 	DBT        data;
 	uint64_t   keyid = 0;
 	uint32_t   shortkeyid = 0;
+	uint64_t  *subkeyids = NULL;
 	char     **uids = NULL;
 	char      *primary = NULL;
 	unsigned char worddb_data[12];
@@ -660,6 +661,39 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update)
 		}
 	}
 
+	if (!deadlock) {
+		subkeyids = keysubkeys(publickey);
+		i = 0;
+		while (subkeyids != NULL && subkeyids[i] != 0) {
+			shortkeyid = subkeyids[i++] & 0xFFFFFFFF;
+
+			memset(&key, 0, sizeof(key));
+			memset(&data, 0, sizeof(data));
+			key.data = &shortkeyid;
+			key.size = sizeof(shortkeyid);
+			data.data = &keyid;
+			data.size = sizeof(keyid);
+
+			ret = id32db->put(id32db,
+				txn,
+				&key,
+				&data,
+				0);
+			if (ret != 0) {
+				logthing(LOGTHING_ERROR,
+					"Problem storing short keyid: %s",
+					db_strerror(ret));
+				if (ret == DB_LOCK_DEADLOCK) {
+					deadlock = true;
+				}
+			}
+		}
+		if (subkeyids != NULL) {
+			free(subkeyids);
+			subkeyids = NULL;
+		}
+	}
+
 	return deadlock ? -1 : 0 ;
 }
 
@@ -677,6 +711,7 @@ int delete_key(uint64_t keyid, bool intrans)
 	DBT key, data;
 	DBC *cursor = NULL;
 	uint32_t   shortkeyid = 0;
+	uint64_t  *subkeyids = NULL;
 	int ret = 0;
 	int i;
 	char **uids = NULL;
@@ -811,6 +846,48 @@ int delete_key(uint64_t keyid, bool intrans)
 				deadlock = true;
 			}
 		}
+
+		subkeyids = keysubkeys(publickey);
+		i = 0;
+		while (subkeyids != NULL && subkeyids[i] != 0) {
+			shortkeyid = subkeyids[i++] & 0xFFFFFFFF;
+
+			memset(&key, 0, sizeof(key));
+			memset(&data, 0, sizeof(data));
+			key.data = &shortkeyid;
+			key.size = sizeof(shortkeyid);
+			data.data = &keyid;
+			data.size = sizeof(keyid);
+
+			ret = cursor->c_get(cursor,
+				&key,
+				&data,
+				DB_GET_BOTH);
+
+			if (ret == 0) {
+				ret = cursor->c_del(cursor, 0);
+				if (ret != 0) {
+					logthing(LOGTHING_ERROR,
+						"Problem deleting short"
+						" keyid: %s",
+						db_strerror(ret));
+				}
+			}
+
+			if (ret != 0) {
+				logthing(LOGTHING_ERROR,
+					"Problem deleting short keyid: %s",
+					db_strerror(ret));
+				if (ret == DB_LOCK_DEADLOCK) {
+					deadlock = true;
+				}
+			}
+		}
+		if (subkeyids != NULL) {
+			free(subkeyids);
+			subkeyids = NULL;
+		}
+
 		ret = cursor->c_close(cursor);
 		cursor = NULL;
 	}