cscvs to tla changeset 125
[onak.git] / keyindex.c
1 /*
2  * keyindex.c - Routines to list an OpenPGP key.
3  *
4  * Jonathan McDowell <noodles@earth.li>
5  *
6  * Copyright 2002 Project Purple
7  *
8  * $Id: keyindex.c,v 1.15 2004/05/27 01:25:37 noodles Exp $
9  */
10
11 #include <assert.h>
12 #include <inttypes.h>
13 #include <stdbool.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <time.h>
18
19 #include "decodekey.h"
20 #include "getcgi.h"
21 #include "hash.h"
22 #include "keydb.h"
23 #include "keyid.h"
24 #include "keyindex.h"
25 #include "keystructs.h"
26 #include "log.h"
27
28 int list_sigs(struct openpgp_packet_list *sigs, bool html)
29 {
30         char *uid = NULL;
31         uint64_t sigid = 0;
32
33         while (sigs != NULL) {
34                 sigid = sig_keyid(sigs->packet);
35                 uid = keyid2uid(sigid);
36                 if (html && uid != NULL) {
37                         printf("sig         <a href=\"lookup?op=get&"
38                                 "search=%08llX\">%08llX</a>             "
39                                 "<a href=\"lookup?op=vindex&search=0x%08llX\">"
40                                 "%s</a>\n",
41                                 sigid & 0xFFFFFFFF,
42                                 sigid & 0xFFFFFFFF,
43                                 sigid & 0xFFFFFFFF,
44                                 txt2html(uid));
45                 } else if (html && uid == NULL) {
46                         printf("sig         %08llX             "
47                                 "[User id not found]\n",
48                                 sigid & 0xFFFFFFFF);
49                 } else {
50                         printf("sig         %08llX"
51                                 "             %s\n",
52                                 sigid & 0xFFFFFFFF,
53                                 (uid != NULL) ? uid :
54                                 "[User id not found]");
55                 }
56                 if (uid != NULL) {
57                         free(uid);
58                         uid = NULL;
59                 }
60                 sigs = sigs->next;
61         }
62
63         return 0;
64 }
65
66 int list_uids(uint64_t keyid, struct openpgp_signedpacket_list *uids,
67                 bool verbose, bool html)
68 {
69         char buf[1024];
70         int  imgindx = 0;
71
72         while (uids != NULL) {
73                 if (uids->packet->tag == 13) {
74                         snprintf(buf, 1023, "%.*s",
75                                 (int) uids->packet->length,
76                                 uids->packet->data);
77                         printf("                                %s\n",
78                                 (html) ? txt2html(buf) : buf);
79                 } else if (uids->packet->tag == 17) {
80                         printf("                                ");
81                         if (html) {
82                                 printf("<img src=\"lookup?op=photo&search=0x%llX&idx=%d\" alt=\"[photo id]\">\n",
83                                                 keyid,
84                                                 imgindx);
85                                 imgindx++;
86                         } else {
87                                 printf("[photo id]\n");
88                         }
89                 }
90                 if (verbose) {
91                         list_sigs(uids->sigs, html);
92                 }
93                 uids = uids->next;
94         }
95
96         return 0;
97 }
98
99 int list_subkeys(struct openpgp_signedpacket_list *subkeys, bool verbose,
100                 bool html)
101 {
102         struct tm       *created = NULL;
103         time_t          created_time = 0;
104         int             type = 0;
105         int             length = 0;
106
107         while (subkeys != NULL) {
108                 if (subkeys->packet->tag == 14) {
109
110                         created_time = (subkeys->packet->data[1] << 24) +
111                                         (subkeys->packet->data[2] << 16) +
112                                         (subkeys->packet->data[3] << 8) +
113                                         subkeys->packet->data[4];
114                         created = gmtime(&created_time);
115
116                         switch (subkeys->packet->data[0]) {
117                         case 2:
118                         case 3:
119                                 type = subkeys->packet->data[7];
120                                 length = (subkeys->packet->data[8] << 8) +
121                                         subkeys->packet->data[9];
122                                 break;
123                         case 4:
124                                 type = subkeys->packet->data[5];
125                                 length = (subkeys->packet->data[6] << 8) +
126                                         subkeys->packet->data[7];
127                                 break;
128                         default:
129                                 logthing(LOGTHING_ERROR,
130                                         "Unknown key type: %d",
131                                         subkeys->packet->data[0]);
132                         }
133                 
134                         printf("sub  %5d%c/%08X %04d/%02d/%02d\n",
135                                 length,
136                                 (type == 1) ? 'R' : ((type == 16) ? 'g' : 
137                                         ((type == 17) ? 'D' : '?')),
138                                 (uint32_t) (get_packetid(subkeys->packet) &
139                                             0xFFFFFFFF),
140                                 created->tm_year + 1900,
141                                 created->tm_mon + 1,
142                                 created->tm_mday);
143
144                 }
145                 if (verbose) {
146                         list_sigs(subkeys->sigs, html);
147                 }
148                 subkeys = subkeys->next;
149         }
150
151         return 0;
152 }
153
154 void display_fingerprint(struct openpgp_publickey *key)
155 {
156         int             i = 0;
157         size_t          length = 0;
158         unsigned char   fp[20];
159
160         get_fingerprint(key->publickey, fp, &length);
161         printf("      Key fingerprint =");
162         for (i = 0; i < length; i++) {
163                 if ((length == 16) ||
164                         (i % 2 == 0)) {
165                         printf(" ");
166                 }
167                 printf("%02X", fp[i]);
168                 if ((i * 2) == length) {
169                         printf(" ");
170                 }
171         }
172         printf("\n");
173
174         return;
175 }
176
177 /**
178  *      key_index - List a set of OpenPGP keys.
179  *      @keys: The keys to display.
180  *      @verbose: Should we list sigs as well?
181  *      @fingerprint: List the fingerprint?
182  *      @html: Should the output be tailored for HTML?
183  *
184  *      This function takes a list of OpenPGP public keys and displays an index
185  *      of them. Useful for debugging or the keyserver Index function.
186  */
187 int key_index(struct openpgp_publickey *keys, bool verbose, bool fingerprint,
188                         bool html)
189 {
190         struct openpgp_signedpacket_list        *curuid = NULL;
191         struct tm                               *created = NULL;
192         time_t                                   created_time = 0;
193         int                                      type = 0;
194         int                                      length = 0;
195         char                                     buf[1024];
196         uint64_t                                 keyid;
197
198         if (html) {
199                 puts("<pre>");
200         }
201         puts("Type   bits/keyID    Date       User ID");
202         while (keys != NULL) {
203                 created_time = (keys->publickey->data[1] << 24) +
204                                         (keys->publickey->data[2] << 16) +
205                                         (keys->publickey->data[3] << 8) +
206                                         keys->publickey->data[4];
207                 created = gmtime(&created_time);
208
209                 switch (keys->publickey->data[0]) {
210                 case 2:
211                 case 3:
212                         type = keys->publickey->data[7];
213                         length = (keys->publickey->data[8] << 8) +
214                                         keys->publickey->data[9];
215                         break;
216                 case 4:
217                         type = keys->publickey->data[5];
218                         length = (keys->publickey->data[6] << 8) +
219                                         keys->publickey->data[7];
220                         break;
221                 default:
222                         logthing(LOGTHING_ERROR, "Unknown key type: %d",
223                                 keys->publickey->data[0]);
224                 }
225                 
226                 keyid = (get_keyid(keys) & 0xFFFFFFFF),
227                 printf("pub  %5d%c/%08X %04d/%02d/%02d ",
228                         length,
229                         (type == 1) ? 'R' : ((type == 16) ? 'g' : 
230                                 ((type == 17) ? 'D' : '?')),
231                         (uint32_t) keyid,
232                         created->tm_year + 1900,
233                         created->tm_mon + 1,
234                         created->tm_mday);
235
236                 curuid = keys->uids;
237                 if (curuid != NULL && curuid->packet->tag == 13) {
238                         snprintf(buf, 1023, "%.*s",
239                                 (int) curuid->packet->length,
240                                 curuid->packet->data);
241                         printf("%s%s\n", 
242                                 (html) ? txt2html(buf) : buf,
243                                 (keys->revocations == NULL) ? "" :
244                                         " *** REVOKED ***");
245                         if (fingerprint) {
246                                 display_fingerprint(keys);
247                         }
248                         if (verbose) {
249                                 list_sigs(curuid->sigs, html);
250                         }
251                         curuid = curuid->next;
252                 } else {
253                         printf("%s\n", 
254                                 (keys->revocations == NULL) ? "" :
255                                         "*** REVOKED ***");
256                         if (fingerprint) {
257                                 display_fingerprint(keys);
258                         }
259                 }
260
261                 list_uids(keyid, curuid, verbose, html);
262                 if (verbose) {
263                         list_subkeys(keys->subkeys, verbose, html);
264                 }
265
266                 keys = keys->next;
267         }
268
269         if (html) {
270                 puts("</pre>");
271         }
272
273         return 0;
274 }
275
276 /**
277  *      mrkey_index - List a set of OpenPGP keys in the MRHKP format.
278  *      @keys: The keys to display.
279  *
280  *      This function takes a list of OpenPGP public keys and displays a
281  *      machine readable list of them.
282  */
283 int mrkey_index(struct openpgp_publickey *keys)
284 {
285         struct openpgp_signedpacket_list        *curuid = NULL;
286         time_t                                   created_time = 0;
287         int                                      type = 0;
288         int                                      length = 0;
289         int                                      i = 0;
290         size_t                                   fplength = 0;
291         unsigned char                            fp[20];
292
293         while (keys != NULL) {
294                 created_time = (keys->publickey->data[1] << 24) +
295                                         (keys->publickey->data[2] << 16) +
296                                         (keys->publickey->data[3] << 8) +
297                                         keys->publickey->data[4];
298
299                 printf("pub:");
300
301                 switch (keys->publickey->data[0]) {
302                 case 2:
303                 case 3:
304                         printf("%016llX", get_keyid(keys));
305                         type = keys->publickey->data[7];
306                         length = (keys->publickey->data[8] << 8) +
307                                         keys->publickey->data[9];
308                         break;
309                 case 4:
310                         (void) get_fingerprint(keys->publickey, fp, &fplength);
311
312                         for (i = 0; i < fplength; i++) {
313                                 printf("%02X", fp[i]);
314                         }
315
316                         type = keys->publickey->data[5];
317                         length = (keys->publickey->data[6] << 8) +
318                                         keys->publickey->data[7];
319                         break;
320                 default:
321                         logthing(LOGTHING_ERROR, "Unknown key type: %d",
322                                 keys->publickey->data[0]);
323                 }
324
325                 printf(":%d:%d:%ld::%s\n",
326                         type,
327                         length,
328                         created_time,
329                         (keys->revocations == NULL) ? "" : "r");
330         
331                 for (curuid = keys->uids; curuid != NULL;
332                          curuid = curuid->next) {
333                 
334                         if (curuid->packet->tag == 13) {
335                                 printf("uid:%.*s\n",
336                                         (int) curuid->packet->length,
337                                         curuid->packet->data);
338                         }
339                 }
340                 keys = keys->next;
341         }
342         return 0;
343 }