b89ba33dcef664863a9da0996999f0633c8e411b
[gpgme.git] / tests / gpg / t-keylist-sig.c
1 /* t-keylist-sig.c - Regression test.
2    Copyright (C) 2000 Werner Koch (dd9jn)
3    Copyright (C) 2001, 2003, 2004 g10 Code GmbH
4
5    This file is part of GPGME.
6  
7    GPGME is free software; you can redistribute it and/or modify it
8    under the terms of the GNU Lesser General Public License as
9    published by the Free Software Foundation; either version 2.1 of
10    the License, or (at your option) any later version.
11    
12    GPGME is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Lesser General Public License for more details.
16    
17    You should have received a copy of the GNU Lesser General Public
18    License along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20    02111-1307, USA.  */
21
22 /* We need to include config.h so that we know whether we are building
23    with large file system (LFS) support. */
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31
32 #include <gpgme.h>
33
34 #include "t-support.h"
35
36 \f
37 struct
38 {
39   char *fpr;
40   char *sec_keyid;
41   struct
42   {
43     char *name;
44     char *comment;
45     char *email;
46     struct
47     {
48       gpgme_pubkey_algo_t algo;
49       char *keyid;
50       char *name;
51       char *comment;
52       char *email;
53       unsigned int sig_class;
54       int exportable;
55     } sig;
56   } uid[3];  
57 }
58 keys[] =
59   {
60     { "A0FF4590BB6122EDEF6E3C542D727CC768697734", "6AE6D7EE46A871F8",
61       { { "Alfa Test", "demo key", "alfa@example.net",
62           { GPGME_PK_DSA, "2D727CC768697734",
63             "Alfa Test", "demo key", "alfa@example.net", 19, 1 } },
64         { "Alpha Test", "demo key", "alpha@example.net",
65           { GPGME_PK_DSA, "2D727CC768697734",
66             "Alfa Test", "demo key", "alfa@example.net", 19, 1 } },
67         { "Alice", "demo key", NULL,
68           { GPGME_PK_DSA, "2D727CC768697734",
69             "Alfa Test", "demo key", "alfa@example.net", 19, 1 } } } },
70     { NULL }
71   };
72
73
74 int 
75 main (int argc, char **argv)
76 {
77   gpgme_error_t err;
78   gpgme_ctx_t ctx;
79   gpgme_key_t key;
80   gpgme_keylist_result_t result;
81   int mode;
82   int i = 0;
83
84   init_gpgme (GPGME_PROTOCOL_OpenPGP);
85
86   err = gpgme_new (&ctx);
87   fail_if_err (err);
88
89   mode  = gpgme_get_keylist_mode (ctx);
90   mode |= GPGME_KEYLIST_MODE_SIGS;
91   err = gpgme_set_keylist_mode (ctx, mode);
92   fail_if_err (err);
93
94   err = gpgme_op_keylist_start (ctx, "Alpha", 0);
95   fail_if_err (err);
96     
97   while (!(err = gpgme_op_keylist_next (ctx, &key)))
98     {
99       if (!keys[i].fpr)
100         {
101           fprintf (stderr, "More keys returned than expected\n");
102           exit (1);
103         }
104
105       /* Global key flags.  */
106       if (key->revoked)
107         {
108           fprintf (stderr, "Key unexpectedly revoked\n");
109           exit (1);
110         }
111       if (key->expired)
112         {
113           fprintf (stderr, "Key unexpectedly expired\n");
114           exit (1);
115         }
116       if (key->disabled)
117         {
118           fprintf (stderr, "Key unexpectedly disabled\n");
119           exit (1);
120         }
121       if (key->invalid)
122         {
123           fprintf (stderr, "Key unexpectedly invalid\n");
124           exit (1);
125         }
126       if (!key->can_encrypt)
127         {
128           fprintf (stderr, "Key unexpectedly unusable for encryption\n");
129           exit (1);
130         }
131       if (!key->can_sign)
132         {
133           fprintf (stderr, "Key unexpectedly unusable for signing\n");
134           exit (1);
135         }
136       if (!key->can_certify)
137         {
138           fprintf (stderr, "Key unexpectedly unusable for certifications\n");
139           exit (1);
140         }
141       if (key->secret)
142         {
143           fprintf (stderr, "Key unexpectedly secret\n");
144           exit (1);
145         }
146       if (key->protocol != GPGME_PROTOCOL_OpenPGP)
147         {
148           fprintf (stderr, "Key has unexpected protocol: %s\n",
149                    gpgme_get_protocol_name (key->protocol));
150           exit (1);
151         }
152       if (key->issuer_serial)
153         {
154           fprintf (stderr, "Key unexpectedly carries issuer serial: %s\n",
155                    key->issuer_serial);
156           exit (1);
157         }
158       if (key->issuer_name)
159         {
160           fprintf (stderr, "Key unexpectedly carries issuer name: %s\n",
161                    key->issuer_name);
162           exit (1);
163         }
164       if (key->chain_id)
165         {
166           fprintf (stderr, "Key unexpectedly carries chain ID: %s\n",
167                    key->chain_id);
168           exit (1);
169         }
170       if (key->owner_trust != GPGME_VALIDITY_UNKNOWN)
171         {
172           fprintf (stderr, "Key has unexpected owner trust: %i\n",
173                    key->owner_trust);
174           exit (1);
175         }
176       if (!key->subkeys || !key->subkeys->next || key->subkeys->next->next)
177         {
178           fprintf (stderr, "Key has unexpected number of subkeys\n");
179           exit (1);
180         }
181
182       /* Primary key.  */
183       if (key->subkeys->revoked)
184         {
185           fprintf (stderr, "Primary key unexpectedly revoked\n");
186           exit (1);
187         }
188       if (key->subkeys->expired)
189         {
190           fprintf (stderr, "Primary key unexpectedly expired\n");
191           exit (1);
192         }
193       if (key->subkeys->disabled)
194         {
195           fprintf (stderr, "Primary key unexpectedly disabled\n");
196           exit (1);
197         }
198       if (key->subkeys->invalid)
199         {
200           fprintf (stderr, "Primary key unexpectedly invalid\n");
201           exit (1);
202         }
203       if (key->subkeys->can_encrypt)
204         {
205           fprintf (stderr, "Primary key unexpectedly usable for encryption\n");
206           exit (1);
207         }
208       if (!key->subkeys->can_sign)
209         {
210           fprintf (stderr, "Primary key unexpectedly unusable for signing\n");
211           exit (1);
212         }
213       if (!key->subkeys->can_certify)
214         {
215           fprintf (stderr, "Primary key unexpectedly unusable for certifications\n");
216           exit (1);
217         }
218       if (key->subkeys->secret)
219         {
220           fprintf (stderr, "Primary key unexpectedly secret\n");
221           exit (1);
222         }
223       if (key->subkeys->pubkey_algo != GPGME_PK_DSA)
224         {
225           fprintf (stderr, "Primary key has unexpected public key algo: %s\n",
226                    gpgme_pubkey_algo_name (key->subkeys->pubkey_algo));
227           exit (1);
228         }
229       if (key->subkeys->length != 1024)
230         {
231           fprintf (stderr, "Primary key has unexpected length: %i\n",
232                    key->subkeys->length);
233           exit (1);
234         }
235       if (strcmp (key->subkeys->keyid, &keys[i].fpr[40 - 16]))
236         {
237           fprintf (stderr, "Primary key has unexpected key ID: %s\n",
238                    key->subkeys->keyid);
239           exit (1);
240         }
241       if (strcmp (key->subkeys->fpr, keys[i].fpr))
242         {
243           fprintf (stderr, "Primary key has unexpected fingerprint: %s\n",
244                    key->subkeys->fpr);
245           exit (1);
246         }
247       if (key->subkeys->expires)
248         {
249           fprintf (stderr, "Primary key unexpectedly expires: %lu\n",
250                    key->subkeys->expires);
251           exit (1);
252         }
253
254       /* Secondary key.  */
255       if (key->subkeys->next->revoked)
256         {
257           fprintf (stderr, "Secondary key unexpectedly revoked\n");
258           exit (1);
259         }
260       if (key->subkeys->next->expired)
261         {
262           fprintf (stderr, "Secondary key unexpectedly expired\n");
263           exit (1);
264         }
265       if (key->subkeys->next->disabled)
266         {
267           fprintf (stderr, "Secondary key unexpectedly disabled\n");
268           exit (1);
269         }
270       if (key->subkeys->next->invalid)
271         {
272           fprintf (stderr, "Secondary key unexpectedly invalid\n");
273           exit (1);
274         }
275       if (!key->subkeys->next->can_encrypt)
276         {
277           fprintf (stderr, "Secondary key unexpectedly unusable for encryption\n");
278           exit (1);
279         }
280       if (key->subkeys->next->can_sign)
281         {
282           fprintf (stderr, "Secondary key unexpectedly usable for signing\n");
283           exit (1);
284         }
285       if (key->subkeys->next->can_certify)
286         {
287           fprintf (stderr, "Secondary key unexpectedly usable for certifications\n");
288           exit (1);
289         }
290       if (key->subkeys->next->secret)
291         {
292           fprintf (stderr, "Secondary key unexpectedly secret\n");
293           exit (1);
294         }
295       if (key->subkeys->next->pubkey_algo != GPGME_PK_ELG_E)
296         {
297           fprintf (stderr, "Secondary key has unexpected public key algo: %s\n",
298                    gpgme_pubkey_algo_name (key->subkeys->next->pubkey_algo));
299           exit (1);
300         }
301       if (key->subkeys->next->length != 1024)
302         {
303           fprintf (stderr, "Secondary key has unexpected length: %i\n",
304                    key->subkeys->next->length);
305           exit (1);
306         }
307       if (strcmp (key->subkeys->next->keyid, keys[i].sec_keyid))
308         {
309           fprintf (stderr, "Secondary key has unexpected key ID: %s\n",
310                    key->subkeys->next->keyid);
311           exit (1);
312         }
313       if (!key->subkeys->next->fpr)
314         {
315           fprintf (stderr, "Secondary key has unexpectedly no fingerprint\n");
316           exit (1);
317         }
318       if (key->subkeys->next->expires)
319         {
320           fprintf (stderr, "Secondary key unexpectedly expires: %lu\n",
321                    key->subkeys->next->expires);
322           exit (1);
323         }
324
325       /* FIXME: The below test will crash if we want to check for a
326          name, comment or email that doesn't exist in the key's user
327          IDs.  */
328       if (!((!keys[i].uid[0].name && !key->uids)
329             || (keys[i].uid[0].name && !keys[i].uid[1].name
330                 && key->uids && !key->uids->next)
331             || (keys[i].uid[0].name && keys[i].uid[1].name
332                 && !keys[i].uid[2].name
333                 && key->uids && key->uids->next && !key->uids->next->next)
334             || (keys[i].uid[0].name && keys[i].uid[1].name
335                 && keys[i].uid[2].name
336                 && key->uids && key->uids->next && key->uids->next->next
337                 && !key->uids->next->next->next)))
338           {
339             fprintf (stderr, "Key has unexpected number of user IDs\n");
340             exit (1);
341           }
342       if (key->uids && key->uids->revoked)
343         {
344           fprintf (stderr, "First user ID unexpectedly revoked\n");
345           exit (1);
346         }
347       if (key->uids && key->uids->invalid)
348         {
349           fprintf (stderr, "First user ID unexpectedly invalid\n");
350           exit (1);
351         }
352       if (key->uids && key->uids->validity != GPGME_VALIDITY_UNKNOWN)
353         {
354           fprintf (stderr, "First user ID has unexpectedly validity: %i\n",
355                    key->uids->validity);
356           exit (1);
357         }
358       if (keys[i].uid[0].name
359           && strcmp (keys[i].uid[0].name, key->uids->name))
360         {
361           fprintf (stderr, "Unexpected name in first user ID: %s\n",
362                    key->uids->name);
363           exit (1);
364         }
365       if (keys[i].uid[0].comment
366           && strcmp (keys[i].uid[0].comment, key->uids->comment))
367         {
368           fprintf (stderr, "Unexpected comment in first user ID: %s\n",
369                    key->uids->comment);
370           exit (1);
371         }
372       if (keys[i].uid[0].email
373           && strcmp (keys[i].uid[0].email, key->uids->email))
374         {
375           fprintf (stderr, "Unexpected email in first user ID: %s\n",
376                    key->uids->email);
377           exit (1);
378         }
379       if (key->uids && (!key->uids->signatures || key->uids->signatures->next))
380         {
381           fprintf (stderr, "First user ID unexpected number of signatures\n");
382           exit (1);
383         }
384       if (keys[i].uid[0].sig.algo != key->uids->signatures->pubkey_algo)
385         {
386           fprintf (stderr, "Unexpected algorithm in first user ID sig: %s\n",
387                    gpgme_pubkey_algo_name (key->uids->signatures->pubkey_algo));
388           exit (1);
389         }
390       if (strcmp (keys[i].uid[0].sig.keyid, key->uids->signatures->keyid))
391         {
392           fprintf (stderr, "Unexpected key ID in first user ID sig: %s\n",
393                    key->uids->signatures->keyid);
394           exit (1);
395         }
396       if (strcmp (keys[i].uid[0].sig.name, key->uids->signatures->name))
397         {
398           fprintf (stderr, "Unexpected name in first user ID sig: %s\n",
399                    key->uids->signatures->name);
400           exit (1);
401         }
402       if (strcmp (keys[i].uid[0].sig.comment, key->uids->signatures->comment))
403         {
404           fprintf (stderr, "Unexpected comment in first user ID sig: %s\n",
405                    key->uids->signatures->comment);
406           exit (1);
407         }
408       if (strcmp (keys[i].uid[0].sig.email, key->uids->signatures->email))
409         {
410           fprintf (stderr, "Unexpected email in first user ID sig: %s\n",
411                    key->uids->signatures->email);
412           exit (1);
413         }
414       if (keys[i].uid[0].sig.sig_class != key->uids->signatures->sig_class)
415         {
416           fprintf (stderr, "Unexpected class in first user ID sig: %i\n",
417                    key->uids->signatures->sig_class);
418           exit (1);
419         }
420       if (keys[i].uid[0].sig.exportable != key->uids->signatures->exportable)
421         {
422           fprintf (stderr, "Unexpected exportable stat in first user ID sig: %i\n",
423                    key->uids->signatures->exportable);
424           exit (1);
425         }
426
427       if (key->uids && key->uids->next && key->uids->next->revoked)
428         {
429           fprintf (stderr, "Second user ID unexpectedly revoked\n");
430           exit (1);
431         }
432       if (key->uids && key->uids->next && key->uids->next->invalid)
433         {
434           fprintf (stderr, "Second user ID unexpectedly invalid\n");
435           exit (1);
436         }
437       if (key->uids && key->uids->next
438           && key->uids->next->validity != GPGME_VALIDITY_UNKNOWN)
439         {
440           fprintf (stderr, "Second user ID has unexpectedly validity: %i\n",
441                    key->uids->next->validity);
442           exit (1);
443         }
444       if (keys[i].uid[1].name
445           && strcmp (keys[i].uid[1].name, key->uids->next->name))
446         {
447           fprintf (stderr, "Unexpected name in second user ID: %s\n",
448                    key->uids->next->name);
449           exit (1);
450         }
451       if (keys[i].uid[1].comment
452           && strcmp (keys[i].uid[1].comment, key->uids->next->comment))
453         {
454           fprintf (stderr, "Unexpected comment in second user ID: %s\n",
455                    key->uids->next->comment);
456           exit (1);
457         }
458       if (keys[i].uid[1].email
459           && strcmp (keys[i].uid[1].email, key->uids->next->email))
460         {
461           fprintf (stderr, "Unexpected email in second user ID: %s\n",
462                    key->uids->next->email);
463           exit (1);
464         }
465       /*FIXME: There is a bug in gpg 1.3.4 which duplicates a signaure
466         after importing the secret key.  We disable this test for
467         now. */
468 #ifdef __GNUC__
469 #warning test disabled due to problems with gpg 1.3.4 generated key
470 #endif
471       if (key->uids && (!key->uids->next->signatures /*|| key->uids->next->signatures->next*/))
472         {
473           fprintf (stderr, "Second user ID unexpected number of signatures\n");
474           exit (1);
475         }
476       if (keys[i].uid[1].sig.algo != key->uids->next->signatures->pubkey_algo)
477         {
478           fprintf (stderr, "Unexpected algorithm in second user ID sig: %s\n",
479                    gpgme_pubkey_algo_name (key->uids->next->signatures->pubkey_algo));
480           exit (1);
481         }
482       if (strcmp (keys[i].uid[1].sig.keyid, key->uids->next->signatures->keyid))
483         {
484           fprintf (stderr, "Unexpected key ID in second user ID sig: %s\n",
485                    key->uids->next->signatures->keyid);
486           exit (1);
487         }
488       if (strcmp (keys[i].uid[1].sig.name, key->uids->next->signatures->name))
489         {
490           fprintf (stderr, "Unexpected name in second user ID sig: %s\n",
491                    key->uids->next->signatures->name);
492           exit (1);
493         }
494       if (strcmp (keys[i].uid[1].sig.comment, key->uids->next->signatures->comment))
495         {
496           fprintf (stderr, "Unexpected comment in second user ID sig: %s\n",
497                    key->uids->next->signatures->comment);
498           exit (1);
499         }
500       if (strcmp (keys[i].uid[1].sig.email, key->uids->next->signatures->email))
501         {
502           fprintf (stderr, "Unexpected email in second user ID sig: %s\n",
503                    key->uids->next->signatures->email);
504           exit (1);
505         }
506       if (keys[i].uid[1].sig.sig_class != key->uids->next->signatures->sig_class)
507         {
508           fprintf (stderr, "Unexpected class in second user ID sig: %i\n",
509                    key->uids->next->signatures->sig_class);
510           exit (1);
511         }
512       if (keys[i].uid[1].sig.exportable != key->uids->next->signatures->exportable)
513         {
514           fprintf (stderr, "Unexpected exportable stat in second user ID sig: %i\n",
515                    key->uids->next->signatures->exportable);
516           exit (1);
517         }
518
519       if (key->uids && key->uids->next && key->uids->next->next
520           && key->uids->next->next->revoked)
521         {
522           fprintf (stderr, "Third user ID unexpectedly revoked\n");
523           exit (1);
524         }
525       if (key->uids && key->uids->next && key->uids->next->next
526           && key->uids->next->next->invalid)
527         {
528           fprintf (stderr, "Third user ID unexpectedly invalid\n");
529           exit (1);
530         }
531       if (key->uids && key->uids->next && key->uids->next->next
532           && key->uids->next->next->validity != GPGME_VALIDITY_UNKNOWN)
533         {
534           fprintf (stderr, "Third user ID has unexpectedly validity: %i\n",
535                    key->uids->next->next->validity);
536           exit (1);
537         }
538       if (keys[i].uid[2].name
539           && strcmp (keys[i].uid[2].name, key->uids->next->next->name))
540         {
541           fprintf (stderr, "Unexpected name in third user ID: %s\n",
542                    key->uids->next->next->name);
543           exit (1);
544         }
545       if (keys[i].uid[2].comment
546           && strcmp (keys[i].uid[2].comment, key->uids->next->next->comment))
547         {
548           fprintf (stderr, "Unexpected comment in third user ID: %s\n",
549                    key->uids->next->next->comment);
550           exit (1);
551         }
552       if (keys[i].uid[2].email
553           && strcmp (keys[i].uid[2].email, key->uids->next->next->email))
554         {
555           fprintf (stderr, "Unexpected email in third user ID: %s\n",
556                    key->uids->next->next->email);
557           exit (1);
558         }
559       if (key->uids && (!key->uids->next->next->signatures
560                         || key->uids->next->next->signatures->next))
561         {
562           fprintf (stderr, "Third user ID unexpected number of signatures\n");
563           exit (1);
564         }
565       if (keys[i].uid[2].sig.algo != key->uids->next->next->signatures->pubkey_algo)
566         {
567           fprintf (stderr, "Unexpected algorithm in third user ID sig: %s\n",
568                    gpgme_pubkey_algo_name (key->uids->next->next->signatures->pubkey_algo));
569           exit (1);
570         }
571       if (strcmp (keys[i].uid[2].sig.keyid, key->uids->next->next->signatures->keyid))
572         {
573           fprintf (stderr, "Unexpected key ID in third user ID sig: %s\n",
574                    key->uids->next->next->signatures->keyid);
575           exit (1);
576         }
577       if (strcmp (keys[i].uid[2].sig.name, key->uids->next->next->signatures->name))
578         {
579           fprintf (stderr, "Unexpected name in third user ID sig: %s\n",
580                    key->uids->next->next->signatures->name);
581           exit (1);
582         }
583       if (strcmp (keys[i].uid[2].sig.comment, key->uids->next->next->signatures->comment))
584         {
585           fprintf (stderr, "Unexpected comment in third user ID sig: %s\n",
586                    key->uids->next->next->signatures->comment);
587           exit (1);
588         }
589       if (strcmp (keys[i].uid[2].sig.email, key->uids->next->next->signatures->email))
590         {
591           fprintf (stderr, "Unexpected email in third user ID sig: %s\n",
592                    key->uids->next->next->signatures->email);
593           exit (1);
594         }
595       if (keys[i].uid[2].sig.sig_class != key->uids->next->next->signatures->sig_class)
596         {
597           fprintf (stderr, "Unexpected class in third user ID sig: %i\n",
598                    key->uids->next->next->signatures->sig_class);
599           exit (1);
600         }
601       if (keys[i].uid[2].sig.exportable != key->uids->next->next->signatures->exportable)
602         {
603           fprintf (stderr, "Unexpected exportable stat in third user ID sig: %i\n",
604                    key->uids->next->next->signatures->exportable);
605           exit (1);
606         }
607
608
609
610
611
612       gpgme_key_unref (key);
613       i++;
614     }
615   if (gpg_err_code (err) != GPG_ERR_EOF)
616     fail_if_err (err);
617   err = gpgme_op_keylist_end (ctx);
618   fail_if_err (err);
619
620   result = gpgme_op_keylist_result (ctx);
621   if (result->truncated)
622     {
623       fprintf (stderr, "Key listing unexpectedly truncated\n");
624       exit (1);
625     }
626
627   if (keys[i].fpr)
628     {
629       fprintf (stderr, "Less keys returned than expected\n");
630       exit (1);
631     }
632
633   gpgme_release (ctx);
634   return 0;
635 }