ec3062497a2c1cc011b9acf0c7daa280324e6f22
[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       /* Note: There is a bug in gpg 1.3.4 which duplicates a
466          signature after importing the secret key.  Thus we disable
467          the second part of the check. */
468       if (key->uids && (!key->uids->next->signatures /*|| key->uids->next->signatures->next*/))
469         {
470           fprintf (stderr, "Second user ID unexpected number of signatures\n");
471           exit (1);
472         }
473       if (keys[i].uid[1].sig.algo != key->uids->next->signatures->pubkey_algo)
474         {
475           fprintf (stderr, "Unexpected algorithm in second user ID sig: %s\n",
476                    gpgme_pubkey_algo_name (key->uids->next->signatures->pubkey_algo));
477           exit (1);
478         }
479       if (strcmp (keys[i].uid[1].sig.keyid, key->uids->next->signatures->keyid))
480         {
481           fprintf (stderr, "Unexpected key ID in second user ID sig: %s\n",
482                    key->uids->next->signatures->keyid);
483           exit (1);
484         }
485       if (strcmp (keys[i].uid[1].sig.name, key->uids->next->signatures->name))
486         {
487           fprintf (stderr, "Unexpected name in second user ID sig: %s\n",
488                    key->uids->next->signatures->name);
489           exit (1);
490         }
491       if (strcmp (keys[i].uid[1].sig.comment, key->uids->next->signatures->comment))
492         {
493           fprintf (stderr, "Unexpected comment in second user ID sig: %s\n",
494                    key->uids->next->signatures->comment);
495           exit (1);
496         }
497       if (strcmp (keys[i].uid[1].sig.email, key->uids->next->signatures->email))
498         {
499           fprintf (stderr, "Unexpected email in second user ID sig: %s\n",
500                    key->uids->next->signatures->email);
501           exit (1);
502         }
503       if (keys[i].uid[1].sig.sig_class != key->uids->next->signatures->sig_class)
504         {
505           fprintf (stderr, "Unexpected class in second user ID sig: %i\n",
506                    key->uids->next->signatures->sig_class);
507           exit (1);
508         }
509       if (keys[i].uid[1].sig.exportable != key->uids->next->signatures->exportable)
510         {
511           fprintf (stderr, "Unexpected exportable stat in second user ID sig: %i\n",
512                    key->uids->next->signatures->exportable);
513           exit (1);
514         }
515
516       if (key->uids && key->uids->next && key->uids->next->next
517           && key->uids->next->next->revoked)
518         {
519           fprintf (stderr, "Third user ID unexpectedly revoked\n");
520           exit (1);
521         }
522       if (key->uids && key->uids->next && key->uids->next->next
523           && key->uids->next->next->invalid)
524         {
525           fprintf (stderr, "Third user ID unexpectedly invalid\n");
526           exit (1);
527         }
528       if (key->uids && key->uids->next && key->uids->next->next
529           && key->uids->next->next->validity != GPGME_VALIDITY_UNKNOWN)
530         {
531           fprintf (stderr, "Third user ID has unexpectedly validity: %i\n",
532                    key->uids->next->next->validity);
533           exit (1);
534         }
535       if (keys[i].uid[2].name
536           && strcmp (keys[i].uid[2].name, key->uids->next->next->name))
537         {
538           fprintf (stderr, "Unexpected name in third user ID: %s\n",
539                    key->uids->next->next->name);
540           exit (1);
541         }
542       if (keys[i].uid[2].comment
543           && strcmp (keys[i].uid[2].comment, key->uids->next->next->comment))
544         {
545           fprintf (stderr, "Unexpected comment in third user ID: %s\n",
546                    key->uids->next->next->comment);
547           exit (1);
548         }
549       if (keys[i].uid[2].email
550           && strcmp (keys[i].uid[2].email, key->uids->next->next->email))
551         {
552           fprintf (stderr, "Unexpected email in third user ID: %s\n",
553                    key->uids->next->next->email);
554           exit (1);
555         }
556       if (key->uids && (!key->uids->next->next->signatures
557                         || key->uids->next->next->signatures->next))
558         {
559           fprintf (stderr, "Third user ID unexpected number of signatures\n");
560           exit (1);
561         }
562       if (keys[i].uid[2].sig.algo != key->uids->next->next->signatures->pubkey_algo)
563         {
564           fprintf (stderr, "Unexpected algorithm in third user ID sig: %s\n",
565                    gpgme_pubkey_algo_name (key->uids->next->next->signatures->pubkey_algo));
566           exit (1);
567         }
568       if (strcmp (keys[i].uid[2].sig.keyid, key->uids->next->next->signatures->keyid))
569         {
570           fprintf (stderr, "Unexpected key ID in third user ID sig: %s\n",
571                    key->uids->next->next->signatures->keyid);
572           exit (1);
573         }
574       if (strcmp (keys[i].uid[2].sig.name, key->uids->next->next->signatures->name))
575         {
576           fprintf (stderr, "Unexpected name in third user ID sig: %s\n",
577                    key->uids->next->next->signatures->name);
578           exit (1);
579         }
580       if (strcmp (keys[i].uid[2].sig.comment, key->uids->next->next->signatures->comment))
581         {
582           fprintf (stderr, "Unexpected comment in third user ID sig: %s\n",
583                    key->uids->next->next->signatures->comment);
584           exit (1);
585         }
586       if (strcmp (keys[i].uid[2].sig.email, key->uids->next->next->signatures->email))
587         {
588           fprintf (stderr, "Unexpected email in third user ID sig: %s\n",
589                    key->uids->next->next->signatures->email);
590           exit (1);
591         }
592       if (keys[i].uid[2].sig.sig_class != key->uids->next->next->signatures->sig_class)
593         {
594           fprintf (stderr, "Unexpected class in third user ID sig: %i\n",
595                    key->uids->next->next->signatures->sig_class);
596           exit (1);
597         }
598       if (keys[i].uid[2].sig.exportable != key->uids->next->next->signatures->exportable)
599         {
600           fprintf (stderr, "Unexpected exportable stat in third user ID sig: %i\n",
601                    key->uids->next->next->signatures->exportable);
602           exit (1);
603         }
604
605       gpgme_key_unref (key);
606       i++;
607     }
608   if (gpgme_err_code (err) != GPG_ERR_EOF)
609     fail_if_err (err);
610   err = gpgme_op_keylist_end (ctx);
611   fail_if_err (err);
612
613   result = gpgme_op_keylist_result (ctx);
614   if (result->truncated)
615     {
616       fprintf (stderr, "Key listing unexpectedly truncated\n");
617       exit (1);
618     }
619
620   if (keys[i].fpr)
621     {
622       fprintf (stderr, "Less keys returned than expected\n");
623       exit (1);
624     }
625
626   gpgme_release (ctx);
627   return 0;
628 }