1 /* run-verify.c - Helper to perform a verify operation
2 * Copyright (C) 2009 g10 Code GmbH
4 * This file is part of GPGME.
6 * GPGME is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
11 * GPGME is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, see <https://gnu.org/licenses/>.
18 * SPDX-License-Identifier: LGPL-2.1-or-later
21 /* We need to include config.h so that we know whether we are building
22 with large file system (LFS) support. */
34 #define PGM "run-verify"
36 #include "run-support.h"
43 isotimestr (unsigned long value)
46 static char buffer[25+5];
54 snprintf (buffer, sizeof buffer, "%04d-%02d-%02d %02d:%02d:%02d",
55 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
56 tp->tm_hour, tp->tm_min, tp->tm_sec);
62 status_cb (void *opaque, const char *keyword, const char *value)
65 fprintf (stderr, "status_cb: %s %s\n", keyword, value);
71 print_summary (gpgme_sigsum_t summary)
73 if ( (summary & GPGME_SIGSUM_VALID ))
74 fputs (" valid", stdout);
75 if ( (summary & GPGME_SIGSUM_GREEN ))
76 fputs (" green", stdout);
77 if ( (summary & GPGME_SIGSUM_RED ))
78 fputs (" red", stdout);
79 if ( (summary & GPGME_SIGSUM_KEY_REVOKED))
80 fputs (" revoked", stdout);
81 if ( (summary & GPGME_SIGSUM_KEY_EXPIRED))
82 fputs (" key-expired", stdout);
83 if ( (summary & GPGME_SIGSUM_SIG_EXPIRED))
84 fputs (" sig-expired", stdout);
85 if ( (summary & GPGME_SIGSUM_KEY_MISSING))
86 fputs (" key-missing", stdout);
87 if ( (summary & GPGME_SIGSUM_CRL_MISSING))
88 fputs (" crl-missing", stdout);
89 if ( (summary & GPGME_SIGSUM_CRL_TOO_OLD))
90 fputs (" crl-too-old", stdout);
91 if ( (summary & GPGME_SIGSUM_BAD_POLICY ))
92 fputs (" bad-policy", stdout);
93 if ( (summary & GPGME_SIGSUM_SYS_ERROR ))
94 fputs (" sys-error", stdout);
98 print_validity (gpgme_validity_t val)
100 const char *s = NULL;
104 case GPGME_VALIDITY_UNKNOWN: s = "unknown"; break;
105 case GPGME_VALIDITY_UNDEFINED:s = "undefined"; break;
106 case GPGME_VALIDITY_NEVER: s = "never"; break;
107 case GPGME_VALIDITY_MARGINAL: s = "marginal"; break;
108 case GPGME_VALIDITY_FULL: s = "full"; break;
109 case GPGME_VALIDITY_ULTIMATE: s = "ultimate"; break;
114 printf ("[bad validity value %u]", (unsigned int)val);
119 print_description (const char *text, int indent)
121 for (; *text; text++)
125 printf ("%*s", indent, "");
132 print_result (gpgme_verify_result_t result)
134 gpgme_signature_t sig;
135 gpgme_sig_notation_t nt;
137 gpgme_tofu_info_t ti;
140 printf ("Original file name .: %s\n", nonnull(result->file_name));
141 printf ("MIME flag ..........: %s\n", result->is_mime? "yes":"no");
142 for (sig = result->signatures; sig; sig = sig->next)
144 printf ("Signature ...: %d\n", count++);
145 printf (" status ....: %s\n", gpgme_strerror (sig->status));
146 printf (" summary ...:"); print_summary (sig->summary); putchar ('\n');
147 printf (" fingerprint: %s\n", nonnull (sig->fpr));
148 printf (" created ...: %lu\n", sig->timestamp);
149 printf (" expires ...: %lu\n", sig->exp_timestamp);
150 printf (" validity ..: ");
151 print_validity (sig->validity); putchar ('\n');
152 printf (" val.reason : %s\n", gpgme_strerror (sig->status));
153 printf (" pubkey algo: %d (%s)\n", sig->pubkey_algo,
154 nonnull(gpgme_pubkey_algo_name (sig->pubkey_algo)));
155 printf (" digest algo: %d (%s)\n", sig->hash_algo,
156 nonnull(gpgme_hash_algo_name (sig->hash_algo)));
157 printf (" pka address: %s\n", nonnull (sig->pka_address));
158 printf (" pka trust .: %s\n",
159 sig->pka_trust == 0? "n/a" :
160 sig->pka_trust == 1? "bad" :
161 sig->pka_trust == 2? "okay": "RFU");
162 printf (" other flags:%s%s%s\n",
163 sig->wrong_key_usage? " wrong-key-usage":"",
164 sig->chain_model? " chain-model":"",
165 sig->is_de_vs? " de-vs":""
167 for (nt = sig->notations; nt; nt = nt->next)
171 printf (" notation ..: '%s'\n", nt->name);
172 if (strlen (nt->name) != nt->name_len)
173 printf (" warning .: name larger (%d)\n", nt->name_len);
174 printf (" flags ...:%s%s (0x%02x)\n",
175 nt->critical? " critical":"",
176 nt->human_readable? " human":"",
179 printf (" value ...: '%s'\n", nt->value);
183 printf (" policy ....: '%s'\n", nt->value);
185 if ((nt->value?strlen (nt->value):0) != nt->value_len)
186 printf (" warning .: value larger (%d)\n", nt->value_len);
190 printf (" primary fpr: %s\n", nonnull (sig->key->fpr));
191 for (uid = sig->key->uids; uid; uid = uid->next)
193 printf (" tofu addr .: %s\n", nonnull (uid->address));
197 printf (" validity : %u (%s)\n", ti->validity,
198 ti->validity == 0? "conflict" :
199 ti->validity == 1? "no history" :
200 ti->validity == 2? "little history" :
201 ti->validity == 3? "enough history" :
202 ti->validity == 4? "lot of history" : "?");
203 printf (" policy ..: %u (%s)\n", ti->policy,
204 ti->policy == GPGME_TOFU_POLICY_NONE? "none" :
205 ti->policy == GPGME_TOFU_POLICY_AUTO? "auto" :
206 ti->policy == GPGME_TOFU_POLICY_GOOD? "good" :
207 ti->policy == GPGME_TOFU_POLICY_UNKNOWN? "unknown" :
208 ti->policy == GPGME_TOFU_POLICY_BAD? "bad" :
209 ti->policy == GPGME_TOFU_POLICY_ASK? "ask" : "?");
210 printf (" signcount: %hu\n", ti->signcount);
211 printf (" first..: %s\n", isotimestr (ti->signfirst));
212 printf (" last ..: %s\n", isotimestr (ti->signlast));
213 printf (" encrcount: %hu\n", ti->encrcount);
214 printf (" first..: %s\n", isotimestr (ti->encrfirst));
215 printf (" last ..: %s\n", isotimestr (ti->encrlast));
216 printf (" desc ....: ");
217 print_description (nonnull (ti->description), 15);
228 fputs ("usage: " PGM " [options] [DETACHEDSIGFILE] FILE\n\n"
230 " --verbose run in verbose mode\n"
231 " --status print status lines from the backend\n"
232 " --openpgp use the OpenPGP protocol (default)\n"
233 " --cms use the CMS protocol\n"
234 " --sender MBOX use MBOX as sender address\n"
235 " --repeat N repeat the operation N times\n"
236 " --auto-key-retrieve\n"
237 " --auto-key-import\n"
244 main (int argc, char **argv)
248 gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
249 int print_status = 0;
250 const char *sender = NULL;
251 int auto_key_retrieve = 0;
252 int auto_key_import = 0;
258 while (argc && last_argc != argc )
261 if (!strcmp (*argv, "--"))
266 else if (!strcmp (*argv, "--help"))
268 else if (!strcmp (*argv, "--verbose"))
273 else if (!strcmp (*argv, "--status"))
278 else if (!strcmp (*argv, "--openpgp"))
280 protocol = GPGME_PROTOCOL_OpenPGP;
283 else if (!strcmp (*argv, "--cms"))
285 protocol = GPGME_PROTOCOL_CMS;
288 else if (!strcmp (*argv, "--sender"))
296 else if (!strcmp (*argv, "--repeat"))
301 repeats = atoi (*argv);
304 else if (!strcmp (*argv, "--auto-key-retrieve"))
306 auto_key_retrieve = 1;
309 else if (!strcmp (*argv, "--auto-key-import"))
314 else if (!strncmp (*argv, "--", 2))
319 if (argc < 1 || argc > 2)
322 init_gpgme (protocol);
324 for (int i = 0; i < repeats; i++)
329 gpgme_data_t sig = NULL;
331 gpgme_data_t msg = NULL;
332 gpgme_verify_result_t result;
336 printf ("Repeat: %i\n", i);
339 fp_sig = fopen (argv[0], "rb");
342 err = gpgme_error_from_syserror ();
343 fprintf (stderr, PGM ": can't open `%s': %s\n",
344 argv[0], gpgme_strerror (err));
349 fp_msg = fopen (argv[1], "rb");
352 err = gpgme_error_from_syserror ();
353 fprintf (stderr, PGM ": can't open `%s': %s\n",
354 argv[1], gpgme_strerror (err));
359 err = gpgme_new (&ctx);
361 gpgme_set_protocol (ctx, protocol);
364 gpgme_set_status_cb (ctx, status_cb, NULL);
365 gpgme_set_ctx_flag (ctx, "full-status", "1");
367 /* gpgme_set_ctx_flag (ctx, "raw-description", "1"); */
369 if (auto_key_retrieve)
371 gpgme_set_ctx_flag (ctx, "auto-key-retrieve", "1");
372 s = gpgme_get_ctx_flag (ctx, "auto-key-retrieve");
373 if (!s || strcmp (s, "1"))
375 fprintf (stderr, PGM ": gpgme_get_ctx_flag failed for '%s'\n",
376 "auto-key-retrieve");
383 gpgme_set_ctx_flag (ctx, "auto-key-import", "1");
384 s = gpgme_get_ctx_flag (ctx, "auto-key-import");
385 if (!s || strcmp (s, "1"))
387 fprintf (stderr, PGM ": gpgme_get_ctx_flag failed for '%s'\n",
395 err = gpgme_set_sender (ctx, sender);
399 err = gpgme_data_new_from_stream (&sig, fp_sig);
402 fprintf (stderr, PGM ": error allocating data object: %s\n",
403 gpgme_strerror (err));
408 err = gpgme_data_new_from_stream (&msg, fp_msg);
411 fprintf (stderr, PGM ": error allocating data object: %s\n",
412 gpgme_strerror (err));
417 err = gpgme_op_verify (ctx, sig, msg, NULL);
418 result = gpgme_op_verify_result (ctx);
420 print_result (result);
423 fprintf (stderr, PGM ": verify failed: %s\n", gpgme_strerror (err));
427 gpgme_data_release (msg);
428 gpgme_data_release (sig);