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=%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=%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) {