LCOV - code coverage report
Current view: top level - agent - protect-tool.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 320 0.0 %
Date: 2016-11-29 15:00:56 Functions: 0 19 0.0 %

          Line data    Source code
       1             : /* protect-tool.c - A tool to test the secret key protection
       2             :  * Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
       3             :  *
       4             :  * This file is part of GnuPG.
       5             :  *
       6             :  * GnuPG is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU General Public License as published by
       8             :  * the Free Software Foundation; either version 3 of the License, or
       9             :  * (at your option) any later version.
      10             :  *
      11             :  * GnuPG is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License
      17             :  * along with this program; if not, see <https://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #include <config.h>
      21             : 
      22             : #include <stdio.h>
      23             : #include <stdlib.h>
      24             : #include <stddef.h>
      25             : #include <stdarg.h>
      26             : #include <string.h>
      27             : #include <errno.h>
      28             : #include <assert.h>
      29             : #include <sys/stat.h>
      30             : #include <unistd.h>
      31             : #ifdef HAVE_LOCALE_H
      32             : #include <locale.h>
      33             : #endif
      34             : #ifdef HAVE_LANGINFO_CODESET
      35             : #include <langinfo.h>
      36             : #endif
      37             : #ifdef HAVE_DOSISH_SYSTEM
      38             : #include <fcntl.h> /* for setmode() */
      39             : #endif
      40             : 
      41             : #include "agent.h"
      42             : #include "i18n.h"
      43             : #include "get-passphrase.h"
      44             : #include "sysutils.h"
      45             : #include "../common/init.h"
      46             : 
      47             : 
      48             : enum cmd_and_opt_values
      49             : {
      50             :   aNull = 0,
      51             :   oVerbose        = 'v',
      52             :   oArmor          = 'a',
      53             :   oPassphrase     = 'P',
      54             : 
      55             :   oProtect        = 'p',
      56             :   oUnprotect      = 'u',
      57             : 
      58             :   oNoVerbose = 500,
      59             :   oShadow,
      60             :   oShowShadowInfo,
      61             :   oShowKeygrip,
      62             :   oS2Kcalibration,
      63             :   oCanonical,
      64             : 
      65             :   oStore,
      66             :   oForce,
      67             :   oHaveCert,
      68             :   oNoFailOnExist,
      69             :   oHomedir,
      70             :   oPrompt,
      71             :   oStatusMsg,
      72             :   oDebugUseOCB,
      73             : 
      74             :   oAgentProgram
      75             : };
      76             : 
      77             : 
      78             : struct rsa_secret_key_s
      79             : {
      80             :   gcry_mpi_t n;     /* public modulus */
      81             :   gcry_mpi_t e;     /* public exponent */
      82             :   gcry_mpi_t d;     /* exponent */
      83             :   gcry_mpi_t p;     /* prime  p. */
      84             :   gcry_mpi_t q;     /* prime  q. */
      85             :   gcry_mpi_t u;     /* inverse of p mod q. */
      86             : };
      87             : 
      88             : 
      89             : static int opt_armor;
      90             : static int opt_canonical;
      91             : static int opt_store;
      92             : static int opt_force;
      93             : static int opt_no_fail_on_exist;
      94             : static int opt_have_cert;
      95             : static const char *opt_passphrase;
      96             : static char *opt_prompt;
      97             : static int opt_status_msg;
      98             : static const char *opt_agent_program;
      99             : static int opt_debug_use_ocb;
     100             : 
     101             : static char *get_passphrase (int promptno);
     102             : static void release_passphrase (char *pw);
     103             : 
     104             : 
     105             : static ARGPARSE_OPTS opts[] = {
     106             :   ARGPARSE_group (300, N_("@Commands:\n ")),
     107             : 
     108             :   ARGPARSE_c (oProtect,   "protect",   "protect a private key"),
     109             :   ARGPARSE_c (oUnprotect, "unprotect", "unprotect a private key"),
     110             :   ARGPARSE_c (oShadow,    "shadow", "create a shadow entry for a public key"),
     111             :   ARGPARSE_c (oShowShadowInfo,  "show-shadow-info", "return the shadow info"),
     112             :   ARGPARSE_c (oShowKeygrip, "show-keygrip", "show the \"keygrip\""),
     113             :   ARGPARSE_c (oS2Kcalibration, "s2k-calibration", "@"),
     114             : 
     115             :   ARGPARSE_group (301, N_("@\nOptions:\n ")),
     116             : 
     117             :   ARGPARSE_s_n (oVerbose, "verbose", "verbose"),
     118             :   ARGPARSE_s_n (oArmor, "armor", "write output in advanced format"),
     119             :   ARGPARSE_s_n (oCanonical, "canonical", "write output in canonical format"),
     120             : 
     121             :   ARGPARSE_s_s (oPassphrase, "passphrase", "|STRING|use passphrase STRING"),
     122             :   ARGPARSE_s_n (oHaveCert, "have-cert",
     123             :                 "certificate to export provided on STDIN"),
     124             :   ARGPARSE_s_n (oStore,    "store",
     125             :                 "store the created key in the appropriate place"),
     126             :   ARGPARSE_s_n (oForce,    "force",
     127             :                 "force overwriting"),
     128             :   ARGPARSE_s_n (oNoFailOnExist, "no-fail-on-exist", "@"),
     129             :   ARGPARSE_s_s (oHomedir, "homedir", "@"),
     130             :   ARGPARSE_s_s (oPrompt,  "prompt",
     131             :                 "|ESCSTRING|use ESCSTRING as prompt in pinentry"),
     132             :   ARGPARSE_s_n (oStatusMsg, "enable-status-msg", "@"),
     133             : 
     134             :   ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
     135             : 
     136             :   ARGPARSE_s_n (oDebugUseOCB,  "debug-use-ocb", "@"), /* For hacking only.  */
     137             : 
     138             :   ARGPARSE_end ()
     139             : };
     140             : 
     141             : static const char *
     142           0 : my_strusage (int level)
     143             : {
     144             :   const char *p;
     145           0 :   switch (level)
     146             :     {
     147           0 :     case 11: p = "gpg-protect-tool (" GNUPG_NAME ")";
     148           0 :       break;
     149           0 :     case 13: p = VERSION; break;
     150           0 :     case 17: p = PRINTABLE_OS_NAME; break;
     151           0 :     case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
     152             : 
     153             :     case 1:
     154           0 :     case 40: p =  _("Usage: gpg-protect-tool [options] (-h for help)\n");
     155           0 :       break;
     156           0 :     case 41: p =  _("Syntax: gpg-protect-tool [options] [args]\n"
     157             :                     "Secret key maintenance tool\n");
     158           0 :     break;
     159             : 
     160           0 :     default: p = NULL;
     161             :     }
     162           0 :   return p;
     163             : }
     164             : 
     165             : 
     166             : /*  static void */
     167             : /*  print_mpi (const char *text, gcry_mpi_t a) */
     168             : /*  { */
     169             : /*    char *buf; */
     170             : /*    void *bufaddr = &buf; */
     171             : /*    int rc; */
     172             : 
     173             : /*    rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a); */
     174             : /*    if (rc) */
     175             : /*      log_info ("%s: [error printing number: %s]\n", text, gpg_strerror (rc)); */
     176             : /*    else */
     177             : /*      { */
     178             : /*        log_info ("%s: %s\n", text, buf); */
     179             : /*        gcry_free (buf); */
     180             : /*      } */
     181             : /*  } */
     182             : 
     183             : 
     184             : 
     185             : static unsigned char *
     186           0 : make_canonical (const char *fname, const char *buf, size_t buflen)
     187             : {
     188             :   int rc;
     189             :   size_t erroff, len;
     190             :   gcry_sexp_t sexp;
     191             :   unsigned char *result;
     192             : 
     193           0 :   rc = gcry_sexp_sscan (&sexp, &erroff, buf, buflen);
     194           0 :   if (rc)
     195             :     {
     196           0 :       log_error ("invalid S-Expression in '%s' (off=%u): %s\n",
     197             :                  fname, (unsigned int)erroff, gpg_strerror (rc));
     198           0 :       return NULL;
     199             :     }
     200           0 :   len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, NULL, 0);
     201           0 :   assert (len);
     202           0 :   result = xmalloc (len);
     203           0 :   len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, result, len);
     204           0 :   assert (len);
     205           0 :   gcry_sexp_release (sexp);
     206           0 :   return result;
     207             : }
     208             : 
     209             : static char *
     210           0 : make_advanced (const unsigned char *buf, size_t buflen)
     211             : {
     212             :   int rc;
     213             :   size_t erroff, len;
     214             :   gcry_sexp_t sexp;
     215             :   char *result;
     216             : 
     217           0 :   rc = gcry_sexp_sscan (&sexp, &erroff, (const char*)buf, buflen);
     218           0 :   if (rc)
     219             :     {
     220           0 :       log_error ("invalid canonical S-Expression (off=%u): %s\n",
     221             :                  (unsigned int)erroff, gpg_strerror (rc));
     222           0 :       return NULL;
     223             :     }
     224           0 :   len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
     225           0 :   assert (len);
     226           0 :   result = xmalloc (len);
     227           0 :   len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, result, len);
     228           0 :   assert (len);
     229           0 :   gcry_sexp_release (sexp);
     230           0 :   return result;
     231             : }
     232             : 
     233             : 
     234             : static char *
     235           0 : read_file (const char *fname, size_t *r_length)
     236             : {
     237             :   FILE *fp;
     238             :   char *buf;
     239             :   size_t buflen;
     240             : 
     241           0 :   if (!strcmp (fname, "-"))
     242             :     {
     243           0 :       size_t nread, bufsize = 0;
     244             : 
     245           0 :       fp = stdin;
     246             : #ifdef HAVE_DOSISH_SYSTEM
     247             :       setmode ( fileno(fp) , O_BINARY );
     248             : #endif
     249           0 :       buf = NULL;
     250           0 :       buflen = 0;
     251             : #define NCHUNK 8192
     252             :       do
     253             :         {
     254           0 :           bufsize += NCHUNK;
     255           0 :           if (!buf)
     256           0 :             buf = xmalloc (bufsize);
     257             :           else
     258           0 :             buf = xrealloc (buf, bufsize);
     259             : 
     260           0 :           nread = fread (buf+buflen, 1, NCHUNK, fp);
     261           0 :           if (nread < NCHUNK && ferror (fp))
     262             :             {
     263           0 :               log_error ("error reading '[stdin]': %s\n", strerror (errno));
     264           0 :               xfree (buf);
     265           0 :               return NULL;
     266             :             }
     267           0 :           buflen += nread;
     268             :         }
     269           0 :       while (nread == NCHUNK);
     270             : #undef NCHUNK
     271             : 
     272             :     }
     273             :   else
     274             :     {
     275             :       struct stat st;
     276             : 
     277           0 :       fp = fopen (fname, "rb");
     278           0 :       if (!fp)
     279             :         {
     280           0 :           log_error ("can't open '%s': %s\n", fname, strerror (errno));
     281           0 :           return NULL;
     282             :         }
     283             : 
     284           0 :       if (fstat (fileno(fp), &st))
     285             :         {
     286           0 :           log_error ("can't stat '%s': %s\n", fname, strerror (errno));
     287           0 :           fclose (fp);
     288           0 :           return NULL;
     289             :         }
     290             : 
     291           0 :       buflen = st.st_size;
     292           0 :       buf = xmalloc (buflen+1);
     293           0 :       if (fread (buf, buflen, 1, fp) != 1)
     294             :         {
     295           0 :           log_error ("error reading '%s': %s\n", fname, strerror (errno));
     296           0 :           fclose (fp);
     297           0 :           xfree (buf);
     298           0 :           return NULL;
     299             :         }
     300           0 :       fclose (fp);
     301             :     }
     302             : 
     303           0 :   *r_length = buflen;
     304           0 :   return buf;
     305             : }
     306             : 
     307             : 
     308             : static unsigned char *
     309           0 : read_key (const char *fname)
     310             : {
     311             :   char *buf;
     312             :   size_t buflen;
     313             :   unsigned char *key;
     314             : 
     315           0 :   buf = read_file (fname, &buflen);
     316           0 :   if (!buf)
     317           0 :     return NULL;
     318           0 :   key = make_canonical (fname, buf, buflen);
     319           0 :   xfree (buf);
     320           0 :   return key;
     321             : }
     322             : 
     323             : 
     324             : 
     325             : static void
     326           0 : read_and_protect (const char *fname)
     327             : {
     328             :   int  rc;
     329             :   unsigned char *key;
     330             :   unsigned char *result;
     331             :   size_t resultlen;
     332             :   char *pw;
     333             : 
     334           0 :   key = read_key (fname);
     335           0 :   if (!key)
     336           0 :     return;
     337             : 
     338           0 :   pw = get_passphrase (1);
     339           0 :   rc = agent_protect (key, pw, &result, &resultlen, 0,
     340           0 :                       opt_debug_use_ocb? 1 : -1);
     341           0 :   release_passphrase (pw);
     342           0 :   xfree (key);
     343           0 :   if (rc)
     344             :     {
     345           0 :       log_error ("protecting the key failed: %s\n", gpg_strerror (rc));
     346           0 :       return;
     347             :     }
     348             : 
     349           0 :   if (opt_armor)
     350             :     {
     351           0 :       char *p = make_advanced (result, resultlen);
     352           0 :       xfree (result);
     353           0 :       if (!p)
     354           0 :         return;
     355           0 :       result = (unsigned char*)p;
     356           0 :       resultlen = strlen (p);
     357             :     }
     358             : 
     359           0 :   fwrite (result, resultlen, 1, stdout);
     360           0 :   xfree (result);
     361             : }
     362             : 
     363             : 
     364             : static void
     365           0 : read_and_unprotect (ctrl_t ctrl, const char *fname)
     366             : {
     367             :   int  rc;
     368             :   unsigned char *key;
     369             :   unsigned char *result;
     370             :   size_t resultlen;
     371             :   char *pw;
     372             :   gnupg_isotime_t protected_at;
     373             : 
     374           0 :   key = read_key (fname);
     375           0 :   if (!key)
     376           0 :     return;
     377             : 
     378           0 :   rc = agent_unprotect (ctrl, key, (pw=get_passphrase (1)),
     379             :                         protected_at, &result, &resultlen);
     380           0 :   release_passphrase (pw);
     381           0 :   xfree (key);
     382           0 :   if (rc)
     383             :     {
     384           0 :       if (opt_status_msg)
     385           0 :         log_info ("[PROTECT-TOOL:] bad-passphrase\n");
     386           0 :       log_error ("unprotecting the key failed: %s\n", gpg_strerror (rc));
     387           0 :       return;
     388             :     }
     389           0 :   if (opt.verbose)
     390             :     {
     391           0 :       if (*protected_at)
     392           0 :         log_info ("key protection done at %.4s-%.2s-%.2s %.2s:%.2s:%s\n",
     393             :                   protected_at, protected_at+4, protected_at+6,
     394             :                   protected_at+9, protected_at+11, protected_at+13);
     395             :       else
     396           0 :         log_info ("key protection done at [unknown]\n");
     397             :     }
     398             : 
     399           0 :   if (opt_armor)
     400             :     {
     401           0 :       char *p = make_advanced (result, resultlen);
     402           0 :       xfree (result);
     403           0 :       if (!p)
     404           0 :         return;
     405           0 :       result = (unsigned char*)p;
     406           0 :       resultlen = strlen (p);
     407             :     }
     408             : 
     409           0 :   fwrite (result, resultlen, 1, stdout);
     410           0 :   xfree (result);
     411             : }
     412             : 
     413             : 
     414             : 
     415             : static void
     416           0 : read_and_shadow (const char *fname)
     417             : {
     418             :   int  rc;
     419             :   unsigned char *key;
     420             :   unsigned char *result;
     421             :   size_t resultlen;
     422           0 :   unsigned char dummy_info[] = "(8:313233342:43)";
     423             : 
     424           0 :   key = read_key (fname);
     425           0 :   if (!key)
     426           0 :     return;
     427             : 
     428           0 :   rc = agent_shadow_key (key, dummy_info, &result);
     429           0 :   xfree (key);
     430           0 :   if (rc)
     431             :     {
     432           0 :       log_error ("shadowing the key failed: %s\n", gpg_strerror (rc));
     433           0 :       return;
     434             :     }
     435           0 :   resultlen = gcry_sexp_canon_len (result, 0, NULL,NULL);
     436           0 :   assert (resultlen);
     437             : 
     438           0 :   if (opt_armor)
     439             :     {
     440           0 :       char *p = make_advanced (result, resultlen);
     441           0 :       xfree (result);
     442           0 :       if (!p)
     443           0 :         return;
     444           0 :       result = (unsigned char*)p;
     445           0 :       resultlen = strlen (p);
     446             :     }
     447             : 
     448           0 :   fwrite (result, resultlen, 1, stdout);
     449           0 :   xfree (result);
     450             : }
     451             : 
     452             : static void
     453           0 : show_shadow_info (const char *fname)
     454             : {
     455             :   int  rc;
     456             :   unsigned char *key;
     457             :   const unsigned char *info;
     458             :   size_t infolen;
     459             : 
     460           0 :   key = read_key (fname);
     461           0 :   if (!key)
     462           0 :     return;
     463             : 
     464           0 :   rc = agent_get_shadow_info (key, &info);
     465           0 :   xfree (key);
     466           0 :   if (rc)
     467             :     {
     468           0 :       log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc));
     469           0 :       return;
     470             :     }
     471           0 :   infolen = gcry_sexp_canon_len (info, 0, NULL,NULL);
     472           0 :   assert (infolen);
     473             : 
     474           0 :   if (opt_armor)
     475             :     {
     476           0 :       char *p = make_advanced (info, infolen);
     477           0 :       if (!p)
     478           0 :         return;
     479           0 :       fwrite (p, strlen (p), 1, stdout);
     480           0 :       xfree (p);
     481             :     }
     482             :   else
     483           0 :     fwrite (info, infolen, 1, stdout);
     484             : }
     485             : 
     486             : 
     487             : static void
     488           0 : show_file (const char *fname)
     489             : {
     490             :   unsigned char *key;
     491             :   size_t keylen;
     492             :   char *p;
     493             : 
     494           0 :   key = read_key (fname);
     495           0 :   if (!key)
     496           0 :     return;
     497             : 
     498           0 :   keylen = gcry_sexp_canon_len (key, 0, NULL,NULL);
     499           0 :   assert (keylen);
     500             : 
     501           0 :   if (opt_canonical)
     502             :     {
     503           0 :       fwrite (key, keylen, 1, stdout);
     504             :     }
     505             :   else
     506             :     {
     507           0 :       p = make_advanced (key, keylen);
     508           0 :       if (p)
     509             :         {
     510           0 :           fwrite (p, strlen (p), 1, stdout);
     511           0 :           xfree (p);
     512             :         }
     513             :     }
     514           0 :   xfree (key);
     515             : }
     516             : 
     517             : static void
     518           0 : show_keygrip (const char *fname)
     519             : {
     520             :   unsigned char *key;
     521             :   gcry_sexp_t private;
     522             :   unsigned char grip[20];
     523             :   int i;
     524             : 
     525           0 :   key = read_key (fname);
     526           0 :   if (!key)
     527           0 :     return;
     528             : 
     529           0 :   if (gcry_sexp_new (&private, key, 0, 0))
     530             :     {
     531           0 :       log_error ("gcry_sexp_new failed\n");
     532           0 :       return;
     533             :     }
     534           0 :   xfree (key);
     535             : 
     536           0 :   if (!gcry_pk_get_keygrip (private, grip))
     537             :     {
     538           0 :       log_error ("can't calculate keygrip\n");
     539           0 :       return;
     540             :     }
     541           0 :   gcry_sexp_release (private);
     542             : 
     543           0 :   for (i=0; i < 20; i++)
     544           0 :     printf ("%02X", grip[i]);
     545           0 :   putchar ('\n');
     546             : }
     547             : 
     548             : 
     549             : 
     550             : 
     551             : 
     552             : int
     553           0 : main (int argc, char **argv )
     554             : {
     555             :   ARGPARSE_ARGS pargs;
     556           0 :   int cmd = 0;
     557             :   const char *fname;
     558             :   ctrl_t ctrl;
     559             : 
     560           0 :   early_system_init ();
     561           0 :   set_strusage (my_strusage);
     562           0 :   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
     563           0 :   log_set_prefix ("gpg-protect-tool", GPGRT_LOG_WITH_PREFIX);
     564             : 
     565             :   /* Make sure that our subsystems are ready.  */
     566           0 :   i18n_init ();
     567           0 :   init_common_subsystems (&argc, &argv);
     568             : 
     569           0 :   setup_libgcrypt_logging ();
     570           0 :   gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
     571             : 
     572           0 :   pargs.argc = &argc;
     573           0 :   pargs.argv = &argv;
     574           0 :   pargs.flags=  1;  /* (do not remove the args) */
     575           0 :   while (arg_parse (&pargs, opts) )
     576             :     {
     577           0 :       switch (pargs.r_opt)
     578             :         {
     579           0 :         case oVerbose: opt.verbose++; break;
     580           0 :         case oArmor:   opt_armor=1; break;
     581           0 :         case oCanonical: opt_canonical=1; break;
     582           0 :         case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
     583             : 
     584           0 :         case oAgentProgram: opt_agent_program = pargs.r.ret_str; break;
     585             : 
     586           0 :         case oProtect: cmd = oProtect; break;
     587           0 :         case oUnprotect: cmd = oUnprotect; break;
     588           0 :         case oShadow: cmd = oShadow; break;
     589           0 :         case oShowShadowInfo: cmd = oShowShadowInfo; break;
     590           0 :         case oShowKeygrip: cmd = oShowKeygrip; break;
     591           0 :         case oS2Kcalibration: cmd = oS2Kcalibration; break;
     592             : 
     593           0 :         case oPassphrase: opt_passphrase = pargs.r.ret_str; break;
     594           0 :         case oStore: opt_store = 1; break;
     595           0 :         case oForce: opt_force = 1; break;
     596           0 :         case oNoFailOnExist: opt_no_fail_on_exist = 1; break;
     597           0 :         case oHaveCert: opt_have_cert = 1; break;
     598           0 :         case oPrompt: opt_prompt = pargs.r.ret_str; break;
     599           0 :         case oStatusMsg: opt_status_msg = 1; break;
     600           0 :         case oDebugUseOCB: opt_debug_use_ocb = 1; break;
     601             : 
     602           0 :         default: pargs.err = ARGPARSE_PRINT_ERROR; break;
     603             :         }
     604             :     }
     605           0 :   if (log_get_errorcount (0))
     606           0 :     exit (2);
     607             : 
     608           0 :   fname = "-";
     609           0 :   if (argc == 1)
     610           0 :     fname = *argv;
     611           0 :   else if (argc > 1)
     612           0 :     usage (1);
     613             : 
     614             :   /* Allocate an CTRL object.  An empty object should be sufficient.  */
     615           0 :   ctrl = xtrycalloc (1, sizeof *ctrl);
     616           0 :   if (!ctrl)
     617             :     {
     618           0 :       log_error ("error allocating connection control data: %s\n",
     619           0 :                  strerror (errno));
     620           0 :       agent_exit (1);
     621             :     }
     622             : 
     623             :   /* Set the information which can't be taken from envvars.  */
     624           0 :   gnupg_prepare_get_passphrase (GPG_ERR_SOURCE_DEFAULT,
     625             :                                 opt.verbose,
     626             :                                 opt_agent_program,
     627             :                                 NULL, NULL, NULL);
     628             : 
     629           0 :   if (opt_prompt)
     630           0 :     opt_prompt = percent_plus_unescape (opt_prompt, 0);
     631             : 
     632           0 :   if (cmd == oProtect)
     633           0 :     read_and_protect (fname);
     634           0 :   else if (cmd == oUnprotect)
     635           0 :     read_and_unprotect (ctrl, fname);
     636           0 :   else if (cmd == oShadow)
     637           0 :     read_and_shadow (fname);
     638           0 :   else if (cmd == oShowShadowInfo)
     639           0 :     show_shadow_info (fname);
     640           0 :   else if (cmd == oShowKeygrip)
     641           0 :     show_keygrip (fname);
     642           0 :   else if (cmd == oS2Kcalibration)
     643             :     {
     644           0 :       if (!opt.verbose)
     645           0 :         opt.verbose++; /* We need to see something.  */
     646           0 :       get_standard_s2k_count ();
     647             :     }
     648             :   else
     649           0 :     show_file (fname);
     650             : 
     651           0 :   xfree (ctrl);
     652             : 
     653           0 :   agent_exit (0);
     654             :   return 8; /*NOTREACHED*/
     655             : }
     656             : 
     657             : void
     658           0 : agent_exit (int rc)
     659             : {
     660           0 :   rc = rc? rc : log_get_errorcount(0)? 2 : 0;
     661           0 :   exit (rc);
     662             : }
     663             : 
     664             : 
     665             : /* Return the passphrase string and ask the agent if it has not been
     666             :    set from the command line  PROMPTNO select the prompt to display:
     667             :      0 = default
     668             :      1 = taken from the option --prompt
     669             :      2 = for unprotecting a pkcs#12 object
     670             :      3 = for protecting a new pkcs#12 object
     671             :      4 = for protecting an imported pkcs#12 in our system
     672             : */
     673             : static char *
     674           0 : get_passphrase (int promptno)
     675             : {
     676             :   char *pw;
     677             :   int err;
     678             :   const char *desc;
     679             :   char *orig_codeset;
     680           0 :   int repeat = 0;
     681             : 
     682           0 :   if (opt_passphrase)
     683           0 :     return xstrdup (opt_passphrase);
     684             : 
     685           0 :   orig_codeset = i18n_switchto_utf8 ();
     686             : 
     687           0 :   if (promptno == 1 && opt_prompt)
     688             :     {
     689           0 :       desc = opt_prompt;
     690             :     }
     691           0 :   else if (promptno == 2)
     692             :     {
     693           0 :       desc = _("Please enter the passphrase to unprotect the "
     694             :                "PKCS#12 object.");
     695             :     }
     696           0 :   else if (promptno == 3)
     697             :     {
     698           0 :       desc = _("Please enter the passphrase to protect the "
     699             :                "new PKCS#12 object.");
     700           0 :       repeat = 1;
     701             :     }
     702           0 :   else if (promptno == 4)
     703             :     {
     704           0 :       desc = _("Please enter the passphrase to protect the "
     705             :                "imported object within the GnuPG system.");
     706           0 :       repeat = 1;
     707             :     }
     708             :   else
     709           0 :     desc = _("Please enter the passphrase or the PIN\n"
     710             :              "needed to complete this operation.");
     711             : 
     712           0 :   i18n_switchback (orig_codeset);
     713             : 
     714           0 :   err = gnupg_get_passphrase (NULL, NULL, _("Passphrase:"), desc,
     715             :                               repeat, repeat, 1, &pw);
     716           0 :   if (err)
     717             :     {
     718           0 :       if (gpg_err_code (err) == GPG_ERR_CANCELED
     719           0 :           || gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
     720           0 :         log_info (_("cancelled\n"));
     721             :       else
     722           0 :         log_error (_("error while asking for the passphrase: %s\n"),
     723             :                    gpg_strerror (err));
     724           0 :       agent_exit (0);
     725             :     }
     726           0 :   assert (pw);
     727             : 
     728           0 :   return pw;
     729             : }
     730             : 
     731             : 
     732             : static void
     733           0 : release_passphrase (char *pw)
     734             : {
     735           0 :   if (pw)
     736             :     {
     737           0 :       wipememory (pw, strlen (pw));
     738           0 :       xfree (pw);
     739             :     }
     740           0 : }
     741             : 
     742             : 
     743             : /* Stub function.  */
     744             : int
     745           0 : agent_key_available (const unsigned char *grip)
     746             : {
     747             :   (void)grip;
     748           0 :   return -1;  /* Not available.  */
     749             : }
     750             : 
     751             : char *
     752           0 : agent_get_cache (const char *key, cache_mode_t cache_mode)
     753             : {
     754             :   (void)key;
     755             :   (void)cache_mode;
     756           0 :   return NULL;
     757             : }
     758             : 
     759             : gpg_error_t
     760           0 : agent_askpin (ctrl_t ctrl,
     761             :               const char *desc_text, const char *prompt_text,
     762             :               const char *initial_errtext,
     763             :               struct pin_entry_info_s *pininfo,
     764             :               const char *keyinfo, cache_mode_t cache_mode)
     765             : {
     766             :   gpg_error_t err;
     767             :   unsigned char *passphrase;
     768             :   size_t size;
     769             : 
     770             :   (void)ctrl;
     771             :   (void)desc_text;
     772             :   (void)prompt_text;
     773             :   (void)initial_errtext;
     774             :   (void)keyinfo;
     775             :   (void)cache_mode;
     776             : 
     777           0 :   *pininfo->pin = 0; /* Reset the PIN. */
     778           0 :   passphrase = get_passphrase (0);
     779           0 :   size = strlen (passphrase);
     780           0 :   if (size >= pininfo->max_length)
     781           0 :     return gpg_error (GPG_ERR_TOO_LARGE);
     782             : 
     783           0 :   memcpy (&pininfo->pin, passphrase, size);
     784           0 :   xfree (passphrase);
     785           0 :   pininfo->pin[size] = 0;
     786           0 :   if (pininfo->check_cb)
     787             :     {
     788             :       /* More checks by utilizing the optional callback. */
     789           0 :       pininfo->cb_errtext = NULL;
     790           0 :       err = pininfo->check_cb (pininfo);
     791             :     }
     792             :   else
     793           0 :     err = 0;
     794           0 :   return err;
     795             : }
     796             : 
     797             : /* Replacement for the function in findkey.c.  Here we write the key
     798             :  * to stdout. */
     799             : int
     800           0 : agent_write_private_key (const unsigned char *grip,
     801             :                          const void *buffer, size_t length, int force)
     802             : {
     803             :   char hexgrip[40+4+1];
     804             :   char *p;
     805             : 
     806             :   (void)force;
     807             : 
     808           0 :   bin2hex (grip, 20, hexgrip);
     809           0 :   strcpy (hexgrip+40, ".key");
     810           0 :   p = make_advanced (buffer, length);
     811           0 :   if (p)
     812             :     {
     813           0 :       printf ("# Begin dump of %s\n%s%s# End dump of %s\n",
     814           0 :               hexgrip, p, (*p && p[strlen(p)-1] == '\n')? "":"\n", hexgrip);
     815           0 :       xfree (p);
     816             :     }
     817             : 
     818           0 :   return 0;
     819             : }

Generated by: LCOV version 1.11