From: Jonathan McDowell Date: Mon, 25 Apr 2011 03:50:40 +0000 (-0700) Subject: Add support for displaying/retrieving by SKS hash to lookup and onak CLI X-Git-Url: https://git.sommitrealweird.co.uk/onak.git/commitdiff_plain/d9432fa0982c0f7a736bf00c04969dedca347ea3?ds=sidebyside;hp=7ca3c239d76ae7112c166f29c35e11620ba93d9f Add support for displaying/retrieving by SKS hash to lookup and onak CLI Now we are storing the SKS hash details of a key add the ability to display the hash in /pks/lookup and retrieve it via the new hget function. This should be compatible with the way in which SKS extends lookup to support its hashes. Also add hget to the onak CLI tool and the -s option for showing the SKS hash of keys. --- diff --git a/keyid.c b/keyid.c index 0516f47..29c61f0 100644 --- a/keyid.c +++ b/keyid.c @@ -6,6 +6,7 @@ * Copyright 2002 Project Purple */ +#include #include #include @@ -216,3 +217,32 @@ void get_skshash(struct openpgp_publickey *key, struct skshash *hash) md5_finish_ctx(&md5_context, &hash->hash); free_packet_list(packets); } + +uint8_t hexdigit(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; + else + return 0; +} + +int parse_skshash(char *search, struct skshash *hash) +{ + int i, len; + + len = strlen(search); + if (len > 32) { + return 0; + } + + for (i = 0; i < len; i += 2) { + hash->hash[i >> 1] = (hexdigit(search[i]) << 4) + + hexdigit(search[i + 1]); + } + + return 1; +} diff --git a/keyid.h b/keyid.h index 202a4a0..08bf1fe 100644 --- a/keyid.h +++ b/keyid.h @@ -55,4 +55,16 @@ uint64_t get_packetid(struct openpgp_packet *packet); */ void get_skshash(struct openpgp_publickey *publickey, struct skshash *hash); +/** + * parse_skshash - Parse a string into an SKS hash structure. + * @search: The string representing the SKS hash. + * @hash: A pointer to the structure to store the hash in. + * + * Takes a string and tries to parse it as an SKS hash hex + * representation. Puts the hash into the supplied structure + * if successful. Returns 1 if we parsed something ok, 0 if + * we failed. + */ +int parse_skshash(char *search, struct skshash *hash); + #endif /* __KEYID_H__ */ diff --git a/keyindex.c b/keyindex.c index 0cc9edd..869befd 100644 --- a/keyindex.c +++ b/keyindex.c @@ -184,6 +184,31 @@ void display_fingerprint(struct openpgp_publickey *key) return; } +void display_skshash(struct openpgp_publickey *key, bool html) +{ + int i = 0; + struct skshash hash; + + get_skshash(key, &hash); + printf(" Key hash = "); + if (html) { + printf(""); + } + for (i = 0; i < sizeof(hash.hash); i++) { + printf("%02X", hash.hash[i]); + } + if (html) { + printf(""); + } + printf("\n"); + + return; +} + /** * key_index - List a set of OpenPGP keys. * @keys: The keys to display. @@ -195,7 +220,7 @@ void display_fingerprint(struct openpgp_publickey *key) * of them. Useful for debugging or the keyserver Index function. */ int key_index(struct openpgp_publickey *keys, bool verbose, bool fingerprint, - bool html) + bool skshash, bool html) { struct openpgp_signedpacket_list *curuid = NULL; struct tm *created = NULL; @@ -289,6 +314,9 @@ int key_index(struct openpgp_publickey *keys, bool verbose, bool fingerprint, (html) ? txt2html(buf) : buf, (html) ? "" : "", (keys->revoked) ? " *** REVOKED ***" : ""); + if (skshash) { + display_skshash(keys, html); + } if (fingerprint) { display_fingerprint(keys); } diff --git a/keyindex.h b/keyindex.h index 247bfda..c3cb9ec 100644 --- a/keyindex.h +++ b/keyindex.h @@ -18,13 +18,14 @@ * @keys: The keys to display. * @verbose: Should we list sigs as well? * @fingerprint: List the fingerprint? + * @skshash: List the sks hash? * @html: Should we tailor the output for HTML? * * This function takes a list of OpenPGP public keys and displays an index * of them. Useful for debugging or the keyserver Index function. */ int key_index(struct openpgp_publickey *keys, bool verbose, - bool fingerprint, bool html); + bool fingerprint, bool skshash, bool html); /** * mrkey_index - List a set of OpenPGP keys in the MRHKP format. diff --git a/lookup.c b/lookup.c index 56394a5..cc7953e 100644 --- a/lookup.c +++ b/lookup.c @@ -19,6 +19,7 @@ #include "cleanup.h" #include "getcgi.h" #include "keydb.h" +#include "keyid.h" #include "keyindex.h" #include "log.h" #include "mem.h" @@ -32,9 +33,11 @@ #define OP_INDEX 2 #define OP_VINDEX 3 #define OP_PHOTO 4 +#define OP_HGET 5 void find_keys(char *search, uint64_t keyid, bool ishex, - bool fingerprint, bool exact, bool verbose, bool mrhkp) + bool fingerprint, bool skshash, bool exact, bool verbose, + bool mrhkp) { struct openpgp_publickey *publickey = NULL; int count = 0; @@ -49,7 +52,8 @@ void find_keys(char *search, uint64_t keyid, bool ishex, printf("info:1:%d\n", count); mrkey_index(publickey); } else { - key_index(publickey, verbose, fingerprint, true); + key_index(publickey, verbose, fingerprint, skshash, + true); } free_publickey(publickey); } else if (count == 0) { @@ -78,6 +82,7 @@ int main(int argc, char *argv[]) int i; int indx = 0; bool fingerprint = false; + bool skshash = false; bool exact = false; bool ishex = false; bool mrhkp = false; @@ -88,12 +93,15 @@ int main(int argc, char *argv[]) struct openpgp_packet_list *packets = NULL; struct openpgp_packet_list *list_end = NULL; int result; + struct skshash hash; params = getcgivars(argc, argv); for (i = 0; params != NULL && params[i] != NULL; i += 2) { if (!strcmp(params[i], "op")) { if (!strcmp(params[i+1], "get")) { op = OP_GET; + } else if (!strcmp(params[i+1], "hget")) { + op = OP_HGET; } else if (!strcmp(params[i+1], "index")) { op = OP_INDEX; } else if (!strcmp(params[i+1], "vindex")) { @@ -118,6 +126,10 @@ int main(int argc, char *argv[]) if (!strcmp(params[i+1], "on")) { fingerprint = true; } + } else if (!strcmp(params[i], "hash")) { + if (!strcmp(params[i+1], "on")) { + skshash = true; + } } else if (!strcmp(params[i], "exact")) { if (!strcmp(params[i+1], "on")) { exact = true; @@ -163,7 +175,12 @@ int main(int argc, char *argv[]) config.dbbackend->initdb(false); switch (op) { case OP_GET: - if (ishex) { + case OP_HGET: + if (op == OP_HGET) { + parse_skshash(search, &hash); + result = config.dbbackend->fetch_key_skshash( + &hash, &publickey); + } else if (ishex) { result = config.dbbackend->fetch_key(keyid, &publickey, false); } else { @@ -193,12 +210,12 @@ int main(int argc, char *argv[]) } break; case OP_INDEX: - find_keys(search, keyid, ishex, fingerprint, exact, - false, mrhkp); + find_keys(search, keyid, ishex, fingerprint, skshash, + exact, false, mrhkp); break; case OP_VINDEX: - find_keys(search, keyid, ishex, fingerprint, exact, - true, mrhkp); + find_keys(search, keyid, ishex, fingerprint, skshash, + exact, true, mrhkp); break; case OP_PHOTO: if (config.dbbackend->fetch_key(keyid, &publickey, diff --git a/onak.c b/onak.c index b3cc27e..4ba3a7a 100644 --- a/onak.c +++ b/onak.c @@ -34,7 +34,7 @@ #include "version.h" void find_keys(char *search, uint64_t keyid, bool ishex, - bool fingerprint, bool exact, bool verbose) + bool fingerprint, bool skshash, bool exact, bool verbose) { struct openpgp_publickey *publickey = NULL; int count = 0; @@ -45,7 +45,7 @@ void find_keys(char *search, uint64_t keyid, bool ishex, count = config.dbbackend->fetch_key_text(search, &publickey); } if (publickey != NULL) { - key_index(publickey, verbose, fingerprint, false); + key_index(publickey, verbose, fingerprint, skshash, false); free_publickey(publickey); } else if (count == 0) { puts("Key not found."); @@ -128,10 +128,12 @@ int main(int argc, char *argv[]) bool update = false; bool binary = false; bool fingerprint = false; + bool skshash = false; int optchar; struct dump_ctx dumpstate; + struct skshash hash; - while ((optchar = getopt(argc, argv, "bc:fuv")) != -1 ) { + while ((optchar = getopt(argc, argv, "bc:fsuv")) != -1 ) { switch (optchar) { case 'b': binary = true; @@ -142,6 +144,9 @@ int main(int argc, char *argv[]) case 'f': fingerprint = true; break; + case 's': + skshash = true; + break; case 'u': update = true; break; @@ -282,10 +287,10 @@ int main(int argc, char *argv[]) } config.dbbackend->initdb(false); if (!strcmp("index", argv[optind])) { - find_keys(search, keyid, ishex, fingerprint, + find_keys(search, keyid, ishex, fingerprint, skshash, false, false); } else if (!strcmp("vindex", argv[optind])) { - find_keys(search, keyid, ishex, fingerprint, + find_keys(search, keyid, ishex, fingerprint, skshash, false, true); } else if (!strcmp("getphoto", argv[optind])) { if (!ishex) { @@ -336,6 +341,30 @@ int main(int argc, char *argv[]) } else { puts("Key not found"); } + } else if (!strcmp("hget", argv[optind])) { + if (!parse_skshash(search, &hash)) { + puts("Couldn't parse sks hash."); + } else if (config.dbbackend->fetch_key_skshash(&hash, + &keys)) { + logthing(LOGTHING_INFO, "Got key."); + flatten_publickey(keys, + &packets, + &list_end); + free_publickey(keys); + if (binary) { + write_openpgp_stream(stdout_putchar, + NULL, + packets); + } else { + armor_openpgp_stream(stdout_putchar, + NULL, + packets); + } + free_packet_list(packets); + packets = NULL; + } else { + puts("Key not found"); + } } config.dbbackend->cleanupdb(); } else {