Add support for displaying/retrieving by SKS hash to lookup and onak CLI
authorJonathan McDowell <noodles@earth.li>
Mon, 25 Apr 2011 03:50:40 +0000 (20:50 -0700)
committerJonathan McDowell <noodles@earth.li>
Mon, 25 Apr 2011 03:50:40 +0000 (20:50 -0700)
  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.

keyid.c
keyid.h
keyindex.c
keyindex.h
lookup.c
onak.c

diff --git a/keyid.c b/keyid.c
index 0516f477e028eac7d7fb584be15a90259c106dfb..29c61f00137134f0685d5bdc382a25a3ac12b2a8 100644 (file)
--- a/keyid.c
+++ b/keyid.c
@@ -6,6 +6,7 @@
  * Copyright 2002 Project Purple
  */
 
+#include <string.h>
 #include <sys/types.h>
 #include <arpa/inet.h>
 
@@ -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 202a4a053d019b7960e45d3ecc2d003bff36df5f..08bf1fea8d694e36231e000f73f0bc581c09b0c2 100644 (file)
--- 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__ */
index 0cc9edd89e1bb20da6966646f6837035ea06b5c0..869befd0138090c0a2a246c2d3e9b8e15cf3bf49 100644 (file)
@@ -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("<a href=\"lookup?op=hget&search=");
+               for (i = 0; i < sizeof(hash.hash); i++) {
+                       printf("%02X", hash.hash[i]);
+               }
+               printf("\">");
+       }
+       for (i = 0; i < sizeof(hash.hash); i++) {
+               printf("%02X", hash.hash[i]);
+       }
+       if (html) {
+               printf("</a>");
+       }
+       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) ? "</a>" : "",
                                (keys->revoked) ? " *** REVOKED ***" : "");
+                       if (skshash) {
+                               display_skshash(keys, html);
+                       }
                        if (fingerprint) {
                                display_fingerprint(keys);
                        }
index 247bfda0799f19d982564eddf53ade1314705109..c3cb9eca4ed6c847f1896697c35ffa978523113e 100644 (file)
  *     @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.
index 56394a5527de29890817d2b603602ef55e31a372..cc7953e56720aecb6256e47465922f8a1690878d 100644 (file)
--- 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"
 #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 b3cc27eb74bbc6203a1d12c8a5c2aec67cd8991f..4ba3a7abda38e76852f0150e1989a903a89fb7aa 100644 (file)
--- 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 {