1 /* t-keylist-secret-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, see <https://gnu.org/licenses/>.
19 * SPDX-License-Identifier: LGPL-2.1-or-later
20 */
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
37 struct
38 {
39 const char *fpr;
40 const char *sec_keyid;
41 struct
42 {
43 const char *name;
44 const char *comment;
45 const char *email;
46 struct
47 {
48 gpgme_pubkey_algo_t algo;
49 const char *keyid;
50 const char *name;
51 const char *comment;
52 const 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
main(void)75 main (void)
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", 1);
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 not 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 not 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 not 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 }
629