2  * keyindex.c - Routines to list an OpenPGP key.
 
   4  * Copyright 2002-2008 Jonathan McDowell <noodles@earth.li>
 
   6  * This program is free software: you can redistribute it and/or modify it
 
   7  * under the terms of the GNU General Public License as published by the Free
 
   8  * Software Foundation; version 2 of the License.
 
  10  * This program is distributed in the hope that it will be useful, but WITHOUT
 
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
  12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 
  15  * You should have received a copy of the GNU General Public License along with
 
  16  * this program; if not, write to the Free Software Foundation, Inc., 51
 
  17  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
  27 #include "decodekey.h"
 
  33 #include "keystructs.h"
 
  35 #include "onak-conf.h"
 
  38 int list_sigs(struct openpgp_packet_list *sigs, bool html)
 
  44         while (sigs != NULL) {
 
  45                 sigid = sig_keyid(sigs->packet);
 
  46                 uid = config.dbbackend->keyid2uid(sigid);
 
  47                 if (sigs->packet->data[0] == 4 &&
 
  48                                 sigs->packet->data[1] == 0x30) {
 
  49                         /* It's a Type 4 sig revocation */
 
  54                 if (html && uid != NULL) {
 
  55                         printf("%s         <a href=\"lookup?op=get&"
 
  56                                 "search=0x%016" PRIX64 "\">%08" PRIX64
 
  58                                 "<a href=\"lookup?op=vindex&search=0x%016"
 
  65                 } else if (html && uid == NULL) {
 
  66                         printf("%s         %08" PRIX64 "             "
 
  67                                 "[User id not found]\n",
 
  71                         printf("%s         %08" PRIX64
 
  76                                 "[User id not found]");
 
  88 int list_uids(uint64_t keyid, struct openpgp_signedpacket_list *uids,
 
  89                 bool verbose, bool html)
 
  94         while (uids != NULL) {
 
  95                 if (uids->packet->tag == OPENPGP_PACKET_UID) {
 
  96                         snprintf(buf, 1023, "%.*s",
 
  97                                 (int) uids->packet->length,
 
 100                                 (html) ? txt2html(buf) : buf);
 
 101                 } else if (uids->packet->tag == OPENPGP_PACKET_UAT) {
 
 104                                 printf("<img src=\"lookup?op=photo&search="
 
 105                                         "0x%016" PRIX64 "&idx=%d\" alt=\""
 
 111                                 printf("[photo id]\n");
 
 115                         list_sigs(uids->sigs, html);
 
 123 int list_subkeys(struct openpgp_signedpacket_list *subkeys, bool verbose,
 
 126         struct tm       *created = NULL;
 
 127         time_t          created_time = 0;
 
 131         while (subkeys != NULL) {
 
 132                 if (subkeys->packet->tag == OPENPGP_PACKET_PUBLICSUBKEY) {
 
 134                         created_time = (subkeys->packet->data[1] << 24) +
 
 135                                         (subkeys->packet->data[2] << 16) +
 
 136                                         (subkeys->packet->data[3] << 8) +
 
 137                                         subkeys->packet->data[4];
 
 138                         created = gmtime(&created_time);
 
 140                         switch (subkeys->packet->data[0]) {
 
 143                                 type = subkeys->packet->data[7];
 
 144                                 length = (subkeys->packet->data[8] << 8) +
 
 145                                         subkeys->packet->data[9];
 
 148                                 type = subkeys->packet->data[5];
 
 149                                 length = (subkeys->packet->data[6] << 8) +
 
 150                                         subkeys->packet->data[7];
 
 153                                 logthing(LOGTHING_ERROR,
 
 154                                         "Unknown key type: %d",
 
 155                                         subkeys->packet->data[0]);
 
 158                         printf("sub  %5d%c/%08X %04d/%02d/%02d\n",
 
 160                                 (type == OPENPGP_PKALGO_RSA) ? 'R' :
 
 161                                 ((type == OPENPGP_PKALGO_ELGAMAL) ? 'g' :
 
 162                                 ((type == OPENPGP_PKALGO_DSA) ? 'D' : '?')),
 
 163                                 (uint32_t) (get_packetid(subkeys->packet) &
 
 165                                 created->tm_year + 1900,
 
 171                         list_sigs(subkeys->sigs, html);
 
 173                 subkeys = subkeys->next;
 
 179 void display_fingerprint(struct openpgp_publickey *key)
 
 183         unsigned char   fp[20];
 
 185         get_fingerprint(key->publickey, fp, &length);
 
 186         printf("      Key fingerprint =");
 
 187         for (i = 0; i < length; i++) {
 
 188                 if ((length == 16) ||
 
 192                 if (length == 20 && (i * 2) == length) {
 
 193                         /* Extra space in the middle of a SHA1 fingerprint */
 
 196                 printf("%02X", fp[i]);
 
 203 void display_skshash(struct openpgp_publickey *key, bool html)
 
 208         get_skshash(key, &hash);
 
 209         printf("      Key hash = ");
 
 211                 printf("<a href=\"lookup?op=hget&search=");
 
 212                 for (i = 0; i < sizeof(hash.hash); i++) {
 
 213                         printf("%02X", hash.hash[i]);
 
 217         for (i = 0; i < sizeof(hash.hash); i++) {
 
 218                 printf("%02X", hash.hash[i]);
 
 229  *      key_index - List a set of OpenPGP keys.
 
 230  *      @keys: The keys to display.
 
 231  *      @verbose: Should we list sigs as well?
 
 232  *      @fingerprint: List the fingerprint?
 
 233  *      @html: Should the output be tailored for HTML?
 
 235  *      This function takes a list of OpenPGP public keys and displays an index
 
 236  *      of them. Useful for debugging or the keyserver Index function.
 
 238 int key_index(struct openpgp_publickey *keys, bool verbose, bool fingerprint,
 
 239                         bool skshash, bool html)
 
 241         struct openpgp_signedpacket_list        *curuid = NULL;
 
 242         struct tm                               *created = NULL;
 
 243         time_t                                   created_time = 0;
 
 253         puts("Type   bits/keyID    Date       User ID");
 
 254         while (keys != NULL) {
 
 255                 created_time = (keys->publickey->data[1] << 24) +
 
 256                                         (keys->publickey->data[2] << 16) +
 
 257                                         (keys->publickey->data[3] << 8) +
 
 258                                         keys->publickey->data[4];
 
 259                 created = gmtime(&created_time);
 
 261                 switch (keys->publickey->data[0]) {
 
 264                         type = keys->publickey->data[7];
 
 265                         length = (keys->publickey->data[8] << 8) +
 
 266                                         keys->publickey->data[9];
 
 269                         type = keys->publickey->data[5];
 
 270                         length = (keys->publickey->data[6] << 8) +
 
 271                                         keys->publickey->data[7];
 
 274                         logthing(LOGTHING_ERROR, "Unknown key type: %d",
 
 275                                 keys->publickey->data[0]);
 
 278                 keyid = get_keyid(keys);
 
 281                 case OPENPGP_PKALGO_RSA:
 
 284                 case OPENPGP_PKALGO_ELGAMAL:
 
 287                 case OPENPGP_PKALGO_DSA:
 
 290                 case OPENPGP_PKALGO_ELGAMAL_SIGN:
 
 299                         printf("pub  %5d%c/<a href=\"lookup?op=get&"
 
 300                                 "search=0x%016" PRIX64 "\">%08" PRIX64
 
 301                                 "</a> %04d/%02d/%02d ",
 
 306                                 created->tm_year + 1900,
 
 310                         printf("pub  %5d%c/%08" PRIX64 " %04d/%02d/%02d ",
 
 314                                 created->tm_year + 1900,
 
 320                 if (curuid != NULL &&
 
 321                                 curuid->packet->tag == OPENPGP_PACKET_UID) {
 
 322                         snprintf(buf, 1023, "%.*s",
 
 323                                 (int) curuid->packet->length,
 
 324                                 curuid->packet->data);
 
 326                                 printf("<a href=\"lookup?op=vindex&"
 
 327                                         "search=0x%016" PRIX64 "\">",
 
 331                                 (html) ? txt2html(buf) : buf,
 
 332                                 (html) ? "</a>" : "",
 
 333                                 (keys->revoked) ? " *** REVOKED ***" : "");
 
 335                                 display_skshash(keys, html);
 
 338                                 display_fingerprint(keys);
 
 341                                 list_sigs(curuid->sigs, html);
 
 343                         curuid = curuid->next;
 
 346                                 (keys->revoked) ? "*** REVOKED ***": "");
 
 348                                 display_fingerprint(keys);
 
 352                 list_uids(keyid, curuid, verbose, html);
 
 354                         list_subkeys(keys->subkeys, verbose, html);
 
 368  *      mrkey_index - List a set of OpenPGP keys in the MRHKP format.
 
 369  *      @keys: The keys to display.
 
 371  *      This function takes a list of OpenPGP public keys and displays a
 
 372  *      machine readable list of them.
 
 374 int mrkey_index(struct openpgp_publickey *keys)
 
 376         struct openpgp_signedpacket_list        *curuid = NULL;
 
 377         time_t                                   created_time = 0;
 
 382         unsigned char                            fp[20];
 
 385         while (keys != NULL) {
 
 386                 created_time = (keys->publickey->data[1] << 24) +
 
 387                                         (keys->publickey->data[2] << 16) +
 
 388                                         (keys->publickey->data[3] << 8) +
 
 389                                         keys->publickey->data[4];
 
 393                 switch (keys->publickey->data[0]) {
 
 396                         printf("%016" PRIX64, get_keyid(keys));
 
 397                         type = keys->publickey->data[7];
 
 398                         length = (keys->publickey->data[8] << 8) +
 
 399                                         keys->publickey->data[9];
 
 402                         (void) get_fingerprint(keys->publickey, fp, &fplength);
 
 404                         for (i = 0; i < fplength; i++) {
 
 405                                 printf("%02X", fp[i]);
 
 408                         type = keys->publickey->data[5];
 
 409                         length = (keys->publickey->data[6] << 8) +
 
 410                                         keys->publickey->data[7];
 
 413                         logthing(LOGTHING_ERROR, "Unknown key type: %d",
 
 414                                 keys->publickey->data[0]);
 
 417                 printf(":%d:%d:%ld::%s\n",
 
 421                         (keys->revoked) ? "r" : "");
 
 423                 for (curuid = keys->uids; curuid != NULL;
 
 424                          curuid = curuid->next) {
 
 426                         if (curuid->packet->tag == OPENPGP_PACKET_UID) {
 
 428                                 for (i = 0; i < (int) curuid->packet->length;
 
 430                                         c = curuid->packet->data[i];
 
 434                                         } else if (c == ':' || c > 127) {