*/
void (*endtrans)(struct onak_dbctx *);
+/**
+ * @brief Given a fingerprint fetch the key from storage.
+ * @param fp The fingerprint to fetch.
+ * @param fpsize Number of bytes in the fingerprint (16 for v3, 20 for v4)
+ * @param publickey A pointer to a structure to return the key in.
+ * @param intrans If we're already in a transaction.
+ *
+ * This function returns a public key from whatever storage mechanism we
+ * are using. This only searches for the fingerprint of the primary key
+ * and will thus only ever return at most a single key.
+ */
+ int (*fetch_key)(struct onak_dbctx *,
+ struct openpgp_fingerprint *fingerprint,
+ struct openpgp_publickey **publickey,
+ bool intrans);
+
/**
* @brief Given a keyid fetch the key from storage.
* @param keyid The keyid to fetch.
* @param intrans If we're already in a transaction.
*
* This function returns a public key from whatever storage mechanism we
- * are using.
- *
- * TODO: What about keyid collisions? Should we use fingerprint instead?
+ * are using. It may return multiple keys in the case where there are
+ * colliding keyids.
*/
int (*fetch_key_id)(struct onak_dbctx *,
uint64_t keyid,
* @param intrans If we're already in a transaction.
*
* This function returns a public key from whatever storage mechanism we
- * are using.
+ * are using. Although the fingerprint should be unique this function may
+ * also search subkeys, which could be bound to multiple primary keys. As
+ * a result multiple keys may be returned.
*/
int (*fetch_key_fp)(struct onak_dbctx *,
struct openpgp_fingerprint *fingerprint,
struct openpgp_publickey **publickey,
bool intrans);
+/**
+ * @brief Tries to find the keys that contain the supplied text.
+ * @param search The text to search for.
+ * @param publickey A pointer to a structure to return the key in.
+ *
+ * This function searches for the supplied text and returns the keys that
+ * contain it. It is likely it will return multiple keys.
+ */
+ int (*fetch_key_text)(struct onak_dbctx *, const char *search,
+ struct openpgp_publickey **publickey);
+
+/**
+ * @brief Tries to find the keys from an SKS hash
+ * @param hash The hash to search for.
+ * @param publickey A pointer to a structure to return the key in.
+ *
+ * This function looks for the key that is referenced by the supplied
+ * SKS hash and returns it.
+ */
+ int (*fetch_key_skshash)(struct onak_dbctx *,
+ const struct skshash *hash,
+ struct openpgp_publickey **publickey);
+
/**
* @brief Takes a key and stores it.
* @param publickey A pointer to the public key to store.
int (*delete_key)(struct onak_dbctx *, struct openpgp_fingerprint *fp,
bool intrans);
-/**
- * @brief Trys to find the keys that contain the supplied text.
- * @param search The text to search for.
- * @param publickey A pointer to a structure to return the key in.
- *
- * This function searches for the supplied text and returns the keys that
- * contain it.
- */
- int (*fetch_key_text)(struct onak_dbctx *, const char *search,
- struct openpgp_publickey **publickey);
-
-/**
- * @brief Tries to find the keys from an SKS hash
- * @param hash The hash to search for.
- * @param publickey A pointer to a structure to return the key in.
- *
- * This function looks for the key that is referenced by the supplied
- * SKS hash and returns it.
- */
- int (*fetch_key_skshash)(struct onak_dbctx *,
- const struct skshash *hash,
- struct openpgp_publickey **publickey);
-
/**
* @brief Takes a list of public keys and updates them in the DB.
* @param keys The keys to update in the DB.
}
}
break;
+ case KEYD_CMD_GET:
+ if (!keyd_write_reply(fd, KEYD_REPLY_OK)) {
+ ret = 1;
+ }
+ if (ret == 0) {
+ if ((read(fd, &bytes, 1) != 1) ||
+ (bytes > MAX_FINGERPRINT_LEN)) {
+ ret = 1;
+ } else {
+ fingerprint.length = bytes;
+ bytes = read(fd, fingerprint.fp,
+ fingerprint.length);
+ if (bytes != fingerprint.length) {
+ ret = 1;
+ }
+ }
+ }
+ if (ret == 0) {
+ logthing(LOGTHING_INFO,
+ "Fetching by fingerprint"
+ ", result: %d",
+ dbctx->fetch_key(dbctx,
+ &fingerprint,
+ &key, false));
+ if (key != NULL) {
+ keyd_write_key(fd, key);
+ free_publickey(key);
+ key = NULL;
+ } else {
+ if (!keyd_write_size(fd, 0)) {
+ ret = 1;
+ }
+ }
+ }
+ break;
case KEYD_CMD_GET_ID:
if (!keyd_write_reply(fd, KEYD_REPLY_OK)) {
ret = 1;
}
}
break;
-
case KEYD_CMD_GET_TEXT:
if (!keyd_write_reply(fd, KEYD_REPLY_OK)) {
ret = 1;
KEYD_CMD_GET_SKSHASH,
KEYD_CMD_GET_FP,
KEYD_CMD_UPDATE,
+ KEYD_CMD_GET,
KEYD_CMD_LAST /* Placeholder */
};
* keys need the top 64 bits. This doesn't work for v3 keys,
* but there's no way to map from v3 fingerprint to v3 key ID so
* if the backend can't do it we're going to fail anyway.
+ *
+ * We are also assuming they store a single key based on the ID, so
+ * we are implementing fetch_key rather than fetch_key_fp
*/
keyid = 0;
if (fingerprint->length == 20) {
return dbctx->fetch_key_id(dbctx, keyid, publickey, intrans);
}
#endif
+
+#ifdef NEED_GET
+/*
+ * This fetches a key by fingerprint from the back end, then filters
+ * out what we got back to ensure it's the primary key that matches the
+ * fingerprint, and that only one is returned.
+ */
+static int generic_fetch_key(struct onak_dbctx *dbctx,
+ struct openpgp_fingerprint *fingerprint,
+ struct openpgp_publickey **publickey,
+ bool intrans)
+{
+ struct openpgp_publickey *curkey, **newkey;
+ struct openpgp_publickey *keys;
+ struct openpgp_fingerprint fp;
+ int count;
+
+ /* Find the last key in the provided set of keys */
+ for (newkey = publickey; *newkey != NULL; newkey = &(*newkey)->next)
+ ;
+
+ keys = NULL;
+ dbctx->fetch_key_fp(dbctx, fingerprint, &keys, intrans);
+
+ count = 0;
+ for (curkey = keys; curkey != NULL; curkey = curkey->next) {
+ if (get_fingerprint(curkey->publickey, &fp) == ONAK_E_OK) {
+ if (fingerprint_cmp(fingerprint, &fp) == 0) {
+ *newkey = curkey;
+ curkey = curkey->next;
+ (*newkey)->next = NULL;
+ count = 1;
+ break;
+ }
+ }
+ }
+ free_publickey(keys);
+
+ return count;
+}
+#endif
/**
* fetch_key_fp - Given a fingerprint fetch the key from storage.
*/
-static int db4_fetch_key_fp(struct onak_dbctx *dbctx,
+static int db4_fetch_key_int(struct onak_dbctx *dbctx,
struct openpgp_fingerprint *fingerprint,
struct openpgp_publickey **publickey,
- bool intrans)
+ bool intrans,
+ bool dosubkey)
{
struct onak_db4_dbctx *privctx = (struct onak_db4_dbctx *) dbctx->priv;
struct openpgp_packet_list *packets = NULL;
&data,
0); /* flags*/
- if (ret == DB_NOTFOUND) {
+ if (ret == DB_NOTFOUND && dosubkey) {
/* If we didn't find the key ID see if it's a subkey ID */
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
return (numkeys);
}
+static int db4_fetch_key(struct onak_dbctx *dbctx,
+ struct openpgp_fingerprint *fingerprint,
+ struct openpgp_publickey **publickey,
+ bool intrans)
+{
+ return db4_fetch_key_int(dbctx, fingerprint, publickey, intrans, false);
+}
+
+static int db4_fetch_key_fp(struct onak_dbctx *dbctx,
+ struct openpgp_fingerprint *fingerprint,
+ struct openpgp_publickey **publickey,
+ bool intrans)
+{
+ return db4_fetch_key_int(dbctx, fingerprint, publickey, intrans, true);
+}
+
/**
* fetch_key_id - Given a keyid fetch the key from storage.
* @keyid: The keyid to fetch.
dbctx->cleanupdb = db4_cleanupdb;
dbctx->starttrans = db4_starttrans;
dbctx->endtrans = db4_endtrans;
- dbctx->fetch_key_id = db4_fetch_key_id;
+ dbctx->fetch_key = db4_fetch_key;
dbctx->fetch_key_fp = db4_fetch_key_fp;
+ dbctx->fetch_key_id = db4_fetch_key_id;
dbctx->fetch_key_text = db4_fetch_key_text;
dbctx->fetch_key_skshash = db4_fetch_key_skshash;
dbctx->store_key = db4_store_key;
privctx->loadeddbctx->endtrans(privctx->loadeddbctx);
}
-static int dynamic_fetch_key_id(struct onak_dbctx *dbctx, uint64_t keyid,
+static int dynamic_fetch_key(struct onak_dbctx *dbctx,
+ struct openpgp_fingerprint *fingerprint,
struct openpgp_publickey **publickey, bool intrans)
{
struct onak_dynamic_dbctx *privctx =
(struct onak_dynamic_dbctx *) dbctx->priv;
- return privctx->loadeddbctx->fetch_key_id(privctx->loadeddbctx, keyid,
- publickey, intrans);
+ return privctx->loadeddbctx->fetch_key(privctx->loadeddbctx,
+ fingerprint, publickey, intrans);
}
static int dynamic_fetch_key_fp(struct onak_dbctx *dbctx,
struct onak_dynamic_dbctx *privctx =
(struct onak_dynamic_dbctx *) dbctx->priv;
- return privctx->loadeddbctx->fetch_key_fp(privctx->loadeddbctx,
+ if (privctx->loadeddbctx->fetch_key_fp)
+ return privctx->loadeddbctx->fetch_key_fp(privctx->loadeddbctx,
fingerprint, publickey, intrans);
+ else
+ return privctx->loadeddbctx->fetch_key(privctx->loadeddbctx,
+ fingerprint, publickey, intrans);
+}
+
+static int dynamic_fetch_key_id(struct onak_dbctx *dbctx, uint64_t keyid,
+ struct openpgp_publickey **publickey, bool intrans)
+{
+ struct onak_dynamic_dbctx *privctx =
+ (struct onak_dynamic_dbctx *) dbctx->priv;
+
+ return privctx->loadeddbctx->fetch_key_id(privctx->loadeddbctx, keyid,
+ publickey, intrans);
}
static int dynamic_fetch_key_text(struct onak_dbctx *dbctx,
dbctx->cleanupdb = dynamic_cleanupdb;
dbctx->starttrans = dynamic_starttrans;
dbctx->endtrans = dynamic_endtrans;
- dbctx->fetch_key_id = dynamic_fetch_key_id;
+ dbctx->fetch_key = dynamic_fetch_key;
dbctx->fetch_key_fp = dynamic_fetch_key_fp;
+ dbctx->fetch_key_id = dynamic_fetch_key_id;
dbctx->fetch_key_text = dynamic_fetch_key_text;
dbctx->fetch_key_skshash = dynamic_fetch_key_skshash;
dbctx->store_key = dynamic_store_key;
dbctx->cleanupdb = file_cleanupdb;
dbctx->starttrans = file_starttrans;
dbctx->endtrans = file_endtrans;
- dbctx->fetch_key_id = file_fetch_key_id;
+ /* Our fetch fp doesn't look at subkeys */
+ dbctx->fetch_key = generic_fetch_key_fp;
dbctx->fetch_key_fp = generic_fetch_key_fp;
+ dbctx->fetch_key_id = file_fetch_key_id;
dbctx->fetch_key_text = file_fetch_key_text;
dbctx->store_key = file_store_key;
dbctx->update_keys = generic_update_keys;
#define NEED_KEYID2UID 1
#define NEED_GETKEYSIGS 1
#define NEED_UPDATEKEYS 1
+#define NEED_GET 1
#define NEED_GET_FP 1
#include "keydb.c"
dbctx->cleanupdb = fs_cleanupdb;
dbctx->starttrans = fs_starttrans;
dbctx->endtrans = fs_endtrans;
- dbctx->fetch_key_id = fs_fetch_key_id;
+ dbctx->fetch_key = generic_fetch_key;
dbctx->fetch_key_fp = generic_fetch_key_fp;
+ dbctx->fetch_key_id = fs_fetch_key_id;
dbctx->fetch_key_text = fs_fetch_key_text;
dbctx->fetch_key_skshash = fs_fetch_key_skshash;
dbctx->store_key = fs_store_key;
return count;
}
-/**
- * hkp_fetch_key_id - Given a keyid fetch the key from HKP server.
- */
-static int hkp_fetch_key_id(struct onak_dbctx *dbctx,
- uint64_t keyid,
- struct openpgp_publickey **publickey,
- bool intrans)
-{
- struct onak_hkp_dbctx *privctx = (struct onak_hkp_dbctx *) dbctx->priv;
- char keyurl[1024];
-
- snprintf(keyurl, sizeof(keyurl),
- "%s/lookup?op=get&search=0x%08" PRIX64,
- privctx->hkpbase, keyid);
-
- return (hkp_fetch_key_url(dbctx, keyurl, publickey, intrans));
-}
-
/**
* hkp_fetch_key_fp - Given a fingerprint fetch the key from HKP server.
*/
return (hkp_fetch_key_url(dbctx, keyurl, publickey, intrans));
}
+/**
+ * hkp_fetch_key_id - Given a keyid fetch the key from HKP server.
+ */
+static int hkp_fetch_key_id(struct onak_dbctx *dbctx,
+ uint64_t keyid,
+ struct openpgp_publickey **publickey,
+ bool intrans)
+{
+ struct onak_hkp_dbctx *privctx = (struct onak_hkp_dbctx *) dbctx->priv;
+ char keyurl[1024];
+
+ snprintf(keyurl, sizeof(keyurl),
+ "%s/lookup?op=get&search=0x%08" PRIX64,
+ privctx->hkpbase, keyid);
+
+ return (hkp_fetch_key_url(dbctx, keyurl, publickey, intrans));
+}
+
/**
* fetch_key_text - Tries to find the keys that contain the supplied text.
* @search: The text to search for.
#define NEED_KEYID2UID 1
#define NEED_GETKEYSIGS 1
#define NEED_UPDATEKEYS 1
+#define NEED_GET 1
#include "keydb.c"
/**
dbctx->cleanupdb = hkp_cleanupdb;
dbctx->starttrans = hkp_starttrans;
dbctx->endtrans = hkp_endtrans;
- dbctx->fetch_key_id = hkp_fetch_key_id;
+ dbctx->fetch_key = generic_fetch_key;
dbctx->fetch_key_fp = hkp_fetch_key_fp;
+ dbctx->fetch_key_id = hkp_fetch_key_id;
dbctx->fetch_key_text = hkp_fetch_key_text;
dbctx->store_key = hkp_store_key;
dbctx->update_keys = generic_update_keys;
*
* This function returns a public key from whatever storage mechanism we
* are using.
- *
- * TODO: What about keyid collisions? Should we use fingerprint instead?
*/
-static int keyd_fetch_key_id(struct onak_dbctx *dbctx,
- uint64_t keyid,
+static int keyd_fetch_key(struct onak_dbctx *dbctx,
+ struct openpgp_fingerprint *fingerprint,
struct openpgp_publickey **publickey,
bool intrans)
{
struct openpgp_packet_list *packets = NULL;
ssize_t bytes = 0;
ssize_t count = 0;
+ uint8_t size;
- if (keyd_send_cmd(keyd_fd, KEYD_CMD_GET_ID)) {
- write(keyd_fd, &keyid, sizeof(keyid));
+ if (fingerprint->length > MAX_FINGERPRINT_LEN) {
+ return 0;
+ }
+
+ if (keyd_send_cmd(keyd_fd, KEYD_CMD_GET)) {
+ size = fingerprint->length;
+ write(keyd_fd, &size, sizeof(size));
+ write(keyd_fd, fingerprint->fp, size);
keybuf.offset = 0;
read(keyd_fd, &keybuf.size, sizeof(keybuf.size));
if (keybuf.size > 0) {
return (count > 0) ? 1 : 0;
}
+static int keyd_fetch_key_id(struct onak_dbctx *dbctx,
+ uint64_t keyid,
+ struct openpgp_publickey **publickey,
+ bool intrans)
+{
+ int keyd_fd = (intptr_t) dbctx->priv;
+ struct buffer_ctx keybuf;
+ struct openpgp_packet_list *packets = NULL;
+ ssize_t bytes = 0;
+ ssize_t count = 0;
+
+ if (keyd_send_cmd(keyd_fd, KEYD_CMD_GET_ID)) {
+ write(keyd_fd, &keyid, sizeof(keyid));
+ keybuf.offset = 0;
+ read(keyd_fd, &keybuf.size, sizeof(keybuf.size));
+ if (keybuf.size > 0) {
+ keybuf.buffer = malloc(keybuf.size);
+ bytes = count = 0;
+ logthing(LOGTHING_TRACE,
+ "Getting %d bytes of key data.",
+ keybuf.size);
+ while (bytes >= 0 && count < keybuf.size) {
+ bytes = read(keyd_fd, &keybuf.buffer[count],
+ keybuf.size - count);
+ logthing(LOGTHING_TRACE,
+ "Read %d bytes.", bytes);
+ count += bytes;
+ }
+ read_openpgp_stream(buffer_fetchchar, &keybuf,
+ &packets, 0);
+ parse_keys(packets, publickey);
+ free_packet_list(packets);
+ packets = NULL;
+ free(keybuf.buffer);
+ keybuf.buffer = NULL;
+ keybuf.size = 0;
+ }
+ }
+
+ return (count > 0) ? 1 : 0;
+}
+
/**
* delete_key - Given a keyid delete the key from storage.
* @fp: The fingerprint of the key to delete.
dbctx->cleanupdb = keyd_cleanupdb;
dbctx->starttrans = keyd_starttrans;
dbctx->endtrans = keyd_endtrans;
- dbctx->fetch_key_id = keyd_fetch_key_id;
+ dbctx->fetch_key = keyd_fetch_key;
dbctx->fetch_key_fp = keyd_fetch_key_fp;
+ dbctx->fetch_key_id = keyd_fetch_key_id;
dbctx->fetch_key_text = keyd_fetch_key_text;
dbctx->fetch_key_skshash = keyd_fetch_key_skshash;
dbctx->store_key = keyd_store_key;
/**
* keyring_fetch_key - fetch a key given its index
*/
-static int keyring_fetch_key(struct onak_keyring_dbctx *privctx,
+static int keyring_fetch_key_idx(struct onak_keyring_dbctx *privctx,
unsigned int index,
struct openpgp_publickey **publickey)
{
return 1;
}
-static int keyring_fetch_key_fp(struct onak_dbctx *dbctx,
+/*
+ * We only index the primary fingerprint of the key, so will only return one
+ * key at most from this function.
+ */
+static int keyring_fetch_key(struct onak_dbctx *dbctx,
struct openpgp_fingerprint *fingerprint,
struct openpgp_publickey **publickey,
bool intrans)
}
if (i < privctx->count) {
- return keyring_fetch_key(privctx, i, publickey);
+ return keyring_fetch_key_idx(privctx, i, publickey);
}
return 0;
count = 0;
for (i = 0; i < privctx->count; i++) {
if (fingerprint2keyid(&privctx->keys[i].fp) == keyid) {
- if (keyring_fetch_key(privctx, i, publickey))
+ if (keyring_fetch_key_idx(privctx, i, publickey))
count++;
}
}
count = 0;
for (i = 0; i < privctx->count; i++) {
- if (keyring_fetch_key(privctx, i, &key)) {
+ if (keyring_fetch_key_idx(privctx, i, &key)) {
iterfunc(ctx, key);
free_publickey(key);
key = NULL;
* We need to fetch the key to calculate the
* fingerprint.
*/
- keyring_fetch_key(privctx, privctx->count - 1,
+ keyring_fetch_key_idx(privctx,
+ privctx->count - 1,
&key);
get_fingerprint(key->publickey,
&privctx->keys[privctx->count - 1].fp);
dbctx->cleanupdb = keyring_cleanupdb;
dbctx->starttrans = keyring_starttrans;
dbctx->endtrans = keyring_endtrans;
+ dbctx->fetch_key = keyring_fetch_key;
+ /* We don't index by subkey fingerprint, so fallback to fetch_key */
+ dbctx->fetch_key_fp = keyring_fetch_key;
dbctx->fetch_key_id = keyring_fetch_key_id;
- dbctx->fetch_key_fp = keyring_fetch_key_fp;
dbctx->fetch_key_text = keyring_fetch_key_text;
dbctx->store_key = keyring_store_key;
dbctx->update_keys = keyring_update_keys;
* Include the basic keydb routines.
*/
#define NEED_UPDATEKEYS 1
+#define NEED_GET 1
#define NEED_GET_FP 1
#include "keydb.c"
dbctx->cleanupdb = pg_cleanupdb;
dbctx->starttrans = pg_starttrans;
dbctx->endtrans = pg_endtrans;
- dbctx->fetch_key_id = pg_fetch_key_id;
+ dbctx->fetch_key = generic_fetch_key;
dbctx->fetch_key_fp = generic_fetch_key_fp;
+ dbctx->fetch_key_id = pg_fetch_key_id;
dbctx->fetch_key_text = pg_fetch_key_text;
dbctx->store_key = pg_store_key;
dbctx->update_keys = generic_update_keys;
* reach the end or get a successful result.
*/
-static int stacked_fetch_key_id(struct onak_dbctx *dbctx, uint64_t keyid,
+static int stacked_fetch_key(struct onak_dbctx *dbctx,
+ struct openpgp_fingerprint *fingerprint,
struct openpgp_publickey **publickey, bool intrans)
{
struct onak_stacked_dbctx *privctx =
for (cur = privctx->backends; cur != NULL && res == 0;
cur = cur->next) {
backend = (struct onak_dbctx *) cur->object;
- res = backend->fetch_key_id(backend, keyid, publickey,
+ res = backend->fetch_key(backend, fingerprint, publickey,
intrans);
}
return res;
}
+static int stacked_fetch_key_id(struct onak_dbctx *dbctx, uint64_t keyid,
+ struct openpgp_publickey **publickey, bool intrans)
+{
+ struct onak_stacked_dbctx *privctx =
+ (struct onak_stacked_dbctx *) dbctx->priv;
+ struct onak_dbctx *backend;
+ struct ll *cur;
+ int res = 0;
+
+ for (cur = privctx->backends; cur != NULL && res == 0;
+ cur = cur->next) {
+ backend = (struct onak_dbctx *) cur->object;
+ res = backend->fetch_key_id(backend, keyid, publickey,
+ intrans);
+ }
+
+ if (privctx->store_on_fallback && cur != privctx->backends) {
+ store_on_fallback(privctx, *publickey, intrans);
+ }
+
+ return res;
+}
+
static int stacked_fetch_key_text(struct onak_dbctx *dbctx,
const char *search,
struct openpgp_publickey **publickey)
dbctx->cleanupdb = stacked_cleanupdb;
dbctx->starttrans = stacked_starttrans;
dbctx->endtrans = stacked_endtrans;
- dbctx->fetch_key_id = stacked_fetch_key_id;
+ dbctx->fetch_key = stacked_fetch_key;
dbctx->fetch_key_fp = stacked_fetch_key_fp;
+ dbctx->fetch_key_id = stacked_fetch_key_id;
dbctx->fetch_key_text = stacked_fetch_key_text;
dbctx->fetch_key_skshash = stacked_fetch_key_skshash;
dbctx->store_key = stacked_store_key;
if (ishex) {
count = dbctx->fetch_key_id(dbctx, keyid, &publickey,
false);
- } else if (isfp) {
+ } else if (isfp && exact) {
+ count = dbctx->fetch_key(dbctx, fingerprint,
+ &publickey, false);
+ } else if (isfp && !exact) {
count = dbctx->fetch_key_fp(dbctx, fingerprint,
&publickey, false);
} else {
char *end = NULL;
uint64_t keyid = 0;
int i;
+ bool exact = false;
bool ishex = false;
bool isfp = false;
bool update = false;
struct onak_dbctx *dbctx;
struct openpgp_fingerprint fingerprint;
- while ((optchar = getopt(argc, argv, "bc:fsuv")) != -1 ) {
+ while ((optchar = getopt(argc, argv, "bc:efsuv")) != -1 ) {
switch (optchar) {
case 'b':
binary = true;
case 'c':
configfile = strdup(optarg);
break;
+ case 'e':
+ exact = true;
+ break;
case 'f':
dispfp = true;
break;
if (!strcmp("index", argv[optind])) {
find_keys(dbctx, search, keyid, &fingerprint, ishex,
isfp, dispfp, skshash,
- false, false);
+ exact, false);
} else if (!strcmp("vindex", argv[optind])) {
find_keys(dbctx, search, keyid, &fingerprint, ishex,
isfp, dispfp, skshash,
- false, true);
+ exact, true);
} else if (!strcmp("getphoto", argv[optind])) {
if (!ishex) {
puts("Can't get a key on uid text."
--- /dev/null
+#!/bin/sh
+# Check we can retrieve a key by keyid
+
+set -e
+
+# Backends should really support full fingerprint retrieval, but they don't
+# always.
+if [ "$2" = "file" ]; then
+ exit 0
+fi
+
+cd ${WORKDIR}
+${BUILDDIR}/onak -b -c $1 add < ${TESTSDIR}/../keys/noodles.key
+if ! ${BUILDDIR}/onak -c $1 index 0x448B17C122A22C19FE289DC1045281F1B9A66E35 2> /dev/null | \
+ grep -q -- 'noodles@earth.li'; then
+ echo "* Did not correctly retrieve key by subkey fingerprint."
+ exit 1
+fi
+if ${BUILDDIR}/onak -e -c $1 index 0x448B17C122A22C19FE289DC1045281F1B9A66E35 2> /dev/null | \
+ grep -q -- 'noodles@earth.li'; then
+ echo "* Incorrectly retrieved key by subkey fingerprint."
+ exit 1
+fi
+
+exit 0