LCOV - code coverage report
Current view: top level - tests - run-verify.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 230 0.0 %
Date: 2018-11-15 08:49:49 Functions: 0 8 0.0 %

          Line data    Source code
       1             : /* run-verify.c  - Helper to perform a verify operation
       2             :    Copyright (C) 2009 g10 Code GmbH
       3             : 
       4             :    This file is part of GPGME.
       5             : 
       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.
      10             : 
      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.
      15             : 
      16             :    You should have received a copy of the GNU Lesser General Public
      17             :    License along with this program; if not, see <https://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : /* We need to include config.h so that we know whether we are building
      21             :    with large file system (LFS) support. */
      22             : #ifdef HAVE_CONFIG_H
      23             : #include <config.h>
      24             : #endif
      25             : 
      26             : #include <stdlib.h>
      27             : #include <stdio.h>
      28             : #include <string.h>
      29             : #include <time.h>
      30             : 
      31             : #include <gpgme.h>
      32             : 
      33             : #define PGM "run-verify"
      34             : 
      35             : #include "run-support.h"
      36             : 
      37             : 
      38             : static int verbose;
      39             : 
      40             : 
      41             : static const char *
      42           0 : isotimestr (unsigned long value)
      43             : {
      44             :   time_t t;
      45             :   static char buffer[25+5];
      46             :   struct tm *tp;
      47             : 
      48           0 :   if (!value)
      49           0 :     return "none";
      50           0 :   t = value;
      51             : 
      52           0 :   tp = gmtime (&t);
      53           0 :   snprintf (buffer, sizeof buffer, "%04d-%02d-%02d %02d:%02d:%02d",
      54           0 :             1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
      55             :             tp->tm_hour, tp->tm_min, tp->tm_sec);
      56           0 :   return buffer;
      57             : }
      58             : 
      59             : 
      60             : static gpg_error_t
      61           0 : status_cb (void *opaque, const char *keyword, const char *value)
      62             : {
      63             :   (void)opaque;
      64           0 :   fprintf (stderr, "status_cb: %s %s\n", keyword, value);
      65           0 :   return 0;
      66             : }
      67             : 
      68             : 
      69             : static void
      70           0 : print_summary (gpgme_sigsum_t summary)
      71             : {
      72           0 :   if ( (summary & GPGME_SIGSUM_VALID      ))
      73           0 :     fputs (" valid", stdout);
      74           0 :   if ( (summary & GPGME_SIGSUM_GREEN      ))
      75           0 :     fputs (" green", stdout);
      76           0 :   if ( (summary & GPGME_SIGSUM_RED        ))
      77           0 :     fputs (" red", stdout);
      78           0 :   if ( (summary & GPGME_SIGSUM_KEY_REVOKED))
      79           0 :     fputs (" revoked", stdout);
      80           0 :   if ( (summary & GPGME_SIGSUM_KEY_EXPIRED))
      81           0 :     fputs (" key-expired", stdout);
      82           0 :   if ( (summary & GPGME_SIGSUM_SIG_EXPIRED))
      83           0 :     fputs (" sig-expired", stdout);
      84           0 :   if ( (summary & GPGME_SIGSUM_KEY_MISSING))
      85           0 :     fputs (" key-missing", stdout);
      86           0 :   if ( (summary & GPGME_SIGSUM_CRL_MISSING))
      87           0 :     fputs (" crl-missing", stdout);
      88           0 :   if ( (summary & GPGME_SIGSUM_CRL_TOO_OLD))
      89           0 :     fputs (" crl-too-old", stdout);
      90           0 :   if ( (summary & GPGME_SIGSUM_BAD_POLICY ))
      91           0 :     fputs (" bad-policy", stdout);
      92           0 :   if ( (summary & GPGME_SIGSUM_SYS_ERROR  ))
      93           0 :     fputs (" sys-error", stdout);
      94           0 : }
      95             : 
      96             : static void
      97           0 : print_validity (gpgme_validity_t val)
      98             : {
      99           0 :   const char *s = NULL;
     100             : 
     101           0 :   switch (val)
     102             :     {
     103           0 :     case GPGME_VALIDITY_UNKNOWN:  s = "unknown"; break;
     104           0 :     case GPGME_VALIDITY_UNDEFINED:s = "undefined"; break;
     105           0 :     case GPGME_VALIDITY_NEVER:    s = "never"; break;
     106           0 :     case GPGME_VALIDITY_MARGINAL: s = "marginal"; break;
     107           0 :     case GPGME_VALIDITY_FULL:     s = "full"; break;
     108           0 :     case GPGME_VALIDITY_ULTIMATE: s = "ultimate"; break;
     109             :     }
     110           0 :   if (s)
     111           0 :     fputs (s, stdout);
     112             :   else
     113           0 :     printf ("[bad validity value %u]", (unsigned int)val);
     114           0 : }
     115             : 
     116             : 
     117             : static void
     118           0 : print_description (const char *text, int indent)
     119             : {
     120           0 :   for (; *text; text++)
     121             :     {
     122           0 :       putchar (*text);
     123           0 :       if (*text == '\n')
     124           0 :         printf ("%*s", indent, "");
     125             :     }
     126           0 :   putchar ('\n');
     127           0 : }
     128             : 
     129             : 
     130             : static void
     131           0 : print_result (gpgme_verify_result_t result)
     132             : {
     133             :   gpgme_signature_t sig;
     134             :   gpgme_sig_notation_t nt;
     135             :   gpgme_user_id_t uid;
     136             :   gpgme_tofu_info_t ti;
     137           0 :   int count = 0;
     138             : 
     139           0 :   printf ("Original file name .: %s\n", nonnull(result->file_name));
     140           0 :   printf ("MIME flag ..........: %s\n", result->is_mime? "yes":"no");
     141           0 :   for (sig = result->signatures; sig; sig = sig->next)
     142             :     {
     143           0 :       printf ("Signature ...: %d\n", count++);
     144           0 :       printf ("  status ....: %s\n", gpgme_strerror (sig->status));
     145           0 :       printf ("  summary ...:"); print_summary (sig->summary); putchar ('\n');
     146           0 :       printf ("  fingerprint: %s\n", nonnull (sig->fpr));
     147           0 :       printf ("  created ...: %lu\n", sig->timestamp);
     148           0 :       printf ("  expires ...: %lu\n", sig->exp_timestamp);
     149           0 :       printf ("  validity ..: ");
     150           0 :       print_validity (sig->validity); putchar ('\n');
     151           0 :       printf ("  val.reason : %s\n", gpgme_strerror (sig->status));
     152           0 :       printf ("  pubkey algo: %d (%s)\n", sig->pubkey_algo,
     153             :               nonnull(gpgme_pubkey_algo_name (sig->pubkey_algo)));
     154           0 :       printf ("  digest algo: %d (%s)\n", sig->hash_algo,
     155             :               nonnull(gpgme_hash_algo_name (sig->hash_algo)));
     156           0 :       printf ("  pka address: %s\n", nonnull (sig->pka_address));
     157           0 :       printf ("  pka trust .: %s\n",
     158           0 :               sig->pka_trust == 0? "n/a" :
     159           0 :               sig->pka_trust == 1? "bad" :
     160           0 :               sig->pka_trust == 2? "okay": "RFU");
     161           0 :       printf ("  other flags:%s%s\n",
     162           0 :               sig->wrong_key_usage? " wrong-key-usage":"",
     163           0 :               sig->chain_model? " chain-model":""
     164             :               );
     165           0 :       for (nt = sig->notations; nt; nt = nt->next)
     166             :         {
     167           0 :           if (nt->name)
     168             :             {
     169           0 :               printf ("  notation ..: '%s'\n", nt->name);
     170           0 :               if (strlen (nt->name) != nt->name_len)
     171           0 :                 printf ("    warning .: name larger (%d)\n", nt->name_len);
     172           0 :               printf ("    flags ...:%s%s (0x%02x)\n",
     173           0 :                       nt->critical? " critical":"",
     174           0 :                       nt->human_readable? " human":"",
     175             :                       nt->flags);
     176           0 :               if (nt->value)
     177           0 :                 printf ("    value ...: '%s'\n", nt->value);
     178             :             }
     179             :           else
     180             :             {
     181           0 :               printf ("  policy ....: '%s'\n", nt->value);
     182             :             }
     183           0 :           if ((nt->value?strlen (nt->value):0) != nt->value_len)
     184           0 :             printf ("    warning .: value larger (%d)\n", nt->value_len);
     185             :         }
     186           0 :       if (sig->key)
     187             :         {
     188           0 :           printf ("  primary fpr: %s\n", nonnull (sig->key->fpr));
     189           0 :           for (uid = sig->key->uids; uid; uid = uid->next)
     190             :             {
     191           0 :               printf ("  tofu addr .: %s\n", nonnull (uid->address));
     192           0 :               ti = uid->tofu;
     193           0 :               if (!ti)
     194           0 :                 continue;
     195           0 :               printf ("    validity : %u (%s)\n", ti->validity,
     196           0 :                       ti->validity == 0? "conflict" :
     197           0 :                       ti->validity == 1? "no history" :
     198           0 :                       ti->validity == 2? "little history" :
     199           0 :                       ti->validity == 3? "enough history" :
     200           0 :                       ti->validity == 4? "lot of history" : "?");
     201           0 :               printf ("    policy ..: %u (%s)\n", ti->policy,
     202           0 :                       ti->policy == GPGME_TOFU_POLICY_NONE? "none" :
     203           0 :                       ti->policy == GPGME_TOFU_POLICY_AUTO? "auto" :
     204           0 :                       ti->policy == GPGME_TOFU_POLICY_GOOD? "good" :
     205           0 :                       ti->policy == GPGME_TOFU_POLICY_UNKNOWN? "unknown" :
     206           0 :                       ti->policy == GPGME_TOFU_POLICY_BAD? "bad" :
     207           0 :                       ti->policy == GPGME_TOFU_POLICY_ASK? "ask" : "?");
     208           0 :               printf ("    signcount: %hu\n", ti->signcount);
     209           0 :               printf ("      first..: %s\n", isotimestr (ti->signfirst));
     210           0 :               printf ("      last ..: %s\n", isotimestr (ti->signlast));
     211           0 :               printf ("    encrcount: %hu\n", ti->encrcount);
     212           0 :               printf ("      first..: %s\n", isotimestr (ti->encrfirst));
     213           0 :               printf ("      last ..: %s\n", isotimestr (ti->encrlast));
     214           0 :               printf ("    desc ....: ");
     215           0 :               print_description (nonnull (ti->description), 15);
     216             :             }
     217             :         }
     218             :     }
     219           0 : }
     220             : 
     221             : 
     222             : 
     223             : static int
     224           0 : show_usage (int ex)
     225             : {
     226           0 :   fputs ("usage: " PGM " [options] [DETACHEDSIGFILE] FILE\n\n"
     227             :          "Options:\n"
     228             :          "  --verbose        run in verbose mode\n"
     229             :          "  --status         print status lines from the backend\n"
     230             :          "  --openpgp        use the OpenPGP protocol (default)\n"
     231             :          "  --cms            use the CMS protocol\n"
     232             :          "  --sender MBOX    use MBOX as sender address\n"
     233             :          "  --repeat N       repeat the operation N times\n"
     234             :          "  --auto-key-retrieve\n"
     235             :          , stderr);
     236           0 :   exit (ex);
     237             : }
     238             : 
     239             : 
     240             : int
     241           0 : main (int argc, char **argv)
     242             : {
     243           0 :   int last_argc = -1;
     244             :   const char *s;
     245           0 :   gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
     246           0 :   int print_status = 0;
     247           0 :   const char *sender = NULL;
     248           0 :   int auto_key_retrieve = 0;
     249           0 :   int repeats = 1;
     250             : 
     251           0 :   if (argc)
     252           0 :     { argc--; argv++; }
     253             : 
     254           0 :   while (argc && last_argc != argc )
     255             :     {
     256           0 :       last_argc = argc;
     257           0 :       if (!strcmp (*argv, "--"))
     258             :         {
     259           0 :           argc--; argv++;
     260           0 :           break;
     261             :         }
     262           0 :       else if (!strcmp (*argv, "--help"))
     263           0 :         show_usage (0);
     264           0 :       else if (!strcmp (*argv, "--verbose"))
     265             :         {
     266           0 :           verbose = 1;
     267           0 :           argc--; argv++;
     268             :         }
     269           0 :       else if (!strcmp (*argv, "--status"))
     270             :         {
     271           0 :           print_status = 1;
     272           0 :           argc--; argv++;
     273             :         }
     274           0 :       else if (!strcmp (*argv, "--openpgp"))
     275             :         {
     276           0 :           protocol = GPGME_PROTOCOL_OpenPGP;
     277           0 :           argc--; argv++;
     278             :         }
     279           0 :       else if (!strcmp (*argv, "--cms"))
     280             :         {
     281           0 :           protocol = GPGME_PROTOCOL_CMS;
     282           0 :           argc--; argv++;
     283             :         }
     284           0 :       else if (!strcmp (*argv, "--sender"))
     285             :         {
     286           0 :           argc--; argv++;
     287           0 :           if (!argc)
     288           0 :             show_usage (1);
     289           0 :           sender = *argv;
     290           0 :           argc--; argv++;
     291             :         }
     292           0 :       else if (!strcmp (*argv, "--repeat"))
     293             :         {
     294           0 :             argc--; argv++;
     295           0 :             if (!argc)
     296           0 :                 show_usage (1);
     297           0 :             repeats = atoi (*argv);
     298           0 :             argc--; argv++;
     299             :         }
     300           0 :       else if (!strcmp (*argv, "--auto-key-retrieve"))
     301             :         {
     302           0 :           auto_key_retrieve = 1;
     303           0 :           argc--; argv++;
     304             :         }
     305             : 
     306           0 :       else if (!strncmp (*argv, "--", 2))
     307           0 :         show_usage (1);
     308             : 
     309             :     }
     310             : 
     311           0 :   if (argc < 1 || argc > 2)
     312           0 :     show_usage (1);
     313             : 
     314           0 :   init_gpgme (protocol);
     315             : 
     316           0 :   for (int i = 0; i < repeats; i++)
     317             :     {
     318             :       gpgme_error_t err;
     319             :       gpgme_ctx_t ctx;
     320           0 :       FILE *fp_sig = NULL;
     321           0 :       gpgme_data_t sig = NULL;
     322           0 :       FILE *fp_msg = NULL;
     323           0 :       gpgme_data_t msg = NULL;
     324             :       gpgme_verify_result_t result;
     325             : 
     326           0 :       if (repeats > 1)
     327             :         {
     328           0 :           printf ("Repeat: %i\n", i);
     329             :         }
     330             : 
     331           0 :       fp_sig = fopen (argv[0], "rb");
     332           0 :       if (!fp_sig)
     333             :         {
     334           0 :           err = gpgme_error_from_syserror ();
     335           0 :           fprintf (stderr, PGM ": can't open `%s': %s\n",
     336             :                    argv[0], gpgme_strerror (err));
     337           0 :           exit (1);
     338             :         }
     339           0 :       if (argc > 1)
     340             :         {
     341           0 :           fp_msg = fopen (argv[1], "rb");
     342           0 :           if (!fp_msg)
     343             :             {
     344           0 :               err = gpgme_error_from_syserror ();
     345           0 :               fprintf (stderr, PGM ": can't open `%s': %s\n",
     346           0 :                        argv[1], gpgme_strerror (err));
     347           0 :               exit (1);
     348             :             }
     349             :         }
     350             : 
     351           0 :       err = gpgme_new (&ctx);
     352           0 :       fail_if_err (err);
     353           0 :       gpgme_set_protocol (ctx, protocol);
     354           0 :       if (print_status)
     355             :         {
     356           0 :           gpgme_set_status_cb (ctx, status_cb, NULL);
     357           0 :           gpgme_set_ctx_flag (ctx, "full-status", "1");
     358             :         }
     359             :       /* gpgme_set_ctx_flag (ctx, "raw-description", "1"); */
     360             : 
     361           0 :       if (auto_key_retrieve)
     362             :         {
     363           0 :           gpgme_set_ctx_flag (ctx, "auto-key-retrieve", "1");
     364           0 :           s = gpgme_get_ctx_flag (ctx, "auto-key-retrieve");
     365           0 :           if (!s || strcmp (s, "1"))
     366             :             {
     367           0 :               fprintf (stderr, PGM ": gpgme_get_ctx_flag failed for '%s'\n",
     368             :                        "auto-key-retrieve");
     369           0 :               exit (1);
     370             :             }
     371             :         }
     372             : 
     373           0 :       if (sender)
     374             :         {
     375           0 :           err = gpgme_set_sender (ctx, sender);
     376           0 :           fail_if_err (err);
     377             :         }
     378             : 
     379           0 :       err = gpgme_data_new_from_stream (&sig, fp_sig);
     380           0 :       if (err)
     381             :         {
     382           0 :           fprintf (stderr, PGM ": error allocating data object: %s\n",
     383             :                    gpgme_strerror (err));
     384           0 :           exit (1);
     385             :         }
     386           0 :       if (fp_msg)
     387             :         {
     388           0 :           err = gpgme_data_new_from_stream (&msg, fp_msg);
     389           0 :           if (err)
     390             :             {
     391           0 :               fprintf (stderr, PGM ": error allocating data object: %s\n",
     392             :                        gpgme_strerror (err));
     393           0 :               exit (1);
     394             :             }
     395             :         }
     396             : 
     397           0 :       err = gpgme_op_verify (ctx, sig, msg, NULL);
     398           0 :       result = gpgme_op_verify_result (ctx);
     399           0 :       if (result)
     400           0 :         print_result (result);
     401           0 :       if (err)
     402             :         {
     403           0 :           fprintf (stderr, PGM ": verify failed: %s\n", gpgme_strerror (err));
     404           0 :           exit (1);
     405             :         }
     406             : 
     407           0 :       gpgme_data_release (msg);
     408           0 :       gpgme_data_release (sig);
     409             : 
     410           0 :       gpgme_release (ctx);
     411             : 
     412           0 :       if (fp_msg)
     413           0 :         fclose (fp_msg);
     414           0 :       if (fp_sig)
     415           0 :         fclose (fp_sig);
     416             :     }
     417           0 :   return 0;
     418             : }

Generated by: LCOV version 1.13