cscvs to tla changeset 52
authorJonathan McDowell <noodles@earth.li>
Mon, 31 May 2004 23:47:23 +0000 (23:47 +0000)
committerJonathan McDowell <noodles@earth.li>
Mon, 31 May 2004 23:47:23 +0000 (23:47 +0000)
Author: noodles
Date: 2002/12/03 08:14:38
Added fingerprint calculation and display.

Makefile
keyid.c
keyid.h
keyindex.c
onak.c

index 35f1674f3c4b74302a5d6cefbd7fefa9cc8204a3..7e04bf7ce903855a5c059b79d09243c73b483cd0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -12,8 +12,8 @@ LIBS = -L/usr/local/lib -ldb3
 
 PROGS = add lookup gpgwww onak
 CORE_OBJS = armor.o charfuncs.o decodekey.o getcgi.o hash.o keydb_$(DBTYPE).o \
-       keyid.o keyindex.o ll.o mem.o onak-conf.o parsekey.o sha.o
-OBJS = merge.o md5.o stats.o sendsync.o $(CORE_OBJS)
+       keyid.o keyindex.o ll.o mem.o onak-conf.o parsekey.o sha.o md5.o
+OBJS = merge.o stats.o sendsync.o $(CORE_OBJS)
 SRCS = armor.c parsekey.c merge.c keyid.c md5.c sha.c main.c getcgi.c stats.c \
        keyindex.c mem.c lookup.c add.c keydb_$(DBTYPE).c ll.c hash.c \
        gpgwww.c onak-conf.c charfuncs.c sendsync.c
diff --git a/keyid.c b/keyid.c
index 6bb2e19d2a893469c7e68012631f0170a286c418..ced0c458997a79818518133067b645b8c851faec 100644 (file)
--- a/keyid.c
+++ b/keyid.c
@@ -24,17 +24,94 @@ uint64_t get_keyid(struct openpgp_publickey *publickey)
 }
 
 /**
- *     get_packetid - Given a PGP packet returns the keyid.
- *     @packet: The packet to calculate the id for.
+ *     get_fingerprint - Given a public key returns the fingerprint.
+ *     @publickey: The key to calculate the id for.
+ *     @fingerprint: The fingerprint (must be at least 20 bytes of space). 
+ *     @len: The length of the returned fingerprint.
+ *
+ *     This function returns the fingerprint for a given public key. As Type 3
+ *     fingerprints are 16 bytes and Type 4 are 20 the len field indicates
+ *     which we've returned.
  */
-uint64_t get_packetid(struct openpgp_packet *packet)
+unsigned char *get_fingerprint(struct openpgp_packet *packet,
+       unsigned char *fingerprint,
+       size_t *len)
 {
        SHA1_CONTEXT sha_ctx;
-       uint64_t keyid = 0;
-       int offset = 0;
-       int i = 0;
+       MD5_CONTEXT md5_ctx;
        unsigned char c;
        unsigned char *buff = NULL;
+       size_t         modlen, explen;
+
+       assert(fingerprint != NULL);
+       assert(len != NULL);
+
+       *len = 0;
+
+       switch (packet->data[0]) {
+       case 2:
+       case 3:
+               md5_init(&md5_ctx);
+
+               /*
+                * MD5 the modulus and exponent.
+                */
+               modlen = ((packet->data[8] << 8) +
+                        packet->data[9] + 7) >> 3;
+               md5_write(&md5_ctx, &packet->data[10], modlen);
+
+               explen = ((packet->data[10+modlen] << 8) +
+                        packet->data[11+modlen] + 7) >> 3;
+               md5_write(&md5_ctx, &packet->data[12 + modlen], explen);
+
+               md5_final(&md5_ctx);
+               buff = md5_read(&md5_ctx);
+
+               *len = 16;
+               memcpy(fingerprint, buff, *len);
+
+               break;
+
+       case 4:
+               sha1_init(&sha_ctx);
+               /*
+                * TODO: Can this be 0x99? Are all public key packets old
+                * format with 2 bytes of length data?
+                */
+               c = 0x99;
+               sha1_write(&sha_ctx, &c, sizeof(c));
+               c = packet->length >> 8;
+               sha1_write(&sha_ctx, &c, sizeof(c));
+               c = packet->length & 0xFF;
+               sha1_write(&sha_ctx, &c, sizeof(c));
+               sha1_write(&sha_ctx, packet->data,
+                       packet->length);
+               sha1_final(&sha_ctx);
+               buff = sha1_read(&sha_ctx);
+
+               *len = 20;
+               memcpy(fingerprint, buff, *len);
+               break;
+       default:
+               fprintf(stderr, "Unknown key type: %d\n",
+                               packet->data[0]);
+       }
+
+       return fingerprint;
+}
+
+
+/**
+ *     get_packetid - Given a PGP packet returns the keyid.
+ *     @packet: The packet to calculate the id for.
+ */
+uint64_t get_packetid(struct openpgp_packet *packet)
+{
+       uint64_t        keyid = 0;
+       int             offset = 0;
+       int             i = 0;
+       size_t          length = 0;
+       unsigned char   buff[20];
 
        assert(packet != NULL);
 
@@ -62,29 +139,7 @@ uint64_t get_packetid(struct openpgp_packet *packet)
                }
                break;
        case 4:
-               /*
-                * For a type 4 key the keyid is the last 64 bits of the
-                * fingerprint, which is the 160 bit SHA-1 hash of the packet
-                * tag, 2 octet packet length and the public key packet
-                * including version field.
-                */
-               sha1_init(&sha_ctx);
-               /*
-                * TODO: Can this be 0x99? Are all public key packets old
-                * format with 2 bytes of length data?
-                */
-               c = 0x99;
-               sha1_write(&sha_ctx, &c, sizeof(c));
-               c = packet->length >> 8;
-               sha1_write(&sha_ctx, &c, sizeof(c));
-               c = packet->length & 0xFF;
-               sha1_write(&sha_ctx, &c, sizeof(c));
-               sha1_write(&sha_ctx, packet->data,
-                       packet->length);
-               sha1_final(&sha_ctx);
-               buff = sha1_read(&sha_ctx);
-
-               assert(buff != NULL);
+               get_fingerprint(packet, buff, &length);
                
                for (keyid = 0, i = 12; i < 20; i++) {
                        keyid <<= 8;
diff --git a/keyid.h b/keyid.h
index d25447c6971c85f0d30508862c211d6900c64dff..c3082090ff8ba5e06ce714dbd51134b8c993df5e 100644 (file)
--- a/keyid.h
+++ b/keyid.h
  */
 uint64_t get_keyid(struct openpgp_publickey *publickey);
 
+/**
+ *     get_fingerprint - Given a public key returns the fingerprint.
+ *     @publickey: The key to calculate the id for.
+ *     @fingerprint: The fingerprint (must be at least 20 bytes of space). 
+ *     @len: The length of the returned fingerprint.
+ *
+ *     This function returns the fingerprint for a given public key. As Type 3
+ *     fingerprints are 16 bytes and Type 4 are 20 the len field indicates
+ *     which we've returned.
+ */
+unsigned char *get_fingerprint(struct openpgp_packet *packet,
+       unsigned char *fingerprint,
+       size_t *len);
+
 /**
  *     get_packetid - Given a PGP packet returns the keyid.
  *     @packet: The packet to calculate the id for.
index 5911cac81736ae53f9b66bca1348ff59edda6b74..2e14e778f2c83a80b1d1f1d9fe90b2ab1377fd9c 100644 (file)
@@ -138,6 +138,29 @@ int list_subkeys(struct openpgp_signedpacket_list *subkeys, bool verbose,
        return 0;
 }
 
+void display_fingerprint(struct openpgp_publickey *key)
+{
+       int             i = 0;
+       size_t          length = 0;
+       unsigned char   fp[20];
+
+       get_fingerprint(key->publickey, fp, &length);
+       printf("      Key fingerprint =");
+       for (i = 0; i < length; i++) {
+               if ((length == 16) ||
+                       (i % 2 == 0)) {
+                       printf(" ");
+               }
+               printf("%02X", fp[i]);
+               if ((i * 2) == length) {
+                       printf(" ");
+               }
+       }
+       printf("\n");
+
+       return;
+}
+
 /**
  *     key_index - List a set of OpenPGP keys.
  *     @keys: The keys to display.
@@ -201,12 +224,18 @@ int key_index(struct openpgp_publickey *keys, bool verbose, bool fingerprint,
                                (int) curuid->packet->length,
                                curuid->packet->data);
                        printf("%s\n", (html) ? txt2html(buf) : buf);
+                       if (fingerprint) {
+                               display_fingerprint(keys);
+                       }
                        if (verbose) {
                                list_sigs(curuid->sigs, html);
                        }
                        curuid = curuid->next;
                } else {
                        putchar('\n');
+                       if (fingerprint) {
+                               display_fingerprint(keys);
+                       }
                }
 
                list_uids(curuid, verbose, html);
diff --git a/onak.c b/onak.c
index 90c6926c95d7fb1db15ad18cbaff91d4aad4f808..07e01a591db64a940497c1bde6e7e0dd3df31adf 100644 (file)
--- a/onak.c
+++ b/onak.c
@@ -96,13 +96,17 @@ int main(int argc, char *argv[])
        bool                             verbose = false;
        bool                             update = false;
        bool                             binary = false;
+       bool                             fingerprint = false;
        int                              optchar;
 
-       while ((optchar = getopt(argc, argv, "buv")) != -1 ) {
+       while ((optchar = getopt(argc, argv, "bfuv")) != -1 ) {
                switch (optchar) {
                case 'b': 
                        binary = true;
                        break;
+               case 'f': 
+                       fingerprint = true;
+                       break;
                case 'u': 
                        update = true;
                        break;
@@ -174,9 +178,11 @@ int main(int argc, char *argv[])
                }
                initdb();
                if (!strcmp("index", argv[optind])) {
-                       find_keys(search, keyid, ishex, false, false, false);
+                       find_keys(search, keyid, ishex, fingerprint,
+                                       false, false);
                } else if (!strcmp("vindex", argv[optind])) {
-                       find_keys(search, keyid, ishex, false, false, true);
+                       find_keys(search, keyid, ishex, fingerprint,
+                                       false, true);
                } else if (!strcmp("delete", argv[optind])) {
                        delete_key(getfullkeyid(keyid), false);
                } else if (!strcmp("get", argv[optind])) {