curkey = findinhash(keyinfoa->parent);
while (curkey != NULL && curkey->keyid != 0) {
if (curkey->keyid != fullwant &&
- config.dbbackend->fetch_key(
+ config.dbbackend->fetch_key_id(
curkey->keyid,
&publickey, false)) {
flatten_publickey(publickey,
/*
* Add the destination key to the list of returned keys.
*/
- if (config.dbbackend->fetch_key(fullwant, &publickey, false)) {
+ if (config.dbbackend->fetch_key_id(fullwant, &publickey, false)) {
flatten_publickey(publickey,
&packets,
&list_end);
ssize_t count = 0;
int ret = 0;
uint64_t keyid = 0;
+ uint8_t fp[MAX_FINGERPRINT_LEN];
char *search = NULL;
struct openpgp_publickey *key = NULL;
struct openpgp_packet_list *packets = NULL;
write(fd, &cmd, sizeof(cmd));
write(fd, &keyd_version, sizeof(keyd_version));
break;
- case KEYD_CMD_GET:
+ case KEYD_CMD_GET_ID:
cmd = KEYD_REPLY_OK;
write(fd, &cmd, sizeof(cmd));
bytes = read(fd, &keyid, sizeof(keyid));
", result: %d",
keyid,
config.dbbackend->
- fetch_key(keyid, &key, false));
+ fetch_key_id(keyid,
+ &key, false));
if (key != NULL) {
storebuf.size = 8192;
storebuf.buffer = malloc(8192);
}
}
break;
- case KEYD_CMD_GETTEXT:
+ case KEYD_CMD_GET_FP:
+ cmd = KEYD_REPLY_OK;
+ write(fd, &cmd, sizeof(cmd));
+ read(fd, &bytes, 1);
+ if (bytes > MAX_FINGERPRINT_LEN) {
+ ret = 1;
+ } else {
+ read(fd, fp, bytes);
+ }
+ storebuf.offset = 0;
+ if (ret == 0) {
+ logthing(LOGTHING_INFO,
+ "Fetching by fingerprint"
+ ", result: %d",
+ config.dbbackend->
+ fetch_key_fp(fp, bytes,
+ &key, false));
+ if (key != NULL) {
+ storebuf.size = 8192;
+ storebuf.buffer = malloc(8192);
+
+ flatten_publickey(key,
+ &packets,
+ &list_end);
+ write_openpgp_stream(buffer_putchar,
+ &storebuf,
+ packets);
+ logthing(LOGTHING_TRACE,
+ "Sending %d bytes.",
+ storebuf.offset);
+ write(fd, &storebuf.offset,
+ sizeof(storebuf.offset));
+ write(fd, storebuf.buffer,
+ storebuf.offset);
+
+ free(storebuf.buffer);
+ storebuf.buffer = NULL;
+ storebuf.size = storebuf.offset = 0;
+ free_packet_list(packets);
+ packets = list_end = NULL;
+ free_publickey(key);
+ key = NULL;
+ } else {
+ write(fd, &storebuf.offset,
+ sizeof(storebuf.offset));
+ }
+ }
+ break;
+
+ case KEYD_CMD_GET_TEXT:
cmd = KEYD_REPLY_OK;
write(fd, &cmd, sizeof(cmd));
bytes = read(fd, &count, sizeof(count));
write(fd, stats,
sizeof(*stats));
break;
- case KEYD_CMD_GETSKSHASH:
+ case KEYD_CMD_GET_SKSHASH:
cmd = KEYD_REPLY_OK;
write(fd, &cmd, sizeof(cmd));
bytes = read(fd, hash.hash, sizeof(hash.hash));
enum keyd_ops {
KEYD_CMD_UNKNOWN = 0,
KEYD_CMD_VERSION = 1,
- KEYD_CMD_GET,
+ KEYD_CMD_GET_ID,
KEYD_CMD_STORE,
KEYD_CMD_DELETE,
- KEYD_CMD_GETTEXT,
+ KEYD_CMD_GET_TEXT,
KEYD_CMD_GETFULLKEYID,
KEYD_CMD_KEYITER,
KEYD_CMD_CLOSE,
KEYD_CMD_QUIT,
KEYD_CMD_STATS,
- KEYD_CMD_GETSKSHASH,
+ KEYD_CMD_GET_SKSHASH,
+ KEYD_CMD_GET_FP,
KEYD_CMD_LAST /* Placeholder */
};
/**
* @brief Version of the keyd protocol currently supported
*/
-static const uint32_t keyd_version = 3;
+static const uint32_t keyd_version = 4;
/**
* @brief Response structure for the @a KEYD_CMD_STATS response
char buf[1024];
buf[0]=0;
- if (config.dbbackend->fetch_key(keyid, &publickey, false) &&
+ if (config.dbbackend->fetch_key_id(keyid, &publickey, false) &&
publickey != NULL) {
curuid = publickey->uids;
while (curuid != NULL && buf[0] == 0) {
struct openpgp_signedpacket_list *uids = NULL;
struct openpgp_publickey *publickey = NULL;
- config.dbbackend->fetch_key(keyid, &publickey, false);
+ config.dbbackend->fetch_key_id(keyid, &publickey, false);
if (publickey != NULL) {
for (uids = publickey->uids; uids != NULL; uids = uids->next) {
struct openpgp_publickey *publickey = NULL;
if (keyid < 0x100000000LL) {
- config.dbbackend->fetch_key(keyid, &publickey, false);
+ config.dbbackend->fetch_key_id(keyid, &publickey, false);
if (publickey != NULL) {
get_keyid(publickey, &keyid);
free_publickey(publickey);
logthing(LOGTHING_INFO,
"Fetching key 0x%" PRIX64 ", result: %d",
keyid,
- config.dbbackend->fetch_key(keyid, &oldkey,
+ config.dbbackend->fetch_key_id(keyid, &oldkey,
intrans));
/*
return newkeys;
}
#endif /* NEED_UPDATEKEYS */
+
+#ifdef NEED_GET_FP
+static int generic_fetch_key_fp(uint8_t *fp, size_t fpsize,
+ struct openpgp_publickey **publickey, bool intrans)
+{
+ uint64_t keyid;
+ int i;
+
+ if (fpsize > MAX_FINGERPRINT_LEN) {
+ return 0;
+ }
+
+ /*
+ * We assume if the backend is using this function it's not storing
+ * anything bigger than the 64 bit key ID and just truncate the
+ * fingerprint to get that value. 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.
+ */
+ keyid = 0;
+ for (i = (fpsize - 8); i < fpsize; i++) {
+ keyid = (keyid << 8) + fp[i];
+ }
+
+ return config.dbbackend->fetch_key_id(keyid, publickey, intrans);
+}
+#endif
*
* TODO: What about keyid collisions? Should we use fingerprint instead?
*/
- int (*fetch_key)(uint64_t keyid, struct openpgp_publickey **publickey,
+ int (*fetch_key_id)(uint64_t keyid,
+ struct openpgp_publickey **publickey,
+ bool intrans);
+
+/**
+ * @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.
+ */
+ int (*fetch_key_fp)(uint8_t *fp,
+ size_t fpsize,
+ struct openpgp_publickey **publickey,
bool intrans);
/**
}
/**
- * fetch_key - Given a keyid fetch the key from storage.
+ * fetch_key_id - Given a keyid fetch the key from storage.
* @keyid: The keyid to fetch.
* @publickey: A pointer to a structure to return the key in.
* @intrans: If we're already in a transaction.
* in and then parse_keys() to parse the packets into a publickey
* structure.
*/
-static int db4_fetch_key(uint64_t keyid, struct openpgp_publickey **publickey,
+static int db4_fetch_key_id(uint64_t keyid,
+ struct openpgp_publickey **publickey,
bool intrans)
{
struct openpgp_packet_list *packets = NULL;
db4_starttrans();
for (i = 0; i < keylist.count; i++) {
- numkeys += db4_fetch_key(keylist.keys[i],
+ numkeys += db4_fetch_key_id(keylist.keys[i],
publickey,
true);
}
ret = cursor->c_close(cursor);
cursor = NULL;
- return db4_fetch_key(keyid, publickey, false);
+ return db4_fetch_key_id(keyid, publickey, false);
}
/**
db4_starttrans();
}
- db4_fetch_key(keyid, &publickey, true);
+ db4_fetch_key_id(keyid, &publickey, true);
/*
* Walk through the uids removing the words from the worddb.
#define NEED_GETKEYSIGS 1
#define NEED_KEYID2UID 1
#define NEED_UPDATEKEYS 1
+#define NEED_GET_FP 1
#include "keydb.c"
struct dbfuncs keydb_db4_funcs = {
.cleanupdb = db4_cleanupdb,
.starttrans = db4_starttrans,
.endtrans = db4_endtrans,
- .fetch_key = db4_fetch_key,
+ .fetch_key_id = db4_fetch_key_id,
+ .fetch_key_fp = generic_fetch_key_fp,
.fetch_key_text = db4_fetch_key_text,
.fetch_key_skshash = db4_fetch_key_skshash,
.store_key = db4_store_key,
}
}
-static int dynamic_fetch_key(uint64_t keyid,
+static int dynamic_fetch_key_id(uint64_t keyid,
struct openpgp_publickey **publickey, bool intrans)
{
if (loaded_backend == NULL) {
load_backend();
}
-
+
if (loaded_backend != NULL) {
- if (loaded_backend->fetch_key != NULL) {
- return loaded_backend->fetch_key(keyid,publickey,intrans);
+ if (loaded_backend->fetch_key_id != NULL) {
+ return loaded_backend->fetch_key_id(keyid,
+ publickey, intrans);
}
}
return -1;
}
+static int dynamic_fetch_key_fp(uint8_t *fp, size_t fpsize,
+ struct openpgp_publickey **publickey, bool intrans)
+{
+ if (loaded_backend == NULL) {
+ load_backend();
+ }
+
+ if (loaded_backend != NULL) {
+ if (loaded_backend->fetch_key_id != NULL) {
+ return loaded_backend->fetch_key_fp(fp, fpsize,
+ publickey, intrans);
+ }
+ }
+
+ return -1;
+}
+
+
+
static int dynamic_store_key(struct openpgp_publickey *publickey, bool intrans,
bool update)
{
}
buf[0]=0;
- if (dynamic_fetch_key(keyid, &publickey, false) && publickey != NULL) {
+ if (dynamic_fetch_key_id(keyid, &publickey, false) &&
+ publickey != NULL) {
curuid = publickey->uids;
while (curuid != NULL && buf[0] == 0) {
if (curuid->packet->tag == OPENPGP_PACKET_UID) {
}
}
- dynamic_fetch_key(keyid, &publickey, false);
+ dynamic_fetch_key_id(keyid, &publickey, false);
if (publickey != NULL) {
for (uids = publickey->uids; uids != NULL; uids = uids->next) {
}
if (keyid < 0x100000000LL) {
- dynamic_fetch_key(keyid, &publickey, false);
+ dynamic_fetch_key_id(keyid, &publickey, false);
if (publickey != NULL) {
get_keyid(publickey, &keyid);
free_publickey(publickey);
logthing(LOGTHING_INFO,
"Fetching key 0x%" PRIX64 ", result: %d",
keyid,
- dynamic_fetch_key(keyid, &oldkey, intrans));
+ dynamic_fetch_key_id(keyid, &oldkey, intrans));
/*
* If we already have the key stored in the DB then merge it
.cleanupdb = dynamic_cleanupdb,
.starttrans = dynamic_starttrans,
.endtrans = dynamic_endtrans,
- .fetch_key = dynamic_fetch_key,
+ .fetch_key_id = dynamic_fetch_key_id,
+ .fetch_key_fp = dynamic_fetch_key_fp,
.fetch_key_text = dynamic_fetch_key_text,
.fetch_key_skshash = dynamic_fetch_key_skshash,
.store_key = dynamic_store_key,
}
/**
- * fetch_key - Given a keyid fetch the key from storage.
+ * fetch_key_id - Given a keyid fetch the key from storage.
* @keyid: The keyid to fetch.
* @publickey: A pointer to a structure to return the key in.
* @intrans: If we're already in a transaction.
* in and then parse_keys() to parse the packets into a publickey
* structure.
*/
-static int file_fetch_key(uint64_t keyid, struct openpgp_publickey **publickey,
+static int file_fetch_key_id(uint64_t keyid,
+ struct openpgp_publickey **publickey,
bool intrans)
{
struct openpgp_packet_list *packets = NULL;
#define NEED_GETKEYSIGS 1
#define NEED_GETFULLKEYID 1
#define NEED_UPDATEKEYS 1
+#define NEED_GET_FP 1
#include "keydb.c"
struct dbfuncs keydb_file_funcs = {
.cleanupdb = file_cleanupdb,
.starttrans = file_starttrans,
.endtrans = file_endtrans,
- .fetch_key = file_fetch_key,
+ .fetch_key_id = file_fetch_key_id,
+ .fetch_key_fp = generic_fetch_key_fp,
.fetch_key_text = file_fetch_key_text,
.store_key = file_store_key,
.update_keys = generic_update_keys,
* @publickey: A pointer to a structure to return the key in.
* @intrans: If we're already in a transaction.
*/
-static int fs_fetch_key(uint64_t keyid, struct openpgp_publickey **publickey,
+static int fs_fetch_key_id(uint64_t keyid,
+ struct openpgp_publickey **publickey,
bool intrans)
{
static char buffer[PATH_MAX];
if (!intrans)
fs_starttrans();
- ret = fs_fetch_key(keyid, &pk, true);
+ ret = fs_fetch_key_id(keyid, &pk, true);
if (ret) {
logthing(LOGTHING_DEBUG, "Wordlist for key %016" PRIX64,
while (wl) {
logthing(LOGTHING_DEBUG, "Adding key: %s", wl->object);
addedkeys +=
- fs_fetch_key(strtoull(wl->object, NULL, 16), publickey,
+ fs_fetch_key_id(strtoull(wl->object, NULL, 16), publickey,
false);
if (addedkeys >= config.maxkeys)
break;
#define NEED_KEYID2UID 1
#define NEED_GETKEYSIGS 1
#define NEED_UPDATEKEYS 1
+#define NEED_GET_FP 1
#include "keydb.c"
struct dbfuncs keydb_fs_funcs = {
.cleanupdb = fs_cleanupdb,
.starttrans = fs_starttrans,
.endtrans = fs_endtrans,
- .fetch_key = fs_fetch_key,
+ .fetch_key_id = fs_fetch_key_id,
+ .fetch_key_fp = generic_fetch_key_fp,
.fetch_key_text = fs_fetch_key_text,
.fetch_key_skshash = fs_fetch_key_skshash,
.store_key = fs_store_key,
return (nmemb * size);
}
-/**
- * fetch_key - Given a keyid fetch the key from storage.
- * @keyid: The keyid to fetch.
- * @publickey: A pointer to a structure to return the key in.
- * @intrans: If we're already in a transaction.
- *
- * We use the hex representation of the keyid as the filename to fetch the
- * key from. The key is stored in the file as a binary OpenPGP stream of
- * packets, so we can just use read_openpgp_stream() to read the packets
- * in and then parse_keys() to parse the packets into a publickey
- * structure.
- */
-static int hkp_fetch_key(uint64_t keyid, struct openpgp_publickey **publickey,
+static int hkp_fetch_key_url(char *url,
+ struct openpgp_publickey **publickey,
bool intrans)
{
struct openpgp_packet_list *packets = NULL;
- char keyurl[1024];
CURLcode res;
struct buffer_ctx buf;
+ int count = 0;
buf.offset = 0;
buf.size = 8192;
buf.buffer = malloc(8192);
- snprintf(keyurl, sizeof(keyurl),
- "%s/lookup?op=get&search=0x%08" PRIX64,
- hkpbase, keyid);
-
- curl_easy_setopt(curl, CURLOPT_URL, keyurl);
+ curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
hkp_curl_recv_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buf);
if (res == 0) {
buf.offset = 0;
dearmor_openpgp_stream(buffer_fetchchar, &buf, &packets);
- parse_keys(packets, publickey);
+ count = parse_keys(packets, publickey);
free_packet_list(packets);
packets = NULL;
} else {
buf.offset = buf.size = 0;
buf.buffer = NULL;
- return (res == 0) ? 1 : 0;
+ return count;
+}
+
+/**
+ * hkp_fetch_key_id - Given a keyid fetch the key from HKP server.
+ */
+static int hkp_fetch_key_id(uint64_t keyid,
+ struct openpgp_publickey **publickey,
+ bool intrans)
+{
+ char keyurl[1024];
+
+ snprintf(keyurl, sizeof(keyurl),
+ "%s/lookup?op=get&search=0x%08" PRIX64,
+ hkpbase, keyid);
+
+ return (hkp_fetch_key_url(keyurl, publickey, intrans));
+}
+
+/**
+ * hkp_fetch_key_fp - Given a fingerprint fetch the key from HKP server.
+ */
+static int hkp_fetch_key_fp(uint8_t *fp, size_t fpsize,
+ struct openpgp_publickey **publickey,
+ bool intrans)
+{
+ char keyurl[1024];
+ int i, ofs;
+
+ if (fpsize > MAX_FINGERPRINT_LEN) {
+ return 0;
+ }
+
+ ofs = snprintf(keyurl, sizeof(keyurl),
+ "%s/lookup?op=get&search=0x", hkpbase);
+
+ if ((ofs + fpsize * 2 + 1)> sizeof(keyurl)) {
+ return 0;
+ }
+
+ for (i = 0; i < fpsize; i++) {
+ ofs += sprintf(&keyurl[ofs], "%02X", fp[i]);
+ }
+
+ return (hkp_fetch_key_url(keyurl, publickey, intrans));
}
/**
static int hkp_fetch_key_text(const char *search,
struct openpgp_publickey **publickey)
{
- struct openpgp_packet_list *packets = NULL;
char keyurl[1024];
- CURLcode res;
- struct buffer_ctx buf;
- int count = 0;
-
- buf.offset = 0;
- buf.size = 8192;
- buf.buffer = malloc(8192);
snprintf(keyurl, sizeof(keyurl),
"%s/lookup?op=get&search=%s",
hkpbase, search);
- curl_easy_setopt(curl, CURLOPT_URL, keyurl);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
- hkp_curl_recv_data);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buf);
- res = curl_easy_perform(curl);
-
- if (res == 0) {
- buf.offset = 0;
- dearmor_openpgp_stream(buffer_fetchchar, &buf, &packets);
- count = parse_keys(packets, publickey);
- free_packet_list(packets);
- packets = NULL;
- } else {
- logthing(LOGTHING_ERROR, "Couldn't find key: %s (%d)",
- curl_easy_strerror(res), res);
- }
-
- free(buf.buffer);
- buf.offset = buf.size = 0;
- buf.buffer = NULL;
-
- return count;
+ return (hkp_fetch_key_url(keyurl, publickey, false));
}
/**
.cleanupdb = hkp_cleanupdb,
.starttrans = hkp_starttrans,
.endtrans = hkp_endtrans,
- .fetch_key = hkp_fetch_key,
+ .fetch_key_id = hkp_fetch_key_id,
+ .fetch_key_fp = hkp_fetch_key_fp,
.fetch_key_text = hkp_fetch_key_text,
.store_key = hkp_store_key,
.update_keys = generic_update_keys,
*
* TODO: What about keyid collisions? Should we use fingerprint instead?
*/
-static int keyd_fetch_key(uint64_t keyid, struct openpgp_publickey **publickey,
+static int keyd_fetch_key_id(uint64_t keyid,
+ struct openpgp_publickey **publickey,
bool intrans)
{
struct buffer_ctx keybuf;
struct openpgp_packet_list *packets = NULL;
- uint32_t cmd = KEYD_CMD_GET;
+ uint32_t cmd = KEYD_CMD_GET_ID;
ssize_t bytes = 0;
ssize_t count = 0;
keybuf.size = 0;
}
}
-
+
+ return (count > 0) ? 1 : 0;
+}
+
+static int keyd_fetch_key_fp(uint8_t *fp, size_t fpsize,
+ struct openpgp_publickey **publickey,
+ bool intrans)
+{
+ struct buffer_ctx keybuf;
+ struct openpgp_packet_list *packets = NULL;
+ uint32_t cmd = KEYD_CMD_GET_FP;
+ ssize_t bytes = 0;
+ ssize_t count = 0;
+ uint8_t size;
+
+ if (fpsize > MAX_FINGERPRINT_LEN) {
+ return 0;
+ }
+
+ write(keyd_fd, &cmd, sizeof(cmd));
+ read(keyd_fd, &cmd, sizeof(cmd));
+ if (cmd == KEYD_REPLY_OK) {
+ size = fpsize;
+ write(keyd_fd, &size, sizeof(size));
+ write(keyd_fd, fp, size);
+ 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;
}
{
struct buffer_ctx keybuf;
struct openpgp_packet_list *packets = NULL;
- uint32_t cmd = KEYD_CMD_GETTEXT;
+ uint32_t cmd = KEYD_CMD_GET_TEXT;
ssize_t bytes = 0;
ssize_t count = 0;
{
struct buffer_ctx keybuf;
struct openpgp_packet_list *packets = NULL;
- uint32_t cmd = KEYD_CMD_GETSKSHASH;
+ uint32_t cmd = KEYD_CMD_GET_SKSHASH;
ssize_t bytes = 0;
ssize_t count = 0;
.cleanupdb = keyd_cleanupdb,
.starttrans = keyd_starttrans,
.endtrans = keyd_endtrans,
- .fetch_key = keyd_fetch_key,
+ .fetch_key_id = keyd_fetch_key_id,
+ .fetch_key_fp = keyd_fetch_key_fp,
.fetch_key_text = keyd_fetch_key_text,
.fetch_key_skshash = keyd_fetch_key_skshash,
.store_key = keyd_store_key,
}
/**
- * fetch_key - Given a keyid fetch the key from storage.
+ * fetch_key_id - Given a keyid fetch the key from storage.
* @keyid: The keyid to fetch.
* @publickey: A pointer to a structure to return the key in.
* @intrans: If we're already in a transaction.
* in and then parse_keys() to parse the packets into a publickey
* structure.
*/
-static int pg_fetch_key(uint64_t keyid, struct openpgp_publickey **publickey,
+static int pg_fetch_key_id(uint64_t keyid,
+ struct openpgp_publickey **publickey,
bool intrans)
{
struct openpgp_packet_list *packets = NULL;
*/
#define NEED_GETFULLKEYID 1
#define NEED_UPDATEKEYS 1
+#define NEED_GET_FP 1
#include "keydb.c"
struct dbfuncs keydb_pg_funcs = {
.cleanupdb = pg_cleanupdb,
.starttrans = pg_starttrans,
.endtrans = pg_endtrans,
- .fetch_key = pg_fetch_key,
+ .fetch_key_id = pg_fetch_key_id,
+ .fetch_key_fp = generic_fetch_key_fp,
.fetch_key_text = pg_fetch_key_text,
.store_key = pg_store_key,
.update_keys = generic_update_keys,
printf("Command statistics:\n");
printf(" Version: %d\n",
stats.command_stats[KEYD_CMD_VERSION]);
- printf(" Get key: %d\n", stats.command_stats[KEYD_CMD_GET]);
+ printf(" Get key by ID: %d\n",
+ stats.command_stats[KEYD_CMD_GET_ID]);
+ printf(" Get key by FP: %d\n",
+ stats.command_stats[KEYD_CMD_GET_FP]);
printf(" Store key: %d\n",
stats.command_stats[KEYD_CMD_STORE]);
printf(" Delete key: %d\n",
stats.command_stats[KEYD_CMD_DELETE]);
printf(" Search key: %d\n",
- stats.command_stats[KEYD_CMD_GETTEXT]);
+ stats.command_stats[KEYD_CMD_GET_TEXT]);
printf(" Get full keyid: %d\n",
stats.command_stats[KEYD_CMD_GETFULLKEYID]);
printf(" Iterate all keys: %d\n",
#include "ll.h"
+/* v3 MD5 fingerprint is 16 characters, v4 SHA-1 fingerprint is 20 */
+#define MAX_FINGERPRINT_LEN 20
+
/**
* @brief Stores an OpenPGP packet.
*
#define OP_PHOTO 4
#define OP_HGET 5
-void find_keys(char *search, uint64_t keyid, bool ishex,
- bool fingerprint, bool skshash, bool exact, bool verbose,
- bool mrhkp)
+void find_keys(char *search, uint64_t keyid, uint8_t *fp, size_t fpsize,
+ bool ishex, bool isfp, bool fingerprint, bool skshash,
+ bool exact, bool verbose, bool mrhkp)
{
struct openpgp_publickey *publickey = NULL;
int count = 0;
if (ishex) {
- count = config.dbbackend->fetch_key(keyid, &publickey, false);
+ count = config.dbbackend->fetch_key_id(keyid, &publickey,
+ false);
+ } else if (isfp) {
+ count = config.dbbackend->fetch_key_fp(fp, fpsize, &publickey,
+ false);
} else {
count = config.dbbackend->fetch_key_text(search, &publickey);
}
}
}
+static uint8_t hex2bin(char c)
+{
+ if (c >= '0' && c <= '9') {
+ return (c - '0');
+ } else if (c >= 'a' && c <= 'f') {
+ return (c - 'a' + 10);
+ } else if (c >= 'A' && c <= 'F') {
+ return (c - 'A' + 10);
+ }
+
+ return 255;
+}
+
int main(int argc, char *argv[])
{
char **params = NULL;
bool skshash = false;
bool exact = false;
bool ishex = false;
+ bool isfp = false;
bool mrhkp = false;
uint64_t keyid = 0;
+ uint8_t fp[MAX_FINGERPRINT_LEN];
char *search = NULL;
char *end = NULL;
struct openpgp_publickey *publickey = NULL;
params[i+1] = NULL;
if (search != NULL && strlen(search) == 42 &&
search[0] == '0' && search[1] == 'x') {
- /*
- * Fingerprint. Truncate to last 64 bits for
- * now.
- */
- keyid = strtoull(&search[26], &end, 16);
- if (end != NULL && *end == 0) {
- ishex = true;
+ for (i = 0; i < MAX_FINGERPRINT_LEN; i++) {
+ fp[i] = (hex2bin(search[2 + i * 2])
+ << 4) +
+ hex2bin(search[3 + i * 2]);
}
+ isfp = true;
} else if (search != NULL) {
keyid = strtoull(search, &end, 16);
if (*search != 0 &&
result = config.dbbackend->fetch_key_skshash(
&hash, &publickey);
} else if (ishex) {
- result = config.dbbackend->fetch_key(keyid,
+ result = config.dbbackend->fetch_key_id(keyid,
&publickey, false);
+ } else if (isfp) {
+ result = config.dbbackend->fetch_key_fp(fp,
+ MAX_FINGERPRINT_LEN, &publickey, false);
} else {
result = config.dbbackend->fetch_key_text(
search,
}
break;
case OP_INDEX:
- find_keys(search, keyid, ishex, fingerprint, skshash,
+ find_keys(search, keyid, fp, MAX_FINGERPRINT_LEN,
+ ishex, isfp, fingerprint, skshash,
exact, false, mrhkp);
break;
case OP_VINDEX:
- find_keys(search, keyid, ishex, fingerprint, skshash,
+ find_keys(search, keyid, fp, MAX_FINGERPRINT_LEN,
+ ishex, isfp, fingerprint, skshash,
exact, true, mrhkp);
break;
case OP_PHOTO:
- if (config.dbbackend->fetch_key(keyid, &publickey,
- false)) {
+ if (isfp) {
+ config.dbbackend->fetch_key_fp(fp,
+ MAX_FINGERPRINT_LEN,
+ &publickey, false);
+ } else {
+ config.dbbackend->fetch_key_id(keyid,
+ &publickey, false);
+ }
+ if (publickey != NULL) {
unsigned char *photo = NULL;
size_t length = 0;
#include "photoid.h"
#include "version.h"
-void find_keys(char *search, uint64_t keyid, bool ishex,
- bool fingerprint, bool skshash, bool exact, bool verbose)
+void find_keys(char *search, uint64_t keyid, uint8_t *fp, bool ishex,
+ bool isfp, bool fingerprint, bool skshash, bool exact,
+ bool verbose)
{
struct openpgp_publickey *publickey = NULL;
int count = 0;
if (ishex) {
- count = config.dbbackend->fetch_key(keyid, &publickey, false);
+ count = config.dbbackend->fetch_key_id(keyid, &publickey,
+ false);
+ } else if (isfp) {
+ count = config.dbbackend->fetch_key_fp(fp, MAX_FINGERPRINT_LEN,
+ &publickey, false);
} else {
count = config.dbbackend->fetch_key_text(search, &publickey);
}
return;
}
+static uint8_t hex2bin(char c)
+{
+ if (c >= '0' && c <= '9') {
+ return (c - '0');
+ } else if (c >= 'a' && c <= 'f') {
+ return (c - 'a' + 10);
+ } else if (c >= 'A' && c <= 'F') {
+ return (c - 'A' + 10);
+ }
+
+ return 255;
+}
+
void usage(void) {
puts("onak " ONAK_VERSION " - an OpenPGP keyserver.\n");
puts("Usage:\n");
char *search = NULL;
char *end = NULL;
uint64_t keyid = 0;
+ uint8_t fp[MAX_FINGERPRINT_LEN];
+ int i;
bool ishex = false;
+ bool isfp = false;
bool verbose = false;
bool update = false;
bool binary = false;
search = argv[optind+1];
if (search != NULL && strlen(search) == 42 &&
search[0] == '0' && search[1] == 'x') {
- /*
- * Fingerprint. Truncate to last 64 bits for
- * now.
- */
- keyid = strtoull(&search[26], &end, 16);
- if (end != NULL && *end == 0) {
- ishex = true;
+ for (i = 0; i < MAX_FINGERPRINT_LEN; i++) {
+ fp[i] = (hex2bin(search[2 + i * 2]) << 4) +
+ hex2bin(search[3 + i * 2]);
}
+ isfp = true;
} else if (search != NULL) {
keyid = strtoul(search, &end, 16);
if (*search != 0 &&
}
config.dbbackend->initdb(false);
if (!strcmp("index", argv[optind])) {
- find_keys(search, keyid, ishex, fingerprint, skshash,
+ find_keys(search, keyid, fp, ishex, isfp,
+ fingerprint, skshash,
false, false);
} else if (!strcmp("vindex", argv[optind])) {
- find_keys(search, keyid, ishex, fingerprint, skshash,
+ find_keys(search, keyid, fp, ishex, isfp,
+ fingerprint, skshash,
false, true);
} else if (!strcmp("getphoto", argv[optind])) {
if (!ishex) {
puts("Can't get a key on uid text."
" You must supply a keyid.");
- } else if (config.dbbackend->fetch_key(keyid, &keys,
+ } else if (config.dbbackend->fetch_key_id(keyid, &keys,
false)) {
unsigned char *photo = NULL;
size_t length = 0;
config.dbbackend->getfullkeyid(keyid),
false);
} else if (!strcmp("get", argv[optind])) {
- if (!ishex) {
+ if (!(ishex || isfp)) {
puts("Can't get a key on uid text."
- " You must supply a keyid.");
- } else if (config.dbbackend->fetch_key(keyid, &keys,
- false)) {
+ " You must supply a keyid / "
+ "fingerprint.");
+ } else if ((isfp &&
+ config.dbbackend->fetch_key_fp(fp,
+ MAX_FINGERPRINT_LEN,
+ &keys, false)) ||
+ (ishex &&
+ config.dbbackend->fetch_key_id(keyid,
+ &keys, false))) {
logthing(LOGTHING_INFO, "Got key.");
flatten_publickey(keys,
&packets,